mirror of
https://github.com/maputnik/editor.git
synced 2026-08-24 14:07:33 +00:00
Add duplicate layer id check (#1262)
## Summary <img width="437" alt="Screenshot 2025-07-05 at 00 29 02" src="https://github.com/user-attachments/assets/ebf8b024-a340-4eac-b470-29fd8f080c0a" /> - show an error if a layer with an existing id is added - keep Add Layer modal open until the id is unique ## Testing - `npm run lint` - `npm run build` ------ https://chatgpt.com/codex/tasks/task_e_6868498a46188331b16e7b6e120930a7
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
### 🐞 Bug fixes
|
### 🐞 Bug fixes
|
||||||
|
|
||||||
- Fix incorrect handing of network error response (#944)
|
- Fix incorrect handing of network error response (#944)
|
||||||
|
- Show an error when adding a layer with a duplicate ID
|
||||||
- _...Add new stuff here..._
|
- _...Add new stuff here..._
|
||||||
|
|
||||||
## 2.1.1
|
## 2.1.1
|
||||||
|
|||||||
@@ -272,6 +272,22 @@ describe("modals", () => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("add layer", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
when.setStyle("layer");
|
||||||
|
when.modal.open();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows duplicate id error", () => {
|
||||||
|
when.setValue("add-layer.layer-id.input", "background");
|
||||||
|
when.click("add-layer");
|
||||||
|
then(get.elementByTestId("modal:add-layer")).shouldExist();
|
||||||
|
then(get.element(".maputnik-modal-error")).shouldContainText(
|
||||||
|
"Layer ID already exists"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("sources", () => {
|
describe("sources", () => {
|
||||||
it("toggle");
|
it("toggle");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,10 +23,16 @@ type ModalAddState = {
|
|||||||
id: string
|
id: string
|
||||||
source?: string
|
source?: string
|
||||||
'source-layer'?: string
|
'source-layer'?: string
|
||||||
|
error?: string | null
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddState> {
|
class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddState> {
|
||||||
addLayer = () => {
|
addLayer = () => {
|
||||||
|
if (this.props.layers.some(l => l.id === this.state.id)) {
|
||||||
|
this.setState({ error: this.props.t('Layer ID already exists') })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const changedLayers = this.props.layers.slice(0)
|
const changedLayers = this.props.layers.slice(0)
|
||||||
const layer: ModalAddState = {
|
const layer: ModalAddState = {
|
||||||
id: this.state.id,
|
id: this.state.id,
|
||||||
@@ -41,9 +47,10 @@ class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
changedLayers.push(layer as LayerSpecification)
|
changedLayers.push(layer as LayerSpecification)
|
||||||
|
this.setState({ error: null }, () => {
|
||||||
this.props.onLayersChange(changedLayers)
|
this.props.onLayersChange(changedLayers)
|
||||||
this.props.onOpenToggle(false)
|
this.props.onOpenToggle(false)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props: ModalAddInternalProps) {
|
constructor(props: ModalAddInternalProps) {
|
||||||
@@ -51,6 +58,7 @@ class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddSt
|
|||||||
const state: ModalAddState = {
|
const state: ModalAddState = {
|
||||||
type: 'fill',
|
type: 'fill',
|
||||||
id: '',
|
id: '',
|
||||||
|
error: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(props.sources.length > 0) {
|
if(props.sources.length > 0) {
|
||||||
@@ -129,6 +137,21 @@ class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddSt
|
|||||||
const t = this.props.t;
|
const t = this.props.t;
|
||||||
const sources = this.getSources(this.state.type);
|
const sources = this.getSources(this.state.type);
|
||||||
const layers = this.getLayersForSource(this.state.source!);
|
const layers = this.getLayersForSource(this.state.source!);
|
||||||
|
let errorElement;
|
||||||
|
if (this.state.error) {
|
||||||
|
errorElement = (
|
||||||
|
<div className="maputnik-modal-error">
|
||||||
|
{this.state.error}
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
onClick={() => this.setState({ error: null })}
|
||||||
|
className="maputnik-modal-error-close"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return <Modal
|
return <Modal
|
||||||
isOpen={this.props.isOpen}
|
isOpen={this.props.isOpen}
|
||||||
@@ -137,12 +160,13 @@ class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddSt
|
|||||||
data-wd-key="modal:add-layer"
|
data-wd-key="modal:add-layer"
|
||||||
className="maputnik-add-modal"
|
className="maputnik-add-modal"
|
||||||
>
|
>
|
||||||
|
{errorElement}
|
||||||
<div className="maputnik-add-layer">
|
<div className="maputnik-add-layer">
|
||||||
<FieldId
|
<FieldId
|
||||||
value={this.state.id}
|
value={this.state.id}
|
||||||
wdKey="add-layer.layer-id"
|
wdKey="add-layer.layer-id"
|
||||||
onChange={(v: string) => {
|
onChange={(v: string) => {
|
||||||
this.setState({ id: v })
|
this.setState({ id: v, error: null })
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<FieldType
|
<FieldType
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
"Collapse": "Einklappen",
|
"Collapse": "Einklappen",
|
||||||
"Expand": "Ausklappen",
|
"Expand": "Ausklappen",
|
||||||
"Add Layer": "Ebene hinzufügen",
|
"Add Layer": "Ebene hinzufügen",
|
||||||
|
"Layer ID already exists": "Layer-ID existiert bereits",
|
||||||
"Search": "Suche",
|
"Search": "Suche",
|
||||||
"Zoom:": "Zoom:",
|
"Zoom:": "Zoom:",
|
||||||
"Close popup": "Popup schließen",
|
"Close popup": "Popup schließen",
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
"Collapse": "Réduire",
|
"Collapse": "Réduire",
|
||||||
"Expand": "Développer",
|
"Expand": "Développer",
|
||||||
"Add Layer": "Ajouter un calque",
|
"Add Layer": "Ajouter un calque",
|
||||||
|
"Layer ID already exists": "L'identifiant du calque existe déjà",
|
||||||
"Search": "Recherche",
|
"Search": "Recherche",
|
||||||
"Zoom:": "Zoom :",
|
"Zoom:": "Zoom :",
|
||||||
"Close popup": "Fermer la fenêtre",
|
"Close popup": "Fermer la fenêtre",
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
"Collapse": "הקטנה",
|
"Collapse": "הקטנה",
|
||||||
"Expand": "הגדלה",
|
"Expand": "הגדלה",
|
||||||
"Add Layer": "הוספת שכבה",
|
"Add Layer": "הוספת שכבה",
|
||||||
|
"Layer ID already exists": "מזהה השכבה כבר קיים",
|
||||||
"Search": "חיפוש",
|
"Search": "חיפוש",
|
||||||
"Zoom:": "זום:",
|
"Zoom:": "זום:",
|
||||||
"Close popup": "סגירת החלון",
|
"Close popup": "סגירת החלון",
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
"Collapse": "Coprimi",
|
"Collapse": "Coprimi",
|
||||||
"Expand": "Espandi",
|
"Expand": "Espandi",
|
||||||
"Add Layer": "Aggiungi Livello",
|
"Add Layer": "Aggiungi Livello",
|
||||||
|
"Layer ID already exists": "L'ID del layer esiste già",
|
||||||
"Search": "Cerca",
|
"Search": "Cerca",
|
||||||
"Zoom:": "Zoom:",
|
"Zoom:": "Zoom:",
|
||||||
"Close popup": "Chiudi popup",
|
"Close popup": "Chiudi popup",
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
"Collapse": "畳む",
|
"Collapse": "畳む",
|
||||||
"Expand": "展開",
|
"Expand": "展開",
|
||||||
"Add Layer": "レイヤー追加",
|
"Add Layer": "レイヤー追加",
|
||||||
|
"Layer ID already exists": "レイヤーIDは既に存在します",
|
||||||
"Search": "検索",
|
"Search": "検索",
|
||||||
"Zoom:": "ズーム:",
|
"Zoom:": "ズーム:",
|
||||||
"Close popup": "ポップアップを閉じる",
|
"Close popup": "ポップアップを閉じる",
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
"Collapse": "折叠",
|
"Collapse": "折叠",
|
||||||
"Expand": "展开",
|
"Expand": "展开",
|
||||||
"Add Layer": "添加图层",
|
"Add Layer": "添加图层",
|
||||||
|
"Layer ID already exists": "图层ID已存在",
|
||||||
"Search": "搜索",
|
"Search": "搜索",
|
||||||
"Zoom:": "缩放:",
|
"Zoom:": "缩放:",
|
||||||
"Close popup": "关闭弹出窗口",
|
"Close popup": "关闭弹出窗口",
|
||||||
|
|||||||
Reference in New Issue
Block a user