From 2f89f9203d07e9d65aaa2e54db3403aeb0a42f8c Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Mon, 7 Jul 2025 18:26:04 +0200 Subject: [PATCH] Feature: add 'copy-button' capabilities --- langs/en.json | 7 + public/css/index-tailwind-output.css | 12 +- .../ThemeConfig/Conversion/PrepareLayer.ts | 16 +- src/UI/Base/Popup.svelte | 2 +- src/UI/Popup/AddNewPoint/CreateCopy.svelte | 159 ++++++++++++++++++ .../UISpecialVisualisations.ts | 18 ++ 6 files changed, 204 insertions(+), 10 deletions(-) create mode 100644 src/UI/Popup/AddNewPoint/CreateCopy.svelte diff --git a/langs/en.json b/langs/en.json index 237d888a8..7fafac790 100644 --- a/langs/en.json +++ b/langs/en.json @@ -23,6 +23,13 @@ "intro": "Get in touch with other people to get to know them, learn from them, …", "title": "Get in touch with others" }, + "copy": { + "button": "Create a copy", + "confirm": "Create copy at the specified location", + "intro": "Creating a copy will create a new POI on the map with the same properties as the current object.", + "loading": "Creating a copy...", + "title": "Create a copy" + }, "delete": { "cancel": "Cancel", "cannotBeDeleted": "This feature can not be deleted", diff --git a/public/css/index-tailwind-output.css b/public/css/index-tailwind-output.css index c5ea56e4c..71b0e8608 100644 --- a/public/css/index-tailwind-output.css +++ b/public/css/index-tailwind-output.css @@ -1766,6 +1766,10 @@ input[type="range"].range-lg::-moz-range-thumb { height: 0.875rem; } +.h-3\/4 { + height: 75%; +} + .h-32 { height: 8rem; } @@ -8420,10 +8424,6 @@ svg.apply-fill path { width: auto; } - .sm\:grow-0 { - flex-grow: 0; - } - .sm\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } @@ -8436,10 +8436,6 @@ svg.apply-fill path { flex-wrap: nowrap; } - .sm\:justify-start { - justify-content: flex-start; - } - .sm\:gap-y-3 { row-gap: 0.75rem; } diff --git a/src/Models/ThemeConfig/Conversion/PrepareLayer.ts b/src/Models/ThemeConfig/Conversion/PrepareLayer.ts index 984987cd8..84acbefe9 100644 --- a/src/Models/ThemeConfig/Conversion/PrepareLayer.ts +++ b/src/Models/ThemeConfig/Conversion/PrepareLayer.ts @@ -408,6 +408,12 @@ export class AddEditingElements extends DesugaringStep { delete json.allowSplit } + if (json.allowCopy && !usedSpecialFunctions.has("create_copy")) { + json.tagRenderings.push({ + id: "create_copy", + render: { "*": "{create_copy()}" }, + }) + } if (json.allowMove && !usedSpecialFunctions.has("move_button")) { json.tagRenderings.push({ id: "move-button", @@ -421,6 +427,14 @@ export class AddEditingElements extends DesugaringStep { }) } + const spacerIndex = json.tagRenderings.findIndex(item => item?.["id"] === "spacer") + if (spacerIndex >= 0) { + json.tagRenderings.splice(spacerIndex, 1) + } + json.tagRenderings.push({ + id: "spacer", + render: { "*": "
" }, + }) json.tagRenderings.push(...this._addedByDefault.filter((tr) => !allIds.has(tr.id))) if (!usedSpecialFunctions.has("all_tags")) { @@ -893,7 +907,7 @@ class AddFavouriteBadges extends DesugaringStep { const pr = json.pointRendering?.[0] if (pr) { pr.iconBadges ??= [] - if (!pr.iconBadges.some((ti) => ti.if === "_favourite=yes")) { + if (!pr.iconBadges.some((ti) => ti["if"] === "_favourite=yes")) { pr.iconBadges.push({ if: "_favourite=yes", then: "circle:white;heart:red" }) } } diff --git a/src/UI/Base/Popup.svelte b/src/UI/Base/Popup.svelte index f5290107b..9aab9c590 100644 --- a/src/UI/Base/Popup.svelte +++ b/src/UI/Base/Popup.svelte @@ -30,7 +30,7 @@ dialogClass += " h-full-child" } let bodyClass = - bodyPadding + " h-full space-y-4 flex-1 overflow-y-auto overscroll-contain background-normal" + bodyPadding + " h-full max-h-leave-room space-y-4 flex-1 overflow-y-auto overscroll-contain background-normal" let headerClass = "flex justify-between items-center p-2 px-4 md:px-5 rounded-t-lg" if (!$$slots.header) { diff --git a/src/UI/Popup/AddNewPoint/CreateCopy.svelte b/src/UI/Popup/AddNewPoint/CreateCopy.svelte new file mode 100644 index 000000000..7ba0a4a05 --- /dev/null +++ b/src/UI/Popup/AddNewPoint/CreateCopy.svelte @@ -0,0 +1,159 @@ + + + + + + {#if $creatingCopy} +
+
+ + + + +
+
+ {:else} + +
+ + +
+ { + preciseInputIsTapped = true + }} + value={preciseCoordinate} + snappedTo={snappedToObject} + {state} + {coordinate} + targetLayer={layer} + presetProperties={$asTags} + /> +
+ + createCopy()} clss="primary w-fit"> +
+ + +
+
+
+
+ +
+
+ +
+ createCopy()}> + + + + +
+ {#if showTags} +
+ +
+ {/if} +
+ {/if} + +
+ +
+ + +
diff --git a/src/UI/SpecialVisualisations/UISpecialVisualisations.ts b/src/UI/SpecialVisualisations/UISpecialVisualisations.ts index cc840d2cf..1a2092ba3 100644 --- a/src/UI/SpecialVisualisations/UISpecialVisualisations.ts +++ b/src/UI/SpecialVisualisations/UISpecialVisualisations.ts @@ -18,6 +18,7 @@ import { VariableUiElement } from "../Base/VariableUIElement" import { Translation } from "../i18n/Translation" import { FixedUiElement } from "../Base/FixedUiElement" import { default as FeatureTitle } from "../Popup/Title.svelte" +import CreateCopy from "../Popup/AddNewPoint/CreateCopy.svelte" /** * Thin wrapper around QuestionBox.svelte to include it into the special Visualisations @@ -336,6 +337,22 @@ class BracedVis extends SpecialVisualization { } +class CreateCopyVis extends SpecialVisualizationSvelte { + group= "UI" + funcName="create_copy" + docs = "Allow to create a copy of the current element" + args = [] + constr(state: SpecialVisualizationState, tags: UIEventSource>, argument: string[], feature: Feature, layer: LayerConfig): SvelteUIElement { + + try{ + console.log(">>> create_copy invoked") + return new SvelteUIElement(CreateCopy, {state, tags, argument, feature, layer} ) + }catch (e) { + console.error(">>> failed",e) + } + } +} + export class UISpecialVisualisations { public static initList(): SpecialVisualization[] { return [ @@ -348,6 +365,7 @@ export class UISpecialVisualisations { new IfNothingKnown(), new ShareLinkViz(), new AddNewPointVis(), + new CreateCopyVis(), new Translated(), new BracedVis(), new TitleVis(),