|
27 | 27 |
|
28 | 28 | let projectList = getProjectList();
|
29 | 29 |
|
30 |
| - function getProjectList(): string[] { |
31 |
| - let list = []; |
| 30 | + // Returns a list, grouped by the optional study_area_name |
| 31 | + function getProjectList(): Map<string, string[]> { |
| 32 | + let perArea = new Map(); |
32 | 33 | for (let i = 0; i < window.localStorage.length; i++) {
|
33 | 34 | let key = window.localStorage.key(i)!;
|
34 | 35 | if (key.startsWith("ltn_")) {
|
35 |
| - list.push(key); |
| 36 | + let study_area_name = ""; |
| 37 | + try { |
| 38 | + let gj = JSON.parse(window.localStorage.getItem(key)!); |
| 39 | + study_area_name = gj.study_area_name; |
| 40 | + } catch (err) { |
| 41 | + // Ignore it |
| 42 | + } |
| 43 | +
|
| 44 | + if (!perArea.has(study_area_name)) { |
| 45 | + perArea.set(study_area_name, []); |
| 46 | + } |
| 47 | + perArea.get(study_area_name)!.push(key); |
36 | 48 | }
|
37 | 49 | }
|
38 |
| - list.sort(); |
39 |
| - return list; |
| 50 | + return perArea; |
40 | 51 | }
|
41 | 52 |
|
42 | 53 | let fileInput: HTMLInputElement;
|
|
99 | 110 |
|
100 | 111 | <p>Load a saved project:</p>
|
101 | 112 | <ul>
|
102 |
| - {#each projectList as project} |
103 |
| - <li> |
104 |
| - <span style="display: flex; justify-content: space-between;"> |
105 |
| - <Link on:click={() => loadProject(project)}> |
106 |
| - {project} |
107 |
| - </Link> |
108 |
| - <button class="secondary" on:click={() => renameProject(project)}> |
109 |
| - <img |
110 |
| - src={$lightMode ? editLight : editDark} |
111 |
| - alt="Rename project" |
112 |
| - /> |
113 |
| - </button> |
114 |
| - <button class="secondary" on:click={() => deleteProject(project)}> |
115 |
| - <img |
116 |
| - src={$lightMode ? deleteLight : deleteDark} |
117 |
| - alt="Delete project" |
118 |
| - /> |
119 |
| - </button> |
120 |
| - </span> |
121 |
| - </li> |
| 113 | + {#each projectList.entries() as [study_area_name, projects]} |
| 114 | + <u>{study_area_name ?? "custom area"}</u> |
| 115 | + {#each projects as project} |
| 116 | + <li> |
| 117 | + <span style="display: flex; justify-content: space-between;"> |
| 118 | + <Link on:click={() => loadProject(project)}> |
| 119 | + {project.slice("ltn_".length)} |
| 120 | + </Link> |
| 121 | + <button |
| 122 | + class="secondary" |
| 123 | + on:click={() => renameProject(project)} |
| 124 | + > |
| 125 | + <img |
| 126 | + src={$lightMode ? editLight : editDark} |
| 127 | + alt="Rename project" |
| 128 | + /> |
| 129 | + </button> |
| 130 | + <button |
| 131 | + class="secondary" |
| 132 | + on:click={() => deleteProject(project)} |
| 133 | + > |
| 134 | + <img |
| 135 | + src={$lightMode ? deleteLight : deleteDark} |
| 136 | + alt="Delete project" |
| 137 | + /> |
| 138 | + </button> |
| 139 | + </span> |
| 140 | + </li> |
| 141 | + {/each} |
122 | 142 | {/each}
|
123 | 143 | </ul>
|
124 | 144 |
|
|
0 commit comments