forked from MapComplete/MapComplete
		
	Styling tweaks, better metadata handling at data upload
This commit is contained in:
		
							parent
							
								
									87bf376b2e
								
							
						
					
					
						commit
						bf7e6376c0
					
				
					 5 changed files with 108 additions and 85 deletions
				
			
		|  | @ -10,12 +10,11 @@ import Constants from "../../Models/Constants"; | ||||||
| 
 | 
 | ||||||
| export class ChangesetHandler { | export class ChangesetHandler { | ||||||
| 
 | 
 | ||||||
|  |     public readonly currentChangeset: UIEventSource<string>; | ||||||
|     private readonly _dryRun: boolean; |     private readonly _dryRun: boolean; | ||||||
|     private readonly userDetails: UIEventSource<UserDetails>; |     private readonly userDetails: UIEventSource<UserDetails>; | ||||||
|     private readonly auth: any; |     private readonly auth: any; | ||||||
| 
 | 
 | ||||||
|     public readonly currentChangeset: UIEventSource<string>; |  | ||||||
| 
 |  | ||||||
|     constructor(layoutName: string, dryRun: boolean, osmConnection: OsmConnection, auth) { |     constructor(layoutName: string, dryRun: boolean, osmConnection: OsmConnection, auth) { | ||||||
|         this._dryRun = dryRun; |         this._dryRun = dryRun; | ||||||
|         this.userDetails = osmConnection.userDetails; |         this.userDetails = osmConnection.userDetails; | ||||||
|  | @ -27,6 +26,26 @@ export class ChangesetHandler { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private static parseUploadChangesetResponse(response: XMLDocument, allElements: ElementStorage) { | ||||||
|  |         const nodes = response.getElementsByTagName("node"); | ||||||
|  |         // @ts-ignore
 | ||||||
|  |         for (const node of nodes) { | ||||||
|  |             const oldId = parseInt(node.attributes.old_id.value); | ||||||
|  |             const newId = parseInt(node.attributes.new_id.value); | ||||||
|  |             if (oldId !== undefined && newId !== undefined && | ||||||
|  |                 !isNaN(oldId) && !isNaN(newId)) { | ||||||
|  |                 if (oldId == newId) { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |                 console.log("Rewriting id: ", oldId, "-->", newId); | ||||||
|  |                 const element = allElements.getEventSourceById("node/" + oldId); | ||||||
|  |                 element.data.id = "node/" + newId; | ||||||
|  |                 allElements.addElementById("node/" + newId, element); | ||||||
|  |                 element.ping(); | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     public UploadChangeset( |     public UploadChangeset( | ||||||
|         layout: LayoutConfig, |         layout: LayoutConfig, | ||||||
|  | @ -34,7 +53,7 @@ export class ChangesetHandler { | ||||||
|         generateChangeXML: (csid: string) => string, |         generateChangeXML: (csid: string) => string, | ||||||
|         continuation: () => void) { |         continuation: () => void) { | ||||||
| 
 | 
 | ||||||
|         if(this.userDetails.data.csCount == 0){ |         if (this.userDetails.data.csCount == 0) { | ||||||
|             // The user became a contributor!
 |             // The user became a contributor!
 | ||||||
|             this.userDetails.data.csCount = 1; |             this.userDetails.data.csCount = 1; | ||||||
|             this.userDetails.ping(); |             this.userDetails.ping(); | ||||||
|  | @ -51,7 +70,7 @@ export class ChangesetHandler { | ||||||
| 
 | 
 | ||||||
|         if (this.currentChangeset.data === undefined || this.currentChangeset.data === "") { |         if (this.currentChangeset.data === undefined || this.currentChangeset.data === "") { | ||||||
|             // We have to open a new changeset
 |             // We have to open a new changeset
 | ||||||
|             this.OpenChangeset(layout,(csId) => { |             this.OpenChangeset(layout, (csId) => { | ||||||
|                 this.currentChangeset.setData(csId); |                 this.currentChangeset.setData(csId); | ||||||
|                 const changeset = generateChangeXML(csId); |                 const changeset = generateChangeXML(csId); | ||||||
|                 console.log(changeset); |                 console.log(changeset); | ||||||
|  | @ -86,31 +105,61 @@ export class ChangesetHandler { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public CloseChangeset(changesetId: string = undefined, continuation: (() => void) = () => { | ||||||
|  |     }) { | ||||||
|  |         if (changesetId === undefined) { | ||||||
|  |             changesetId = this.currentChangeset.data; | ||||||
|  |         } | ||||||
|  |         if (changesetId === undefined) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         console.log("closing changeset", changesetId); | ||||||
|  |         this.currentChangeset.setData(""); | ||||||
|  |         this.auth.xhr({ | ||||||
|  |             method: 'PUT', | ||||||
|  |             path: '/api/0.6/changeset/' + changesetId + '/close', | ||||||
|  |         }, function (err, response) { | ||||||
|  |             if (response == null) { | ||||||
|  | 
 | ||||||
|  |                 console.log("err", err); | ||||||
|  |             } | ||||||
|  |             console.log("Closed changeset ", changesetId) | ||||||
|  | 
 | ||||||
|  |             if (continuation !== undefined) { | ||||||
|  |                 continuation(); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     private OpenChangeset( |     private OpenChangeset( | ||||||
|         layout : LayoutConfig, |         layout: LayoutConfig, | ||||||
|         continuation: (changesetId: string) => void) { |         continuation: (changesetId: string) => void) { | ||||||
| 
 | 
 | ||||||
|         const commentExtra = layout.changesetmessage !== undefined ? " - " + layout.changesetmessage : ""; |         const commentExtra = layout.changesetmessage !== undefined ? " - " + layout.changesetmessage : ""; | ||||||
| 
 | 
 | ||||||
|         let surveySource = ""; |         let path = window.location.pathname; | ||||||
|         if (State.state.currentGPSLocation.data !== undefined) { |         path = path.substr(1, path.lastIndexOf("/")); | ||||||
|             surveySource = '<tag k="source" v="survey"/>' |         const metadata = [ | ||||||
|         } |             ["created_by", `MapComplete ${Constants.vNumber}`], | ||||||
|  |             ["comment", `Adding data with #MapComplete for theme #${layout.id}${commentExtra}`], | ||||||
|  |             ["theme", layout.id], | ||||||
|  |             ["language", Locale.language.data], | ||||||
|  |             ["host", window.location.host], | ||||||
|  |             ["path", path], | ||||||
|  |             ["source", State.state.currentGPSLocation.data !== undefined ? "survey" : undefined], | ||||||
|  |             ["imagery", State.state.backgroundLayer.data.id], | ||||||
|  |             ["theme-creator", layout.maintainer] | ||||||
|  |         ] | ||||||
|  |             .filter(kv => (kv[1] ?? "") !== "") | ||||||
|  |             .map(kv => `<tag k="${kv[0]}" v="${escapeHtml(kv[1])}"/>`) | ||||||
|  |             .join("\n") | ||||||
| 
 | 
 | ||||||
|         this.auth.xhr({ |         this.auth.xhr({ | ||||||
|             method: 'PUT', |             method: 'PUT', | ||||||
|             path: '/api/0.6/changeset/create', |             path: '/api/0.6/changeset/create', | ||||||
|             options: {header: {'Content-Type': 'text/xml'}}, |             options: {header: {'Content-Type': 'text/xml'}}, | ||||||
|             content: [`<osm><changeset>`, |             content: [`<osm><changeset>`, | ||||||
|                 `<tag k="created_by" v="MapComplete ${Constants.vNumber}" />`, |                 metadata, | ||||||
|                 `<tag k="comment" v="Adding data with #MapComplete for theme #${layout.id}${commentExtra}"/>`, |  | ||||||
|                 `<tag k="theme" v="${layout.id}"/>`, |  | ||||||
|                 `<tag k="language" v="${Locale.language.data}"/>`, |  | ||||||
|                 `<tag k="host" v="${escapeHtml(window.location.host)}"/>`, |  | ||||||
|                 `<tag k="imagery" v="${State.state.backgroundLayer.data.id}"/>`, |  | ||||||
|                 surveySource, |  | ||||||
|                 (layout.maintainer ?? "") !== "" ? `<tag k="theme-creator" v="${escapeHtml(layout.maintainer)}"/>` : "", |  | ||||||
|                 `</changeset></osm>`].join("") |                 `</changeset></osm>`].join("") | ||||||
|         }, function (err, response) { |         }, function (err, response) { | ||||||
|             if (response === undefined) { |             if (response === undefined) { | ||||||
|  | @ -147,52 +196,5 @@ export class ChangesetHandler { | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public CloseChangeset(changesetId: string = undefined, continuation: (() => void) = () => { |  | ||||||
|     }) { |  | ||||||
|         if (changesetId === undefined) { |  | ||||||
|             changesetId = this.currentChangeset.data; |  | ||||||
|         } |  | ||||||
|         if (changesetId === undefined) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         console.log("closing changeset", changesetId); |  | ||||||
|         this.currentChangeset.setData(""); |  | ||||||
|         this.auth.xhr({ |  | ||||||
|             method: 'PUT', |  | ||||||
|             path: '/api/0.6/changeset/' + changesetId + '/close', |  | ||||||
|         }, function (err, response) { |  | ||||||
|             if (response == null) { |  | ||||||
| 
 |  | ||||||
|                 console.log("err", err); |  | ||||||
|             } |  | ||||||
|             console.log("Closed changeset ", changesetId) |  | ||||||
| 
 |  | ||||||
|             if (continuation !== undefined) { |  | ||||||
|                 continuation(); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static parseUploadChangesetResponse(response: XMLDocument, allElements: ElementStorage) { |  | ||||||
|         const nodes = response.getElementsByTagName("node"); |  | ||||||
|         // @ts-ignore
 |  | ||||||
|         for (const node of nodes) { |  | ||||||
|             const oldId = parseInt(node.attributes.old_id.value); |  | ||||||
|             const newId = parseInt(node.attributes.new_id.value); |  | ||||||
|             if (oldId !== undefined && newId !== undefined && |  | ||||||
|                 !isNaN(oldId) && !isNaN(newId)) { |  | ||||||
|                 if(oldId == newId){ |  | ||||||
|                     continue; |  | ||||||
|                 } |  | ||||||
|                 console.log("Rewriting id: ", oldId, "-->", newId); |  | ||||||
|                 const element = allElements.getEventSourceById("node/" + oldId); |  | ||||||
|                 element.data.id = "node/" + newId; |  | ||||||
|                 allElements.addElementById("node/" + newId, element); |  | ||||||
|                 element.ping(); |  | ||||||
| 
 |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | @ -25,7 +25,7 @@ export class SubtleButton extends UIElement { | ||||||
|         if ((imageUrl ?? "") === "") { |         if ((imageUrl ?? "") === "") { | ||||||
|             img = undefined; |             img = undefined; | ||||||
|         } else if (typeof (imageUrl) === "string") { |         } else if (typeof (imageUrl) === "string") { | ||||||
|             img = new Img(imageUrl).SetClass("w-full") |             img = new Img(imageUrl) | ||||||
|         } else { |         } else { | ||||||
|             img = imageUrl; |             img = imageUrl; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -159,8 +159,7 @@ export default class SimpleAddUI extends Toggle { | ||||||
|         return new Toggle( |         return new Toggle( | ||||||
|             Translations.t.general.presetInfo.Subs({ |             Translations.t.general.presetInfo.Subs({ | ||||||
|                 tags: preset.tags.map(t => t.asHumanString(optionallyLinkToWiki && csCount > Constants.userJourney.tagsVisibleAndWikiLinked, true)).join("&"), |                 tags: preset.tags.map(t => t.asHumanString(optionallyLinkToWiki && csCount > Constants.userJourney.tagsVisibleAndWikiLinked, true)).join("&"), | ||||||
| 
 |             }).SetStyle("word-break: break-all"), | ||||||
|             }), |  | ||||||
| 
 | 
 | ||||||
|             undefined, |             undefined, | ||||||
|             State.state.osmConnection.userDetails.map(userdetails => userdetails.csCount >= Constants.userJourney.tagsVisibleAt) |             State.state.osmConnection.userDetails.map(userdetails => userdetails.csCount >= Constants.userJourney.tagsVisibleAt) | ||||||
|  |  | ||||||
|  | @ -44,7 +44,7 @@ export default class CheckBoxes extends InputElement<number[]> { | ||||||
|             input.id = "checkbox" + id |             input.id = "checkbox" + id | ||||||
| 
 | 
 | ||||||
|             input.type = "checkbox" |             input.type = "checkbox" | ||||||
|             input.classList.add("p-1","cursor-pointer","ml-3","pl-3") |             input.classList.add("p-1","cursor-pointer","m-3","pl-3","mr-0") | ||||||
| 
 | 
 | ||||||
|             const label = document.createElement("label") |             const label = document.createElement("label") | ||||||
|             label.htmlFor = input.id |             label.htmlFor = input.id | ||||||
|  | @ -52,7 +52,7 @@ export default class CheckBoxes extends InputElement<number[]> { | ||||||
|             label.classList.add("block","w-full","p-2","cursor-pointer","bg-red") |             label.classList.add("block","w-full","p-2","cursor-pointer","bg-red") | ||||||
| 
 | 
 | ||||||
|             const wrapper = document.createElement("span") |             const wrapper = document.createElement("span") | ||||||
|             wrapper.classList.add("flex","w-full","border", "border-gray-400") |             wrapper.classList.add("flex","w-full","border", "border-gray-400","m-1") | ||||||
|             wrapper.appendChild(input) |             wrapper.appendChild(input) | ||||||
|             wrapper.appendChild(label) |             wrapper.appendChild(label) | ||||||
|             el.appendChild(wrapper) |             el.appendChild(wrapper) | ||||||
|  | @ -64,6 +64,16 @@ export default class CheckBoxes extends InputElement<number[]> { | ||||||
|                 if (selectedValues.indexOf(i) >= 0) { |                 if (selectedValues.indexOf(i) >= 0) { | ||||||
|                     input.checked = true; |                     input.checked = true; | ||||||
|                 } |                 } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                 if(input.checked){ | ||||||
|  |                     wrapper.classList.remove("border-gray-400") | ||||||
|  |                     wrapper.classList.add("border-black") | ||||||
|  |                 }else{ | ||||||
|  |                     wrapper.classList.add("border-gray-400") | ||||||
|  |                     wrapper.classList.remove("border-black") | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|             }) |             }) | ||||||
| 
 | 
 | ||||||
|             input.onchange = () => { |             input.onchange = () => { | ||||||
|  |  | ||||||
|  | @ -70,18 +70,7 @@ export class RadioButton<T> extends InputElement<T> { | ||||||
| 
 | 
 | ||||||
|         const form = document.createElement("form") |         const form = document.createElement("form") | ||||||
|         const inputs = [] |         const inputs = [] | ||||||
| 
 |         const wrappers: HTMLElement[] = [] | ||||||
|         value.addCallbackAndRun( |  | ||||||
|             selected => { |  | ||||||
|                  |  | ||||||
|                 let somethingChecked = false; |  | ||||||
|                 for (let i = 0; i < inputs.length; i++){ |  | ||||||
|                     let input = inputs[i]; |  | ||||||
|                     input.checked = !somethingChecked && elements[i].IsValid(selected); |  | ||||||
|                     somethingChecked = somethingChecked || input.checked |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         ) |  | ||||||
|          |          | ||||||
|         for (let i1 = 0; i1 < elements.length; i1++) { |         for (let i1 = 0; i1 < elements.length; i1++) { | ||||||
|             let element = elements[i1]; |             let element = elements[i1]; | ||||||
|  | @ -94,7 +83,7 @@ export class RadioButton<T> extends InputElement<T> { | ||||||
|             input.id = "radio" + groupId + "-" + i1; |             input.id = "radio" + groupId + "-" + i1; | ||||||
|             input.name = groupId; |             input.name = groupId; | ||||||
|             input.type = "radio" |             input.type = "radio" | ||||||
|                input.classList.add("p-1","cursor-pointer","ml-2","pl-2","pr-0","m-0","ml-3") |                input.classList.add("p-1","cursor-pointer","ml-2","pl-2","pr-0","m-3","mr-0") | ||||||
| 
 | 
 | ||||||
|             input.onchange = () => { |             input.onchange = () => { | ||||||
|                 if(input.checked){ |                 if(input.checked){ | ||||||
|  | @ -114,12 +103,35 @@ export class RadioButton<T> extends InputElement<T> { | ||||||
|             const block = document.createElement("div") |             const block = document.createElement("div") | ||||||
|             block.appendChild(input) |             block.appendChild(input) | ||||||
|             block.appendChild(label) |             block.appendChild(label) | ||||||
|             block.classList.add("flex","w-full","border", "rounded-full", "border-gray-400") |             block.classList.add("flex","w-full","border", "rounded-full", "border-gray-400","m-1") | ||||||
|  |             wrappers.push(block) | ||||||
| 
 | 
 | ||||||
|             form.appendChild(block) |             form.appendChild(block) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |         value.addCallbackAndRun( | ||||||
|  |             selected => { | ||||||
|  | 
 | ||||||
|  |                 let somethingChecked = false; | ||||||
|  |                 for (let i = 0; i < inputs.length; i++){ | ||||||
|  |                     let input = inputs[i]; | ||||||
|  |                     input.checked = !somethingChecked && elements[i].IsValid(selected); | ||||||
|  |                     somethingChecked = somethingChecked || input.checked | ||||||
|  | 
 | ||||||
|  |                     if(input.checked){ | ||||||
|  |                         wrappers[i].classList.remove("border-gray-400") | ||||||
|  |                         wrappers[i].classList.add("border-black") | ||||||
|  |                     }else{ | ||||||
|  |                         wrappers[i].classList.add("border-gray-400") | ||||||
|  |                         wrappers[i].classList.remove("border-black") | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|         this.SetClass("flex flex-col") |         this.SetClass("flex flex-col") | ||||||
|         return form; |         return form; | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue