| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  | <script lang="ts"> | 
					
						
							|  |  |  |   import type { Feature } from "geojson" | 
					
						
							|  |  |  |   import { Store, UIEventSource } from "../../Logic/UIEventSource" | 
					
						
							|  |  |  |   import OsmObjectDownloader from "../../Logic/Osm/OsmObjectDownloader" | 
					
						
							|  |  |  |   import { OsmObject } from "../../Logic/Osm/OsmObject" | 
					
						
							|  |  |  |   import Loading from "../Base/Loading.svelte" | 
					
						
							|  |  |  |   import { HistoryUtils } from "./HistoryUtils" | 
					
						
							| 
									
										
										
										
											2025-05-26 11:50:23 +02:00
										 |  |  |   import * as favourite from "../../../public/assets/generated/layers/favourite.json" | 
					
						
							| 
									
										
										
										
											2024-12-01 01:39:13 +01:00
										 |  |  |   import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig" | 
					
						
							|  |  |  |   import Tr from "../Base/Tr.svelte" | 
					
						
							|  |  |  |   import AccordionSingle from "../Flowbite/AccordionSingle.svelte" | 
					
						
							| 
									
										
										
										
											2024-12-04 18:48:05 +01:00
										 |  |  |   import Translations from "../i18n/Translations" | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |   import TagRenderingChart from "../BigComponents/TagRenderingChart" | 
					
						
							|  |  |  |   import ToSvelte from "../Base/ToSvelte.svelte" | 
					
						
							|  |  |  |   import type { TagRenderingConfigJson } from "../../Models/ThemeConfig/Json/TagRenderingConfigJson" | 
					
						
							| 
									
										
										
										
											2025-05-26 11:50:23 +02:00
										 |  |  |   import { Or } from "../../Logic/Tags/Or" | 
					
						
							|  |  |  |   import { Utils } from "../../Utils" | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 18:48:05 +01:00
										 |  |  |   export let onlyShowUsername: string[] | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |   export let features: Feature[] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 18:48:05 +01:00
										 |  |  |   let usernames = new Set(onlyShowUsername) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |   const downloader = new OsmObjectDownloader() | 
					
						
							|  |  |  |   let allHistories: UIEventSource<OsmObject[][]> = UIEventSource.FromPromise( | 
					
						
							| 
									
										
										
										
											2024-12-11 02:45:44 +01:00
										 |  |  |     Promise.all(features.map((f) => downloader.downloadHistory(f.properties.id))) | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |   ) | 
					
						
							| 
									
										
										
										
											2024-12-11 02:45:44 +01:00
										 |  |  |   let allDiffs: Store< | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       key: string | 
					
						
							|  |  |  |       value?: string | 
					
						
							|  |  |  |       oldValue?: string | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |       step: OsmObject | 
					
						
							| 
									
										
										
										
											2024-12-11 02:45:44 +01:00
										 |  |  |     }[] | 
					
						
							|  |  |  |   > = allHistories.mapD((histories) => HistoryUtils.fullHistoryDiff(histories, usernames)) | 
					
						
							| 
									
										
										
										
											2024-12-01 01:39:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-26 11:50:23 +02:00
										 |  |  |   // We use the favourite-layer as it contains _all_ questions | 
					
						
							|  |  |  |   const trs = favourite.tagRenderings.map( | 
					
						
							| 
									
										
										
										
											2025-04-26 22:06:59 +02:00
										 |  |  |     (tr) => new TagRenderingConfig(<TagRenderingConfigJson>tr) | 
					
						
							|  |  |  |   ) | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-01 01:39:13 +01:00
										 |  |  |   function detectQuestion(key: string): TagRenderingConfig { | 
					
						
							| 
									
										
										
										
											2025-05-26 11:50:23 +02:00
										 |  |  |     const byKey = trs.find((tr) => tr.freeform?.key === key) | 
					
						
							|  |  |  |     if (byKey) { | 
					
						
							|  |  |  |       return byKey | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-06-04 00:21:28 +02:00
										 |  |  |     return trs.find((tr) => | 
					
						
							|  |  |  |       tr.mappings.some((mapping) => { | 
					
						
							|  |  |  |         const ifTags = Or.construct(Utils.NoNull([mapping.if, mapping.alsoShowIf])) | 
					
						
							|  |  |  |         const keys = ifTags.usedKeys() | 
					
						
							|  |  |  |         return keys.some((k) => k == key) | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-12-01 01:39:13 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-11 02:45:44 +01:00
										 |  |  |   const mergedCount: Store< | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       key: string | 
					
						
							|  |  |  |       tr: TagRenderingConfig | 
					
						
							|  |  |  |       count: number | 
					
						
							|  |  |  |       values: { value: string; count: number }[] | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |       features: Feature[] | 
					
						
							| 
									
										
										
										
											2024-12-11 02:45:44 +01:00
										 |  |  |     }[] | 
					
						
							|  |  |  |   > = allDiffs.mapD((allDiffs) => { | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |     const keyCounts = new Map<string, Map<string, OsmObject[]>>() | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |     for (const diff of allDiffs) { | 
					
						
							|  |  |  |       const k = diff.key | 
					
						
							| 
									
										
										
										
											2024-12-01 01:39:13 +01:00
										 |  |  |       if (!keyCounts.has(k)) { | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |         keyCounts.set(k, new Map<string, OsmObject[]>()) | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |       const valueCounts = keyCounts.get(k) | 
					
						
							|  |  |  |       const v = diff.value ?? "" | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |       const oldFeaturesList = valueCounts.get(v) ?? [] | 
					
						
							|  |  |  |       valueCounts.set(v, [...oldFeaturesList, diff.step]) | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-01 01:39:13 +01:00
										 |  |  |     const perKey: { | 
					
						
							| 
									
										
										
										
											2024-12-11 02:45:44 +01:00
										 |  |  |       key: string | 
					
						
							|  |  |  |       tr: TagRenderingConfig | 
					
						
							|  |  |  |       count: number | 
					
						
							|  |  |  |       values: { value: string; count: number }[] | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |       features: Feature[] | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |     }[] = [] | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |     keyCounts.forEach((values: Map<string, OsmObject[]>, key: string) => { | 
					
						
							|  |  |  |       const keyTotal: { value: string; features: Feature[] }[] = [] | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |       values.forEach((count, value) => { | 
					
						
							| 
									
										
										
										
											2025-04-26 22:06:59 +02:00
										 |  |  |         keyTotal.push({ value, features: count.map((step) => step.asGeoJson()) }) | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |       let countForKey: Feature[] = [] | 
					
						
							|  |  |  |       for (const { features } of keyTotal) { | 
					
						
							|  |  |  |         countForKey.push(...features) | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |       keyTotal.sort((a, b) => b.features.length - a.features.length) | 
					
						
							| 
									
										
										
										
											2024-12-01 01:39:13 +01:00
										 |  |  |       const tr = detectQuestion(key) | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |       perKey.push({ | 
					
						
							| 
									
										
										
										
											2025-04-26 22:06:59 +02:00
										 |  |  |         count: countForKey.length, | 
					
						
							|  |  |  |         tr, | 
					
						
							|  |  |  |         key, | 
					
						
							|  |  |  |         values: keyTotal.map(({ value, features }) => ({ | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |           value, | 
					
						
							| 
									
										
										
										
											2025-04-26 22:06:59 +02:00
										 |  |  |           count: features.length, | 
					
						
							|  |  |  |         })), | 
					
						
							|  |  |  |         features: countForKey, | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |     }) | 
					
						
							|  |  |  |     perKey.sort((a, b) => b.count - a.count) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return perKey | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 18:48:05 +01:00
										 |  |  |   const t = Translations.t.inspector | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {#if allHistories === undefined} | 
					
						
							|  |  |  |   <Loading /> | 
					
						
							|  |  |  | {:else if $allDiffs !== undefined} | 
					
						
							|  |  |  |   {#each $mergedCount as diff} | 
					
						
							| 
									
										
										
										
											2024-12-01 01:39:13 +01:00
										 |  |  |     <h3> | 
					
						
							|  |  |  |       {#if diff.tr} | 
					
						
							|  |  |  |         <Tr t={diff.tr.question} /> | 
					
						
							|  |  |  |       {:else} | 
					
						
							|  |  |  |         {diff.key} | 
					
						
							|  |  |  |       {/if} | 
					
						
							|  |  |  |     </h3> | 
					
						
							|  |  |  |     <AccordionSingle> | 
					
						
							|  |  |  |       <span slot="header"> | 
					
						
							| 
									
										
										
										
											2024-12-11 02:45:44 +01:00
										 |  |  |         <Tr t={t.answeredCountTimes.Subs(diff)} /> | 
					
						
							| 
									
										
										
										
											2024-12-01 01:39:13 +01:00
										 |  |  |       </span> | 
					
						
							|  |  |  |       <ul> | 
					
						
							|  |  |  |         {#each diff.values as value} | 
					
						
							|  |  |  |           <li> | 
					
						
							|  |  |  |             <b>{value.value}</b> | 
					
						
							|  |  |  |             {#if value.count > 1} | 
					
						
							|  |  |  |               - {value.count} | 
					
						
							|  |  |  |             {/if} | 
					
						
							|  |  |  |           </li> | 
					
						
							|  |  |  |         {/each} | 
					
						
							|  |  |  |       </ul> | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |       {#if diff.tr} | 
					
						
							| 
									
										
										
										
											2025-04-26 22:06:59 +02:00
										 |  |  |         <div class="h-48 w-48"> | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |           <ToSvelte | 
					
						
							|  |  |  |             construct={new TagRenderingChart(diff.features, diff.tr, { | 
					
						
							| 
									
										
										
										
											2025-04-26 22:06:59 +02:00
										 |  |  |               groupToOtherCutoff: 0, | 
					
						
							|  |  |  |               chartType: "pie", | 
					
						
							|  |  |  |               sort: true, | 
					
						
							|  |  |  |             })} | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |           /> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       {:else} | 
					
						
							| 
									
										
										
										
											2025-05-26 11:50:23 +02:00
										 |  |  |         Could not create a graph - this item type has no associated question | 
					
						
							| 
									
										
										
										
											2025-04-25 18:04:25 +02:00
										 |  |  |       {/if} | 
					
						
							| 
									
										
										
										
											2024-12-01 01:39:13 +01:00
										 |  |  |     </AccordionSingle> | 
					
						
							| 
									
										
										
										
											2024-11-25 23:44:26 +01:00
										 |  |  |   {/each} | 
					
						
							|  |  |  | {/if} |