First steps for import helper
This commit is contained in:
parent
5c71bfa294
commit
8cb41d14ff
12 changed files with 217 additions and 146 deletions
|
@ -40,6 +40,7 @@ export default class Constants {
|
|||
addNewPointWithUnreadMessagesUnlock: 500,
|
||||
minZoomLevelToAddNewPoints: (Constants.isRetina() ? 18 : 19),
|
||||
|
||||
importHelperUnlock: 5000
|
||||
};
|
||||
/**
|
||||
* Used by 'PendingChangesUploader', which waits this amount of seconds to upload changes.
|
||||
|
|
20
UI/BigComponents/BackToIndex.ts
Normal file
20
UI/BigComponents/BackToIndex.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import {SubtleButton} from "../Base/SubtleButton";
|
||||
import Combine from "../Base/Combine";
|
||||
import Svg from "../../Svg";
|
||||
import Translations from "../i18n/Translations";
|
||||
import BaseUIElement from "../BaseUIElement";
|
||||
|
||||
export default class BackToIndex extends SubtleButton {
|
||||
|
||||
constructor(message? : string | BaseUIElement) {
|
||||
super(
|
||||
Svg.back_svg().SetStyle("height: 1.5rem;"),
|
||||
message ?? Translations.t.general.backToMapcomplete,
|
||||
{
|
||||
url: "./index.html"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -110,7 +110,7 @@ export default class MoreScreen extends Combine {
|
|||
]), {url: linkText, newTab: false});
|
||||
}
|
||||
|
||||
private static CreateProffessionalSerivesButton() {
|
||||
public static CreateProffessionalSerivesButton() {
|
||||
const t = Translations.t.professional.indexPage;
|
||||
return new Combine([
|
||||
new Title(t.hook, 4),
|
||||
|
|
60
UI/ImportHelperGui.ts
Normal file
60
UI/ImportHelperGui.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
import {FixedUiElement} from "./Base/FixedUiElement";
|
||||
import {LoginToggle} from "./Popup/LoginButton";
|
||||
import {OsmConnection} from "../Logic/Osm/OsmConnection";
|
||||
import UserRelatedState from "../Logic/State/UserRelatedState";
|
||||
import Combine from "./Base/Combine";
|
||||
import BackToIndex from "./BigComponents/BackToIndex";
|
||||
import BaseUIElement from "./BaseUIElement";
|
||||
import TableOfContents from "./Base/TableOfContents";
|
||||
import LanguagePicker from "./LanguagePicker";
|
||||
import Translations from "./i18n/Translations";
|
||||
import Constants from "../Models/Constants";
|
||||
import Toggle from "./Input/Toggle";
|
||||
import MoreScreen from "./BigComponents/MoreScreen";
|
||||
import Title from "./Base/Title";
|
||||
|
||||
export default class ImportHelperGui extends LoginToggle{
|
||||
|
||||
constructor() {
|
||||
const t = Translations.t.importHelper;
|
||||
|
||||
const state = new UserRelatedState(undefined)
|
||||
|
||||
const leftContents: BaseUIElement[] = [
|
||||
new BackToIndex().SetClass("block pl-4"),
|
||||
LanguagePicker.CreateLanguagePicker(Translations.t.importHelper.title.SupportedLanguages())?.SetClass("mt-4 self-end flex-col"),
|
||||
].map(el => el?.SetClass("pl-4"))
|
||||
|
||||
const leftBar = new Combine([
|
||||
new Combine(leftContents).SetClass("sticky top-4 m-4")
|
||||
]).SetClass("block w-full md:w-2/6 lg:w-1/6")
|
||||
|
||||
|
||||
super(
|
||||
|
||||
new Toggle(
|
||||
new Combine([
|
||||
leftBar,
|
||||
new Combine([
|
||||
new Title(t.title,1),
|
||||
t.description
|
||||
]).SetClass("flex flex-col m-8")
|
||||
]).SetClass("block md:flex")
|
||||
|
||||
,
|
||||
new Combine([
|
||||
t.lockNotice.Subs(Constants.userJourney),
|
||||
MoreScreen.CreateProffessionalSerivesButton()
|
||||
])
|
||||
|
||||
,
|
||||
state.osmConnection.userDetails.map(ud => ud.csCount >= Constants.userJourney.importHelperUnlock)),
|
||||
|
||||
"Login needed...",
|
||||
state)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
new ImportHelperGui().AttachTo("main")
|
|
@ -6,9 +6,8 @@ import Toggleable, {Accordeon} from "./Base/Toggleable";
|
|||
import List from "./Base/List";
|
||||
import BaseUIElement from "./BaseUIElement";
|
||||
import LanguagePicker from "./LanguagePicker";
|
||||
import {SubtleButton} from "./Base/SubtleButton";
|
||||
import Svg from "../Svg";
|
||||
import TableOfContents from "./Base/TableOfContents";
|
||||
import BackToIndex from "./BigComponents/BackToIndex";
|
||||
|
||||
class Snippet extends Toggleable {
|
||||
constructor(translations, ...extraContent: BaseUIElement[]) {
|
||||
|
@ -40,7 +39,7 @@ class SnippetContent extends Combine {
|
|||
}
|
||||
}
|
||||
|
||||
export default class ProfessionalGui {
|
||||
class ProfessionalGui {
|
||||
|
||||
|
||||
constructor() {
|
||||
|
@ -93,16 +92,8 @@ export default class ProfessionalGui {
|
|||
]).SetClass("flex flex-col pb-12 m-3 lg:w-3/4 lg:ml-10 link-underline")
|
||||
|
||||
|
||||
const backToIndex = new Combine([new SubtleButton(
|
||||
Svg.back_svg().SetStyle("height: 1.5rem;"),
|
||||
t.backToMapcomplete,
|
||||
{
|
||||
url: "./index.html"
|
||||
}
|
||||
)]).SetClass("block")
|
||||
|
||||
const leftContents: BaseUIElement[] = [
|
||||
backToIndex,
|
||||
new BackToIndex().SetClass("block"),
|
||||
new TableOfContents(content, {
|
||||
noTopLevel: true,
|
||||
maxDepth: 2
|
||||
|
@ -110,6 +101,7 @@ export default class ProfessionalGui {
|
|||
|
||||
LanguagePicker.CreateLanguagePicker(Translations.t.professional.title.SupportedLanguages())?.SetClass("mt-4 self-end flex-col"),
|
||||
].map(el => el?.SetClass("pl-4"))
|
||||
|
||||
const leftBar = new Combine([
|
||||
new Combine(leftContents).SetClass("sticky top-4 m-4")
|
||||
]).SetClass("block w-full md:w-2/6 lg:w-1/6")
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- WARNING: index.html serves as a template. If you want to change something, change it there -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- WARNING: index.html serves as a template. If you want to change something, change it there -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
"readMessages": "You have unread messages. Read these before deleting a point - someone might have feedback"
|
||||
},
|
||||
"general": {
|
||||
"backToMapcomplete": "Back to the theme overview",
|
||||
"loading": "Loading...",
|
||||
"pdf": {
|
||||
"generatedWith": "Generated with MapComplete.osm.be",
|
||||
|
@ -332,8 +333,7 @@
|
|||
"surveillance": "As you are reading the privacy policy, you probably care about privacy - so do we! We even made <a href='https://mapcomplete.osm.be/surveillance'>a theme showing surveillance cameras.</a> Feel free to map them all!"
|
||||
},
|
||||
"professional": {
|
||||
"backToMapcomplete": "Back to the theme overview",
|
||||
"indexPage": {
|
||||
"indexPage": {
|
||||
"hook": "Need professional support?",
|
||||
"hookMore": "We can help with setting up surveys, data imports and OpenStreetMap-consultancy",
|
||||
"button": "Discover our services"
|
||||
|
@ -463,5 +463,10 @@
|
|||
"layerName": "Possible {title}",
|
||||
"description": "A layer which imports entries for {title}",
|
||||
"popupTitle": "Possible {title}"
|
||||
},
|
||||
"importHelper": {
|
||||
"title": "Import helper",
|
||||
"description": "The import helper converts an external dataset to notes",
|
||||
"lockNotice": "This page is locked. You need {importHelperUnlock} changesets before you can access here."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
{
|
||||
"address": {
|
||||
"description": "Adresses",
|
||||
"name": "Adresses connues d’OpenStreetMap",
|
||||
"tagRenderings": {
|
||||
"fixme": {
|
||||
"question": "Précisez ce qui devrait être corrigé ici"
|
||||
},
|
||||
"housenumber": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce bâtiment n’a pas de numéro"
|
||||
}
|
||||
},
|
||||
"question": "Quel est le numéro de ce bâtiment ?",
|
||||
"render": "Son numéro est le <b>{addr:housenumber}</b>"
|
||||
},
|
||||
"street": {
|
||||
"question": "Dans quelle rue est située l’adresse ?",
|
||||
"render": "Le nom de la voie est <b>{addr:street}</b>"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Adresse connue"
|
||||
}
|
||||
},
|
||||
"ambulancestation": {
|
||||
"description": "Une station d’ambulance est un lieu où sont stockés les véhicules d’urgence ainsi que de l’équipement médical.",
|
||||
"name": "Couche des ambulances",
|
||||
|
@ -122,10 +147,12 @@
|
|||
}
|
||||
},
|
||||
"barrier": {
|
||||
"description": "Obstacles à vélo, tels que des potelets ou des barrières",
|
||||
"name": "Barrières",
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Bollard",
|
||||
"description": "Un potelet sur le chemin"
|
||||
"description": "Un potelet sur le chemin",
|
||||
"title": "Bollard"
|
||||
},
|
||||
"1": {
|
||||
"description": "Barrières cyclables, ralentissant les cyclistes",
|
||||
|
@ -153,9 +180,34 @@
|
|||
},
|
||||
"question": "Quel est le type de bollard (borne) ?"
|
||||
},
|
||||
"Cycle barrier type": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Simple, deux barrières côte à côte <img src='./assets/themes/cycle_infra/Cycle_barrier_single.png' style='width:8em'>"
|
||||
},
|
||||
"1": {
|
||||
"then": "Double, deux barrières successives"
|
||||
},
|
||||
"2": {
|
||||
"then": "Triple, trois barrières successives <img src='./assets/themes/cycle_infra/Cycle_barrier_triple.png' style='width:8em'>"
|
||||
},
|
||||
"3": {
|
||||
"then": "Poire, l’espace en hauteur est plus faible qu’au sol <img src='./assets/themes/cycle_infra/Cycle_barrier_squeeze.png' style='width:8em'>"
|
||||
}
|
||||
},
|
||||
"question": "Quel est ce type de barrière cyclable ?"
|
||||
},
|
||||
"MaxWidth": {
|
||||
"render": "Largeur maximale: {maxwidth:physical} m",
|
||||
"question": "Quelle est la largeur du passage ?"
|
||||
"question": "Quelle est la largeur du passage ?",
|
||||
"render": "Largeur maximale: {maxwidth:physical} m"
|
||||
},
|
||||
"Overlap (cyclebarrier)": {
|
||||
"question": "Quel est le chevauchement des barrières ?",
|
||||
"render": "Chevauchement : {overlap} m"
|
||||
},
|
||||
"Space between barrier (cyclebarrier)": {
|
||||
"question": "Combien d’espace sépare deux barrières successives ?",
|
||||
"render": "Espace entre deux barrières successives : {width:separation} m"
|
||||
},
|
||||
"Width of opening (cyclebarrier)": {
|
||||
"render": "Largeur de l'ouverture : {width:opening} m"
|
||||
|
@ -169,31 +221,6 @@
|
|||
"then": "Un cycliste ne peut pas franchir ceci."
|
||||
}
|
||||
}
|
||||
},
|
||||
"Cycle barrier type": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Simple, deux barrières côte à côte <img src='./assets/themes/cycle_infra/Cycle_barrier_single.png' style='width:8em'>"
|
||||
},
|
||||
"2": {
|
||||
"then": "Triple, trois barrières successives <img src='./assets/themes/cycle_infra/Cycle_barrier_triple.png' style='width:8em'>"
|
||||
},
|
||||
"3": {
|
||||
"then": "Poire, l’espace en hauteur est plus faible qu’au sol <img src='./assets/themes/cycle_infra/Cycle_barrier_squeeze.png' style='width:8em'>"
|
||||
},
|
||||
"1": {
|
||||
"then": "Double, deux barrières successives"
|
||||
}
|
||||
},
|
||||
"question": "Quel est ce type de barrière cyclable ?"
|
||||
},
|
||||
"Overlap (cyclebarrier)": {
|
||||
"question": "Quel est le chevauchement des barrières ?",
|
||||
"render": "Chevauchement : {overlap} m"
|
||||
},
|
||||
"Space between barrier (cyclebarrier)": {
|
||||
"question": "Combien d’espace sépare deux barrières successives ?",
|
||||
"render": "Espace entre deux barrières successives : {width:separation} m"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
|
@ -206,9 +233,7 @@
|
|||
}
|
||||
},
|
||||
"render": "Barrière"
|
||||
},
|
||||
"description": "Obstacles à vélo, tels que des potelets ou des barrières",
|
||||
"name": "Barrières"
|
||||
}
|
||||
},
|
||||
"bench": {
|
||||
"name": "Bancs",
|
||||
|
@ -979,6 +1004,54 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"crossings": {
|
||||
"description": "Traversée pour piétons et cyclistes",
|
||||
"name": "Traversée",
|
||||
"presets": {
|
||||
"0": {
|
||||
"description": "Traversée pour piétons et/ou cyclistes",
|
||||
"title": "Traversée"
|
||||
},
|
||||
"1": {
|
||||
"description": "Feu de signalisation sur la voie",
|
||||
"title": "Feu de signalisation"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Feu de signalisation"
|
||||
},
|
||||
"1": {
|
||||
"then": "Traversée avec feu de signalisation"
|
||||
}
|
||||
},
|
||||
"render": "Traversée"
|
||||
}
|
||||
},
|
||||
"cycleways_and_roads": {
|
||||
"name": "Pistes cyclables et routes",
|
||||
"title": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Piste cyclable"
|
||||
},
|
||||
"1": {
|
||||
"then": "Voie partagée"
|
||||
},
|
||||
"2": {
|
||||
"then": "Bande cyclable"
|
||||
},
|
||||
"3": {
|
||||
"then": "Piste cyclable séparée de la route"
|
||||
},
|
||||
"4": {
|
||||
"then": "Vélorue"
|
||||
}
|
||||
},
|
||||
"render": "Pistes cyclables"
|
||||
}
|
||||
},
|
||||
"defibrillator": {
|
||||
"name": "Défibrillateurs",
|
||||
"presets": {
|
||||
|
@ -2168,6 +2241,12 @@
|
|||
"render": "Toilettes"
|
||||
}
|
||||
},
|
||||
"trail": {
|
||||
"name": "Sentiers",
|
||||
"title": {
|
||||
"render": "Sentier"
|
||||
}
|
||||
},
|
||||
"tree_node": {
|
||||
"name": "Arbre",
|
||||
"presets": {
|
||||
|
@ -2311,57 +2390,6 @@
|
|||
"render": "Point de vue"
|
||||
}
|
||||
},
|
||||
"cycleways_and_roads": {
|
||||
"name": "Pistes cyclables et routes",
|
||||
"title": {
|
||||
"mappings": {
|
||||
"3": {
|
||||
"then": "Piste cyclable séparée de la route"
|
||||
},
|
||||
"2": {
|
||||
"then": "Bande cyclable"
|
||||
},
|
||||
"4": {
|
||||
"then": "Vélorue"
|
||||
},
|
||||
"0": {
|
||||
"then": "Piste cyclable"
|
||||
},
|
||||
"1": {
|
||||
"then": "Voie partagée"
|
||||
}
|
||||
},
|
||||
"render": "Pistes cyclables"
|
||||
}
|
||||
},
|
||||
"watermill": {
|
||||
"name": "Moulin à eau"
|
||||
},
|
||||
"crossings": {
|
||||
"presets": {
|
||||
"0": {
|
||||
"description": "Traversée pour piétons et/ou cyclistes",
|
||||
"title": "Traversée"
|
||||
},
|
||||
"1": {
|
||||
"description": "Feu de signalisation sur la voie",
|
||||
"title": "Feu de signalisation"
|
||||
}
|
||||
},
|
||||
"description": "Traversée pour piétons et cyclistes",
|
||||
"title": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Feu de signalisation"
|
||||
},
|
||||
"1": {
|
||||
"then": "Traversée avec feu de signalisation"
|
||||
}
|
||||
},
|
||||
"render": "Traversée"
|
||||
},
|
||||
"name": "Traversée"
|
||||
},
|
||||
"visitor_information_centre": {
|
||||
"title": {
|
||||
"mappings": {
|
||||
|
@ -2372,35 +2400,7 @@
|
|||
"render": "{name}"
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"description": "Adresses",
|
||||
"name": "Adresses connues d’OpenStreetMap",
|
||||
"tagRenderings": {
|
||||
"fixme": {
|
||||
"question": "Précisez ce qui devrait être corrigé ici"
|
||||
},
|
||||
"housenumber": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce bâtiment n’a pas de numéro"
|
||||
}
|
||||
},
|
||||
"question": "Quel est le numéro de ce bâtiment ?",
|
||||
"render": "Son numéro est le <b>{addr:housenumber}</b>"
|
||||
},
|
||||
"street": {
|
||||
"question": "Dans quelle rue est située l’adresse ?",
|
||||
"render": "Le nom de la voie est <b>{addr:street}</b>"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Adresse connue"
|
||||
}
|
||||
},
|
||||
"trail": {
|
||||
"name": "Sentiers",
|
||||
"title": {
|
||||
"render": "Sentier"
|
||||
}
|
||||
"watermill": {
|
||||
"name": "Moulin à eau"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,17 +61,17 @@
|
|||
},
|
||||
"service:electricity": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Il y a suffisamment de prises disponibles pour les client·e·s en intérieur souhaitant recharger leurs appareils"
|
||||
},
|
||||
"1": {
|
||||
"then": "Il y a peu de prises disponibles pour les client·e·s en intérieur souhaitant recharger leurs appareils"
|
||||
},
|
||||
"2": {
|
||||
"then": "Il n'y a pas de prises disponibles à l'intérieur pour les clients, mais la recharge est peut-être possible sur demande auprès des employés"
|
||||
},
|
||||
"3": {
|
||||
"then": "Il n'y a pas de prises secteur disponibles pour les clients assis à l'intérieur"
|
||||
},
|
||||
"1": {
|
||||
"then": "Il y a peu de prises disponibles pour les client·e·s en intérieur souhaitant recharger leurs appareils"
|
||||
},
|
||||
"0": {
|
||||
"then": "Il y a suffisamment de prises disponibles pour les client·e·s en intérieur souhaitant recharger leurs appareils"
|
||||
}
|
||||
},
|
||||
"question": "Des prises sont elles à disposition des client·e·s en intérieur ?"
|
||||
|
@ -113,4 +113,4 @@
|
|||
"question": "Quel est l’élément Wikipédia correspondant ?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,6 @@
|
|||
import {FixedUiElement} from "./UI/Base/FixedUiElement";
|
||||
import Combine from "./UI/Base/Combine";
|
||||
import {SubtleButton} from "./UI/Base/SubtleButton";
|
||||
import Svg from "./Svg";
|
||||
import BackToIndex from "./UI/BigComponents/BackToIndex";
|
||||
|
||||
new Combine([new FixedUiElement("This page is not found"),
|
||||
new SubtleButton(Svg.back_svg(), "Back to index", {
|
||||
url: "./index.html",
|
||||
newTab: false
|
||||
})
|
||||
]).AttachTo("maindiv")
|
||||
new BackToIndex()]).AttachTo("maindiv")
|
|
@ -42,7 +42,7 @@
|
|||
"prepare-deploy": "./scripts/build.sh",
|
||||
"gittag": "ts-node scripts/printVersion.ts | bash",
|
||||
"lint": "tslint --project . -c tslint.json '**.ts' ",
|
||||
"clean": "rm -rf .cache/ && (find *.html | grep -v \"\\(404\\|index\\|land\\|test\\|preferences\\|customGenerator\\|professional\\|automaton\\|theme\\).html\" | xargs rm) && (ls | grep \"^index_[a-zA-Z_]\\+\\.ts$\" | xargs rm) && (ls | grep \".*.webmanifest$\" | xargs rm)",
|
||||
"clean": "rm -rf .cache/ && (find *.html | grep -v \"\\(404\\|index\\|land\\|test\\|preferences\\|customGenerator\\|professional\\|automaton\\|import_helper\\|theme\\).html\" | xargs rm) && (ls | grep \"^index_[a-zA-Z_]\\+\\.ts$\" | xargs rm) && (ls | grep \".*.webmanifest$\" | xargs rm)",
|
||||
"generate:dependency-graph": "node_modules/.bin/depcruise --exclude \"^node_modules\" --output-type dot Logic/State/MapState.ts > dependencies.dot && dot dependencies.dot -T svg -o dependencies.svg && rm dependencies.dot",
|
||||
"bicycle_rental": "ts-node ./scripts/extractBikeRental.ts"
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue