forked from MapComplete/MapComplete
chore: automated housekeeping...
This commit is contained in:
parent
14b2799f08
commit
4add2d1aff
151 changed files with 4561 additions and 3315 deletions
|
|
@ -3,7 +3,6 @@
|
|||
* Allows to search through wikidata and to select one value
|
||||
*/
|
||||
|
||||
|
||||
import Translations from "../../i18n/Translations"
|
||||
import Tr from "../../Base/Tr.svelte"
|
||||
import { ImmutableStore, Store, Stores, UIEventSource } from "../../../Logic/UIEventSource"
|
||||
|
|
@ -30,13 +29,13 @@
|
|||
let selectedMany: Record<string, boolean> = {}
|
||||
let previouslySeen = new Map<string, WikidataResponse>()
|
||||
|
||||
$:{
|
||||
$: {
|
||||
if (selectedWikidataSingle) {
|
||||
value.setData(selectedWikidataSingle.id)
|
||||
}
|
||||
}
|
||||
|
||||
$:{
|
||||
$: {
|
||||
const v = []
|
||||
for (const id in selectedMany) {
|
||||
if (selectedMany[id]) {
|
||||
|
|
@ -46,11 +45,10 @@
|
|||
value.setData(v.join(";"))
|
||||
}
|
||||
|
||||
|
||||
let tooShort = new ImmutableStore<{ success: WikidataResponse[] }>({ success: undefined })
|
||||
|
||||
let searchResult: Store<{ success?: WikidataResponse[]; error?: any }> = searchValue
|
||||
.bind((searchText) => {
|
||||
let searchResult: Store<{ success?: WikidataResponse[]; error?: any }> = searchValue.bind(
|
||||
(searchText) => {
|
||||
if (searchText.length < 3 && !searchText.match(/[qQ][0-9]+/)) {
|
||||
return tooShort
|
||||
}
|
||||
|
|
@ -62,18 +60,19 @@
|
|||
lang,
|
||||
maxCount: 5,
|
||||
notInstanceOf,
|
||||
instanceOf
|
||||
instanceOf,
|
||||
})
|
||||
WikidataValidator._searchCache.set(key, promise)
|
||||
}
|
||||
return Stores.FromPromiseWithErr(promise)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
let selectedWithoutSearch: Store<WikidataResponse[]> = searchResult.map(sr => {
|
||||
let selectedWithoutSearch: Store<WikidataResponse[]> = searchResult.map((sr) => {
|
||||
for (const wikidataItem of sr?.success ?? []) {
|
||||
previouslySeen.set(wikidataItem.id, wikidataItem)
|
||||
}
|
||||
let knownIds: Set<string> = new Set(sr?.success?.map(item => item.id))
|
||||
let knownIds: Set<string> = new Set(sr?.success?.map((item) => item.id))
|
||||
const seen = [selectedWikidataSingle]
|
||||
for (const id in selectedMany) {
|
||||
if (selectedMany[id]) {
|
||||
|
|
@ -81,9 +80,8 @@
|
|||
seen.push(item)
|
||||
}
|
||||
}
|
||||
return Utils.NoNull(seen).filter(i => !knownIds.has(i.id))
|
||||
return Utils.NoNull(seen).filter((i) => !knownIds.has(i.id))
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<h3>
|
||||
|
|
@ -91,33 +89,37 @@
|
|||
</h3>
|
||||
|
||||
<form>
|
||||
<SearchField {searchValue} placeholderText={placeholder}></SearchField>
|
||||
<SearchField {searchValue} placeholderText={placeholder} />
|
||||
|
||||
{#if $searchValue.trim().length === 0}
|
||||
<Tr cls="w-full flex justify-center p-4" t={ t.doSearch} />
|
||||
<Tr cls="w-full flex justify-center p-4" t={t.doSearch} />
|
||||
{:else if $searchValue.trim().length < 3}
|
||||
<Tr t={ t.searchToShort} />
|
||||
<Tr t={t.searchToShort} />
|
||||
{:else if $searchResult === undefined}
|
||||
<div class="w-full flex justify-center p-4">
|
||||
<div class="flex w-full justify-center p-4">
|
||||
<Loading>
|
||||
<Tr t={Translations.t.general.loading} />
|
||||
</Loading>
|
||||
</div>
|
||||
{:else if $searchResult.error !== undefined}
|
||||
<div class="w-full flex justify-center p-4">
|
||||
<div class="flex w-full justify-center p-4">
|
||||
<Tr cls="alert" t={t.failed} />
|
||||
</div>
|
||||
{:else if $searchResult.success}
|
||||
{#if $searchResult.success.length === 0}
|
||||
<Tr cls="w-full flex justify-center p-4" t={ t.noResults.Subs({search: $searchValue})} />
|
||||
<Tr cls="w-full flex justify-center p-4" t={t.noResults.Subs({ search: $searchValue })} />
|
||||
{:else}
|
||||
{#each $searchResult.success as wikidata}
|
||||
|
||||
<label class="low-interaction m-4 p-2 rounded-xl flex items-center">
|
||||
<label class="low-interaction m-4 flex items-center rounded-xl p-2">
|
||||
{#if allowMultiple}
|
||||
<input type="checkbox" bind:checked={selectedMany[wikidata.id]} />
|
||||
{:else}
|
||||
<input type="radio" name="selectedWikidata" value={wikidata} bind:group={selectedWikidataSingle} />
|
||||
<input
|
||||
type="radio"
|
||||
name="selectedWikidata"
|
||||
value={wikidata}
|
||||
bind:group={selectedWikidataSingle}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<Wikidatapreview {wikidata} />
|
||||
|
|
@ -127,17 +129,19 @@
|
|||
{/if}
|
||||
|
||||
{#each $selectedWithoutSearch as wikidata}
|
||||
|
||||
<label class="low-interaction m-4 p-2 rounded-xl flex items-center">
|
||||
<label class="low-interaction m-4 flex items-center rounded-xl p-2">
|
||||
{#if allowMultiple}
|
||||
<input type="checkbox" bind:checked={selectedMany[wikidata.id]} />
|
||||
{:else}
|
||||
<input type="radio" name="selectedWikidata" value={wikidata} bind:group={selectedWikidataSingle} />
|
||||
<input
|
||||
type="radio"
|
||||
name="selectedWikidata"
|
||||
value={wikidata}
|
||||
bind:group={selectedWikidataSingle}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<Wikidatapreview {wikidata} />
|
||||
</label>
|
||||
{/each}
|
||||
|
||||
</form>
|
||||
|
||||
|
|
|
|||
|
|
@ -28,13 +28,15 @@
|
|||
export let feature: Feature
|
||||
export let args: (string | number | boolean)[] = undefined
|
||||
export let state: SpecialVisualizationState
|
||||
|
||||
</script>
|
||||
|
||||
{#if type === "translation"}
|
||||
<TranslationInput {value} on:submit {args} />
|
||||
{:else if type === "direction"}
|
||||
<DirectionInput {value} mapProperties={InputHelpers.constructMapProperties( { feature, args: args ?? [] })} />
|
||||
<DirectionInput
|
||||
{value}
|
||||
mapProperties={InputHelpers.constructMapProperties({ feature, args: args ?? [] })}
|
||||
/>
|
||||
{:else if type === "date"}
|
||||
<DateInput {value} />
|
||||
{:else if type === "color"}
|
||||
|
|
@ -50,5 +52,5 @@
|
|||
{:else if type === "slope"}
|
||||
<SlopeInput {value} {feature} {state} />
|
||||
{:else if type === "wikidata"}
|
||||
<WikidataInputHelper {value} {feature} {state} {args}/>
|
||||
<WikidataInputHelper {value} {feature} {state} {args} />
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,4 @@ export default class InputHelpers {
|
|||
}
|
||||
return mapProperties
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
preferredFiltered = preferredLanguages?.filter((l) => availableLanguages.indexOf(l) >= 0)
|
||||
})
|
||||
|
||||
|
||||
export let clss: string = undefined
|
||||
let current = Locale.language
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -100,9 +100,10 @@ export default class Validators {
|
|||
private static _byType = Validators._byTypeConstructor()
|
||||
|
||||
public static HelpText(): string {
|
||||
const explanations: string[] = Validators.AllValidators.flatMap((type) =>
|
||||
["### "+type.name, type.explanation]
|
||||
)
|
||||
const explanations: string[] = Validators.AllValidators.flatMap((type) => [
|
||||
"### " + type.name,
|
||||
type.explanation,
|
||||
])
|
||||
return [
|
||||
"# Available types for text fields",
|
||||
"The listed types here trigger a special input element. Use them in `tagrendering.freeform.type` of your tagrendering to activate them",
|
||||
|
|
|
|||
|
|
@ -3,12 +3,18 @@ import { Translation } from "../../i18n/Translation"
|
|||
import Translations from "../../i18n/Translations"
|
||||
|
||||
export default class StringValidator extends Validator {
|
||||
|
||||
constructor(type?: string, doc?: string, inputmode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search", textArea?: boolean) {
|
||||
super(type ?? "string",
|
||||
constructor(
|
||||
type?: string,
|
||||
doc?: string,
|
||||
inputmode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search",
|
||||
textArea?: boolean
|
||||
) {
|
||||
super(
|
||||
type ?? "string",
|
||||
doc ?? "A simple piece of text which is at most 255 characters long",
|
||||
inputmode,
|
||||
textArea)
|
||||
textArea
|
||||
)
|
||||
}
|
||||
|
||||
isValid(s: string): boolean {
|
||||
|
|
|
|||
|
|
@ -42,8 +42,10 @@ export default class WikidataValidator extends Validator {
|
|||
"notInstanceof",
|
||||
"A list of Q-identifiers which indicates that the search results _must not_ be an entity of this type, e.g. [`Q79007`](https://www.wikidata.org/wiki/Q79007) to filter away all streets from the search results",
|
||||
],
|
||||
["multiple",
|
||||
"If 'yes' or 'true', will allow to select multiple values at once"]
|
||||
[
|
||||
"multiple",
|
||||
"If 'yes' or 'true', will allow to select multiple values at once",
|
||||
],
|
||||
]
|
||||
),
|
||||
]),
|
||||
|
|
@ -145,7 +147,12 @@ Another example is to search for species and trees:
|
|||
* WikidataValidator.removePostAndPrefixes("Elf-Julistraat", [], {"nl":["straat", "laan"], "en": ["street"]}, "nl") // => "Elf-Juli"
|
||||
* WikidataValidator.removePostAndPrefixes("Elf-Julistraat", [], {"nl":["straat", "laan"], "en": ["street"]}, "en") // => "Elf-Julistraat"
|
||||
*/
|
||||
public static removePostAndPrefixes(searchTerm: string, prefixesToRemove: string[] | Record<string, string[]>, postfixesToRemove: string[] | Record<string, string[]>, language: string): string {
|
||||
public static removePostAndPrefixes(
|
||||
searchTerm: string,
|
||||
prefixesToRemove: string[] | Record<string, string[]>,
|
||||
postfixesToRemove: string[] | Record<string, string[]>,
|
||||
language: string
|
||||
): string {
|
||||
const prefixes = prefixesToRemove
|
||||
const postfixes = postfixesToRemove
|
||||
const prefixesUnwrapped: RegExp[] = (
|
||||
|
|
@ -156,7 +163,6 @@ Another example is to search for species and trees:
|
|||
Array.isArray(postfixes) ? postfixes : postfixes[language] ?? []
|
||||
).map((s) => new RegExp(s + "$", "i"))
|
||||
|
||||
|
||||
let clipped = searchTerm.trim()
|
||||
|
||||
for (const postfix of postfixesUnwrapped) {
|
||||
|
|
|
|||
|
|
@ -1,57 +1,57 @@
|
|||
<script lang="ts">/**
|
||||
<script lang="ts">
|
||||
/**
|
||||
*
|
||||
Wrapper around 'WikidataInput.svelte' which handles the arguments
|
||||
*/
|
||||
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import Locale from "../i18n/Locale"
|
||||
import { Utils } from "../../Utils"
|
||||
import Wikidata from "../../Logic/Web/Wikidata"
|
||||
import WikidataInput from "./Helpers/WikidataInput.svelte"
|
||||
import type { Feature } from "geojson"
|
||||
import { onDestroy } from "svelte"
|
||||
import WikidataValidator from "./Validators/WikidataValidator"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import Locale from "../i18n/Locale"
|
||||
import { Utils } from "../../Utils"
|
||||
import Wikidata from "../../Logic/Web/Wikidata"
|
||||
import WikidataInput from "./Helpers/WikidataInput.svelte"
|
||||
import type { Feature } from "geojson"
|
||||
import { onDestroy } from "svelte"
|
||||
import WikidataValidator from "./Validators/WikidataValidator"
|
||||
|
||||
export let args: (string | number | boolean)[] = []
|
||||
export let feature: Feature
|
||||
export let args: (string | number | boolean)[] = []
|
||||
export let feature: Feature
|
||||
|
||||
export let value: UIEventSource<string>
|
||||
export let value: UIEventSource<string>
|
||||
|
||||
let searchKey: string = <string>args[0] ?? "name"
|
||||
let searchKey: string = <string>args[0] ?? "name"
|
||||
|
||||
let searchFor: string =
|
||||
searchKey
|
||||
.split(";")
|
||||
.map((k) => feature?.properties[k]?.toLowerCase())
|
||||
.find((foundValue) => !!foundValue) ?? ""
|
||||
let searchFor: string =
|
||||
searchKey
|
||||
.split(";")
|
||||
.map((k) => feature?.properties[k]?.toLowerCase())
|
||||
.find((foundValue) => !!foundValue) ?? ""
|
||||
|
||||
const options: any = args[1]
|
||||
const options: any = args[1]
|
||||
|
||||
let searchForValue: UIEventSource<string> = new UIEventSource(searchFor)
|
||||
let searchForValue: UIEventSource<string> = new UIEventSource(searchFor)
|
||||
|
||||
onDestroy(
|
||||
Locale.language.addCallbackAndRunD(lg => {
|
||||
console.log(options)
|
||||
if (searchFor !== undefined && options !== undefined) {
|
||||
const post = options["removePostfixes"] ?? []
|
||||
const pre = options["removePrefixes"] ?? []
|
||||
const clipped = WikidataValidator.removePostAndPrefixes(searchFor, pre, post, lg)
|
||||
console.log("Got clipped value:", clipped, post, pre)
|
||||
searchForValue.setData(clipped)
|
||||
}
|
||||
})
|
||||
)
|
||||
onDestroy(
|
||||
Locale.language.addCallbackAndRunD((lg) => {
|
||||
console.log(options)
|
||||
if (searchFor !== undefined && options !== undefined) {
|
||||
const post = options["removePostfixes"] ?? []
|
||||
const pre = options["removePrefixes"] ?? []
|
||||
const clipped = WikidataValidator.removePostAndPrefixes(searchFor, pre, post, lg)
|
||||
console.log("Got clipped value:", clipped, post, pre)
|
||||
searchForValue.setData(clipped)
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
let instanceOf: number[] = Utils.NoNull(
|
||||
(options?.instanceOf ?? []).map((i) => Wikidata.QIdToNumber(i))
|
||||
)
|
||||
let notInstanceOf: number[] = Utils.NoNull(
|
||||
(options?.notInstanceOf ?? []).map((i) => Wikidata.QIdToNumber(i))
|
||||
)
|
||||
|
||||
let instanceOf: number[] = Utils.NoNull(
|
||||
(options?.instanceOf ?? []).map((i) => Wikidata.QIdToNumber(i))
|
||||
)
|
||||
let notInstanceOf: number[] = Utils.NoNull(
|
||||
(options?.notInstanceOf ?? []).map((i) => Wikidata.QIdToNumber(i))
|
||||
)
|
||||
|
||||
let allowMultipleArg = options?.["multiple"]
|
||||
let allowMultiple = allowMultipleArg === "yes" || (""+allowMultipleArg) === "true"
|
||||
let allowMultipleArg = options?.["multiple"]
|
||||
let allowMultiple = allowMultipleArg === "yes" || "" + allowMultipleArg === "true"
|
||||
</script>
|
||||
|
||||
<WikidataInput searchValue={searchForValue} {value} {instanceOf} {notInstanceOf} {allowMultiple}/>
|
||||
<WikidataInput searchValue={searchForValue} {value} {instanceOf} {notInstanceOf} {allowMultiple} />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue