| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  | import {Store} from "../../Logic/UIEventSource"; | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  | import BaseUIElement from "../BaseUIElement"; | 
					
						
							|  |  |  | import Combine from "../Base/Combine"; | 
					
						
							|  |  |  | import {SubtleButton} from "../Base/SubtleButton"; | 
					
						
							|  |  |  | import {Changes} from "../../Logic/Osm/Changes"; | 
					
						
							|  |  |  | import {FixedUiElement} from "../Base/FixedUiElement"; | 
					
						
							|  |  |  | import Translations from "../i18n/Translations"; | 
					
						
							|  |  |  | import {VariableUiElement} from "../Base/VariableUIElement"; | 
					
						
							|  |  |  | import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction"; | 
					
						
							|  |  |  | import {Tag} from "../../Logic/Tags/Tag"; | 
					
						
							|  |  |  | import {ElementStorage} from "../../Logic/ElementStorage"; | 
					
						
							|  |  |  | import {And} from "../../Logic/Tags/And"; | 
					
						
							|  |  |  | import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; | 
					
						
							|  |  |  | import Toggle from "../Input/Toggle"; | 
					
						
							|  |  |  | import {OsmConnection} from "../../Logic/Osm/OsmConnection"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export interface MultiApplyParams { | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |     featureIds: Store<string[]>, | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |     keysToApply: string[], | 
					
						
							|  |  |  |     text: string, | 
					
						
							|  |  |  |     autoapply: boolean, | 
					
						
							|  |  |  |     overwrite: boolean, | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |     tagsSource: Store<any>, | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |     state: { | 
					
						
							|  |  |  |         changes: Changes, | 
					
						
							|  |  |  |         allElements: ElementStorage, | 
					
						
							|  |  |  |         layoutToUse: LayoutConfig, | 
					
						
							|  |  |  |         osmConnection: OsmConnection | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MultiApplyExecutor { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-07 16:34:51 +01:00
										 |  |  |     private static executorCache = new Map<string, MultiApplyExecutor>() | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |     private readonly originalValues = new Map<string, string>() | 
					
						
							|  |  |  |     private readonly params: MultiApplyParams; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private constructor(params: MultiApplyParams) { | 
					
						
							|  |  |  |         this.params = params; | 
					
						
							|  |  |  |         const p = params | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const key of p.keysToApply) { | 
					
						
							|  |  |  |             this.originalValues.set(key, p.tagsSource.data[key]) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (p.autoapply) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const self = this; | 
					
						
							|  |  |  |             const relevantValues = p.tagsSource.map(tags => { | 
					
						
							|  |  |  |                 const currentValues = p.keysToApply.map(key => tags[key]) | 
					
						
							| 
									
										
										
										
											2021-11-07 16:34:51 +01:00
										 |  |  |                 // By stringifying, we have a very clear ping when they changec
 | 
					
						
							| 
									
										
										
										
											2021-10-12 02:25:31 +02:00
										 |  |  |                 return JSON.stringify(currentValues); | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |             }) | 
					
						
							|  |  |  |             relevantValues.addCallbackD(_ => { | 
					
						
							|  |  |  |                 self.applyTaggingOnOtherFeatures() | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-07 16:34:51 +01:00
										 |  |  |     public static GetApplicator(id: string, params: MultiApplyParams): MultiApplyExecutor { | 
					
						
							|  |  |  |         if (MultiApplyExecutor.executorCache.has(id)) { | 
					
						
							|  |  |  |             return MultiApplyExecutor.executorCache.get(id) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const applicator = new MultiApplyExecutor(params) | 
					
						
							|  |  |  |         MultiApplyExecutor.executorCache.set(id, applicator) | 
					
						
							|  |  |  |         return applicator | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |     public applyTaggingOnOtherFeatures() { | 
					
						
							|  |  |  |         console.log("Multi-applying changes...") | 
					
						
							|  |  |  |         const featuresToChange = this.params.featureIds.data | 
					
						
							|  |  |  |         const changes = this.params.state.changes | 
					
						
							|  |  |  |         const allElements = this.params.state.allElements | 
					
						
							|  |  |  |         const keysToChange = this.params.keysToApply | 
					
						
							|  |  |  |         const overwrite = this.params.overwrite | 
					
						
							|  |  |  |         const selfTags = this.params.tagsSource.data; | 
					
						
							|  |  |  |         const theme = this.params.state.layoutToUse.id | 
					
						
							|  |  |  |         for (const id of featuresToChange) { | 
					
						
							|  |  |  |             const tagsToApply: Tag[] = [] | 
					
						
							|  |  |  |             const otherFeatureTags = allElements.getEventSourceById(id).data | 
					
						
							|  |  |  |             for (const key of keysToChange) { | 
					
						
							|  |  |  |                 const newValue = selfTags[key] | 
					
						
							|  |  |  |                 if (newValue === undefined) { | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 const otherValue = otherFeatureTags[key] | 
					
						
							|  |  |  |                 if (newValue === otherValue) { | 
					
						
							|  |  |  |                     continue;// No changes to be made
 | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (overwrite) { | 
					
						
							|  |  |  |                     tagsToApply.push(new Tag(key, newValue)) | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (otherValue === undefined || otherValue === "" || otherValue === this.originalValues.get(key)) { | 
					
						
							|  |  |  |                     tagsToApply.push(new Tag(key, newValue)) | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (tagsToApply.length == 0) { | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             changes.applyAction( | 
					
						
							|  |  |  |                 new ChangeTagAction(id, new And(tagsToApply), otherFeatureTags, { | 
					
						
							|  |  |  |                     theme, | 
					
						
							|  |  |  |                     changeType: "answer" | 
					
						
							|  |  |  |                 })) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default class MultiApply extends Toggle { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor(params: MultiApplyParams) { | 
					
						
							|  |  |  |         const p = params | 
					
						
							|  |  |  |         const t = Translations.t.multi_apply | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-10 16:26:25 +01:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |         const featureId = p.tagsSource.data.id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (featureId === undefined) { | 
					
						
							|  |  |  |             throw "MultiApply needs a feature id" | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const applicator = MultiApplyExecutor.GetApplicator(featureId, params) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const elems: (string | BaseUIElement)[] = [] | 
					
						
							|  |  |  |         if (p.autoapply) { | 
					
						
							| 
									
										
										
										
											2021-10-12 02:25:31 +02:00
										 |  |  |             elems.push(new FixedUiElement(p.text).SetClass("block")) | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |             elems.push(new VariableUiElement(p.featureIds.map(featureIds => | 
					
						
							|  |  |  |                 t.autoApply.Subs({ | 
					
						
							|  |  |  |                     attr_names: p.keysToApply.join(", "), | 
					
						
							|  |  |  |                     count: "" + featureIds.length | 
					
						
							|  |  |  |                 }))).SetClass("block subtle text-sm")) | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             elems.push( | 
					
						
							|  |  |  |                 new SubtleButton(undefined, p.text).onClick(() => applicator.applyTaggingOnOtherFeatures()) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |         const isShown: Store<boolean> = p.state.osmConnection.isLoggedIn.map(loggedIn => { | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |             return loggedIn && p.featureIds.data.length > 0 | 
					
						
							|  |  |  |         }, [p.featureIds]) | 
					
						
							|  |  |  |         super(new Combine(elems), undefined, isShown); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |