import Combine from "../Base/Combine" import { Store, UIEventSource } from "../../Logic/UIEventSource" import UserRelatedState from "../../Logic/State/UserRelatedState" import Translations from "../i18n/Translations" import { Utils } from "../../Utils" import { FlowStep } from "./FlowStep" import Title from "../Base/Title" import BaseUIElement from "../BaseUIElement" import Histogram from "../BigComponents/Histogram" import Toggleable from "../Base/Toggleable" import List from "../Base/List" import CheckBoxes from "../Input/Checkboxes" /** * Shows the attributes by value, requests to check them of */ export class PreviewAttributesPanel extends Combine implements FlowStep<{ features: { properties: any; geometry: { coordinates: [number, number] } }[] }> { public readonly IsValid: Store public readonly Value: Store<{ features: { properties: any; geometry: { coordinates: [number, number] } }[] }> constructor( state: UserRelatedState, geojson: { features: { properties: any; geometry: { coordinates: [number, number] } }[] } ) { const t = Translations.t.importHelper.previewAttributes const propertyKeys = new Set() for (const f of geojson.features) { Object.keys(f.properties).forEach((key) => propertyKeys.add(key)) } const attributeOverview: BaseUIElement[] = [] const n = geojson.features.length for (const key of Array.from(propertyKeys)) { const values = Utils.NoNull(geojson.features.map((f) => f.properties[key])) const allSame = !values.some((v) => v !== values[0]) let countSummary: BaseUIElement if (values.length === n) { countSummary = t.allAttributesSame } else { countSummary = t.someHaveSame.Subs({ count: values.length, percentage: Math.floor((100 * values.length) / n), }) } if (allSame) { attributeOverview.push(new Title(key + "=" + values[0])) attributeOverview.push(countSummary) continue } const uniqueCount = new Set(values).size if (uniqueCount !== values.length && uniqueCount < 15) { attributeOverview.push() // There are some overlapping values: histogram time! let hist: BaseUIElement = new Combine([ countSummary, new Histogram(new UIEventSource(values), "Value", "Occurence", { sortMode: "count-rev", }), ]).SetClass("flex flex-col") const title = new Title(key + "=*") if (uniqueCount > 15) { hist = new Toggleable(title, hist.SetClass("block")).Collapse() } else { attributeOverview.push(title) } attributeOverview.push(hist) continue } // All values are different or too much unique values, we add a boring (but collapsable) list attributeOverview.push( new Toggleable(new Title(key + "=*"), new Combine([countSummary, new List(values)])) ) } const confirm = new CheckBoxes([t.inspectLooksCorrect]) super([ new Title(t.inspectDataTitle.Subs({ count: geojson.features.length })), "Extra remark: An attribute with 'source' or 'src' will be added as 'source' into the map pin; an attribute 'note' will be added into the map pin as well. These values won't be imported", ...attributeOverview, confirm, ]) this.Value = new UIEventSource<{ features: { properties: any; geometry: { coordinates: [number, number] } }[] }>(geojson) this.IsValid = confirm.GetValue().map((selected) => selected.length == 1) } }