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,14 +26,34 @@ 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,
|
||||||
allElements: ElementStorage,
|
allElements: ElementStorage,
|
||||||
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