mirror of
https://github.com/maputnik/editor.git
synced 2025-12-06 06:10:00 +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
|
||||
|
||||
- Fix incorrect handing of network error response (#944)
|
||||
- Show an error when adding a layer with a duplicate ID
|
||||
- _...Add new stuff here..._
|
||||
|
||||
## 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", () => {
|
||||
it("toggle");
|
||||
});
|
||||
|
||||
@@ -23,10 +23,16 @@ type ModalAddState = {
|
||||
id: string
|
||||
source?: string
|
||||
'source-layer'?: string
|
||||
error?: string | null
|
||||
};
|
||||
|
||||
class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddState> {
|
||||
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 layer: ModalAddState = {
|
||||
id: this.state.id,
|
||||
@@ -41,9 +47,10 @@ class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddSt
|
||||
}
|
||||
|
||||
changedLayers.push(layer as LayerSpecification)
|
||||
|
||||
this.props.onLayersChange(changedLayers)
|
||||
this.props.onOpenToggle(false)
|
||||
this.setState({ error: null }, () => {
|
||||
this.props.onLayersChange(changedLayers)
|
||||
this.props.onOpenToggle(false)
|
||||
})
|
||||
}
|
||||
|
||||
constructor(props: ModalAddInternalProps) {
|
||||
@@ -51,6 +58,7 @@ class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddSt
|
||||
const state: ModalAddState = {
|
||||
type: 'fill',
|
||||
id: '',
|
||||
error: null,
|
||||
}
|
||||
|
||||
if(props.sources.length > 0) {
|
||||
@@ -129,6 +137,21 @@ class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddSt
|
||||
const t = this.props.t;
|
||||
const sources = this.getSources(this.state.type);
|
||||
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
|
||||
isOpen={this.props.isOpen}
|
||||
@@ -137,12 +160,13 @@ class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddSt
|
||||
data-wd-key="modal:add-layer"
|
||||
className="maputnik-add-modal"
|
||||
>
|
||||
{errorElement}
|
||||
<div className="maputnik-add-layer">
|
||||
<FieldId
|
||||
value={this.state.id}
|
||||
wdKey="add-layer.layer-id"
|
||||
onChange={(v: string) => {
|
||||
this.setState({ id: v })
|
||||
this.setState({ id: v, error: null })
|
||||
}}
|
||||
/>
|
||||
<FieldType
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Collapse": "Einklappen",
|
||||
"Expand": "Ausklappen",
|
||||
"Add Layer": "Ebene hinzufügen",
|
||||
"Layer ID already exists": "Layer-ID existiert bereits",
|
||||
"Search": "Suche",
|
||||
"Zoom:": "Zoom:",
|
||||
"Close popup": "Popup schließen",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Collapse": "Réduire",
|
||||
"Expand": "Développer",
|
||||
"Add Layer": "Ajouter un calque",
|
||||
"Layer ID already exists": "L'identifiant du calque existe déjà",
|
||||
"Search": "Recherche",
|
||||
"Zoom:": "Zoom :",
|
||||
"Close popup": "Fermer la fenêtre",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Collapse": "הקטנה",
|
||||
"Expand": "הגדלה",
|
||||
"Add Layer": "הוספת שכבה",
|
||||
"Layer ID already exists": "מזהה השכבה כבר קיים",
|
||||
"Search": "חיפוש",
|
||||
"Zoom:": "זום:",
|
||||
"Close popup": "סגירת החלון",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Collapse": "Coprimi",
|
||||
"Expand": "Espandi",
|
||||
"Add Layer": "Aggiungi Livello",
|
||||
"Layer ID already exists": "L'ID del layer esiste già",
|
||||
"Search": "Cerca",
|
||||
"Zoom:": "Zoom:",
|
||||
"Close popup": "Chiudi popup",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Collapse": "畳む",
|
||||
"Expand": "展開",
|
||||
"Add Layer": "レイヤー追加",
|
||||
"Layer ID already exists": "レイヤーIDは既に存在します",
|
||||
"Search": "検索",
|
||||
"Zoom:": "ズーム:",
|
||||
"Close popup": "ポップアップを閉じる",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"Collapse": "折叠",
|
||||
"Expand": "展开",
|
||||
"Add Layer": "添加图层",
|
||||
"Layer ID already exists": "图层ID已存在",
|
||||
"Search": "搜索",
|
||||
"Zoom:": "缩放:",
|
||||
"Close popup": "关闭弹出窗口",
|
||||
|
||||
Reference in New Issue
Block a user