| 
									
										
										
										
											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", | 
					
						
							|  |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default class MultiApply extends Toggle { | 
					
						
							|  |  |  |     constructor(params: MultiApplyParams) { | 
					
						
							|  |  |  |         const p = params | 
					
						
							|  |  |  |         const t = Translations.t.multi_apply | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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, | 
					
						
							|  |  |  |                         }) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |                 ).SetClass("block subtle text-sm") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             elems.push( | 
					
						
							|  |  |  |                 new SubtleButton(undefined, p.text).onClick(() => | 
					
						
							|  |  |  |                     applicator.applyTaggingOnOtherFeatures() | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2021-10-12 02:12:45 +02:00
										 |  |  |             ) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |