From f2fca2dad8576a18629591e886e511912c1d99e9 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sat, 14 Sep 2024 20:40:32 +0200 Subject: [PATCH 01/30] Fix: fix #2142 --- src/UI/InputElement/Helpers/OpeningHours/OHTable.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/UI/InputElement/Helpers/OpeningHours/OHTable.svelte b/src/UI/InputElement/Helpers/OpeningHours/OHTable.svelte index a95f1d383..9d845dafe 100644 --- a/src/UI/InputElement/Helpers/OpeningHours/OHTable.svelte +++ b/src/UI/InputElement/Helpers/OpeningHours/OHTable.svelte @@ -220,8 +220,8 @@ {/if} {#each range(7) as wd} - startSelection(wd, h)} on:end={() => endSelection(wd, h)} - on:move={() => moved(wd, h)} on:clear={() => clearSelection()} /> + startSelection(wd, h + 0.5)} on:end={() => endSelection(wd, h + 0.5)} + on:move={() => moved(wd, h + 0.5)} on:clear={() => clearSelection()} /> {/each} From 9b82a5ef63913e54a0d971fbd9b950b6bdd3df2e Mon Sep 17 00:00:00 2001 From: danieldegroot2 Date: Sat, 14 Sep 2024 15:12:04 +0000 Subject: [PATCH 02/30] Translated using Weblate (English) Currently translated at 100.0% (682 of 682 strings) Translation: MapComplete/Core Translate-URL: https://hosted.weblate.org/projects/mapcomplete/core/en/ --- langs/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/langs/en.json b/langs/en.json index 7f468f8e3..94170812d 100644 --- a/langs/en.json +++ b/langs/en.json @@ -618,7 +618,7 @@ "#": "These texts are shown above the theme buttons when no theme is loaded", "about": "About MapComplete", "featuredThemeTitle": "Featured this week", - "intro": "Maps about various topics which you contribute to", + "intro": "Maps about various topics which you can contribute to", "learnMore": "Learn more", "logIn": "Log in to see other themes you previously visited", "pickTheme": "Pick a theme below to get started.", @@ -873,4 +873,4 @@ "startsWithQ": "A wikidata identifier starts with Q and is followed by a number" } } -} \ No newline at end of file +} From f4d306e3ed2294f288327d9bb914d5df4a092384 Mon Sep 17 00:00:00 2001 From: kjon Date: Fri, 13 Sep 2024 18:57:57 +0000 Subject: [PATCH 03/30] Translated using Weblate (German) Currently translated at 99.8% (681 of 682 strings) Translation: MapComplete/Core Translate-URL: https://hosted.weblate.org/projects/mapcomplete/core/de/ --- langs/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langs/de.json b/langs/de.json index 984be656c..17670ef1e 100644 --- a/langs/de.json +++ b/langs/de.json @@ -194,7 +194,7 @@ "josmNotOpened": "JOSM konnte nicht erreicht werden. Bitte sicherstellen, dass das Programm geöffnet und Remote Control aktiviert ist", "josmOpened": "JOSM ist geöffnet", "madeBy": "Erstellt von {author}", - "mapContributionsBy": "Die angezeigten Daten wurden bearbeitet durch {contributors}", + "mapContributionsBy": "Angezeigte Daten wurden bearbeitet durch {contributors}", "mapContributionsByAndHidden": "Die angezeigten Daten wurden bearbeitet von {contributors} und {hiddenCount} weiteren Beitragenden", "mapDataByOsm": "Kartendaten: OpenStreetMap", "mapillaryHelp": "Mapillary ist ein Online-Dienst, der Straßenbilder sammelt und sie unter einer freien Lizenz anbietet. Mitwirkende dürfen diese Bilder verwenden, um OpenStreetMap zu verbessern", From 69094bb58f71328be9f388426d698718b82bd98c Mon Sep 17 00:00:00 2001 From: danieldegroot2 Date: Sat, 14 Sep 2024 15:12:05 +0000 Subject: [PATCH 04/30] Translated using Weblate (Spanish) Currently translated at 64.8% (442 of 682 strings) Translation: MapComplete/Core Translate-URL: https://hosted.weblate.org/projects/mapcomplete/core/es/ --- langs/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langs/es.json b/langs/es.json index a749a08a7..8526a6eb0 100644 --- a/langs/es.json +++ b/langs/es.json @@ -592,4 +592,4 @@ "description": "Un identificador de Wikidata" } } -} \ No newline at end of file +} From 075363534cc895b28ea730ead311bfb3149f9587 Mon Sep 17 00:00:00 2001 From: danieldegroot2 Date: Sat, 14 Sep 2024 15:12:05 +0000 Subject: [PATCH 05/30] Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 96.3% (657 of 682 strings) Translation: MapComplete/Core Translate-URL: https://hosted.weblate.org/projects/mapcomplete/core/zh_Hant/ --- langs/zh_Hant.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langs/zh_Hant.json b/langs/zh_Hant.json index 2027183fc..c8a747652 100644 --- a/langs/zh_Hant.json +++ b/langs/zh_Hant.json @@ -848,4 +848,4 @@ "startsWithQ": "維基數據編號以 Q 開頭後面接數字" } } -} \ No newline at end of file +} From 085c087c26d880eb96edb588e73e7d6b17f3ffa9 Mon Sep 17 00:00:00 2001 From: danieldegroot2 Date: Sat, 14 Sep 2024 15:12:05 +0000 Subject: [PATCH 06/30] Translated using Weblate (Czech) Currently translated at 98.0% (669 of 682 strings) Translation: MapComplete/Core Translate-URL: https://hosted.weblate.org/projects/mapcomplete/core/cs/ --- langs/cs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langs/cs.json b/langs/cs.json index 121337b98..e5294a30c 100644 --- a/langs/cs.json +++ b/langs/cs.json @@ -859,4 +859,4 @@ "startsWithQ": "Identifikátor wikidat začíná písmenem Q a následuje za ním číslo" } } -} \ No newline at end of file +} From 7ca93034b437a6b783caf312026c9c03d39a7754 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Sat, 14 Sep 2024 16:06:58 +0000 Subject: [PATCH 07/30] Translated using Weblate (Spanish) Currently translated at 65.1% (444 of 682 strings) Translation: MapComplete/Core Translate-URL: https://hosted.weblate.org/projects/mapcomplete/core/es/ --- langs/es.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/langs/es.json b/langs/es.json index 8526a6eb0..e615ea35d 100644 --- a/langs/es.json +++ b/langs/es.json @@ -420,7 +420,8 @@ "index": { "#": "Estos textos son mostrados sobre los botones del tema cuando no hay un tema cargado", "featuredThemeTitle": "Esta semana destacamos", - "intro": "Mapas sobre diversos temas a los que contribuye", + "intro": "Mapas sobre diversos temas a los que puedes contribuir", + "learnMore": "Más información", "logIn": "Inicia sesión para ver otros temas que visitaste anteriormente", "pickTheme": "Elige un tema de abajo para empezar.", "title": "MapComplete" From 2443717b56f0f54a6985ee5e5ad7dcb55ac62ab1 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Sat, 14 Sep 2024 16:07:45 +0000 Subject: [PATCH 08/30] Translated using Weblate (Spanish) Currently translated at 95.8% (434 of 453 strings) Translation: MapComplete/themes Translate-URL: https://hosted.weblate.org/projects/mapcomplete/themes/es/ --- langs/themes/es.json | 68 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/langs/themes/es.json b/langs/themes/es.json index ef19ec679..f4e86d351 100644 --- a/langs/themes/es.json +++ b/langs/themes/es.json @@ -808,6 +808,72 @@ "description": "Los faros son edificios altos con una luz en la parte superior para guiar el tráfico marítimo.", "title": "Faros" }, + "mapcomplete-changes": { + "description": "Este mapa muestra todos los cambios realizados con MapComplete", + "layers": { + "0": { + "description": "Muestra todos los cambios de MapComplete", + "filter": { + "0": { + "options": { + "0": { + "question": "El nombre contiene {search}" + } + } + }, + "1": { + "options": { + "0": { + "question": "El nombre del tema no contiene {search}" + } + } + }, + "10": { + "options": { + "0": { + "question": "Excluir el tema de la etimología" + } + } + }, + "2": { + "options": { + "0": { + "question": "Hecho por el colaborador {search}" + } + } + }, + "3": { + "options": { + "0": { + "question": "No realizado por el colaborador {search}" + } + } + }, + "4": { + "options": { + "0": { + "question": "Realizado antes de {search}" + } + } + }, + "5": { + "options": { + "0": { + "question": "Realizado después de {search}" + } + } + }, + "6": { + "options": { + "0": { + "question": "Idioma del usuario (código iso) {search}" + } + } + } + } + } + } + }, "maproulette": { "description": "Tema que muestra las tareas de MapRoulette, permitiendo buscarlas, filtrarlas y arreglarlas.", "title": "Tareas de MapRoulette" @@ -1347,4 +1413,4 @@ "shortDescription": "Un mapa con papeleras", "title": "Papeleras" } -} \ No newline at end of file +} From 6672fc87b4326db65289dfa31599ec0583d6c0f4 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sat, 14 Sep 2024 22:43:09 +0200 Subject: [PATCH 09/30] Fix: some fixes to make studio useable again, probably fixes #2139 --- .../CollapsedTagRenderingPreview.svelte | 4 +- src/UI/Studio/EditLayerState.ts | 3 + src/UI/Studio/SchemaBasedArray.svelte | 134 ++++++++++-------- src/Utils.ts | 13 ++ 4 files changed, 89 insertions(+), 65 deletions(-) diff --git a/src/UI/Studio/CollapsedTagRenderingPreview.svelte b/src/UI/Studio/CollapsedTagRenderingPreview.svelte index 9c21d82ae..2552f6699 100644 --- a/src/UI/Studio/CollapsedTagRenderingPreview.svelte +++ b/src/UI/Studio/CollapsedTagRenderingPreview.svelte @@ -30,7 +30,7 @@ .getSchemaStartingWith(schema.path) .filter((part) => part.path.length - 1 === schema.path.length) - let usesOverride = value["builtin"] !== undefined + let usesOverride = value?.["builtin"] !== undefined function schemaForMultitype() { const sch = { ...schema } @@ -138,7 +138,7 @@ {:else if typeof value === "string"} Builtin: {value} - {:else if value["builtin"]} + {:else if value?.["builtin"]} reused tagrendering {JSON.stringify(value["builtin"])} {:else} diff --git a/src/UI/Studio/EditLayerState.ts b/src/UI/Studio/EditLayerState.ts index 3fb627a4e..871b75f17 100644 --- a/src/UI/Studio/EditLayerState.ts +++ b/src/UI/Studio/EditLayerState.ts @@ -159,6 +159,9 @@ export abstract class EditJsonState { } public getSchemaStartingWith(path: string[]) { + if(path === undefined){ + return undefined + } return this.schema.filter( (sch) => !path.some((part, i) => !(sch.path.length > path.length && sch.path[i] === part)) diff --git a/src/UI/Studio/SchemaBasedArray.svelte b/src/UI/Studio/SchemaBasedArray.svelte index 21bd1259f..ca874a262 100644 --- a/src/UI/Studio/SchemaBasedArray.svelte +++ b/src/UI/Studio/SchemaBasedArray.svelte @@ -5,18 +5,23 @@ import { TrashIcon } from "@babeard/svelte-heroicons/mini" import ShowConversionMessage from "./ShowConversionMessage.svelte" import Markdown from "../Base/Markdown.svelte" - import type { QuestionableTagRenderingConfigJson } from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson" + import type { + QuestionableTagRenderingConfigJson + } from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson" import CollapsedTagRenderingPreview from "./CollapsedTagRenderingPreview.svelte" import { Accordion } from "flowbite-svelte" + import { Utils } from "../../Utils" export let state: EditJsonState export let path: (string | number)[] = [] let schema: ConfigMeta = state.getSchema(path)[0] + console.log("SBA got schema", schema, "for path", path) - let title = schema.path.at(-1) + + let title = schema?.path?.at(-1) let singular = title if (title?.endsWith("s")) { - singular = title.slice(0, title.length - 1) + singular = title?.slice(0, title.length - 1) } let article = "a" if (singular?.match(/^[aeoui]/)) { @@ -25,18 +30,20 @@ const isTagRenderingBlock = path.length === 1 && path[0] === "tagRenderings" - if (isTagRenderingBlock) { + if (isTagRenderingBlock && schema !== undefined) { schema = { ...schema } schema.description = undefined } const subparts: ConfigMeta[] = state - .getSchemaStartingWith(schema.path) - .filter((part) => part.path.length - 1 === schema.path.length) + .getSchemaStartingWith(schema?.path) + ?.filter((part) => part.path.length - 1 === schema?.path?.length) let messages = state.messagesFor(path) let datapath = path const currentValue = state.getStoreFor<(string | QuestionableTagRenderingConfigJson)[]>(datapath) + currentValue.set(Utils.DedupT(currentValue.data)) + console.log("Current value is", currentValue.data) if (currentValue.data === undefined) { currentValue.setData([]) } @@ -62,68 +69,69 @@ currentValue.ping() } +{#if schema !== undefined} +
+

{schema.path.at(-1)}

-
-

{schema.path.at(-1)}

- - {#if subparts.length > 0} - - {/if} - {#if $currentValue === undefined} - No array defined - {:else if !Array.isArray($currentValue)} - Not an array: {typeof $currentValue} - {JSON.stringify(path)} - {JSON.stringify($currentValue).slice(0, 120)} - {:else if $currentValue?.length === 0} - No values are defined - {#if $messages.length > 0} - {#each $messages as message} - - {/each} + {#if subparts.length > 0} + {/if} - {:else if subparts.length === 0} - - {#each $currentValue as value, i} -
- - -
- {/each} - {:else} - - {#each $currentValue as value, i (value)} - + > + + +
{/each} - - {/if} -
- - {#if path.length === 1 && path[0] === "tagRenderings"} - + {#if path.length === 1 && path[0] === "tagRenderings"} + - {/if} - + > + Add a builtin tagRendering + + {/if} + +
- +{/if} diff --git a/src/Utils.ts b/src/Utils.ts index 99674d926..03fe94883 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -401,6 +401,19 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be return newArr } + public static DedupT(arr: T[]): T[]{ + if(!arr){ + return arr + } + const items = [] + for (const item of arr) { + if(items.indexOf(item) < 0){ + items.push(item) + } + } + return items + } + /** * Finds all duplicates in a list of strings * From 418a4a71af5824487e4aa6754701e5d14371beae Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sat, 14 Sep 2024 23:30:30 +0200 Subject: [PATCH 10/30] Themes(disaster_respone): add a police station layer, add this and more layers to disaster_response theme --- assets/layers/police/license_info.json | 12 ++ assets/layers/police/police.json | 142 ++++++++++++++++++ assets/layers/police/police.svg | 1 + assets/layers/police/police.svg.license | 2 + .../disaster_response/disaster_response.json | 11 +- assets/themes/surveillance/surveillance.json | 3 +- 6 files changed, 168 insertions(+), 3 deletions(-) create mode 100644 assets/layers/police/license_info.json create mode 100644 assets/layers/police/police.json create mode 100644 assets/layers/police/police.svg create mode 100644 assets/layers/police/police.svg.license diff --git a/assets/layers/police/license_info.json b/assets/layers/police/license_info.json new file mode 100644 index 000000000..e1d743c53 --- /dev/null +++ b/assets/layers/police/license_info.json @@ -0,0 +1,12 @@ +[ + { + "path": "police.svg", + "license": "CC-BY 4.0", + "authors": [ + "Twemoji" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Twemoji12_1f693.svg" + ] + } +] \ No newline at end of file diff --git a/assets/layers/police/police.json b/assets/layers/police/police.json new file mode 100644 index 000000000..a79631991 --- /dev/null +++ b/assets/layers/police/police.json @@ -0,0 +1,142 @@ +{ + "id": "police", + "name": { + "en": "Police stations" + }, + "description": { + "en": "Many types of police facilities " + }, + "source": { + "osmTags": { + "or": [ + "amenity=police", + "police~*" + ] + } + }, + "minzoom": 10, + "title": { + "render": { + "en": "{name}" + } + }, + "pointRendering": [ + { + "location": [ + "point", + "centroid" + ], + "marker": [ + { + "icon": "circle", + "color": "#00000000" + }, + { + "icon": "./assets/layers/police/police.svg" + } + ] + } + ], + "lineRendering": [ + { + "width": 1, + "color": "blue" + } + ], + "presets": [ + { + "tags": [ + "amenity=police" + ], + "title": { + "en": "a police office" + }, + "description": { + "en": "A police office where the general public can enter for inquiries" + } + }, + { + "tags": [ + "police=checkpoint" + ], + "title": { + "en": "a police checkpoint" + }, + "description": { + "en": "A place where police performs checks on travelling people" + } + }, + { + "tags": [ + "police=offices" + ], + "title": { + "en": "an administrative, police backoffice" + }, + "description": { + "en": "An administrative police office without services for the general public." + } + }, + { + "tags": [ + "police=detention" + ], + "title": "a police detention center", + "description": { + "en": "A jail run by the police without public services. People are detained here for a short time (at most a few days), e.g. for small misdemeanors, disturbance of the public order or awaiting a trial" + } + }, + { + "tags": [ + "police=naval_base" + ], + "title": "a police naval base", + "description": { + "en": "A naval or maritime base for the maritime police; often with a pier and police boats nearby" + } + } + ], + "tagRenderings": [ + "images", + "reviews", + { + "question": { + "en": "What is the name of this police facility?" + }, + "id": "police_name", + "render": { + "en": "{name}" + }, + "freeform": { + "key": "name" + } + }, + "{preset_type_select()}", + "contact", + "opening_hours", + { + "question": { + "en": "Does this police office have detention facilities?" + }, + "id": "4_z2nrdhy6tyyh4fd", + "condition": "amenity=police", + "mappings": [ + { + "if": "detention=yes", + "then": { + "en": "This police office has some cells to detain people" + } + }, + { + "if": "detention=no", + "then": { + "en": "This police office does not have cells to detain people" + } + } + ] + } + ], + "deletion": true, + "allowMove": true, + "enableMorePrivacy": true +} diff --git a/assets/layers/police/police.svg b/assets/layers/police/police.svg new file mode 100644 index 000000000..cbf344d7c --- /dev/null +++ b/assets/layers/police/police.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/layers/police/police.svg.license b/assets/layers/police/police.svg.license new file mode 100644 index 000000000..77a8edb48 --- /dev/null +++ b/assets/layers/police/police.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Twemoji +SPDX-License-Identifier: CC-BY 4.0 \ No newline at end of file diff --git a/assets/themes/disaster_response/disaster_response.json b/assets/themes/disaster_response/disaster_response.json index 23ba39a20..f39fccf12 100644 --- a/assets/themes/disaster_response/disaster_response.json +++ b/assets/themes/disaster_response/disaster_response.json @@ -18,8 +18,15 @@ "socialImage": "./assets/themes/disaster_response/social.svg", "layers": [ "hospital", + "pharmacy", + "doctors", "assembly_point", - "disaster_response" + "disaster_response", + "police", + "fire_station", + "ambulancestation", + "extinguisher", + "hydrant" ], "docs": "https://wiki.openstreetmap.org/wiki/Emergency_facilities_and_amenities" -} \ No newline at end of file +} diff --git a/assets/themes/surveillance/surveillance.json b/assets/themes/surveillance/surveillance.json index 684c36660..83fd347e5 100644 --- a/assets/themes/surveillance/surveillance.json +++ b/assets/themes/surveillance/surveillance.json @@ -59,7 +59,8 @@ "override": { "minzoom": 12 } - } + }, + "police" ], "enableMorePrivacy": true } From 48644cde670853fe4e1e499a3843afd6dfa050dd Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sat, 14 Sep 2024 23:30:42 +0200 Subject: [PATCH 11/30] Chore: lint themes --- assets/layers/caravansites/caravansites.json | 210 +++++++-------- .../charging_station/charging_station.json | 252 +++++++++--------- .../climbing_opportunity.json | 6 +- .../cycleways_and_roads.json | 10 +- assets/layers/dumpstations/dumpstations.json | 158 +++++------ .../layers/geocoded_image/geocoded_image.json | 6 +- assets/layers/indoors/indoors.json | 8 +- assets/layers/kerbs/kerbs.json | 8 +- assets/layers/note/note.json | 1 - .../pedestrian_path/pedestrian_path.json | 8 +- assets/layers/shelter/shelter.json | 6 +- assets/layers/usersettings/usersettings.json | 1 - .../walls_and_buildings.json | 10 +- assets/themes/uk_addresses/uk_addresses.json | 4 +- 14 files changed, 343 insertions(+), 345 deletions(-) diff --git a/assets/layers/caravansites/caravansites.json b/assets/layers/caravansites/caravansites.json index 8964f3596..a0143f04f 100644 --- a/assets/layers/caravansites/caravansites.json +++ b/assets/layers/caravansites/caravansites.json @@ -21,7 +21,27 @@ "pl": "Miejsca kamperowe", "zh_Hans": "露营地" }, - "minzoom": 7, + "description": { + "en": "camper sites", + "it": "Aree camper", + "ru": "площадки для кемпинга", + "ja": "キャンプサイト", + "fr": "campings", + "zh_Hant": "露營地", + "nl": "camperplaatsen", + "pt_BR": "Locais de acampamento", + "de": "Wohnmobilstellplätze", + "hu": "Lakóautós megállóhelyek", + "id": "Tempat camping", + "ca": "llocs d'acampada", + "es": "Sitios de acampada", + "da": "autocamperpladser", + "pa_PK": "کیمب‌سائیٹاں", + "cs": "kempovací místa", + "eu": "Kanpatzeko tokiak", + "pl": "miejsca dla kamperów", + "zh_Hans": "露营地" + }, "source": { "osmTags": { "and": [ @@ -30,6 +50,7 @@ ] } }, + "minzoom": 7, "title": { "render": { "en": "Camper site {name}", @@ -77,27 +98,89 @@ } ] }, - "description": { - "en": "camper sites", - "it": "Aree camper", - "ru": "площадки для кемпинга", - "ja": "キャンプサイト", - "fr": "campings", - "zh_Hant": "露營地", - "nl": "camperplaatsen", - "pt_BR": "Locais de acampamento", - "de": "Wohnmobilstellplätze", - "hu": "Lakóautós megállóhelyek", - "id": "Tempat camping", - "ca": "llocs d'acampada", - "es": "Sitios de acampada", - "da": "autocamperpladser", - "pa_PK": "کیمب‌سائیٹاں", - "cs": "kempovací místa", - "eu": "Kanpatzeko tokiak", - "pl": "miejsca dla kamperów", - "zh_Hans": "露营地" - }, + "pointRendering": [ + { + "marker": [ + { + "icon": "circle", + "color": "white" + }, + { + "icon": { + "render": "./assets/themes/campersite/caravan.svg", + "mappings": [ + { + "if": { + "and": [ + "fee=no" + ] + }, + "then": "./assets/themes/campersite/caravan_green.svg" + } + ] + } + } + ], + "iconSize": "40,40", + "location": [ + "point", + "centroid" + ], + "anchor": "center" + } + ], + "lineRendering": [ + { + "color": "#00f", + "width": "8" + } + ], + "presets": [ + { + "tags": [ + "tourism=caravan_site" + ], + "title": { + "en": "a camper site", + "ru": "площадка для кемпинга", + "ja": "キャンプサイト", + "zh_Hant": "露營地", + "it": "una luogo di campeggio", + "fr": "une aire de camping", + "pt_BR": "uma local de acampamento", + "de": "ein Wohnmobilstellplatz", + "nl": "een camperplaats", + "hu": "lakóautós megállóhely", + "ca": "un lloc d'acampada", + "es": "Un camping", + "da": "en autocamperplads", + "pa_PK": "اِک کیمپ‌سائیٹ", + "cs": "kempovací místa", + "eu": "Kanpin bat", + "pl": "miejsce dla kampera", + "pt": "uma local de acampamento", + "zh_Hans": "露营地" + }, + "description": { + "en": "Add a new official camper site. These are designated places to stay overnight with your camper. They might look like a real camping or just look like a parking. They might not be signposted at all, but just be defined in a municipal decision. A regular parking intended for campers where it is not expected to spend the night, is -not- a camper site ", + "ru": "Добавьте новую официальную площадку для кемпинга. Это специально отведённые места для ночлега с автофургоном. Они могут выглядеть как настоящий кемпинг или просто выглядеть как парковка. Они не могут быть обозначены вообще, а просто быть определены в муниципальном решении. Обычная парковка, предназначенная для отдыхающих, где не ожидается, что они проведут ночь это -НЕ- площадка для кемпинга ", + "ja": "新しい公式キャンプサイトを追加します。お客様のキャンピングカーで一泊する指定の場所です。本物のキャンプのように見えるかもしれないし、単なる駐車場のように見えるかもしれない。それらは全く署名されていないかもしれませんが、自治体の決定で定義されているだけです。夜を過ごすことが予想されないキャンパー向けの通常の駐車場は、キャンプサイトではない ", + "it": "Aggiungi una nuova area di sosta ufficiale per camper. Si tratta di aree destinate alla sosta notturna dei camper. Potrebbe trattarsi di luoghi di campeggio o semplici parcheggi. Potrebbero anche non essere segnalati sul posto, ma semplicemente indicati in una delibera comunale. Un parcheggio destinato ai camper in cui non è però consentito trascorrere la notte -non- va considerato un'area di sosta per camper. ", + "fr": "Ajouter une nouvelle aire officielle pour campings-cars, destinée à y passer la nuit avec un camping-car. Elle ne nécessite pas d’infrastructures particulières et peut être simplement désignée sous arrêté municipal, un simple parking pour camping-cars non destiné au stationnement de nuit ne rentre pas dans cette catégorie ", + "de": "Fügen Sie einen neuen offiziellen Wohnmobilstellplatz hinzu. Dies sind ausgewiesene Plätze, an denen Sie in Ihrem Wohnmobil übernachten können. Sie können wie ein richtiger Campingplatz oder nur wie ein Parkplatz aussehen. Möglicherweise sind sie gar nicht ausgeschildert, sondern nur in einem Gemeindebeschluss festgelegt. Ein normaler Parkplatz für Wohnmobile, auf dem übernachten nicht zulässig ist, zählt nicht als Wohnmobilstellplatz. ", + "nl": "Voeg een nieuwe officiële camperplaats toe. Dit zijn speciaal aangeduide plaatsen waar het toegestaan is om te overnachten met een camper. Ze kunnen er uitzien als een parking, of soms eerder als een camping. Soms staan ze niet ter plaatse aangeduid, maar heeft de gemeente wel degelijk beslist dat dit een camperplaats is. Een parking voor campers waar je niet mag overnachten is géén camperplaats. ", + "zh_Hant": "新增正式露營地點,通常是設計給過夜的露營者的地點。看起來像是真的露營地或是一般的停車場,而且也許沒有任何指標,但在城鎮被定議地點。如果一般給露營者的停車場並不是用來過夜,則不是露營地點 ", + "hu": "Új hivatalos lakóautóhely hozzáadása. Ez arra vannak kijelölve, hogy lakóautóval ott éjszakázzunk. Lehet, hogy úgy néz ki, mint egy igazi kemping, de az is lehet, hogy csak olyan, mint egy parkoló. Előfordulhat, hogy egyáltalán nem jelzik őket, hanem csak egy önkormányzati határozatban vannak kijelölve. A lakóautósoknak szánt olyan hagyományos parkolók, ahol nem várhatóan nem fognak éjszakázni, -nem minősül- lakóautóhelynek. ", + "es": "Añade un nuevo sitio de acampada oficial. Son lugares designados para pasar la noche con tu caravana. Pueden parecerse a un camping real o simplemente a un aparcamiento. Puede que no estén señalizados en absoluto, sino que simplemente estén definidos en una decisión municipal. Un aparcamiento normal destinado a los campistas en el que no se espera que se pase la noche, no es un camping. ", + "ca": "Afig un nou lloc d'acampada oficial. Són llocs designats per a passar la nit amb la teua caravana. Poden semblar-se a un càmping real o simplement a un aparcament. Pot ser que no estiguen senyalitzats en absolut, sinó que simplement estiguen definits per una decisió municipal. Un aparcament normal destinat als acampadors en el qual no s'espera que es passe la nit, no és un càmping. ", + "da": "Tilføj en ny officiel campingplads. Disse er udpegede steder at overnatte med din autocamper. De kan ligne en rigtig campingplads eller bare ligne en parkeringsplads. De er måske slet ikke skiltet, men er blot defineret i en kommunal beslutning. En almindelig parkering beregnet til campister, hvor det ikke forventes at overnatte, er -ikke- en autocamperplads ", + "cs": "Přidejte nové oficiální kempovací místo. Jedná se o místa, určená pro přenocování s karavanem. Mohou vypadat jako skutečný kemp nebo jen jako parkoviště. Takováto místa nemusí být označena, ale stačí, pokud jsou pouze definována v rozhodnutí obce. Běžné parkoviště určené pro táborníky, kde se nepovažuje za kempovací místo. ", + "eu": "Kanpaleku ofizialeko beste leku bat gehitu du. Gaua zure karabanarekin igarotzeko lekuak dira. Benetako kanpin baten edo, besterik gabe, aparkaleku baten itxura izan dezakete. Baliteke ez egotea inola ere seinaleztatuta, baizik eta udal erabaki batean definitzea. Kanpinlarientzako aparkaleku arrunt bat ez da kanpin bat, gaua bertan pasatzea espero ez bada ere. ", + "pl": "Dodaj nowe oficjalne miejsce dla kamperów. Są to wyznaczone miejsca, w których można przenocować w swoim kamperze. Mogą wyglądać jak prawdziwy kemping lub po prostu wyglądać jak parking. Mogą one w ogóle nie być oznakowane, a jedynie określone w decyzji gminy. Zwykły parking przeznaczony dla kamperów, na którym nie przewiduje się nocowania, nie jest miejscem dla kamperów ", + "zh_Hans": "添加一个新的官方露营车场地。这些是专门设置的供露营车过夜的地点。它们可能看起来像真正的露营地,也可能只是看起来像一个停车场。它们可能没有任何标识,仅在市政决策中定义。普通的停车场,尽管可能供露营车使用,但不期望在其中过夜的,不算作露营车场地 " + } + } + ], "tagRenderings": [ "images", { @@ -848,88 +931,5 @@ "questions", "reviews" ], - "presets": [ - { - "tags": [ - "tourism=caravan_site" - ], - "title": { - "en": "a camper site", - "ru": "площадка для кемпинга", - "ja": "キャンプサイト", - "zh_Hant": "露營地", - "it": "una luogo di campeggio", - "fr": "une aire de camping", - "pt_BR": "uma local de acampamento", - "de": "ein Wohnmobilstellplatz", - "nl": "een camperplaats", - "hu": "lakóautós megállóhely", - "ca": "un lloc d'acampada", - "es": "Un camping", - "da": "en autocamperplads", - "pa_PK": "اِک کیمپ‌سائیٹ", - "cs": "kempovací místa", - "eu": "Kanpin bat", - "pl": "miejsce dla kampera", - "pt": "uma local de acampamento", - "zh_Hans": "露营地" - }, - "description": { - "en": "Add a new official camper site. These are designated places to stay overnight with your camper. They might look like a real camping or just look like a parking. They might not be signposted at all, but just be defined in a municipal decision. A regular parking intended for campers where it is not expected to spend the night, is -not- a camper site ", - "ru": "Добавьте новую официальную площадку для кемпинга. Это специально отведённые места для ночлега с автофургоном. Они могут выглядеть как настоящий кемпинг или просто выглядеть как парковка. Они не могут быть обозначены вообще, а просто быть определены в муниципальном решении. Обычная парковка, предназначенная для отдыхающих, где не ожидается, что они проведут ночь это -НЕ- площадка для кемпинга ", - "ja": "新しい公式キャンプサイトを追加します。お客様のキャンピングカーで一泊する指定の場所です。本物のキャンプのように見えるかもしれないし、単なる駐車場のように見えるかもしれない。それらは全く署名されていないかもしれませんが、自治体の決定で定義されているだけです。夜を過ごすことが予想されないキャンパー向けの通常の駐車場は、キャンプサイトではない ", - "it": "Aggiungi una nuova area di sosta ufficiale per camper. Si tratta di aree destinate alla sosta notturna dei camper. Potrebbe trattarsi di luoghi di campeggio o semplici parcheggi. Potrebbero anche non essere segnalati sul posto, ma semplicemente indicati in una delibera comunale. Un parcheggio destinato ai camper in cui non è però consentito trascorrere la notte -non- va considerato un'area di sosta per camper. ", - "fr": "Ajouter une nouvelle aire officielle pour campings-cars, destinée à y passer la nuit avec un camping-car. Elle ne nécessite pas d’infrastructures particulières et peut être simplement désignée sous arrêté municipal, un simple parking pour camping-cars non destiné au stationnement de nuit ne rentre pas dans cette catégorie ", - "de": "Fügen Sie einen neuen offiziellen Wohnmobilstellplatz hinzu. Dies sind ausgewiesene Plätze, an denen Sie in Ihrem Wohnmobil übernachten können. Sie können wie ein richtiger Campingplatz oder nur wie ein Parkplatz aussehen. Möglicherweise sind sie gar nicht ausgeschildert, sondern nur in einem Gemeindebeschluss festgelegt. Ein normaler Parkplatz für Wohnmobile, auf dem übernachten nicht zulässig ist, zählt nicht als Wohnmobilstellplatz. ", - "nl": "Voeg een nieuwe officiële camperplaats toe. Dit zijn speciaal aangeduide plaatsen waar het toegestaan is om te overnachten met een camper. Ze kunnen er uitzien als een parking, of soms eerder als een camping. Soms staan ze niet ter plaatse aangeduid, maar heeft de gemeente wel degelijk beslist dat dit een camperplaats is. Een parking voor campers waar je niet mag overnachten is géén camperplaats. ", - "zh_Hant": "新增正式露營地點,通常是設計給過夜的露營者的地點。看起來像是真的露營地或是一般的停車場,而且也許沒有任何指標,但在城鎮被定議地點。如果一般給露營者的停車場並不是用來過夜,則不是露營地點 ", - "hu": "Új hivatalos lakóautóhely hozzáadása. Ez arra vannak kijelölve, hogy lakóautóval ott éjszakázzunk. Lehet, hogy úgy néz ki, mint egy igazi kemping, de az is lehet, hogy csak olyan, mint egy parkoló. Előfordulhat, hogy egyáltalán nem jelzik őket, hanem csak egy önkormányzati határozatban vannak kijelölve. A lakóautósoknak szánt olyan hagyományos parkolók, ahol nem várhatóan nem fognak éjszakázni, -nem minősül- lakóautóhelynek. ", - "es": "Añade un nuevo sitio de acampada oficial. Son lugares designados para pasar la noche con tu caravana. Pueden parecerse a un camping real o simplemente a un aparcamiento. Puede que no estén señalizados en absoluto, sino que simplemente estén definidos en una decisión municipal. Un aparcamiento normal destinado a los campistas en el que no se espera que se pase la noche, no es un camping. ", - "ca": "Afig un nou lloc d'acampada oficial. Són llocs designats per a passar la nit amb la teua caravana. Poden semblar-se a un càmping real o simplement a un aparcament. Pot ser que no estiguen senyalitzats en absolut, sinó que simplement estiguen definits per una decisió municipal. Un aparcament normal destinat als acampadors en el qual no s'espera que es passe la nit, no és un càmping. ", - "da": "Tilføj en ny officiel campingplads. Disse er udpegede steder at overnatte med din autocamper. De kan ligne en rigtig campingplads eller bare ligne en parkeringsplads. De er måske slet ikke skiltet, men er blot defineret i en kommunal beslutning. En almindelig parkering beregnet til campister, hvor det ikke forventes at overnatte, er -ikke- en autocamperplads ", - "cs": "Přidejte nové oficiální kempovací místo. Jedná se o místa, určená pro přenocování s karavanem. Mohou vypadat jako skutečný kemp nebo jen jako parkoviště. Takováto místa nemusí být označena, ale stačí, pokud jsou pouze definována v rozhodnutí obce. Běžné parkoviště určené pro táborníky, kde se nepovažuje za kempovací místo. ", - "eu": "Kanpaleku ofizialeko beste leku bat gehitu du. Gaua zure karabanarekin igarotzeko lekuak dira. Benetako kanpin baten edo, besterik gabe, aparkaleku baten itxura izan dezakete. Baliteke ez egotea inola ere seinaleztatuta, baizik eta udal erabaki batean definitzea. Kanpinlarientzako aparkaleku arrunt bat ez da kanpin bat, gaua bertan pasatzea espero ez bada ere. ", - "pl": "Dodaj nowe oficjalne miejsce dla kamperów. Są to wyznaczone miejsca, w których można przenocować w swoim kamperze. Mogą wyglądać jak prawdziwy kemping lub po prostu wyglądać jak parking. Mogą one w ogóle nie być oznakowane, a jedynie określone w decyzji gminy. Zwykły parking przeznaczony dla kamperów, na którym nie przewiduje się nocowania, nie jest miejscem dla kamperów ", - "zh_Hans": "添加一个新的官方露营车场地。这些是专门设置的供露营车过夜的地点。它们可能看起来像真正的露营地,也可能只是看起来像一个停车场。它们可能没有任何标识,仅在市政决策中定义。普通的停车场,尽管可能供露营车使用,但不期望在其中过夜的,不算作露营车场地 " - } - } - ], - "pointRendering": [ - { - "marker": [ - { - "icon": "circle", - "color": "white" - }, - { - "icon": { - "render": "./assets/themes/campersite/caravan.svg", - "mappings": [ - { - "if": { - "and": [ - "fee=no" - ] - }, - "then": "./assets/themes/campersite/caravan_green.svg" - } - ] - } - } - ], - "iconSize": "40,40", - "location": [ - "point", - "centroid" - ], - "anchor": "center" - } - ], - "lineRendering": [ - { - "color": "#00f", - "width": "8" - } - ], "allowMove": true } diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index 1d5bccb6d..132a6710e 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -5,7 +5,13 @@ "nl": "Oplaadpunten", "de": "Ladestationen" }, - "minzoom": 10, + "description": { + "en": "A charging station", + "nl": "Oplaadpunten", + "ca": "Una estació de càrrega", + "de": "Eine Ladestation", + "fr": "Une station de recharge" + }, "source": { "osmTags": { "and": [ @@ -20,6 +26,7 @@ ] } }, + "minzoom": 10, "title": { "render": { "en": "Charging station", @@ -65,14 +72,109 @@ } ] }, - "description": { - "en": "A charging station", - "nl": "Oplaadpunten", - "ca": "Una estació de càrrega", - "de": "Eine Ladestation", - "fr": "Une station de recharge" - }, - "#": "no-question-hint-check", + "pointRendering": [ + { + "location": [ + "point", + "centroid" + ], + "marker": [ + { + "icon": "pin", + "color": "#fff" + }, + { + "icon": { + "render": "./assets/themes/charging_stations/plug.svg", + "mappings": [ + { + "if": "bicycle=yes", + "then": "./assets/themes/charging_stations/bicycle.svg" + }, + { + "if": { + "or": [ + "car=yes", + "motorcar=yes" + ] + }, + "then": "./assets/themes/charging_stations/car.svg" + } + ] + } + } + ], + "iconBadges": [ + { + "if": { + "or": [ + "disused:amenity=charging_station", + "operational_status=broken" + ] + }, + "then": "close:#c22;" + }, + { + "if": { + "or": [ + "proposed:amenity=charging_station", + "planned:amenity=charging_station" + ] + }, + "then": "./assets/layers/charging_station/under_construction.svg" + }, + { + "if": { + "and": [ + "bicycle=yes", + { + "or": [ + "motorcar=yes", + "car=yes" + ] + } + ] + }, + "then": "circle:#fff;./assets/themes/charging_stations/car.svg" + } + ], + "anchor": "bottom", + "iconSize": "50,50" + } + ], + "lineRendering": [ + { + "color": "black", + "width": 2, + "fillColor": "#80808080" + } + ], + "presets": [ + { + "tags": [ + "amenity=charging_station", + "motorcar=no", + "bicycle=yes" + ], + "title": { + "en": "charging station for electrical bikes", + "nl": "oplaadpunt voor elektrische fietsen", + "de": "Ladestation für Elektrofahrräder" + } + }, + { + "tags": [ + "amenity=charging_station", + "motorcar=yes", + "bicycle=no" + ], + "title": { + "en": "charging station for cars", + "nl": "oplaadstation voor elektrische auto's", + "de": "Ladestation für Autos" + } + } + ], "tagRenderings": [ "images", { @@ -2778,109 +2880,6 @@ } } ], - "lineRendering": [ - { - "color": "black", - "width": 2, - "fillColor": "#80808080" - } - ], - "pointRendering": [ - { - "location": [ - "point", - "centroid" - ], - "marker": [ - { - "icon": "pin", - "color": "#fff" - }, - { - "icon": { - "render": "./assets/themes/charging_stations/plug.svg", - "mappings": [ - { - "if": "bicycle=yes", - "then": "./assets/themes/charging_stations/bicycle.svg" - }, - { - "if": { - "or": [ - "car=yes", - "motorcar=yes" - ] - }, - "then": "./assets/themes/charging_stations/car.svg" - } - ] - } - } - ], - "iconBadges": [ - { - "if": { - "or": [ - "disused:amenity=charging_station", - "operational_status=broken" - ] - }, - "then": "close:#c22;" - }, - { - "if": { - "or": [ - "proposed:amenity=charging_station", - "planned:amenity=charging_station" - ] - }, - "then": "./assets/layers/charging_station/under_construction.svg" - }, - { - "if": { - "and": [ - "bicycle=yes", - { - "or": [ - "motorcar=yes", - "car=yes" - ] - } - ] - }, - "then": "circle:#fff;./assets/themes/charging_stations/car.svg" - } - ], - "anchor": "bottom", - "iconSize": "50,50" - } - ], - "presets": [ - { - "tags": [ - "amenity=charging_station", - "motorcar=no", - "bicycle=yes" - ], - "title": { - "en": "charging station for electrical bikes", - "nl": "oplaadpunt voor elektrische fietsen", - "de": "Ladestation für Elektrofahrräder" - } - }, - { - "tags": [ - "amenity=charging_station", - "motorcar=yes", - "bicycle=no" - ], - "title": { - "en": "charging station for cars", - "nl": "oplaadstation voor elektrische auto's", - "de": "Ladestation für Autos" - } - } - ], "filter": [ { "id": "vehicle-type", @@ -3128,6 +3127,19 @@ ] } ], + "deletion": { + "softDeletionTags": { + "and": [ + "amenity=", + "disused:amenity=charging_station" + ] + }, + "neededChangesets": 10 + }, + "allowMove": { + "enableRelocation": false, + "enableImproveAccuracy": true + }, "units": [ { "maxstay": { @@ -3322,17 +3334,5 @@ } } ], - "allowMove": { - "enableRelocation": false, - "enableImproveAccuracy": true - }, - "deletion": { - "softDeletionTags": { - "and": [ - "amenity=", - "disused:amenity=charging_station" - ] - }, - "neededChangesets": 10 - } -} \ No newline at end of file + "#": "no-question-hint-check" +} diff --git a/assets/layers/climbing_opportunity/climbing_opportunity.json b/assets/layers/climbing_opportunity/climbing_opportunity.json index b25ca2c69..031ec13a8 100644 --- a/assets/layers/climbing_opportunity/climbing_opportunity.json +++ b/assets/layers/climbing_opportunity/climbing_opportunity.json @@ -34,9 +34,6 @@ ] } }, - "snapName": { - "en": "a wall, cliff or rock" - }, "minzoom": 18, "title": { "render": { @@ -152,5 +149,8 @@ } ], "allowMove": false, + "snapName": { + "en": "a wall, cliff or rock" + }, "doCount": false } diff --git a/assets/layers/cycleways_and_roads/cycleways_and_roads.json b/assets/layers/cycleways_and_roads/cycleways_and_roads.json index 61337d9a5..27d669d2e 100644 --- a/assets/layers/cycleways_and_roads/cycleways_and_roads.json +++ b/assets/layers/cycleways_and_roads/cycleways_and_roads.json @@ -9,10 +9,6 @@ "ca": "Vies ciclistes i carreteres", "cs": "Cyklostezky a silnice" }, - "snapName": { - "en": "a road or a cycleway", - "nl": "een weg, straat of fietspad" - }, "description": { "en": "All infrastructure that someone can cycle over, accompanied with questions about this infrastructure", "nl": "Alle infrastructuur waar je over kunt fietsen, met vragen over die infrastructuur", @@ -1917,5 +1913,9 @@ } ], "allowMove": false, - "allowSplit": true + "allowSplit": true, + "snapName": { + "en": "a road or a cycleway", + "nl": "een weg, straat of fietspad" + } } diff --git a/assets/layers/dumpstations/dumpstations.json b/assets/layers/dumpstations/dumpstations.json index 66003ad53..bd4f3cf87 100644 --- a/assets/layers/dumpstations/dumpstations.json +++ b/assets/layers/dumpstations/dumpstations.json @@ -18,7 +18,24 @@ "pl": "Stacje zrzutów sanitarnych", "pt": "Estações de despejo sanitário" }, - "minzoom": 7, + "description": { + "en": "Sanitary dump stations", + "ru": "Ассенизационные сливные станции", + "ja": "衛生ゴミ捨て場", + "it": "Luoghi di sversamento delle acque reflue", + "fr": "Site de vidange sanitaire", + "pt_BR": "Estações de despejo sanitário", + "de": "Sanitäre Entsorgungsstationen", + "zh_Hant": "垃圾處理站", + "id": "Tempat pembuangan sanitasi", + "nl": "Loosplaatsen", + "ca": "Estacions d'abocament sanitari", + "da": "Sanitære afleveringspladser", + "cs": "Sanitární skládky", + "es": "Vertederos Sanitarios", + "pl": "Stacje zrzutów sanitarnych", + "pt": "Estações de despejo sanitário" + }, "source": { "osmTags": { "and": [ @@ -27,6 +44,7 @@ ] } }, + "minzoom": 7, "title": { "render": { "en": "Dump station {name}", @@ -70,24 +88,66 @@ } ] }, - "description": { - "en": "Sanitary dump stations", - "ru": "Ассенизационные сливные станции", - "ja": "衛生ゴミ捨て場", - "it": "Luoghi di sversamento delle acque reflue", - "fr": "Site de vidange sanitaire", - "pt_BR": "Estações de despejo sanitário", - "de": "Sanitäre Entsorgungsstationen", - "zh_Hant": "垃圾處理站", - "id": "Tempat pembuangan sanitasi", - "nl": "Loosplaatsen", - "ca": "Estacions d'abocament sanitari", - "da": "Sanitære afleveringspladser", - "cs": "Sanitární skládky", - "es": "Vertederos Sanitarios", - "pl": "Stacje zrzutów sanitarnych", - "pt": "Estações de despejo sanitário" - }, + "pointRendering": [ + { + "marker": [ + { + "icon": "circle", + "color": "white" + }, + { + "icon": "./assets/themes/campersite/sanitary_dump_station.svg" + } + ], + "iconSize": "32,32", + "location": [ + "point" + ], + "anchor": "center" + } + ], + "lineRendering": [ + { + "color": "#00f", + "width": "8" + } + ], + "presets": [ + { + "tags": [ + "amenity=sanitary_dump_station" + ], + "title": { + "en": "a sanitary dump station", + "ja": "衛生ゴミ捨て場", + "it": "una luogo di sversamento delle acque reflue", + "fr": "une site de vidange", + "de": "eine sanitäre Entsorgungsstation", + "zh_Hant": "垃圾丟棄站", + "nl": "een loosplaats", + "da": "en sanitær afleveringsplads", + "ca": "una estació d'abocament sanitari", + "cs": "sanitární skládka", + "es": "un vertedero sanitario", + "pl": "stacja zrzutu sanitarnego" + }, + "description": { + "en": "Add a new sanitary dump station. This is a place where camper drivers can dump waste water or chemical toilet waste. Often there's also drinking water and electricity.", + "ja": "新しい衛生ゴミ捨て場を追加します。ここは、キャンピングカーの運転手が排水や携帯トイレの廃棄物を捨てることができる場所です。飲料水や電気もあることが多いです。", + "it": "Aggiungi un nuovo luogo di sversamento delle acque reflue. Si tratta di luoghi dove chi viaggia in camper può smaltire le acque grigie o le acque nere. Spesso forniscono anche acqua ed elettricità.", + "fr": "Ajouter un nouveau site de vidange. Un espace où évacuer ses eaux usées (grises et/ou noires). Généralement alimenté en eau potable et électricité.", + "de": "Fügen Sie eine neue sanitäre Entsorgungsstation hinzu. Hier können Camper Abwasser oder chemischen Toilettenabfälle entsorgen. Oft gibt es auch Trinkwasser und Strom.", + "zh_Hant": "新增垃圾站,這通常是提供露營駕駛丟棄廢水與化學性廁所廢水的地方,也會有飲用水與電力。", + "hu": "Új egészségügyihulldék-lerakó hozzáadása. Ez egy olyan hely, ahol a lakókocsisok a szennyvizet vagy a vegyi WC hulladékát kiüríthetik. Gyakran van ivóvíz és áram is.", + "nl": "Voeg een nieuwe loosplaats toe. Dat is een plaats waar campers hun grijs water en toiletten kunnen lozen. Vaak is er ook een kraan om water te tanken en een stopcontact.", + "da": "Tilføj en ny sanitær afleveringsplads. Dette er et sted, hvor autocamperchauffører kan dumpe spildevand eller kemisk toiletaffald. Ofte er der også drikkevand og el.", + "cs": "Přidejte novou sanitární skládku. Toto je místo, kam mohou řidiči obytných vozů vypouštět odpadní vodu nebo odpad z chemických toalet. Často je zde také dostupná pitná voda a elektřina.", + "es": "Añadir un nuevo vertedero sanitario. Se trata de un lugar donde los autocaravanistas pueden verter las aguas residuales o los residuos químicos de los aseos. A menudo también hay agua potable y electricidad.", + "ca": "Afegir una nova estació d'abocador sanitari. Aquest és un lloc on els conductors de campers poden abocar aigües residuals o residus de vàter químic. Sovint també hi ha aigua potable i electricitat.", + "pl": "Dodaj nową stację zrzutu sanitarnego. To miejsce, w którym kierowcy kamperów mogą wyrzucać ścieki lub odpady z toalet chemicznych. Często jest tam też woda pitna i prąd." + } + } + ], "tagRenderings": [ "images", { @@ -569,66 +629,6 @@ "id": "dumpstations-network" } ], - "presets": [ - { - "tags": [ - "amenity=sanitary_dump_station" - ], - "title": { - "en": "a sanitary dump station", - "ja": "衛生ゴミ捨て場", - "it": "una luogo di sversamento delle acque reflue", - "fr": "une site de vidange", - "de": "eine sanitäre Entsorgungsstation", - "zh_Hant": "垃圾丟棄站", - "nl": "een loosplaats", - "da": "en sanitær afleveringsplads", - "ca": "una estació d'abocament sanitari", - "cs": "sanitární skládka", - "es": "un vertedero sanitario", - "pl": "stacja zrzutu sanitarnego" - }, - "description": { - "en": "Add a new sanitary dump station. This is a place where camper drivers can dump waste water or chemical toilet waste. Often there's also drinking water and electricity.", - "ja": "新しい衛生ゴミ捨て場を追加します。ここは、キャンピングカーの運転手が排水や携帯トイレの廃棄物を捨てることができる場所です。飲料水や電気もあることが多いです。", - "it": "Aggiungi un nuovo luogo di sversamento delle acque reflue. Si tratta di luoghi dove chi viaggia in camper può smaltire le acque grigie o le acque nere. Spesso forniscono anche acqua ed elettricità.", - "fr": "Ajouter un nouveau site de vidange. Un espace où évacuer ses eaux usées (grises et/ou noires). Généralement alimenté en eau potable et électricité.", - "de": "Fügen Sie eine neue sanitäre Entsorgungsstation hinzu. Hier können Camper Abwasser oder chemischen Toilettenabfälle entsorgen. Oft gibt es auch Trinkwasser und Strom.", - "zh_Hant": "新增垃圾站,這通常是提供露營駕駛丟棄廢水與化學性廁所廢水的地方,也會有飲用水與電力。", - "hu": "Új egészségügyihulldék-lerakó hozzáadása. Ez egy olyan hely, ahol a lakókocsisok a szennyvizet vagy a vegyi WC hulladékát kiüríthetik. Gyakran van ivóvíz és áram is.", - "nl": "Voeg een nieuwe loosplaats toe. Dat is een plaats waar campers hun grijs water en toiletten kunnen lozen. Vaak is er ook een kraan om water te tanken en een stopcontact.", - "da": "Tilføj en ny sanitær afleveringsplads. Dette er et sted, hvor autocamperchauffører kan dumpe spildevand eller kemisk toiletaffald. Ofte er der også drikkevand og el.", - "cs": "Přidejte novou sanitární skládku. Toto je místo, kam mohou řidiči obytných vozů vypouštět odpadní vodu nebo odpad z chemických toalet. Často je zde také dostupná pitná voda a elektřina.", - "es": "Añadir un nuevo vertedero sanitario. Se trata de un lugar donde los autocaravanistas pueden verter las aguas residuales o los residuos químicos de los aseos. A menudo también hay agua potable y electricidad.", - "ca": "Afegir una nova estació d'abocador sanitari. Aquest és un lloc on els conductors de campers poden abocar aigües residuals o residus de vàter químic. Sovint també hi ha aigua potable i electricitat.", - "pl": "Dodaj nową stację zrzutu sanitarnego. To miejsce, w którym kierowcy kamperów mogą wyrzucać ścieki lub odpady z toalet chemicznych. Często jest tam też woda pitna i prąd." - } - } - ], - "pointRendering": [ - { - "marker": [ - { - "icon": "circle", - "color": "white" - }, - { - "icon": "./assets/themes/campersite/sanitary_dump_station.svg" - } - ], - "iconSize": "32,32", - "location": [ - "point" - ], - "anchor": "center" - } - ], - "lineRendering": [ - { - "color": "#00f", - "width": "8" - } - ], "allowMove": { "enableImproveAccuracy": true, "enableRelocation": false diff --git a/assets/layers/geocoded_image/geocoded_image.json b/assets/layers/geocoded_image/geocoded_image.json index c5a9d8b13..dd6f57efd 100644 --- a/assets/layers/geocoded_image/geocoded_image.json +++ b/assets/layers/geocoded_image/geocoded_image.json @@ -1,8 +1,7 @@ { "id": "geocoded_image", - "source": "special", "name": null, - "tagRenderings": [], + "source": "special", "pointRendering": [ { "location": [ @@ -66,5 +65,6 @@ ], "iconSize": "14,14" } - ] + ], + "tagRenderings": [] } diff --git a/assets/layers/indoors/indoors.json b/assets/layers/indoors/indoors.json index 9d4c7abfc..3ef29d1ba 100644 --- a/assets/layers/indoors/indoors.json +++ b/assets/layers/indoors/indoors.json @@ -8,10 +8,6 @@ "ca": "Interiors", "cs": "Vnitřní prostory" }, - "snapName": { - "en": "an indoor wall", - "nl": "een binnenmuur" - }, "description": { "en": "Basic indoor mapping: shows room outlines", "de": "Grundlegende Innenraumkartierung: zeigt Umrisse von Räumen", @@ -623,5 +619,9 @@ "allowMove": { "enableImproveAccuracy": true, "enableRelocation": false + }, + "snapName": { + "en": "an indoor wall", + "nl": "een binnenmuur" } } diff --git a/assets/layers/kerbs/kerbs.json b/assets/layers/kerbs/kerbs.json index b10bc4061..51614d02b 100644 --- a/assets/layers/kerbs/kerbs.json +++ b/assets/layers/kerbs/kerbs.json @@ -11,9 +11,6 @@ "ca": "Vroades", "cs": "Obrubníky" }, - "snapName": { - "en": "a kerb" - }, "description": { "en": "A layer showing kerbs.", "nl": "Een laag met stoepranden.", @@ -409,5 +406,8 @@ ] } } - ] + ], + "snapName": { + "en": "a kerb" + } } diff --git a/assets/layers/note/note.json b/assets/layers/note/note.json index be307958b..9405256f8 100644 --- a/assets/layers/note/note.json +++ b/assets/layers/note/note.json @@ -270,7 +270,6 @@ } ] }, - { "id": "not", "options": [ diff --git a/assets/layers/pedestrian_path/pedestrian_path.json b/assets/layers/pedestrian_path/pedestrian_path.json index ac8ccef8c..007ff1411 100644 --- a/assets/layers/pedestrian_path/pedestrian_path.json +++ b/assets/layers/pedestrian_path/pedestrian_path.json @@ -8,9 +8,6 @@ "ca": "Camins per a vianants", "cs": "Cesty pro chodce" }, - "snapName": { - "en": "a pedestrian path" - }, "description": { "en": "Pedestrian footpaths, especially used for indoor navigation and snapping entrances to this layer", "nl": "Pad voor voetgangers, in het bijzonder gebruikt voor navigatie binnen gebouwen en om aan toegangen vast te klikken in deze laag", @@ -49,5 +46,8 @@ "dashArray": "12 6" } ], - "allowMove": false + "allowMove": false, + "snapName": { + "en": "a pedestrian path" + } } diff --git a/assets/layers/shelter/shelter.json b/assets/layers/shelter/shelter.json index 26361dc07..8b7f169be 100644 --- a/assets/layers/shelter/shelter.json +++ b/assets/layers/shelter/shelter.json @@ -8,9 +8,6 @@ "fr": "Abri", "cs": "Přístřešek" }, - "snapName": { - "en": "a shelter" - }, "description": { "en": "Layer showing shelter structures", "de": "Eine Ebene, die verschiedene Bauformen von Unterständen zeigt", @@ -128,5 +125,8 @@ "allowMove": { "enableRelocation": false, "enableImproveAccuracy": true + }, + "snapName": { + "en": "a shelter" } } diff --git a/assets/layers/usersettings/usersettings.json b/assets/layers/usersettings/usersettings.json index 1f7e5b37d..d7f465103 100644 --- a/assets/layers/usersettings/usersettings.json +++ b/assets/layers/usersettings/usersettings.json @@ -487,7 +487,6 @@ { "if": "mapcomplete-preference-show-scale=false", "alsoShowIf": "mapcomplete-preference-show-scale=", - "then": { "en": "Hide the scalebar", "nl": "Verberg de schaalbalk" diff --git a/assets/layers/walls_and_buildings/walls_and_buildings.json b/assets/layers/walls_and_buildings/walls_and_buildings.json index d1e62cbfa..9e41a19b1 100644 --- a/assets/layers/walls_and_buildings/walls_and_buildings.json +++ b/assets/layers/walls_and_buildings/walls_and_buildings.json @@ -12,10 +12,6 @@ "zh_Hant": "特殊的內建圖層顯示所有牆壁與建築。這個圖層對於規畫要靠牆的東西 (例如 AED、郵筒、入口、地址、監視器等) 相當實用。這個圖層預設顯示而且無法由使用者開關。", "pl": "Specjalna warstwa zabudowana zapewniająca wszystkie mury i budynki. Warstwa ta jest przydatna w ustawieniach wstępnych obiektów, które można umieścić przy ścianach (np. AED, skrzynki pocztowe, wejścia, adresy, kamery monitorujące itp.). Warstwa ta jest domyślnie niewidoczna i użytkownik nie może jej przełączać." }, - "snapName": { - "en": "a wall or building", - "nl": "een muur of gebouw" - }, "source": { "osmTags": { "or": [ @@ -144,5 +140,9 @@ ] } } - ] + ], + "snapName": { + "en": "a wall or building", + "nl": "een muur of gebouw" + } } diff --git a/assets/themes/uk_addresses/uk_addresses.json b/assets/themes/uk_addresses/uk_addresses.json index 85959a8e2..cecc26a2a 100644 --- a/assets/themes/uk_addresses/uk_addresses.json +++ b/assets/themes/uk_addresses/uk_addresses.json @@ -683,8 +683,8 @@ } ], "allowMove": { - "enableImproveAccuraccy": true, - "enableRelocation": false + "enableRelocation": false, + "enableImproveAccuracy": true } }, "named_streets" From 65fceb9434294051c8f565d89f42443c6afe3fb8 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 15 Sep 2024 00:02:09 +0200 Subject: [PATCH 12/30] Themes(disaster_response): add defibrillators and logical zoom levels --- .../disaster_response/disaster_response.json | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/assets/themes/disaster_response/disaster_response.json b/assets/themes/disaster_response/disaster_response.json index f39fccf12..70bdc00f3 100644 --- a/assets/themes/disaster_response/disaster_response.json +++ b/assets/themes/disaster_response/disaster_response.json @@ -17,16 +17,38 @@ "icon": "./assets/themes/disaster_response/CivilDefence.svg", "socialImage": "./assets/themes/disaster_response/social.svg", "layers": [ - "hospital", - "pharmacy", - "doctors", - "assembly_point", - "disaster_response", - "police", - "fire_station", - "ambulancestation", - "extinguisher", - "hydrant" + { + "builtin": [ + "hospital", + "fire_station", + "disaster_response", + "police" + ], + "override": { + "minzoom": 6 + } + }, + { + "builtin": [ + "extinguisher", + "assembly_point", + "defibrillator", + "hydrant" + ], + "override": { + "minzoom": 15 + } + }, + { + "builtin": [ + "doctors", + "ambulancestation", + "pharmacy" + ], + "override": { + "minzoom": 14 + } + } ], "docs": "https://wiki.openstreetmap.org/wiki/Emergency_facilities_and_amenities" } From 9faaad063df757decc89091b7c446ed01d60ff0a Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 15 Sep 2024 00:02:51 +0200 Subject: [PATCH 13/30] UX(index): reorder themes, see #2153 --- src/Models/Constants.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Models/Constants.ts b/src/Models/Constants.ts index 40c070ad5..20190e43c 100644 --- a/src/Models/Constants.ts +++ b/src/Models/Constants.ts @@ -84,17 +84,29 @@ export default class Constants { static distanceToChangeObjectBins = [25, 50, 100, 500, 1000, 5000, Number.MAX_VALUE] static themeOrder = [ "personal", + "cyclofix", - "waste", "etymology", + "waste", + "food", "cafes_and_pubs", "shops", + "healthcare", + "sports", + + "artwork", + "bookcases", "playgrounds", - "hailhydrant", + "drinking_water", "toilets", + "vending_machine", "aed", - "bookcases", + "clock", + + "surveillance", + "advertising", + "circular_economy", ] /** * Upon initialization, the GPS will search the location. From a6b501706926b32098295ef6ae9ea16d93e0e2c5 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 15 Sep 2024 00:10:01 +0200 Subject: [PATCH 14/30] Tooling: move translations for "mapcomplete-changes" into .proto.json to add more stability --- .../mapcomplete-changes.proto.json | 97 +++++++++++++------ scripts/ScriptUtils.ts | 7 +- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json index 4a55a1cf1..096d7c8fc 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json @@ -1,13 +1,17 @@ { "id": "mapcomplete-changes", "title": { - "en": "Changes made with MapComplete" + "en": "Changes made with MapComplete", + "de": "Änderungen mit MapComplete" }, "shortDescription": { - "en": "Shows changes made by MapComplete" + "en": "Shows changes made by MapComplete", + "de": "Zeigt die von MapComplete vorgenommenen Änderungen an" }, "description": { - "en": "This maps shows all the changes made with MapComplete" + "en": "This maps shows all the changes made with MapComplete", + "de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen", + "es": "Este mapa muestra todos los cambios realizados con MapComplete" }, "icon": "./assets/svg/logo.svg", "hideFromOverview": true, @@ -18,7 +22,8 @@ { "id": "mapcomplete-changes", "name": { - "en": "Changeset centers" + "en": "Changeset centers", + "de": "Changeset-Zentren" }, "minzoom": 0, "source": { @@ -28,41 +33,49 @@ }, "title": { "render": { - "en": "Changeset for {theme}" + "en": "Changeset for {theme}", + "de": "Änderungssatz für {theme}" } }, "description": { - "en": "Shows all MapComplete changes" + "en": "Shows all MapComplete changes", + "de": "Zeigt alle MapComplete-Änderungen", + "es": "Muestra todos los cambios de MapComplete" }, "tagRenderings": [ { "id": "show_changeset_id", "render": { - "en": "Changeset {id}" + "en": "Changeset {id}", + "de": "Änderungssatz {id}" } }, { "id": "contributor", "question": { - "en": "What contributor did make this change?" + "en": "What contributor did make this change?", + "de": "Wer hat zu dieser Änderung beigetragen?" }, "freeform": { "key": "user" }, "render": { - "en": "Change made by {user}" + "en": "Change made by {user}", + "de": "Änderung vorgenommen von {user}" } }, { "id": "theme-id", "question": { - "en": "What theme was used to make this change?" + "en": "What theme was used to make this change?", + "de": "Welches Thema wurde für diese Änderung verwendet?" }, "freeform": { "key": "theme" }, "render": { - "en": "Change with theme {theme}" + "en": "Change with theme {theme}", + "de": "Änderung mit Thema {theme}" } }, { @@ -71,19 +84,23 @@ "key": "locale" }, "question": { - "en": "What locale (language) was this change made in?" + "en": "What locale (language) was this change made in?", + "de": "In welcher Sprache (Locale) wurde diese Änderung vorgenommen?" }, "render": { - "en": "User locale is {locale}" + "en": "User locale is {locale}", + "de": "Die Benutzersprache ist {locale}" } }, { "id": "host", "render": { - "en": "Change with with {host}" + "en": "Change with with {host}", + "de": "Änderung mit {host}" }, "question": { - "en": "What host (website) was this change made with?" + "en": "What host (website) was this change made with?", + "de": "Bei welchem Host (Website) wurde diese Änderung vorgenommen?" }, "freeform": { "key": "host" @@ -104,10 +121,12 @@ { "id": "version", "question": { - "en": "What version of MapComplete was used to make this change?" + "en": "What version of MapComplete was used to make this change?", + "de": "Welche Version von MapComplete wurde verwendet, um diese Änderung vorzunehmen?" }, "render": { - "en": "Made with {editor}" + "en": "Made with {editor}", + "de": "Erstellt mit {editor}" }, "freeform": { "key": "editor" @@ -143,7 +162,9 @@ } ], "question": { - "en": "Themename contains {search}" + "en": "Themename contains {search}", + "de": "Themenname enthält {search}", + "es": "El nombre contiene {search}" } } ] @@ -159,7 +180,9 @@ } ], "question": { - "en": "Themename does not contain {search}" + "en": "Themename does not contain {search}", + "de": "Themename enthält nicht {search}", + "es": "El nombre del tema no contiene {search}" } } ] @@ -175,7 +198,9 @@ } ], "question": { - "en": "Made by contributor {search}" + "en": "Made by contributor {search}", + "de": "Erstellt von Mitwirkendem {search}", + "es": "Hecho por el colaborador {search}" } } ] @@ -191,7 +216,9 @@ } ], "question": { - "en": "Not made by contributor {search}" + "en": "Not made by contributor {search}", + "de": "Nicht erstellt von Mitwirkendem {search}", + "es": "No realizado por el colaborador {search}" } } ] @@ -208,7 +235,9 @@ } ], "question": { - "en": "Made before {search}" + "en": "Made before {search}", + "de": "Erstellt vor {search}", + "es": "Realizado antes de {search}" } } ] @@ -225,7 +254,9 @@ } ], "question": { - "en": "Made after {search}" + "en": "Made after {search}", + "de": "Erstellt nach {search}", + "es": "Realizado después de {search}" } } ] @@ -241,7 +272,9 @@ } ], "question": { - "en": "User language (iso-code) {search}" + "en": "User language (iso-code) {search}", + "de": "Benutzersprache (ISO-Code) {search}", + "es": "Idioma del usuario (código iso) {search}" } } ] @@ -257,7 +290,8 @@ } ], "question": { - "en": "Made with host {search}" + "en": "Made with host {search}", + "de": "Erstellt mit Host {search}" } } ] @@ -268,7 +302,8 @@ { "osmTags": "add-image>0", "question": { - "en": "Changeset added at least one image" + "en": "Changeset added at least one image", + "de": "Changeset hat mindestens ein Bild hinzugefügt" } } ] @@ -279,7 +314,8 @@ { "osmTags": "theme!=grb", "question": { - "en": "Exclude GRB theme" + "en": "Exclude GRB theme", + "de": "GRB-Thema ausschließen" } } ] @@ -290,7 +326,9 @@ { "osmTags": "theme!=etymology", "question": { - "en": "Exclude etymology theme" + "en": "Exclude etymology theme", + "de": "Etymologie-Thema ausschließen", + "es": "Excluir el tema de la etimología" } } ] @@ -305,7 +343,8 @@ { "id": "link_to_more", "render": { - "en": "More statistics can be found here" + "en": "More statistics can be found here", + "de": "Weitere Statistiken findest du hier" } }, { diff --git a/scripts/ScriptUtils.ts b/scripts/ScriptUtils.ts index d006e8740..2db71de76 100644 --- a/scripts/ScriptUtils.ts +++ b/scripts/ScriptUtils.ts @@ -95,9 +95,14 @@ export default class ScriptUtils { } public static getThemePaths(): string[] { - return ScriptUtils.readDirRecSync("./assets/themes") + const blacklist = ["assets/themes/mapcomplete-changes/mapcomplete-changes.json"] + const normalFiles = ScriptUtils.readDirRecSync("./assets/themes") .filter((path) => path.endsWith(".json") && !path.endsWith(".proto.json")) .filter((path) => path.indexOf("license_info.json") < 0) + .filter(path => !blacklist.some(black => path.endsWith(black))) + const specialfiles = ["./assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json"] + return normalFiles.concat(specialfiles) + } public static getThemeFiles(): { parsed: LayoutConfigJson; path: string; raw: string }[] { From 7d809c35099a5e396a57c55dc86641f866db93e8 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 15 Sep 2024 00:14:01 +0200 Subject: [PATCH 15/30] Chore: add some missing translations --- .../mapcomplete-changes/mapcomplete-changes.proto.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json index 096d7c8fc..54b92aeaf 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json @@ -11,7 +11,9 @@ "description": { "en": "This maps shows all the changes made with MapComplete", "de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen", - "es": "Este mapa muestra todos los cambios realizados con MapComplete" + "es": "Este mapa muestra todos los cambios realizados con MapComplete", + "pl": "Ta mapa pokazuje wszystkie zmiany wprowadzone za pomocą MapComplete" + }, "icon": "./assets/svg/logo.svg", "hideFromOverview": true, @@ -164,7 +166,8 @@ "question": { "en": "Themename contains {search}", "de": "Themenname enthält {search}", - "es": "El nombre contiene {search}" + "es": "El nombre contiene {search}", + "pl": "Nazwa tematu zawiera {search}" } } ] From 72135c41418ec0f8b2e294dc17b425bbd056b7bd Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 15 Sep 2024 00:17:03 +0200 Subject: [PATCH 16/30] chore(release): 0.46.9 --- CHANGELOG.md | 16 ++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c01a70c5..7eb16a3e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.46.9](https://github.com/USERNAME/REPOSITORY_NAME/compare/v0.46.8...v0.46.9) (2024-09-14) + + +### Bug Fixes + +* fix [#2142](https://github.com/pietervdvn/MapComplete/issues/2142) ([f2fca2d](https://github.com/USERNAME/REPOSITORY_NAME/commitsf2fca2dad8576a18629591e886e511912c1d99e9)) +* nobrand= is actually applied when using the Name suggestion index ([c3bb0cb](https://github.com/USERNAME/REPOSITORY_NAME/commitsc3bb0cb83787c299ee4a92e8df6046aa448d77c8)) +* scroll horizontal images into view ([0397863](https://github.com/USERNAME/REPOSITORY_NAME/commits03978631ebd1e61abd13dd7a53bdb400c3d0f059)) +* some fixes to make studio useable again, probably fixes [#2139](https://github.com/pietervdvn/MapComplete/issues/2139) ([6672fc8](https://github.com/USERNAME/REPOSITORY_NAME/commits6672fc87b4326db65289dfa31599ec0583d6c0f4)) + + +### Theme improvements + +* **disaster_respone:** add a police station layer, add this and more layers to disaster_response theme ([418a4a7](https://github.com/USERNAME/REPOSITORY_NAME/commits418a4a71af5824487e4aa6754701e5d14371beae)) +* **disaster_response:** add defibrillators and logical zoom levels ([65fceb9](https://github.com/USERNAME/REPOSITORY_NAME/commits65fceb9434294051c8f565d89f42443c6afe3fb8)) + ### [0.46.8](https://github.com/USERNAME/REPOSITORY_NAME/compare/v0.46.7...v0.46.8) (2024-09-13) diff --git a/package-lock.json b/package-lock.json index a42d04cf4..be13f6370 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mapcomplete", - "version": "0.46.8", + "version": "0.46.9", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mapcomplete", - "version": "0.46.8", + "version": "0.46.9", "license": "GPL-3.0-or-later", "dependencies": { "@comunica/core": "^3.0.1", diff --git a/package.json b/package.json index c8ca8d9c9..fae4bdf1a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mapcomplete", - "version": "0.46.8", + "version": "0.46.9", "repository": "https://github.com/pietervdvn/MapComplete", "description": "A small website to edit OSM easily", "bugs": "https://github.com/pietervdvn/MapComplete/issues", From 89aaae427dde500f7d4c363d7051c8d91aa84316 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 15 Sep 2024 00:19:39 +0200 Subject: [PATCH 17/30] Tooling: automatically push --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fae4bdf1a..0bdfe22db 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "reuse-compliance": "reuse lint", "housekeeping": "git pull && npx update-browserslist-db@latest && npm run weblate:merge-heavy && npm run generate && npm run generate:docs && npm run generate:schemas && npm run generate:contributor-list && vite-node scripts/fetchLanguages.ts && vite-node scripts/generateSunnyUnlabeled.ts && npm run format && git add assets/ langs/ Docs/ **/*.ts Docs/* src/* && git commit -m 'chore: automated housekeeping...'", "###": "MICROSERVICES AND SERVER MAINTAINENCE", - "release": "standard-version", + "release": "standard-version && git push --follow-tags", "release:minor": "standard-version --release-as minor", "release:patch": "standard-version --release-as patch", "release:major": "standard-version --release-as major", From bf38d09032141f40e2b2c8026bc547057979307d Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 15 Sep 2024 00:56:39 +0200 Subject: [PATCH 18/30] Chore: translation sync --- langs/cs.json | 2 +- langs/de.json | 2 +- langs/en.json | 2 +- langs/es.json | 2 +- langs/layers/en.json | 44 ++++++++++++++++++++++++++++++++++++++++++++ langs/themes/de.json | 2 +- langs/themes/es.json | 2 +- langs/themes/pl.json | 16 ++++++++++++++++ langs/zh_Hant.json | 2 +- 9 files changed, 67 insertions(+), 7 deletions(-) diff --git a/langs/cs.json b/langs/cs.json index e5294a30c..121337b98 100644 --- a/langs/cs.json +++ b/langs/cs.json @@ -859,4 +859,4 @@ "startsWithQ": "Identifikátor wikidat začíná písmenem Q a následuje za ním číslo" } } -} +} \ No newline at end of file diff --git a/langs/de.json b/langs/de.json index 17670ef1e..3d4932ead 100644 --- a/langs/de.json +++ b/langs/de.json @@ -873,4 +873,4 @@ "startsWithQ": "Ein Wikidata-Identifikator beginnt mit Q und wird von einer Zahl gefolgt" } } -} +} \ No newline at end of file diff --git a/langs/en.json b/langs/en.json index 94170812d..e4e1cbda7 100644 --- a/langs/en.json +++ b/langs/en.json @@ -873,4 +873,4 @@ "startsWithQ": "A wikidata identifier starts with Q and is followed by a number" } } -} +} \ No newline at end of file diff --git a/langs/es.json b/langs/es.json index e615ea35d..07f6f6e7d 100644 --- a/langs/es.json +++ b/langs/es.json @@ -593,4 +593,4 @@ "description": "Un identificador de Wikidata" } } -} +} \ No newline at end of file diff --git a/langs/layers/en.json b/langs/layers/en.json index 1115d81bf..5dc29a970 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -7697,6 +7697,50 @@ "render": "Playground device" } }, + "police": { + "description": "Many types of police facilities ", + "name": "Police stations", + "presets": { + "0": { + "description": "A police office where the general public can enter for inquiries", + "title": "a police office" + }, + "1": { + "description": "A place where police performs checks on travelling people", + "title": "a police checkpoint" + }, + "2": { + "description": "An administrative police office without services for the general public.", + "title": "an administrative, police backoffice" + }, + "3": { + "description": "A jail run by the police without public services. People are detained here for a short time (at most a few days), e.g. for small misdemeanors, disturbance of the public order or awaiting a trial" + }, + "4": { + "description": "A naval or maritime base for the maritime police; often with a pier and police boats nearby" + } + }, + "tagRenderings": { + "4_z2nrdhy6tyyh4fd": { + "mappings": { + "0": { + "then": "This police office has some cells to detain people" + }, + "1": { + "then": "This police office does not have cells to detain people" + } + }, + "question": "Does this police office have detention facilities?" + }, + "police_name": { + "question": "What is the name of this police facility?", + "render": "{name}" + } + }, + "title": { + "render": "{name}" + } + }, "postboxes": { "description": "The layer showing postboxes.", "name": "Postboxes", diff --git a/langs/themes/de.json b/langs/themes/de.json index d7e258cc7..afd7a1114 100644 --- a/langs/themes/de.json +++ b/langs/themes/de.json @@ -1474,4 +1474,4 @@ "shortDescription": "Eine Karte mit Abfalleimern", "title": "Abfalleimer" } -} +} \ No newline at end of file diff --git a/langs/themes/es.json b/langs/themes/es.json index f4e86d351..ae9284db1 100644 --- a/langs/themes/es.json +++ b/langs/themes/es.json @@ -1413,4 +1413,4 @@ "shortDescription": "Un mapa con papeleras", "title": "Papeleras" } -} +} \ No newline at end of file diff --git a/langs/themes/pl.json b/langs/themes/pl.json index e3be5755f..347bf3fdd 100644 --- a/langs/themes/pl.json +++ b/langs/themes/pl.json @@ -644,6 +644,22 @@ }, "title": "Krawężniki i przejścia" }, + "mapcomplete-changes": { + "description": "Ta mapa pokazuje wszystkie zmiany wprowadzone za pomocą MapComplete", + "layers": { + "0": { + "filter": { + "0": { + "options": { + "0": { + "question": "Nazwa tematu zawiera {search}" + } + } + } + } + } + } + }, "maproulette": { "description": "Temat pokazujący zadania MapRoulette, umożliwiający ich wyszukiwanie, filtrowanie i naprawianie.", "title": "Zadania MapRoulette" diff --git a/langs/zh_Hant.json b/langs/zh_Hant.json index c8a747652..2027183fc 100644 --- a/langs/zh_Hant.json +++ b/langs/zh_Hant.json @@ -848,4 +848,4 @@ "startsWithQ": "維基數據編號以 Q 開頭後面接數字" } } -} +} \ No newline at end of file From 114f484faf34a39cad032ce1caf7ae3558af1602 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 15 Sep 2024 00:57:38 +0200 Subject: [PATCH 19/30] Chore: Fix build --- .../mapcomplete-changes.json | 99 +++++++++++++------ .../mapcomplete-changes.proto.json | 1 - scripts/ScriptUtils.ts | 31 ++++-- scripts/generateTranslations.ts | 4 +- 4 files changed, 93 insertions(+), 42 deletions(-) diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.json index 7873f6b66..67501aaef 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.json @@ -1,13 +1,18 @@ { "id": "mapcomplete-changes", "title": { - "en": "Changes made with MapComplete" + "en": "Changes made with MapComplete", + "de": "Änderungen mit MapComplete" }, "shortDescription": { - "en": "Shows changes made by MapComplete" + "en": "Shows changes made by MapComplete", + "de": "Zeigt die von MapComplete vorgenommenen Änderungen an" }, "description": { - "en": "This maps shows all the changes made with MapComplete" + "en": "This maps shows all the changes made with MapComplete", + "de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen", + "es": "Este mapa muestra todos los cambios realizados con MapComplete", + "pl": "Ta mapa pokazuje wszystkie zmiany wprowadzone za pomocą MapComplete" }, "icon": "./assets/svg/logo.svg", "hideFromOverview": true, @@ -18,7 +23,8 @@ { "id": "mapcomplete-changes", "name": { - "en": "Changeset centers" + "en": "Changeset centers", + "de": "Changeset-Zentren" }, "minzoom": 0, "source": { @@ -28,41 +34,49 @@ }, "title": { "render": { - "en": "Changeset for {theme}" + "en": "Changeset for {theme}", + "de": "Änderungssatz für {theme}" } }, "description": { - "en": "Shows all MapComplete changes" + "en": "Shows all MapComplete changes", + "de": "Zeigt alle MapComplete-Änderungen", + "es": "Muestra todos los cambios de MapComplete" }, "tagRenderings": [ { "id": "show_changeset_id", "render": { - "en": "Changeset {id}" + "en": "Changeset {id}", + "de": "Änderungssatz {id}" } }, { "id": "contributor", "question": { - "en": "What contributor did make this change?" + "en": "What contributor did make this change?", + "de": "Wer hat zu dieser Änderung beigetragen?" }, "freeform": { "key": "user" }, "render": { - "en": "Change made by {user}" + "en": "Change made by {user}", + "de": "Änderung vorgenommen von {user}" } }, { "id": "theme-id", "question": { - "en": "What theme was used to make this change?" + "en": "What theme was used to make this change?", + "de": "Welches Thema wurde für diese Änderung verwendet?" }, "freeform": { "key": "theme" }, "render": { - "en": "Change with theme {theme}" + "en": "Change with theme {theme}", + "de": "Änderung mit Thema {theme}" } }, { @@ -71,19 +85,23 @@ "key": "locale" }, "question": { - "en": "What locale (language) was this change made in?" + "en": "What locale (language) was this change made in?", + "de": "In welcher Sprache (Locale) wurde diese Änderung vorgenommen?" }, "render": { - "en": "User locale is {locale}" + "en": "User locale is {locale}", + "de": "Die Benutzersprache ist {locale}" } }, { "id": "host", "render": { - "en": "Change with with {host}" + "en": "Change with with {host}", + "de": "Änderung mit {host}" }, "question": { - "en": "What host (website) was this change made with?" + "en": "What host (website) was this change made with?", + "de": "Bei welchem Host (Website) wurde diese Änderung vorgenommen?" }, "freeform": { "key": "host" @@ -104,10 +122,12 @@ { "id": "version", "question": { - "en": "What version of MapComplete was used to make this change?" + "en": "What version of MapComplete was used to make this change?", + "de": "Welche Version von MapComplete wurde verwendet, um diese Änderung vorzunehmen?" }, "render": { - "en": "Made with {editor}" + "en": "Made with {editor}", + "de": "Erstellt mit {editor}" }, "freeform": { "key": "editor" @@ -505,7 +525,10 @@ } ], "question": { - "en": "Themename contains {search}" + "en": "Themename contains {search}", + "de": "Themenname enthält {search}", + "es": "El nombre contiene {search}", + "pl": "Nazwa tematu zawiera {search}" } } ] @@ -521,7 +544,9 @@ } ], "question": { - "en": "Themename does not contain {search}" + "en": "Themename does not contain {search}", + "de": "Themename enthält nicht {search}", + "es": "El nombre del tema no contiene {search}" } } ] @@ -537,7 +562,9 @@ } ], "question": { - "en": "Made by contributor {search}" + "en": "Made by contributor {search}", + "de": "Erstellt von Mitwirkendem {search}", + "es": "Hecho por el colaborador {search}" } } ] @@ -553,7 +580,9 @@ } ], "question": { - "en": "Not made by contributor {search}" + "en": "Not made by contributor {search}", + "de": "Nicht erstellt von Mitwirkendem {search}", + "es": "No realizado por el colaborador {search}" } } ] @@ -570,7 +599,9 @@ } ], "question": { - "en": "Made before {search}" + "en": "Made before {search}", + "de": "Erstellt vor {search}", + "es": "Realizado antes de {search}" } } ] @@ -587,7 +618,9 @@ } ], "question": { - "en": "Made after {search}" + "en": "Made after {search}", + "de": "Erstellt nach {search}", + "es": "Realizado después de {search}" } } ] @@ -603,7 +636,9 @@ } ], "question": { - "en": "User language (iso-code) {search}" + "en": "User language (iso-code) {search}", + "de": "Benutzersprache (ISO-Code) {search}", + "es": "Idioma del usuario (código iso) {search}" } } ] @@ -619,7 +654,8 @@ } ], "question": { - "en": "Made with host {search}" + "en": "Made with host {search}", + "de": "Erstellt mit Host {search}" } } ] @@ -630,7 +666,8 @@ { "osmTags": "add-image>0", "question": { - "en": "Changeset added at least one image" + "en": "Changeset added at least one image", + "de": "Changeset hat mindestens ein Bild hinzugefügt" } } ] @@ -641,7 +678,8 @@ { "osmTags": "theme!=grb", "question": { - "en": "Exclude GRB theme" + "en": "Exclude GRB theme", + "de": "GRB-Thema ausschließen" } } ] @@ -652,7 +690,9 @@ { "osmTags": "theme!=etymology", "question": { - "en": "Exclude etymology theme" + "en": "Exclude etymology theme", + "de": "Etymologie-Thema ausschließen", + "es": "Excluir el tema de la etimología" } } ] @@ -667,7 +707,8 @@ { "id": "link_to_more", "render": { - "en": "More statistics can be found here" + "en": "More statistics can be found here", + "de": "Weitere Statistiken findest du hier" } }, { diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json index 54b92aeaf..cde6afad7 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json @@ -13,7 +13,6 @@ "de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen", "es": "Este mapa muestra todos los cambios realizados con MapComplete", "pl": "Ta mapa pokazuje wszystkie zmiany wprowadzone za pomocą MapComplete" - }, "icon": "./assets/svg/logo.svg", "hideFromOverview": true, diff --git a/scripts/ScriptUtils.ts b/scripts/ScriptUtils.ts index 2db71de76..7eb369a3a 100644 --- a/scripts/ScriptUtils.ts +++ b/scripts/ScriptUtils.ts @@ -94,19 +94,28 @@ export default class ScriptUtils { }) } - public static getThemePaths(): string[] { - const blacklist = ["assets/themes/mapcomplete-changes/mapcomplete-changes.json"] + public static getThemePaths(useTranslationPaths = false): string[] { const normalFiles = ScriptUtils.readDirRecSync("./assets/themes") .filter((path) => path.endsWith(".json") && !path.endsWith(".proto.json")) .filter((path) => path.indexOf("license_info.json") < 0) - .filter(path => !blacklist.some(black => path.endsWith(black))) + + if (!useTranslationPaths) { + return normalFiles + } const specialfiles = ["./assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json"] - return normalFiles.concat(specialfiles) + const blacklist = ["assets/themes/mapcomplete-changes/mapcomplete-changes.json"] + + const filtered = normalFiles.filter(path => !blacklist.some(black => path.endsWith(black))) + return filtered.concat(specialfiles) } - public static getThemeFiles(): { parsed: LayoutConfigJson; path: string; raw: string }[] { - return this.getThemePaths().map((path) => { + public static getThemeFiles(useTranslationPaths = false): { + parsed: LayoutConfigJson; + path: string; + raw: string + }[] { + return this.getThemePaths(useTranslationPaths).map((path) => { try { const contents = readFileSync(path, { encoding: "utf8" }) if (contents === "") { @@ -153,6 +162,7 @@ export default class ScriptUtils { const data = await ScriptUtils.Download(url, headers) return JSON.parse(data["content"]) } + public static async DownloadFetch( url: string, headers?: any @@ -163,6 +173,7 @@ export default class ScriptUtils { console.log("Fetched", url, data) return { content: data } } + public static Download( url: string, headers?: any @@ -198,17 +209,17 @@ export default class ScriptUtils { path: urlObj.pathname + urlObj.search, port: urlObj.port, - headers: headers, + headers: headers }, (res) => { const parts: string[] = [] res.setEncoding("utf8") - res.on("data", function (chunk) { + res.on("data", function(chunk) { // @ts-ignore parts.push(chunk) }) - res.addListener("end", function () { + res.addListener("end", function() { if (res.statusCode === 301 || res.statusCode === 302) { console.log("Got a redirect:", res.headers.location) resolve({ redirect: res.headers.location }) @@ -226,7 +237,7 @@ export default class ScriptUtils { }) } ) - request.on("error", function (e) { + request.on("error", function(e) { reject(e) }) } catch (e) { diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index 8521188c9..0bde6e9ee 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -670,7 +670,7 @@ function removeNonEnglishTranslations(object: any) { * Load the translations into the theme files */ function mergeThemeTranslations(englishOnly: boolean = false) { - const themeFiles = ScriptUtils.getThemeFiles() + const themeFiles = ScriptUtils.getThemeFiles(true) for (const themeFile of themeFiles) { let config = themeFile.parsed mergeLayerTranslation(config, themeFile.path, loadTranslationFilesFrom("themes")) @@ -723,7 +723,7 @@ class GenerateTranslations extends Script { { const l1 = generateTranslationsObjectFrom(ScriptUtils.getLayerFiles(), "layers") const l2 = generateTranslationsObjectFrom( - ScriptUtils.getThemeFiles().filter( + ScriptUtils.getThemeFiles(true).filter( (th) => th.parsed.mustHaveLanguage === undefined ), "themes" From a867379cd4e598184d89603e58720d06f350b432 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 15 Sep 2024 01:12:24 +0200 Subject: [PATCH 20/30] Chore: fix build --- scripts/generateLayerOverview.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/generateLayerOverview.ts b/scripts/generateLayerOverview.ts index 30cd92116..81fade807 100644 --- a/scripts/generateLayerOverview.ts +++ b/scripts/generateLayerOverview.ts @@ -426,7 +426,8 @@ class LayerOverviewUtils extends Script { priviliged.delete("summary") priviliged.delete("last_click") - if (priviliged.size > 0) { + const isBoostrapping = AllSharedLayers.getSharedLayersConfigs().size == 0 + if (!isBoostrapping && priviliged.size > 0) { throw ( "Priviliged layer " + Array.from(priviliged).join(", ") + From de699b6ea30fc452e7bfd38d72784fd6eaae6a2e Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 15 Sep 2024 01:16:09 +0200 Subject: [PATCH 21/30] Merge translations --- langs/layers/de.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/langs/layers/de.json b/langs/layers/de.json index 3884c53d4..378413c6b 100644 --- a/langs/layers/de.json +++ b/langs/layers/de.json @@ -5176,6 +5176,9 @@ "4": { "then": "Sandwichladen" }, + "5": { + "then": "Burgerrestaurant" + }, "6": { "then": "Hier wird Sushi serviert" }, @@ -12228,4 +12231,4 @@ "render": "Windrad" } } -} \ No newline at end of file +} From d6f0e010673e401fdc60a69b154524942f1e88eb Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Mon, 16 Sep 2024 15:12:05 +0200 Subject: [PATCH 22/30] UX: move theme pages above selectedElement, fix #2144 --- src/UI/BigComponents/MenuDrawer.svelte | 5 ++--- src/UI/ThemeViewGUI.svelte | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/UI/BigComponents/MenuDrawer.svelte b/src/UI/BigComponents/MenuDrawer.svelte index 989e19ebe..fef89a69d 100644 --- a/src/UI/BigComponents/MenuDrawer.svelte +++ b/src/UI/BigComponents/MenuDrawer.svelte @@ -10,7 +10,7 @@ import CommunityIndexView from "./CommunityIndexView.svelte" import Community from "../../assets/svg/Community.svelte" import LoginToggle from "../Base/LoginToggle.svelte" - import { CloseButton, Sidebar } from "flowbite-svelte" + import { CloseButton } from "flowbite-svelte" import HotkeyTable from "./HotkeyTable.svelte" import { Utils } from "../../Utils" import Constants from "../../Models/Constants" @@ -23,7 +23,6 @@ import MapillaryLink from "./MapillaryLink.svelte" import Github from "../../assets/svg/Github.svelte" import Bug from "../../assets/svg/Bug.svelte" - import Add from "../../assets/svg/Add.svelte" import CopyrightPanel from "./CopyrightPanel.svelte" import CopyrightAllIcons from "./CopyrightAllIcons.svelte" import LanguagePicker from "../InputElement/LanguagePicker.svelte" @@ -90,7 +89,7 @@
{#if $userdetails.img} - + avatar {/if} {$userdetails.name}
diff --git a/src/UI/ThemeViewGUI.svelte b/src/UI/ThemeViewGUI.svelte index ab4b296d4..d52b3ce00 100644 --- a/src/UI/ThemeViewGUI.svelte +++ b/src/UI/ThemeViewGUI.svelte @@ -44,7 +44,7 @@ import DrawerLeft from "./Base/DrawerLeft.svelte" import Hash from "../Logic/Web/Hash" import { Drawer } from "flowbite-svelte" - import { linear, sineIn } from "svelte/easing" + import { linear } from "svelte/easing" export let state: ThemeViewState let layout = state.layout @@ -418,7 +418,6 @@ - {#if $selectedElement !== undefined && $selectedLayer !== undefined && !$selectedLayer.popupInFloatover} @@ -472,4 +471,6 @@ {/if} {/if} + + From af2905dc6d1cbbcfb2d9cd2583369eebd90ced70 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Mon, 16 Sep 2024 17:04:34 +0200 Subject: [PATCH 23/30] Feat: add download as json to 'allTags'-panel (for debugging) --- src/UI/Popup/AllTagsPanel.svelte | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/UI/Popup/AllTagsPanel.svelte b/src/UI/Popup/AllTagsPanel.svelte index 86238924f..614e88bcf 100644 --- a/src/UI/Popup/AllTagsPanel.svelte +++ b/src/UI/Popup/AllTagsPanel.svelte @@ -2,6 +2,7 @@ import { Store, UIEventSource } from "../../Logic/UIEventSource" import SimpleMetaTaggers from "../../Logic/SimpleMetaTagger" import LayerConfig from "../../Models/ThemeConfig/LayerConfig" + import { Utils } from "../../Utils" export let tags: UIEventSource> export let tagKeys = tags.map((tgs) => (tgs === undefined ? [] : Object.keys(tgs))) @@ -31,9 +32,18 @@ const metaKeys: string[] = [].concat(...SimpleMetaTaggers.metatags.map((k) => k.keys)) let allCalculatedTags = new Set([...calculatedTags, ...metaKeys]) + + function downloadAsJson(){ + Utils.offerContentsAsDownloadableFile( + JSON.stringify(tags.data, null, " "), "tags-"+(tags.data.id ?? layer?.id ?? "")+".json" + ) + }
+ From 9b4f59b383a27eba748041cc042c2625a149e5fe Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Mon, 16 Sep 2024 17:04:43 +0200 Subject: [PATCH 24/30] UI: add padding --- src/UI/BigComponents/MenuDrawer.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/BigComponents/MenuDrawer.svelte b/src/UI/BigComponents/MenuDrawer.svelte index fef89a69d..a08e402a7 100644 --- a/src/UI/BigComponents/MenuDrawer.svelte +++ b/src/UI/BigComponents/MenuDrawer.svelte @@ -95,7 +95,7 @@ - + From e08ce00850e5cc45c280b7ec5adb9dcbbf337a28 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Mon, 16 Sep 2024 17:33:56 +0200 Subject: [PATCH 25/30] UX(plantnet): add retry button if detection failed, fix #2148 --- src/Logic/Web/PlantNet.ts | 2 +- src/UI/PlantNet/PlantNet.svelte | 13 +++++++++---- src/Utils.ts | 17 ++++++++++++++--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/Logic/Web/PlantNet.ts b/src/Logic/Web/PlantNet.ts index 4012040e0..769fb60c9 100644 --- a/src/Logic/Web/PlantNet.ts +++ b/src/Logic/Web/PlantNet.ts @@ -15,7 +15,7 @@ export default class PlantNet { for (const image of imageUrls) { url += "&images=" + encodeURIComponent(image) } - return Utils.downloadJsonCached(url, 365 * 24 * 60 * 60 * 1000) + return Utils.downloadJsonCached(url, 365 * 24 * 60 * 60 * 1000, undefined, true) } public static exampleResult: PlantNetResult = { diff --git a/src/UI/PlantNet/PlantNet.svelte b/src/UI/PlantNet/PlantNet.svelte index 893aa86c1..d9f0651cd 100644 --- a/src/UI/PlantNet/PlantNet.svelte +++ b/src/UI/PlantNet/PlantNet.svelte @@ -9,8 +9,8 @@ import BackButton from "../Base/BackButton.svelte" import NextButton from "../Base/NextButton.svelte" import WikipediaPanel from "../Wikipedia/WikipediaPanel.svelte" - import { createEventDispatcher } from "svelte" import Plantnet_logo from "../../assets/svg/Plantnet_logo.svelte" + import ArrowPath from "@babeard/svelte-heroicons/mini/ArrowPath" /** * The main entry point for the plantnet wizard @@ -23,7 +23,6 @@ */ export let imageUrls: Store export let onConfirm: (wikidataId: string) => void - const dispatch = createEventDispatcher<{ selected: string }>() let collapsedMode = true let options: UIEventSource = new UIEventSource( undefined @@ -38,18 +37,20 @@ let done = false - function speciesSelected(species: PlantNetSpeciesMatch) { + function speciesSelected(species: string) { console.log("Selected:", species) selectedOption = species } async function detectSpecies() { + error = undefined collapsedMode = false try { const result = await PlantNet.query(imageUrls.data.slice(0, 5)) options.set(result.results.filter((r) => r.score > 0.005).slice(0, 8)) } catch (e) { + console.error("Caught", e) error = e } } @@ -60,8 +61,12 @@ - {:else if $error !== undefined} + {:else if error !== undefined} + + {:else if $imageUrls.length === 0}
diff --git a/src/Utils.ts b/src/Utils.ts index 2a23d76fd..483c48eac 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -1073,19 +1073,22 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be public static async downloadJsonCached( url: string, maxCacheTimeMs: number, - headers?: Record + headers?: Record, + dontCacheErrors: boolean = false ): Promise { - const result = await Utils.downloadJsonCachedAdvanced(url, maxCacheTimeMs, headers) + const result = await Utils.downloadJsonCachedAdvanced(url, maxCacheTimeMs, headers, dontCacheErrors) if (result["content"]) { return result["content"] } throw result["error"] + } public static async downloadJsonCachedAdvanced( url: string, maxCacheTimeMs: number, - headers?: Record + headers?: Record, + dontCacheErrors = false ): Promise<{ content: T } | { error: string; url: string; statuscode?: number }> { const cached = Utils._download_cache.get(url) if (cached !== undefined) { @@ -1099,7 +1102,15 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be headers ) Utils._download_cache.set(url, { promise, timestamp: new Date().getTime() }) + try { + return await promise + }catch (e) { + if(dontCacheErrors){ + Utils._download_cache.delete(url) + } + throw e + } } public static async downloadJson( From 5da63bf83aa7d8b230c8dbc082be3fba33344289 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Mon, 16 Sep 2024 22:40:26 +0200 Subject: [PATCH 26/30] Themes(waste): add filter for 'recycling centre' --- assets/layers/recycling/recycling.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/assets/layers/recycling/recycling.json b/assets/layers/recycling/recycling.json index e2e4eb522..ccc12a897 100644 --- a/assets/layers/recycling/recycling.json +++ b/assets/layers/recycling/recycling.json @@ -1380,6 +1380,17 @@ ], "filter": [ "open_now", + { + "id": "centres_only", + "options": [ + { + "osmTags": "recycling_type=centre", + "question": { + "en": "Recycling centre" + } + } + ] + }, { "id": "recyclingType", "options": [ From fb250fb928da576b5649d398272387da72e89e5c Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 17 Sep 2024 02:33:05 +0200 Subject: [PATCH 27/30] Fix: search fields in a filter are now wrapped into parentheses, allowing for OR as regex --- src/Models/FilteredLayer.ts | 9 ++++++++- src/Models/ThemeConfig/FilterConfig.ts | 12 ++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Models/FilteredLayer.ts b/src/Models/FilteredLayer.ts index 2ced53af5..01b5de0b8 100644 --- a/src/Models/FilteredLayer.ts +++ b/src/Models/FilteredLayer.ts @@ -131,6 +131,13 @@ export default class FilteredLayer { return values } + /** + * import Translations from "../UI/i18n/Translations" + * import { RegexTag } from "../Logic/Tags/RegexTag" + * + * const option: FilterConfigOption = {question: Translations.T("question"), osmTags: undefined, originalTagsSpec: "key~.*{search}.*", fields: [{name: "search", type: "string"}] } + * FilteredLayer.fieldsToTags(option, {search: "value_regex"}) // => new RegexTag("key", /^(.*(value_regex).*)$/) + */ private static fieldsToTags( option: FilterConfigOption, fieldstate: string | Record @@ -153,7 +160,7 @@ export default class FilteredLayer { } for (const key in properties) { - v = (v).replace("{" + key + "}", properties[key]) + v = (v).replace("{" + key + "}", "(" + properties[key] + ")") } return v diff --git a/src/Models/ThemeConfig/FilterConfig.ts b/src/Models/ThemeConfig/FilterConfig.ts index 8e80b581b..13a994d51 100644 --- a/src/Models/ThemeConfig/FilterConfig.ts +++ b/src/Models/ThemeConfig/FilterConfig.ts @@ -60,8 +60,8 @@ export default class FilterConfig { } const fields: { name: string; type: ValidatorType }[] = (option.fields ?? []).map((f, i) => { - const type = f.type ?? "string" - if(Validators.availableTypes.indexOf(type) < 0){ + const type = f.type ?? "string" + if (Validators.availableTypes.indexOf(type) < 0) { throw `Invalid filter: type is not a valid validator. Did you mean one of ${Utils.sortedByLevenshteinDistance(type, Validators.availableTypes, x => x).slice(0, 3)}` } // Type is validated against 'ValidatedTextField' in Validation.ts, in ValidateFilterConfig @@ -70,12 +70,12 @@ export default class FilterConfig { } return { name: f.name, - type, + type } }) for (const field of fields) { - for (let ln in question.translations) { + for (const ln in question.translations) { const txt = question.translations[ln] if (ln.startsWith("_")) { continue @@ -111,7 +111,7 @@ export default class FilterConfig { question: question, osmTags: osmTags, fields, - originalTagsSpec: option.osmTags, + originalTagsSpec: option.osmTags } }) @@ -223,7 +223,7 @@ export default class FilterConfig { opt.osmTags?.asHumanString() ?? "", opt.fields?.length > 0 ? opt.fields.map((f) => f.name + " (" + f.type + ")").join(" ") - : undefined, + : undefined ]) ) }) From 9c09da3c137a6af88b935108fe55aa8e1163ed2c Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 17 Sep 2024 02:35:07 +0200 Subject: [PATCH 28/30] Themes(note): add filter removing anything matching one or more keywords --- assets/layers/note/note.json | 17 +++++++++++++++++ langs/layers/ca.json | 22 +++++++++++----------- langs/layers/cs.json | 22 +++++++++++----------- langs/layers/da.json | 2 +- langs/layers/de.json | 27 ++++++++++++--------------- langs/layers/en.json | 23 +++++++++++++++-------- langs/layers/es.json | 22 +++++++++++----------- langs/layers/fr.json | 20 ++++++++++---------- langs/layers/nl.json | 22 +++++++++++----------- 9 files changed, 99 insertions(+), 78 deletions(-) diff --git a/assets/layers/note/note.json b/assets/layers/note/note.json index 9405256f8..39e251fec 100644 --- a/assets/layers/note/note.json +++ b/assets/layers/note/note.json @@ -291,6 +291,23 @@ } ] }, + { + "id": "search_not_any", + "options": [ + { + "osmTags": "_all_comments!~i~.*{search}.*", + "fields": [ + { + "name": "search" + } + ], + "question": { + "en": "Should not mention {search} in any comment" + } + } + ] + }, + { "id": "opened_by", "options": [ diff --git a/langs/layers/ca.json b/langs/layers/ca.json index e92ff82db..32b1ce0db 100644 --- a/langs/layers/ca.json +++ b/langs/layers/ca.json @@ -5137,14 +5137,21 @@ } } }, - "11": { + "10": { "options": { "0": { - "question": "Creada abans de {search}" + "question": "Editat per última vega pel contribuïdor {search}" } } }, "12": { + "options": { + "0": { + "question": "Creada abans de {search}" + } + } + }, + "13": { "options": { "0": { "question": "Creada després de {search}" @@ -5178,26 +5185,19 @@ } } }, - "6": { + "7": { "options": { "0": { "question": "Obert pel contribuïdor {search}" } } }, - "7": { + "8": { "options": { "0": { "question": "No obert pel contribuïdor {search}" } } - }, - "9": { - "options": { - "0": { - "question": "Editat per última vega pel contribuïdor {search}" - } - } } }, "name": "Notes d'OpenStreetMap", diff --git a/langs/layers/cs.json b/langs/layers/cs.json index f0cf51d7f..72389b371 100644 --- a/langs/layers/cs.json +++ b/langs/layers/cs.json @@ -5363,14 +5363,21 @@ } } }, - "11": { + "10": { "options": { "0": { - "question": "Vytvořeno před {search}" + "question": "Naposledy upravil přispěvatel {search}" } } }, "12": { + "options": { + "0": { + "question": "Vytvořeno před {search}" + } + } + }, + "13": { "options": { "0": { "question": "Vytvořeno po {search}" @@ -5404,26 +5411,19 @@ } } }, - "6": { + "7": { "options": { "0": { "question": "Otevřeno přispěvatelem {search}" } } }, - "7": { + "8": { "options": { "0": { "question": "Není otevřeno přispěvatelem {search}" } } - }, - "9": { - "options": { - "0": { - "question": "Naposledy upravil přispěvatel {search}" - } - } } }, "name": "Poznámky OpenStreetMap", diff --git a/langs/layers/da.json b/langs/layers/da.json index 2d570bcc6..9ea5bbee4 100644 --- a/langs/layers/da.json +++ b/langs/layers/da.json @@ -1633,7 +1633,7 @@ }, "note": { "filter": { - "9": { + "10": { "options": { "0": { "question": "Senest redigeret af bidragsyder {search}" diff --git a/langs/layers/de.json b/langs/layers/de.json index 378413c6b..5a5718447 100644 --- a/langs/layers/de.json +++ b/langs/layers/de.json @@ -5176,9 +5176,6 @@ "4": { "then": "Sandwichladen" }, - "5": { - "then": "Burgerrestaurant" - }, "6": { "then": "Hier wird Sushi serviert" }, @@ -6773,14 +6770,21 @@ } } }, - "11": { + "10": { "options": { "0": { - "question": "Erstellt vor dem {search}" + "question": "Zuletzt bearbeitet von {search}" } } }, "12": { + "options": { + "0": { + "question": "Erstellt vor dem {search}" + } + } + }, + "13": { "options": { "0": { "question": "Erstellt nach dem {search}" @@ -6814,26 +6818,19 @@ } } }, - "6": { + "7": { "options": { "0": { "question": "Erstellt von {search}" } } }, - "7": { + "8": { "options": { "0": { "question": "Nicht erstellt von {search}" } } - }, - "9": { - "options": { - "0": { - "question": "Zuletzt bearbeitet von {search}" - } - } } }, "name": "OpenStreetMap-Hinweise", @@ -12231,4 +12228,4 @@ "render": "Windrad" } } -} +} \ No newline at end of file diff --git a/langs/layers/en.json b/langs/layers/en.json index 5dc29a970..c67d85317 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -6786,32 +6786,39 @@ "10": { "options": { "0": { - "question": "Not edited as last by {search}" + "question": "Last edited by contributor {search}" } } }, "11": { "options": { "0": { - "question": "Created before {search}" + "question": "Not edited as last by {search}" } } }, "12": { "options": { "0": { - "question": "Created after {search}" + "question": "Created before {search}" } } }, "13": { "options": { "0": { - "question": "Last edited before {search}" + "question": "Created after {search}" } } }, "14": { + "options": { + "0": { + "question": "Last edited before {search}" + } + } + }, + "15": { "options": { "0": { "question": "Last edited after {search}" @@ -6855,28 +6862,28 @@ "6": { "options": { "0": { - "question": "Opened by contributor {search}" + "question": "Should not mention {search} in any comment" } } }, "7": { "options": { "0": { - "question": "Not opened by contributor {search}" + "question": "Opened by contributor {search}" } } }, "8": { "options": { "0": { - "question": "Edited or commented on by any user with name {search}" + "question": "Not opened by contributor {search}" } } }, "9": { "options": { "0": { - "question": "Last edited by contributor {search}" + "question": "Edited or commented on by any user with name {search}" } } } diff --git a/langs/layers/es.json b/langs/layers/es.json index 5a9881870..0279b5b2d 100644 --- a/langs/layers/es.json +++ b/langs/layers/es.json @@ -3146,14 +3146,21 @@ } } }, - "11": { + "10": { "options": { "0": { - "question": "Creada antes de {search}" + "question": "Editada por última vez por el contributor {search}" } } }, "12": { + "options": { + "0": { + "question": "Creada antes de {search}" + } + } + }, + "13": { "options": { "0": { "question": "Creada después de {search}" @@ -3187,26 +3194,19 @@ } } }, - "6": { + "7": { "options": { "0": { "question": "Abierto por el contributor {search}" } } }, - "7": { + "8": { "options": { "0": { "question": "No abierto por el contributor {search}" } } - }, - "9": { - "options": { - "0": { - "question": "Editada por última vez por el contributor {search}" - } - } } }, "name": "Notas de OpenStreetMap", diff --git a/langs/layers/fr.json b/langs/layers/fr.json index 0a320cd47..42d05b6af 100644 --- a/langs/layers/fr.json +++ b/langs/layers/fr.json @@ -4439,45 +4439,45 @@ } } }, - "11": { + "10": { "options": { "0": { - "question": "Créée avant le {search}" + "question": "Dernière modification par {search}" } } }, "12": { "options": { "0": { - "question": "Créée après le {search}" + "question": "Créée avant le {search}" } } }, - "2": { + "13": { "options": { "0": { - "question": "Toutes les notes" + "question": "Créée après le {search}" } } }, - "6": { + "2": { "options": { "0": { - "question": "Ouverte par {search}" + "question": "Toutes les notes" } } }, "7": { "options": { "0": { - "question": "Exclureles notes ouvertes par {search}" + "question": "Ouverte par {search}" } } }, - "9": { + "8": { "options": { "0": { - "question": "Dernière modification par {search}" + "question": "Exclureles notes ouvertes par {search}" } } } diff --git a/langs/layers/nl.json b/langs/layers/nl.json index fb412fb08..693637837 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -5534,14 +5534,21 @@ } } }, - "11": { + "10": { "options": { "0": { - "question": "Aangemaakt voor {search}" + "question": "Laatst bewerkt door bijdrager {search}" } } }, "12": { + "options": { + "0": { + "question": "Aangemaakt voor {search}" + } + } + }, + "13": { "options": { "0": { "question": "Aangemaakt na {search}" @@ -5575,26 +5582,19 @@ } } }, - "6": { + "7": { "options": { "0": { "question": "Geopend door bijdrager {search}" } } }, - "7": { + "8": { "options": { "0": { "question": "Niet geopend door bijdrager {search}" } } - }, - "9": { - "options": { - "0": { - "question": "Laatst bewerkt door bijdrager {search}" - } - } } }, "name": "OpenStreetMap Notes", From e205fd744f45c94a9bf7f6c3eda2511b98232712 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 17 Sep 2024 02:35:51 +0200 Subject: [PATCH 29/30] Chore: remove unused imports --- src/Models/ThemeConfig/FilterConfig.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Models/ThemeConfig/FilterConfig.ts b/src/Models/ThemeConfig/FilterConfig.ts index 13a994d51..53d079d55 100644 --- a/src/Models/ThemeConfig/FilterConfig.ts +++ b/src/Models/ThemeConfig/FilterConfig.ts @@ -8,9 +8,6 @@ import { UIEventSource } from "../../Logic/UIEventSource" import { QueryParameters } from "../../Logic/Web/QueryParameters" import { Utils } from "../../Utils" import { RegexTag } from "../../Logic/Tags/RegexTag" -import BaseUIElement from "../../UI/BaseUIElement" -import Table from "../../UI/Base/Table" -import Combine from "../../UI/Base/Combine" import MarkdownUtils from "../../Utils/MarkdownUtils" import Validators, { ValidatorType } from "../../UI/InputElement/Validators" From ebe7ff85f8137bc9c8e86d2a42eb8d14060094f3 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 17 Sep 2024 02:51:02 +0200 Subject: [PATCH 30/30] UX: indicate that a search field is actually a regex, add feedback to the filterview --- langs/en.json | 3 +++ src/Models/ThemeConfig/FilterConfig.ts | 2 +- .../BigComponents/FilterviewWithFields.svelte | 13 ++++++++--- src/UI/InputElement/Validators.ts | 6 ++--- .../InputElement/Validators/RegexValidator.ts | 22 +++++++++++++++++++ 5 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 src/UI/InputElement/Validators/RegexValidator.ts diff --git a/langs/en.json b/langs/en.json index e4e1cbda7..5d838da07 100644 --- a/langs/en.json +++ b/langs/en.json @@ -850,6 +850,9 @@ "description": "a positive, whole number", "noZero": "Zero is not allowed" }, + "regex": { + "description": "a regular expression" + }, "slope": { "inputExplanation": "Place your phone on the ground with the top side of your phone pointing towards the top of the slope.", "inputIncorrect": "For correct measurements, make sure the arrow is within the green area." diff --git a/src/Models/ThemeConfig/FilterConfig.ts b/src/Models/ThemeConfig/FilterConfig.ts index 8e80b581b..4dfddc64b 100644 --- a/src/Models/ThemeConfig/FilterConfig.ts +++ b/src/Models/ThemeConfig/FilterConfig.ts @@ -60,7 +60,7 @@ export default class FilterConfig { } const fields: { name: string; type: ValidatorType }[] = (option.fields ?? []).map((f, i) => { - const type = f.type ?? "string" + const type = f.type ?? "regex" if(Validators.availableTypes.indexOf(type) < 0){ throw `Invalid filter: type is not a valid validator. Did you mean one of ${Utils.sortedByLevenshteinDistance(type, Validators.availableTypes, x => x).slice(0, 3)}` } diff --git a/src/UI/BigComponents/FilterviewWithFields.svelte b/src/UI/BigComponents/FilterviewWithFields.svelte index 9d9a52e43..5245c9c2f 100644 --- a/src/UI/BigComponents/FilterviewWithFields.svelte +++ b/src/UI/BigComponents/FilterviewWithFields.svelte @@ -8,6 +8,8 @@ import { Utils } from "../../Utils" import type { ValidatorType } from "../InputElement/Validators" import InputHelper from "../InputElement/InputHelper.svelte" + import { Translation } from "../i18n/Translation" + import Tr from "../Base/Tr.svelte" export let filteredLayer: FilteredLayer export let option: FilterConfigOption @@ -36,7 +38,7 @@ appliedFilter?.setData(FilteredLayer.fieldsToString(properties)) } - let firstValue : UIEventSource + let firstValue: UIEventSource for (const field of option.fields) { // A bit of cheating: the 'parts' will have '}' suffixed for fields const src = new UIEventSource(initialState[field.name] ?? "") @@ -47,9 +49,10 @@ onDestroy( src.stabilized(200).addCallback(() => { setFields() - }), + }) ) } + let feedback: UIEventSource = new UIEventSource(undefined)
0}> @@ -58,11 +61,15 @@ - + {:else} {@html part["message"]} {/if} {/each} + {#if $feedback} +
+ {/if} diff --git a/src/UI/InputElement/Validators.ts b/src/UI/InputElement/Validators.ts index ec0896948..eb768f2b1 100644 --- a/src/UI/InputElement/Validators.ts +++ b/src/UI/InputElement/Validators.ts @@ -15,9 +15,6 @@ import UrlValidator from "./Validators/UrlValidator" import PhoneValidator from "./Validators/PhoneValidator" import OpeningHoursValidator from "./Validators/OpeningHoursValidator" import ColorValidator from "./Validators/ColorValidator" -import BaseUIElement from "../BaseUIElement" -import Combine from "../Base/Combine" -import Title from "../Base/Title" import SimpleTagValidator from "./Validators/SimpleTagValidator" import ImageUrlValidator from "./Validators/ImageUrlValidator" import TagKeyValidator from "./Validators/TagKeyValidator" @@ -30,6 +27,7 @@ import SlopeValidator from "./Validators/SlopeValidator" import VeloparkValidator from "./Validators/VeloparkValidator" import NameSuggestionIndexValidator from "./Validators/NameSuggestionIndexValidator" import CurrencyValidator from "./Validators/CurrencyValidator" +import RegexValidator from "./Validators/RegexValidator" export type ValidatorType = (typeof Validators.availableTypes)[number] @@ -64,6 +62,7 @@ export default class Validators { "velopark", "nsi", "currency", + "regex" ] as const public static readonly AllValidators: ReadonlyArray = [ @@ -95,6 +94,7 @@ export default class Validators { new VeloparkValidator(), new NameSuggestionIndexValidator(), new CurrencyValidator(), + new RegexValidator() ] private static _byType = Validators._byTypeConstructor() diff --git a/src/UI/InputElement/Validators/RegexValidator.ts b/src/UI/InputElement/Validators/RegexValidator.ts new file mode 100644 index 000000000..9323db8fd --- /dev/null +++ b/src/UI/InputElement/Validators/RegexValidator.ts @@ -0,0 +1,22 @@ +import StringValidator from "./StringValidator" +import { s } from "vitest/dist/env-afee91f0" +import { Translation } from "../../i18n/Translation" +import Translations from "../../i18n/Translations" + +export default class RegexValidator extends StringValidator{ + constructor() { + super("regex", "Validates a regex") + } + + getFeedback(s: string): Translation | undefined { + try{ + new RegExp(s) + }catch (e) { + return Translations.T("Not a valid Regex: "+e) + } + } + + isValid(s: string): boolean { + return this.getFeedback(s) === undefined + } +}
Key