forked from MapComplete/MapComplete
Bugfix: if a filter is enabled, a new point of that layer cannot be added anymore; instead the filter should be disabled (to prevent duplicates)
This commit is contained in:
parent
ebf0427b1f
commit
9de4ff9abf
4 changed files with 52 additions and 22 deletions
|
@ -1,9 +1,10 @@
|
||||||
import {UIEventSource} from "../Logic/UIEventSource";
|
import {UIEventSource} from "../Logic/UIEventSource";
|
||||||
import {TagsFilter} from "../Logic/Tags/TagsFilter";
|
import {TagsFilter} from "../Logic/Tags/TagsFilter";
|
||||||
import LayerConfig from "./ThemeConfig/LayerConfig";
|
import LayerConfig from "./ThemeConfig/LayerConfig";
|
||||||
|
import {And} from "../Logic/Tags/And";
|
||||||
|
|
||||||
export default interface FilteredLayer {
|
export default interface FilteredLayer {
|
||||||
readonly isDisplayed: UIEventSource<boolean>;
|
readonly isDisplayed: UIEventSource<boolean>;
|
||||||
readonly appliedFilters: UIEventSource<TagsFilter>;
|
readonly appliedFilters: UIEventSource<And>;
|
||||||
readonly layerDef: LayerConfig;
|
readonly layerDef: LayerConfig;
|
||||||
}
|
}
|
|
@ -14,7 +14,6 @@ import BaseUIElement from "../BaseUIElement";
|
||||||
import State from "../../State";
|
import State from "../../State";
|
||||||
import FilteredLayer from "../../Models/FilteredLayer";
|
import FilteredLayer from "../../Models/FilteredLayer";
|
||||||
import BackgroundSelector from "./BackgroundSelector";
|
import BackgroundSelector from "./BackgroundSelector";
|
||||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
|
||||||
import FilterConfig from "../../Models/ThemeConfig/FilterConfig";
|
import FilterConfig from "../../Models/ThemeConfig/FilterConfig";
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +23,7 @@ import FilterConfig from "../../Models/ThemeConfig/FilterConfig";
|
||||||
|
|
||||||
export default class FilterView extends VariableUiElement {
|
export default class FilterView extends VariableUiElement {
|
||||||
constructor(filteredLayer: UIEventSource<FilteredLayer[]>) {
|
constructor(filteredLayer: UIEventSource<FilteredLayer[]>) {
|
||||||
const backgroundSelector = new Toggle(
|
const backgroundSelector = new Toggle(
|
||||||
new BackgroundSelector(),
|
new BackgroundSelector(),
|
||||||
undefined,
|
undefined,
|
||||||
State.state.featureSwitchBackgroundSlection
|
State.state.featureSwitchBackgroundSlection
|
||||||
|
@ -36,8 +35,8 @@ export default class FilterView extends VariableUiElement {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createOneFilteredLayerElement(filteredLayer) {
|
private static createOneFilteredLayerElement(filteredLayer: FilteredLayer) {
|
||||||
if(filteredLayer.layerDef.name === undefined){
|
if (filteredLayer.layerDef.name === undefined) {
|
||||||
// Name is not defined: we hide this one
|
// Name is not defined: we hide this one
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -71,9 +70,9 @@ export default class FilterView extends VariableUiElement {
|
||||||
Translations.t.general.layerSelection.zoomInToSeeThisLayer.Clone()
|
Translations.t.general.layerSelection.zoomInToSeeThisLayer.Clone()
|
||||||
.SetClass("alert")
|
.SetClass("alert")
|
||||||
.SetStyle("display: block ruby;width:min-content;"),
|
.SetStyle("display: block ruby;width:min-content;"),
|
||||||
State.state.locationControl.map(location =>location.zoom >= filteredLayer.layerDef.minzoom )
|
State.state.locationControl.map(location => location.zoom >= filteredLayer.layerDef.minzoom)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
const style =
|
const style =
|
||||||
"display:flex;align-items:center;padding:0.5rem 0;";
|
"display:flex;align-items:center;padding:0.5rem 0;";
|
||||||
|
@ -89,7 +88,6 @@ export default class FilterView extends VariableUiElement {
|
||||||
const filterPanel: BaseUIElement = FilterView.createFilterPanel(filteredLayer)
|
const filterPanel: BaseUIElement = FilterView.createFilterPanel(filteredLayer)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return new Toggle(
|
return new Toggle(
|
||||||
new Combine([layerChecked, filterPanel]),
|
new Combine([layerChecked, filterPanel]),
|
||||||
layerNotChecked,
|
layerNotChecked,
|
||||||
|
@ -97,10 +95,7 @@ export default class FilterView extends VariableUiElement {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static createFilterPanel(flayer: {
|
private static createFilterPanel(flayer: FilteredLayer): BaseUIElement {
|
||||||
layerDef: LayerConfig,
|
|
||||||
appliedFilters: UIEventSource<TagsFilter>
|
|
||||||
}): BaseUIElement {
|
|
||||||
const layer = flayer.layerDef
|
const layer = flayer.layerDef
|
||||||
if (layer.filters.length === 0) {
|
if (layer.filters.length === 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -121,12 +116,19 @@ export default class FilterView extends VariableUiElement {
|
||||||
inputElement[1].addCallback((_) => update())
|
inputElement[1].addCallback((_) => update())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
flayer.appliedFilters.addCallbackAndRun(appliedFilters => {
|
||||||
|
if (appliedFilters === undefined || appliedFilters.and.length === 0) {
|
||||||
|
listFilterElements.forEach(filter => filter[1].setData(undefined))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return new Combine(listFilterElements.map(input => input[0].SetClass("mt-3")))
|
return new Combine(listFilterElements.map(input => input[0].SetClass("mt-3")))
|
||||||
.SetClass("flex flex-col ml-8 bg-gray-300 rounded-xl p-2")
|
.SetClass("flex flex-col ml-8 bg-gray-300 rounded-xl p-2")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static createFilter(filterConfig: FilterConfig): [BaseUIElement, UIEventSource<TagsFilter>] {
|
private static createFilter(filterConfig: FilterConfig): [BaseUIElement, UIEventSource<TagsFilter>] {
|
||||||
if (filterConfig.options.length === 1) {
|
if (filterConfig.options.length === 1) {
|
||||||
let option = filterConfig.options[0];
|
let option = filterConfig.options[0];
|
||||||
|
|
||||||
|
@ -140,7 +142,7 @@ export default class FilterView extends VariableUiElement {
|
||||||
.ToggleOnClick()
|
.ToggleOnClick()
|
||||||
.SetClass("block m-1")
|
.SetClass("block m-1")
|
||||||
|
|
||||||
return [toggle, toggle.isEnabled.map(enabled => enabled ? option.osmTags : undefined)]
|
return [toggle, toggle.isEnabled.map(enabled => enabled ? option.osmTags : undefined, [], tags => tags !== undefined)]
|
||||||
}
|
}
|
||||||
|
|
||||||
let options = filterConfig.options;
|
let options = filterConfig.options;
|
||||||
|
|
|
@ -18,7 +18,8 @@ import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers";
|
||||||
import CreateNewNodeAction from "../../Logic/Osm/Actions/CreateNewNodeAction";
|
import CreateNewNodeAction from "../../Logic/Osm/Actions/CreateNewNodeAction";
|
||||||
import {OsmObject, OsmWay} from "../../Logic/Osm/OsmObject";
|
import {OsmObject, OsmWay} from "../../Logic/Osm/OsmObject";
|
||||||
import PresetConfig from "../../Models/ThemeConfig/PresetConfig";
|
import PresetConfig from "../../Models/ThemeConfig/PresetConfig";
|
||||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
import FilteredLayer from "../../Models/FilteredLayer";
|
||||||
|
import {And} from "../../Logic/Tags/And";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The SimpleAddUI is a single panel, which can have multiple states:
|
* The SimpleAddUI is a single panel, which can have multiple states:
|
||||||
|
@ -32,10 +33,7 @@ import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
||||||
interface PresetInfo extends PresetConfig {
|
interface PresetInfo extends PresetConfig {
|
||||||
name: string | BaseUIElement,
|
name: string | BaseUIElement,
|
||||||
icon: () => BaseUIElement,
|
icon: () => BaseUIElement,
|
||||||
layerToAddTo: {
|
layerToAddTo: FilteredLayer
|
||||||
layerDef: LayerConfig,
|
|
||||||
isDisplayed: UIEventSource<boolean>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SimpleAddUI extends Toggle {
|
export default class SimpleAddUI extends Toggle {
|
||||||
|
@ -189,14 +187,39 @@ export default class SimpleAddUI extends Toggle {
|
||||||
Translations.t.general.add.openLayerControl
|
Translations.t.general.add.openLayerControl
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
|
||||||
.onClick(() => State.state.filterIsOpened.setData(true))
|
.onClick(() => State.state.filterIsOpened.setData(true))
|
||||||
|
|
||||||
|
|
||||||
const openLayerOrConfirm = new Toggle(
|
const openLayerOrConfirm = new Toggle(
|
||||||
confirmButton,
|
confirmButton,
|
||||||
openLayerControl,
|
openLayerControl,
|
||||||
preset.layerToAddTo.isDisplayed
|
preset.layerToAddTo.isDisplayed
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const disableFilter = new SubtleButton(
|
||||||
|
new Combine([
|
||||||
|
Svg.filter_ui().SetClass("absolute w-full"),
|
||||||
|
Svg.cross_bottom_right_svg().SetClass("absolute red-svg")
|
||||||
|
]).SetClass("relative"),
|
||||||
|
new Combine(
|
||||||
|
[
|
||||||
|
Translations.t.general.add.disableFiltersExplanation.Clone(),
|
||||||
|
Translations.t.general.add.disableFilters.Clone().SetClass("text-xl")
|
||||||
|
]
|
||||||
|
).SetClass("flex flex-col")
|
||||||
|
).onClick(() => {
|
||||||
|
preset.layerToAddTo.appliedFilters.setData(new And([]))
|
||||||
|
cancel()
|
||||||
|
})
|
||||||
|
|
||||||
|
const disableFiltersOrConfirm = new Toggle(
|
||||||
|
openLayerOrConfirm,
|
||||||
|
disableFilter,
|
||||||
|
preset.layerToAddTo.appliedFilters.map(filters => filters === undefined || filters.and.length === 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const tagInfo = SimpleAddUI.CreateTagInfoFor(preset);
|
const tagInfo = SimpleAddUI.CreateTagInfoFor(preset);
|
||||||
|
|
||||||
const cancelButton = new SubtleButton(Svg.close_ui(),
|
const cancelButton = new SubtleButton(Svg.close_ui(),
|
||||||
|
@ -207,7 +230,7 @@ export default class SimpleAddUI extends Toggle {
|
||||||
// Translations.t.general.add.confirmIntro.Subs({title: preset.name}),
|
// Translations.t.general.add.confirmIntro.Subs({title: preset.name}),
|
||||||
State.state.osmConnection.userDetails.data.dryRun ?
|
State.state.osmConnection.userDetails.data.dryRun ?
|
||||||
Translations.t.general.testing.Clone().SetClass("alert") : undefined,
|
Translations.t.general.testing.Clone().SetClass("alert") : undefined,
|
||||||
openLayerOrConfirm,
|
disableFiltersOrConfirm,
|
||||||
cancelButton,
|
cancelButton,
|
||||||
preset.description,
|
preset.description,
|
||||||
tagInfo
|
tagInfo
|
||||||
|
|
|
@ -98,6 +98,10 @@ svg, img {
|
||||||
fill: var(--subtle-detail-color-contrast) !important;
|
fill: var(--subtle-detail-color-contrast) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.red-svg svg path {
|
||||||
|
stroke: #d71010 !important;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: var(--foreground-color);
|
color: var(--foreground-color);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue