MapComplete/src/UI/History/AggregateView.svelte

142 lines
4.2 KiB
Svelte
Raw Normal View History

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"
2024-12-01 01:39:13 +01:00
import * as shared_questions from "../../assets/generated/layers/questions.json"
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
import Tr from "../Base/Tr.svelte"
import AccordionSingle from "../Flowbite/AccordionSingle.svelte"
import Translations from "../i18n/Translations"
import TagRenderingChart from "../BigComponents/TagRenderingChart"
import ToSvelte from "../Base/ToSvelte.svelte"
import type { TagRenderingConfigJson } from "../../Models/ThemeConfig/Json/TagRenderingConfigJson"
2024-11-25 23:44:26 +01:00
export let onlyShowUsername: string[]
2024-11-25 23:44:26 +01:00
export let features: Feature[]
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
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-04-26 22:06:59 +02:00
const trs = shared_questions.tagRenderings.map(
(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 {
2024-12-11 02:45:44 +01:00
return trs.find((tr) => tr.freeform?.key === 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 }[]
features: Feature[]
2024-12-11 02:45:44 +01:00
}[]
> = allDiffs.mapD((allDiffs) => {
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)) {
keyCounts.set(k, new Map<string, OsmObject[]>())
2024-11-25 23:44:26 +01:00
}
const valueCounts = keyCounts.get(k)
const v = diff.value ?? ""
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 }[]
features: Feature[]
2024-11-25 23:44:26 +01: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
})
let countForKey: Feature[] = []
for (const { features } of keyTotal) {
countForKey.push(...features)
2024-11-25 23:44:26 +01:00
}
keyTotal.sort((a, b) => b.features.length - a.features.length)
2024-12-01 01:39:13 +01:00
const tr = detectQuestion(key)
perKey.push({
2025-04-26 22:06:59 +02:00
count: countForKey.length,
tr,
key,
values: keyTotal.map(({ value, features }) => ({
value,
2025-04-26 22:06:59 +02:00
count: features.length,
})),
features: countForKey,
})
2024-11-25 23:44:26 +01:00
})
perKey.sort((a, b) => b.count - a.count)
return perKey
})
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>
{#if diff.tr}
2025-04-26 22:06:59 +02:00
<div class="h-48 w-48">
<ToSvelte
construct={new TagRenderingChart(diff.features, diff.tr, {
2025-04-26 22:06:59 +02:00
groupToOtherCutoff: 0,
chartType: "pie",
sort: true,
})}
/>
</div>
{:else}
Could not create a graph
{/if}
2024-12-01 01:39:13 +01:00
</AccordionSingle>
2024-11-25 23:44:26 +01:00
{/each}
{/if}