diff --git a/Svg.ts b/Svg.ts index 9a5c94b8f..d24c1072a 100644 --- a/Svg.ts +++ b/Svg.ts @@ -264,6 +264,11 @@ export default class Svg { public static ring_svg() { return new Img(Svg.ring, true);} public static ring_ui() { return new FixedUiElement(Svg.ring_img);} + public static scissors = "Created by basith ibrahimfrom the Noun Project" + public static scissors_img = Img.AsImageElement(Svg.scissors) + public static scissors_svg() { return new Img(Svg.scissors, true);} + public static scissors_ui() { return new FixedUiElement(Svg.scissors_img);} + public static search = " " public static search_img = Img.AsImageElement(Svg.search) public static search_svg() { return new Img(Svg.search, true);} @@ -334,4 +339,4 @@ export default class Svg { public static wikipedia_svg() { return new Img(Svg.wikipedia, true);} public static wikipedia_ui() { return new FixedUiElement(Svg.wikipedia_img);} -public static All = {"SocialImageForeground.svg": Svg.SocialImageForeground,"add.svg": Svg.add,"addSmall.svg": Svg.addSmall,"ampersand.svg": Svg.ampersand,"arrow-left-smooth.svg": Svg.arrow_left_smooth,"arrow-right-smooth.svg": Svg.arrow_right_smooth,"back.svg": Svg.back,"bug.svg": Svg.bug,"camera-plus.svg": Svg.camera_plus,"checkmark.svg": Svg.checkmark,"circle.svg": Svg.circle,"clock.svg": Svg.clock,"close.svg": Svg.close,"compass.svg": Svg.compass,"cross_bottom_right.svg": Svg.cross_bottom_right,"crosshair-blue-center.svg": Svg.crosshair_blue_center,"crosshair-blue.svg": Svg.crosshair_blue,"crosshair.svg": Svg.crosshair,"delete_icon.svg": Svg.delete_icon,"direction.svg": Svg.direction,"direction_gradient.svg": Svg.direction_gradient,"direction_masked.svg": Svg.direction_masked,"direction_outline.svg": Svg.direction_outline,"direction_stroke.svg": Svg.direction_stroke,"down.svg": Svg.down,"envelope.svg": Svg.envelope,"floppy.svg": Svg.floppy,"gear.svg": Svg.gear,"help.svg": Svg.help,"home.svg": Svg.home,"home_white_bg.svg": Svg.home_white_bg,"josm_logo.svg": Svg.josm_logo,"layers.svg": Svg.layers,"layersAdd.svg": Svg.layersAdd,"logo.svg": Svg.logo,"logout.svg": Svg.logout,"mapcomplete_logo.svg": Svg.mapcomplete_logo,"mapillary.svg": Svg.mapillary,"mapillary_black.svg": Svg.mapillary_black,"min.svg": Svg.min,"no_checkmark.svg": Svg.no_checkmark,"or.svg": Svg.or,"osm-copyright.svg": Svg.osm_copyright,"osm-logo-us.svg": Svg.osm_logo_us,"osm-logo.svg": Svg.osm_logo,"pencil.svg": Svg.pencil,"phone.svg": Svg.phone,"pin.svg": Svg.pin,"plus.svg": Svg.plus,"pop-out.svg": Svg.pop_out,"reload.svg": Svg.reload,"ring.svg": Svg.ring,"search.svg": Svg.search,"send_email.svg": Svg.send_email,"share.svg": Svg.share,"square.svg": Svg.square,"star.svg": Svg.star,"star_half.svg": Svg.star_half,"star_outline.svg": Svg.star_outline,"star_outline_half.svg": Svg.star_outline_half,"statistics.svg": Svg.statistics,"translate.svg": Svg.translate,"up.svg": Svg.up,"wikidata.svg": Svg.wikidata,"wikimedia-commons-white.svg": Svg.wikimedia_commons_white,"wikipedia.svg": Svg.wikipedia};} +public static All = {"SocialImageForeground.svg": Svg.SocialImageForeground,"add.svg": Svg.add,"addSmall.svg": Svg.addSmall,"ampersand.svg": Svg.ampersand,"arrow-left-smooth.svg": Svg.arrow_left_smooth,"arrow-right-smooth.svg": Svg.arrow_right_smooth,"back.svg": Svg.back,"bug.svg": Svg.bug,"camera-plus.svg": Svg.camera_plus,"checkmark.svg": Svg.checkmark,"circle.svg": Svg.circle,"clock.svg": Svg.clock,"close.svg": Svg.close,"compass.svg": Svg.compass,"cross_bottom_right.svg": Svg.cross_bottom_right,"crosshair-blue-center.svg": Svg.crosshair_blue_center,"crosshair-blue.svg": Svg.crosshair_blue,"crosshair.svg": Svg.crosshair,"delete_icon.svg": Svg.delete_icon,"direction.svg": Svg.direction,"direction_gradient.svg": Svg.direction_gradient,"direction_masked.svg": Svg.direction_masked,"direction_outline.svg": Svg.direction_outline,"direction_stroke.svg": Svg.direction_stroke,"down.svg": Svg.down,"envelope.svg": Svg.envelope,"floppy.svg": Svg.floppy,"gear.svg": Svg.gear,"help.svg": Svg.help,"home.svg": Svg.home,"home_white_bg.svg": Svg.home_white_bg,"josm_logo.svg": Svg.josm_logo,"layers.svg": Svg.layers,"layersAdd.svg": Svg.layersAdd,"logo.svg": Svg.logo,"logout.svg": Svg.logout,"mapcomplete_logo.svg": Svg.mapcomplete_logo,"mapillary.svg": Svg.mapillary,"mapillary_black.svg": Svg.mapillary_black,"min.svg": Svg.min,"no_checkmark.svg": Svg.no_checkmark,"or.svg": Svg.or,"osm-copyright.svg": Svg.osm_copyright,"osm-logo-us.svg": Svg.osm_logo_us,"osm-logo.svg": Svg.osm_logo,"pencil.svg": Svg.pencil,"phone.svg": Svg.phone,"pin.svg": Svg.pin,"plus.svg": Svg.plus,"pop-out.svg": Svg.pop_out,"reload.svg": Svg.reload,"ring.svg": Svg.ring,"scissors.svg": Svg.scissors,"search.svg": Svg.search,"send_email.svg": Svg.send_email,"share.svg": Svg.share,"square.svg": Svg.square,"star.svg": Svg.star,"star_half.svg": Svg.star_half,"star_outline.svg": Svg.star_outline,"star_outline_half.svg": Svg.star_outline_half,"statistics.svg": Svg.statistics,"translate.svg": Svg.translate,"up.svg": Svg.up,"wikidata.svg": Svg.wikidata,"wikimedia-commons-white.svg": Svg.wikimedia_commons_white,"wikipedia.svg": Svg.wikipedia};} diff --git a/UI/Popup/SplitRoadWizard.ts b/UI/Popup/SplitRoadWizard.ts new file mode 100644 index 000000000..5caf0ec61 --- /dev/null +++ b/UI/Popup/SplitRoadWizard.ts @@ -0,0 +1,163 @@ +import {VariableUiElement} from "../Base/VariableUIElement"; +import Toggle from "../Input/Toggle"; +import Translations from "../i18n/Translations"; +import Svg from "../../Svg"; +import {UIEventSource} from "../../Logic/UIEventSource"; +import {TagsFilter} from "../../Logic/Tags/TagsFilter"; +import TagRenderingConfig from "../../Customizations/JSON/TagRenderingConfig"; +import Combine from "../Base/Combine"; +import {SubtleButton} from "../Base/SubtleButton"; +import {FixedUiElement} from "../Base/FixedUiElement"; +import {Translation} from "../i18n/Translation"; +import {AndOrTagConfigJson} from "../../Customizations/JSON/TagConfigJson"; +import BaseUIElement from "../BaseUIElement"; +import SplitRoadAction from "../../Logic/Osm/SplitRoadAction"; +import Minimap from "../Base/Minimap"; +import State from "../../State"; + +export default class SplitRoadWizard extends Toggle { + /** + * A UI Element used for splitting roads + * + * @param id: The id of the road to remove + */ + constructor(id: string) { + + + const splitClicked = new UIEventSource(false); + + const splitButton = new SubtleButton(Svg.scissors_ui(), "Split road"); + splitButton.onClick( + () => { + splitClicked.setData(true) + } + ) + + // const isShown = new UIEventSource(id.indexOf("-") < 0) + + const miniMap = new Minimap({background: State.state.backgroundLayer}); + + super(miniMap, splitButton, splitClicked); + + } + + + private static constructConfirmButton(deleteReasons: UIEventSource): BaseUIElement { + const t = Translations.t.delete; + const btn = new Combine([ + Svg.delete_icon_ui().SetClass("w-6 h-6 mr-3 block"), + t.delete.Clone() + ]).SetClass("flex btn bg-red-500") + + + const btnNonActive = new Combine([ + Svg.delete_icon_ui().SetClass("w-6 h-6 mr-3 block"), + t.delete.Clone() + ]).SetClass("flex btn btn-disabled bg-red-200") + + return new Toggle( + btn, + btnNonActive, + deleteReasons.map(reason => reason !== undefined) + ) + + } + + + private static constructExplanation(tags: UIEventSource, deleteAction: SplitRoadAction) { + const t = Translations.t.delete; + return new VariableUiElement(tags.map( + currentTags => { + const cbd = deleteAction.canBeDeleted.data; + if (currentTags === undefined) { + return t.explanations.selectReason.Clone().SetClass("subtle"); + } + + const hasDeletionTag = currentTags.asChange(currentTags).some(kv => kv.k === "_delete_reason") + + if (cbd.canBeDeleted && hasDeletionTag) { + return t.explanations.hardDelete.Clone() + } + return new Combine([t.explanations.softDelete.Subs({reason: cbd.reason}), + new FixedUiElement(currentTags.asHumanString(false, true, currentTags)).SetClass("subtle") + ]).SetClass("flex flex-col") + + + } + , [deleteAction.canBeDeleted] + )).SetClass("block") + } + + private static generateDeleteTagRenderingConfig(softDeletionTags: TagsFilter, + nonDeleteOptions: { if: TagsFilter; then: Translation }[], + extraDeleteReasons: { explanation: Translation; changesetMessage: string }[], + currentTags: any) { + const t = Translations.t.delete + nonDeleteOptions = nonDeleteOptions ?? [] + const softDeletionTagsStr = [] + if (softDeletionTags !== undefined) { + softDeletionTags.asChange(currentTags) + } + const extraOptionsStr: { if: AndOrTagConfigJson, then: any }[] = [] + for (const nonDeleteOption of nonDeleteOptions) { + const newIf: string[] = nonDeleteOption.if.asChange({}).map(kv => kv.k + "=" + kv.v) + + extraOptionsStr.push({ + if: {and: newIf}, + then: nonDeleteOption.then + }) + } + + for (const extraDeleteReason of (extraDeleteReasons ?? [])) { + extraOptionsStr.push({ + if: {and: ["_delete_reason=" + extraDeleteReason.changesetMessage]}, + then: extraDeleteReason.explanation + }) + } + return new TagRenderingConfig( + { + question: t.whyDelete, + render: "Deleted because {_delete_reason}", + freeform: { + key: "_delete_reason", + addExtraTags: softDeletionTagsStr + }, + mappings: [ + + ...extraOptionsStr, + + { + if: { + and: [ + "_delete_reason=testing point", + ...softDeletionTagsStr + ] + }, + then: t.reasons.test + }, + { + if: { + and: [ + "_delete_reason=disused", + ...softDeletionTagsStr + ] + }, + then: t.reasons.disused + }, + { + if: { + and: [ + "_delete_reason=not found", + ...softDeletionTagsStr + ] + }, + then: t.reasons.notFound + } + ] + + + }, undefined, "Delete wizard" + ) + } + +} \ No newline at end of file diff --git a/assets/svg/scissors.svg b/assets/svg/scissors.svg new file mode 100644 index 000000000..be55cb476 --- /dev/null +++ b/assets/svg/scissors.svg @@ -0,0 +1 @@ +Created by basith ibrahimfrom the Noun Project \ No newline at end of file diff --git a/test.ts b/test.ts index eb29b9921..630d0a7dc 100644 --- a/test.ts +++ b/test.ts @@ -1,166 +1,6 @@ -import {OsmObject} from "./Logic/Osm/OsmObject"; -import DeleteButton from "./UI/Popup/DeleteWizard"; -import Combine from "./UI/Base/Combine"; +import SplitRoadWizard from "./UI/Popup/SplitRoadWizard"; import State from "./State"; -import DeleteWizard from "./UI/Popup/DeleteWizard"; -import {UIEventSource} from "./Logic/UIEventSource"; -import {Tag} from "./Logic/Tags/Tag"; -import {QueryParameters} from "./Logic/Web/QueryParameters"; -import {Translation} from "./UI/i18n/Translation"; -/*import ValidatedTextField from "./UI/Input/ValidatedTextField"; -import Combine from "./UI/Base/Combine"; -import {VariableUiElement} from "./UI/Base/VariableUIElement"; -import {UIEventSource} from "./Logic/UIEventSource"; -import TagRenderingConfig from "./Customizations/JSON/TagRenderingConfig"; -import State from "./State"; -import TagRenderingQuestion from "./UI/Popup/TagRenderingQuestion"; -import {SlideShow} from "./UI/Image/SlideShow"; -import {FixedUiElement} from "./UI/Base/FixedUiElement"; -import Img from "./UI/Base/Img"; -import {AttributedImage} from "./UI/Image/AttributedImage"; -import {Imgur} from "./Logic/ImageProviders/Imgur"; -import Minimap from "./UI/Base/Minimap"; -import Loc from "./Models/Loc"; -import AvailableBaseLayers from "./Logic/Actors/AvailableBaseLayers"; -import ShowDataLayer from "./UI/ShowDataLayer"; -import LayoutConfig from "./Customizations/JSON/LayoutConfig"; import {AllKnownLayouts} from "./Customizations/AllKnownLayouts"; - -function TestSlideshow() { - const elems = new UIEventSource([ - new FixedUiElement("A"), - new FixedUiElement("qmsldkfjqmlsdkjfmqlskdjfmqlksdf").SetClass("text-xl"), - new Img("https://i.imgur.com/8lIQ5Hv.jpg"), - new AttributedImage("https://i.imgur.com/y5XudzW.jpg", Imgur.singleton), - new Img("https://www.grunge.com/img/gallery/the-real-reason-your-cat-sleeps-so-much/intro-1601496900.webp") - ]) - new SlideShow(elems).AttachTo("maindiv") -} - -function TestTagRendering() { - State.state = new State(undefined) - const tagsSource = new UIEventSource({ - id: "node/1" - }) - new TagRenderingQuestion( - tagsSource, - new TagRenderingConfig({ - multiAnswer: false, - freeform: { - key: "valve" - }, - question: "What valves are supported?", - render: "This pump supports {valve}", - mappings: [ - { - if: "valve=dunlop", - then: "This pump supports dunlop" - }, - { - if: "valve=shrader", - then: "shrader is supported", - } - ], - - }, undefined, "test"), - [] - ).AttachTo("maindiv") - new VariableUiElement(tagsSource.map(tags => tags["valves"])).SetClass("alert").AttachTo("extradiv") -} - -function TestAllInputMethods() { - - new Combine(ValidatedTextField.tpList.map(tp => { - const tf = ValidatedTextField.InputForType(tp.name); - - return new Combine([tf, new VariableUiElement(tf.GetValue()).SetClass("alert")]); - })).AttachTo("maindiv") -} - -function TestMiniMap() { - - const location = new UIEventSource({ - lon: 4.84771728515625, - lat: 51.17920846421931, - zoom: 14 - }) - const map0 = new Minimap({ - location: location, - allowMoving: true, - background: new AvailableBaseLayers(location).availableEditorLayers.map(layers => layers[2]) - }) - map0.SetStyle("width: 500px; height: 250px; overflow: hidden; border: 2px solid red") - .AttachTo("maindiv") - - const layout = AllKnownLayouts.layoutsList[1] - State.state = new State(layout) - console.log("LAYOUT is", layout.id) - - const feature = { - "type": "Feature", - _matching_layer_id: "bike_repair_station", - "properties": { - id: "node/-1", - "amenity": "bicycle_repair_station" - }, - "geometry": { - "type": "Point", - "coordinates": [ - 4.84771728515625, - 51.17920846421931 - ] - } - } - - ; - - State.state.allElements.addOrGetElement(feature) - - const featureSource = new UIEventSource([{ - freshness: new Date(), - feature: feature - }]) - - new ShowDataLayer( - featureSource, - map0.leafletMap, - new UIEventSource(layout) - ) - - const map1 = new Minimap({ - location: location, - allowMoving: true, - background: new AvailableBaseLayers(location).availableEditorLayers.map(layers => layers[5]) - }, - ) - - map1.SetStyle("width: 500px; height: 250px; overflow: hidden; border : 2px solid black") - .AttachTo("extradiv") - - - new ShowDataLayer( - featureSource, - map1.leafletMap, - new UIEventSource(layout) - ) - - featureSource.ping() -} -//*/ -QueryParameters.GetQueryParameter("test", "true").setData("true") -State.state= new State(undefined) -const id = "node/5414688303" -State.state.allElements.addElementById(id, new UIEventSource({id: id})) -new Combine([ - new DeleteWizard(id, { - noDeleteOptions: [ - { - if:[ new Tag("access","private")], - then: new Translation({ - en: "Very private! Delete now or me send lawfull lawyer" - }) - } - ] - }), -]).AttachTo("maindiv") +State.state = new State(AllKnownLayouts.layoutsList[4]); +new SplitRoadWizard("way/1234").AttachTo("maindiv") \ No newline at end of file