Hook deleteWizard into the specialVisualisations (WIP)
This commit is contained in:
parent
5d3365afb8
commit
de5f8f95bb
3 changed files with 61 additions and 21 deletions
|
@ -10,10 +10,12 @@ export default class DeleteAction {
|
|||
public readonly canBeDeleted: UIEventSource<{ canBeDeleted?: boolean, reason: Translation }>;
|
||||
public readonly isDeleted = new UIEventSource<boolean>(false);
|
||||
private readonly _id: string;
|
||||
private readonly _allowDeletionAtChangesetCount: number;
|
||||
|
||||
|
||||
constructor(id: string) {
|
||||
constructor(id: string, allowDeletionAtChangesetCount?: number) {
|
||||
this._id = id;
|
||||
this._allowDeletionAtChangesetCount = allowDeletionAtChangesetCount ?? Number.MAX_VALUE;
|
||||
|
||||
this.canBeDeleted = new UIEventSource<{ canBeDeleted?: boolean; reason: Translation }>({
|
||||
canBeDeleted: undefined,
|
||||
|
@ -104,7 +106,7 @@ export default class DeleteAction {
|
|||
if (!ud.loggedIn) {
|
||||
return false;
|
||||
}
|
||||
return ud.csCount >= Constants.userJourney.deletePointsOfOthersUnlock;
|
||||
return ud.csCount >= Math.min(Constants.userJourney.deletePointsOfOthersUnlock, this._allowDeletionAtChangesetCount);
|
||||
})
|
||||
|
||||
const previousEditors = new UIEventSource<number[]>(undefined)
|
||||
|
|
|
@ -41,11 +41,12 @@ export default class DeleteWizard extends Toggle {
|
|||
constructor(id: string,
|
||||
options?: {
|
||||
noDeleteOptions?: { if: Tag[], then: Translation }[]
|
||||
softDeletionTags?: Tag[]
|
||||
softDeletionTags?: Tag[],
|
||||
neededChangesets?: number
|
||||
}) {
|
||||
|
||||
options = options ?? {}
|
||||
const deleteAction = new DeleteAction(id);
|
||||
const deleteAction = new DeleteAction(id, options.neededChangesets);
|
||||
const tagsSource = State.state.allElements.getEventSourceById(id)
|
||||
|
||||
let softDeletionTags = options.softDeletionTags ?? []
|
||||
|
|
|
@ -24,8 +24,10 @@ import Histogram from "./BigComponents/Histogram";
|
|||
import Loc from "../Models/Loc";
|
||||
import {Utils} from "../Utils";
|
||||
import BaseLayer from "../Models/BaseLayer";
|
||||
import DeleteWizard from "./Popup/DeleteWizard";
|
||||
import Constants from "../Models/Constants";
|
||||
|
||||
export interface SpecialVisualization{
|
||||
export interface SpecialVisualization {
|
||||
funcName: string,
|
||||
constr: ((state: State, tagSource: UIEventSource<any>, argument: string[]) => BaseUIElement),
|
||||
docs: string,
|
||||
|
@ -36,6 +38,14 @@ export interface SpecialVisualization{
|
|||
export default class SpecialVisualizations {
|
||||
|
||||
|
||||
public static specialVisualisationsByName: Map<string, SpecialVisualization> = SpecialVisualizations.byName();
|
||||
static HelpMessage: BaseUIElement = SpecialVisualizations.GenHelpMessage();
|
||||
static constructMiniMap: (options?: {
|
||||
background?: UIEventSource<BaseLayer>,
|
||||
location?: UIEventSource<Loc>,
|
||||
allowMoving?: boolean
|
||||
}) => BaseUIElement;
|
||||
static constructShowDataLayer: (features: UIEventSource<{ feature: any; freshness: Date }[]>, leafletMap: UIEventSource<any>, layoutToUse: UIEventSource<any>, enablePopups?: boolean, zoomToFeatures?: boolean) => any;
|
||||
public static specialVisualizations: SpecialVisualization[] =
|
||||
[
|
||||
{
|
||||
|
@ -137,7 +147,7 @@ export default class SpecialVisualizations {
|
|||
zoom = parsed;
|
||||
}
|
||||
}
|
||||
const locationSource =new UIEventSource<Loc>({
|
||||
const locationSource = new UIEventSource<Loc>({
|
||||
lat: Number(properties._lat),
|
||||
lon: Number(properties._lon),
|
||||
zoom: zoom
|
||||
|
@ -151,7 +161,7 @@ export default class SpecialVisualizations {
|
|||
)
|
||||
|
||||
locationSource.addCallback(loc => {
|
||||
if(loc.zoom > zoom){
|
||||
if (loc.zoom > zoom) {
|
||||
// We zoom back
|
||||
locationSource.data.zoom = zoom;
|
||||
locationSource.ping();
|
||||
|
@ -370,11 +380,48 @@ export default class SpecialVisualizations {
|
|||
[state.layoutToUse])
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "delete",
|
||||
docs: `Offers a dialog to (soft) delete the point. The dialog is built to be user friendly and to prevent mistakes. If deletion is not possible, the dialog will hide itself.
|
||||
|
||||
#### Hard deletion if enough experience
|
||||
|
||||
A feature can only be deleted by mapcomplete if:
|
||||
|
||||
- It is a node
|
||||
- No ways or relations use the node
|
||||
- The logged-in user has enough experience (at least ${Constants.userJourney.deletePointsOfOthersUnlock} changesets) OR the user is the only one to have edited the point previously
|
||||
- The user did not select one of the 'non-delete-options' (see below)
|
||||
|
||||
In all other cases, a 'soft deletion' is used.
|
||||
|
||||
#### Soft deletion
|
||||
|
||||
A 'soft deletion' is when the point isn't deleted from OSM but retagged so that it'll won't how up in the mapcomplete theme anymore.
|
||||
This makes it look like it was deleted, without doing damage. A fixme will be added to the point.
|
||||
|
||||
Note that a soft deletion is _only_ possible if these tags are provided by the theme creator, as they'll be different for every theme
|
||||
|
||||
#### No-delete options
|
||||
|
||||
In some cases, the contributor might want to delete something for the wrong reason (e.g. someone who wants to have a path removed "because the path is on their private property").
|
||||
However, the path exists in reality and should thus be on OSM - otherwise the next contributor will pass by and notice "hey, there is a path missing here! Let me redraw it in OSM!)
|
||||
|
||||
The correct approach is to retag the feature in such a way that it is semantically correct *and* that it doesn't show up on the theme anymore.
|
||||
A no-delete option is offered as 'reason to delete it', but secretly retags.
|
||||
|
||||
`,
|
||||
args: [],
|
||||
constr: (state, tagSource, args) => {
|
||||
return new VariableUiElement(tagSource.map(tags => tags.id).map(id =>
|
||||
new DeleteWizard(id)))
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
private static byName() : Map<string, SpecialVisualization>{
|
||||
private static byName(): Map<string, SpecialVisualization> {
|
||||
const result = new Map<string, SpecialVisualization>();
|
||||
|
||||
for (const specialVisualization of SpecialVisualizations.specialVisualizations) {
|
||||
|
@ -384,16 +431,6 @@ export default class SpecialVisualizations {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static specialVisualisationsByName: Map<string, SpecialVisualization> = SpecialVisualizations.byName();
|
||||
|
||||
static HelpMessage: BaseUIElement = SpecialVisualizations.GenHelpMessage();
|
||||
static constructMiniMap: (options?: {
|
||||
background?: UIEventSource<BaseLayer>,
|
||||
location?: UIEventSource<Loc>,
|
||||
allowMoving?: boolean
|
||||
}) => BaseUIElement;
|
||||
static constructShowDataLayer: (features: UIEventSource<{ feature: any; freshness: Date }[]>, leafletMap: UIEventSource<any>, layoutToUse: UIEventSource<any>, enablePopups?: boolean, zoomToFeatures?: boolean) => any;
|
||||
|
||||
private static GenHelpMessage() {
|
||||
|
||||
const helpTexts =
|
||||
|
|
Loading…
Reference in a new issue