UX: add indicicator in settings of pending changes, add button to clear the selected changes

This commit is contained in:
Pieter Vander Vennet 2024-08-02 13:31:45 +02:00
parent 13d00608d5
commit 2e7703c8ec
5 changed files with 59 additions and 7 deletions

View file

@ -901,6 +901,12 @@
} }
] ]
}, },
{
"id": "pending_changes",
"render": {
"*": "{pending_changes()}"
}
},
{ {
"id": "show_debug", "id": "show_debug",
"question": { "question": {

View file

@ -213,6 +213,7 @@
"backgroundMap": "Select a background layer", "backgroundMap": "Select a background layer",
"backgroundSwitch": "Switch background", "backgroundSwitch": "Switch background",
"cancel": "Cancel", "cancel": "Cancel",
"clearPendingChanges": "Clear pending changes",
"confirm": "Confirm", "confirm": "Confirm",
"customThemeIntro": "These are previously visited user-generated themes.", "customThemeIntro": "These are previously visited user-generated themes.",
"customThemeTitle": "Custom themes", "customThemeTitle": "Custom themes",

View file

@ -218,7 +218,7 @@ export class TagUtils {
* *
* TagUtils.KVtoProperties([new Tag("a","b"), new Tag("c","d")] // => {a: "b", c: "d"} * TagUtils.KVtoProperties([new Tag("a","b"), new Tag("c","d")] // => {a: "b", c: "d"}
*/ */
static KVtoProperties(tags: Tag[]): Record<string, string> { static KVtoProperties(tags: {key: string, value: string}[]): Record<string, string> {
const properties: Record<string, string> = {} const properties: Record<string, string> = {}
for (const tag of tags) { for (const tag of tags) {
properties[tag.key] = tag.value properties[tag.key] = tag.value
@ -226,6 +226,14 @@ export class TagUtils {
return properties return properties
} }
static KVObjtoProperties(tags: {k: string, v: string}[]): Record<string, string> {
const properties: Record<string, string> = {}
for (const tag of tags) {
properties[tag.k] = tag.v
}
return properties
}
static changeAsProperties(kvs: { k: string; v: string }[]): Record<string, string> { static changeAsProperties(kvs: { k: string; v: string }[]): Record<string, string> {
const tags: Record<string, string> = {} const tags: Record<string, string> = {}
for (const kv of kvs) { for (const kv of kvs) {

View file

@ -5,13 +5,15 @@
import Loading from "../Base/Loading.svelte" import Loading from "../Base/Loading.svelte"
import Translations from "../i18n/Translations" import Translations from "../i18n/Translations"
import Tr from "../Base/Tr.svelte" import Tr from "../Base/Tr.svelte"
import { TagUtils } from "../../Logic/Tags/TagUtils"
export let state: SpecialVisualizationState export let state: SpecialVisualizationState
export let compact: boolean = true
const changes: Changes = state.changes const changes: Changes = state.changes
const isUploading: Store<boolean> = changes.isUploading const isUploading: Store<boolean> = changes.isUploading
const pendingChangesCount: Store<number> = changes.pendingChanges.map((ls) => ls.length)
const errors = changes.errors const errors = changes.errors
const pending = changes.pendingChanges
</script> </script>
<div <div
@ -22,16 +24,43 @@
<Loading> <Loading>
<Tr cls="thx" t={Translations.t.general.uploadingChanges} /> <Tr cls="thx" t={Translations.t.general.uploadingChanges} />
</Loading> </Loading>
{:else if $pendingChangesCount === 1} {:else if $pending.length === 1}
<Tr cls="alert" t={Translations.t.general.uploadPendingSingle} /> <Tr cls="alert" t={Translations.t.general.uploadPendingSingle} />
{:else if $pendingChangesCount > 1} {:else if $pending.length > 1}
<Tr <Tr
cls="alert" cls="alert"
t={Translations.t.general.uploadPending.Subs({ count: $pendingChangesCount })} t={Translations.t.general.uploadPending.Subs({ count: $pending.length })}
/> />
{/if} {/if}
{#each $errors as error} {#each $errors as error}
<Tr cls="alert" t={Translations.t.general.uploadError.Subs({ error })} /> <Tr cls="alert" t={Translations.t.general.uploadError.Subs({ error })} />
{/each} {/each}
{#if !compact && $pending.length > 0}
<button on:click={() => state.changes.pendingChanges.set([])}>
<Tr t={Translations.t.general.clearPendingChanges} />
</button>
<ul>
{#each $pending as pending}
<li>
{#if pending.changes !== undefined}
Create {pending.type}/{pending.id} {JSON.stringify(TagUtils.KVObjtoProperties(pending.tags))}
{:else}
Modify {pending.type}/{pending.id} {JSON.stringify(pending.tags)}
{/if}
{#if pending.type === "way" && pending.changes?.nodes}
{pending.changes.nodes.join(" ")}
{/if}
</li>
{/each}
</ul>
{/if}
</div> </div>

View file

@ -99,6 +99,7 @@ import NothingKnown from "./Popup/NothingKnown.svelte"
import { CombinedFetcher } from "../Logic/Web/NearbyImagesSearch" import { CombinedFetcher } from "../Logic/Web/NearbyImagesSearch"
import { And } from "../Logic/Tags/And" import { And } from "../Logic/Tags/And"
import CloseNoteButton from "./Popup/Notes/CloseNoteButton.svelte" import CloseNoteButton from "./Popup/Notes/CloseNoteButton.svelte"
import PendingChangesIndicator from "./BigComponents/PendingChangesIndicator.svelte"
class NearbyImageVis implements SpecialVisualization { class NearbyImageVis implements SpecialVisualization {
// Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests // Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests
@ -118,7 +119,6 @@ class NearbyImageVis implements SpecialVisualization {
"A component showing nearby images loaded from various online services such as Mapillary. In edit mode and when used on a feature, the user can select an image to add to the feature" "A component showing nearby images loaded from various online services such as Mapillary. In edit mode and when used on a feature, the user can select an image to add to the feature"
funcName = "nearby_images" funcName = "nearby_images"
needsUrls = CombinedFetcher.apiUrls needsUrls = CombinedFetcher.apiUrls
svelteBased = true
constr( constr(
state: SpecialVisualizationState, state: SpecialVisualizationState,
@ -2014,8 +2014,16 @@ export default class SpecialVisualizations {
return mostShadowed?.description ?? matchingPresets[0]?.description return mostShadowed?.description ?? matchingPresets[0]?.description
}) })
return new VariableUiElement(translation) return new VariableUiElement(translation)
}, }
}, },
{
funcName:"pending_changes",
docs: "A module showing the pending changes, with the option to clear the pending changes",
args:[],
constr(state: SpecialVisualizationState, tagSource: UIEventSource<Record<string, string>>, argument: string[], feature: Feature, layer: LayerConfig): BaseUIElement {
return new SvelteUIElement(PendingChangesIndicator, {state, compact: false})
}
}
] ]
specialVisualizations.push(new AutoApplyButton(specialVisualizations)) specialVisualizations.push(new AutoApplyButton(specialVisualizations))