mirror of
https://github.com/maputnik/editor.git
synced 2026-07-16 02:47:26 +00:00
Move modals and rename classes to match file names (#1367)
## Launch Checklist I've created a folder for modals and moved them all inside. I removed the icons which were small files with no real benefit and moved the icons to where they were used. I fixed an issue with the close button position in modal. I've added missing translation to "Links" in debug modal. Before: <img width="610" height="81" alt="image" src="https://github.com/user-attachments/assets/dd7520f6-9634-4ff1-a83d-99ceae7c9144" /> After: <img width="610" height="81" alt="image" src="https://github.com/user-attachments/assets/fe3a2ccf-6c09-42ab-bf6f-dd30d3c68e13" /> - [x] Briefly describe the changes in this PR. - [x] Include before/after visuals or gifs if this PR includes visual changes. - [ ] Add an entry to `CHANGELOG.md` under the `## main` section.
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
import React from 'react'
|
||||
import { WithTranslation, withTranslation } from 'react-i18next';
|
||||
import type {LayerSpecification, SourceSpecification} from 'maplibre-gl'
|
||||
|
||||
import InputButton from '../InputButton'
|
||||
import Modal from './Modal'
|
||||
import FieldType from '../FieldType'
|
||||
import FieldId from '../FieldId'
|
||||
import FieldSource from '../FieldSource'
|
||||
import FieldSourceLayer from '../FieldSourceLayer'
|
||||
import { NON_SOURCE_LAYERS } from '../../libs/non-source-layers'
|
||||
|
||||
type ModalAddInternalProps = {
|
||||
layers: LayerSpecification[]
|
||||
onLayersChange(layers: LayerSpecification[]): unknown
|
||||
isOpen: boolean
|
||||
onOpenToggle(open: boolean): unknown
|
||||
// A dict of source id's and the available source layers
|
||||
sources: Record<string, SourceSpecification & {layers: string[]}>;
|
||||
} & WithTranslation;
|
||||
|
||||
type ModalAddState = {
|
||||
type: LayerSpecification["type"]
|
||||
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,
|
||||
type: this.state.type,
|
||||
}
|
||||
|
||||
if(this.state.type !== 'background') {
|
||||
layer.source = this.state.source
|
||||
if(!NON_SOURCE_LAYERS.includes(this.state.type) && this.state['source-layer']) {
|
||||
layer['source-layer'] = this.state['source-layer']
|
||||
}
|
||||
}
|
||||
|
||||
changedLayers.push(layer as LayerSpecification)
|
||||
this.setState({ error: null }, () => {
|
||||
this.props.onLayersChange(changedLayers)
|
||||
this.props.onOpenToggle(false)
|
||||
})
|
||||
}
|
||||
|
||||
constructor(props: ModalAddInternalProps) {
|
||||
super(props)
|
||||
const state: ModalAddState = {
|
||||
type: 'fill',
|
||||
id: '',
|
||||
error: null,
|
||||
}
|
||||
|
||||
if(Object.keys(props.sources).length > 0) {
|
||||
state.source = Object.keys(this.props.sources)[0];
|
||||
const sourceLayers = this.props.sources[state.source].layers || []
|
||||
if (sourceLayers.length > 0) {
|
||||
state['source-layer'] = sourceLayers[0];
|
||||
}
|
||||
}
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
componentDidUpdate(_prevProps: ModalAddInternalProps, prevState: ModalAddState) {
|
||||
// Check if source is valid for new type
|
||||
const oldType = prevState.type;
|
||||
const newType = this.state.type;
|
||||
|
||||
const availableSourcesOld = this.getSources(oldType);
|
||||
const availableSourcesNew = this.getSources(newType);
|
||||
|
||||
if(
|
||||
// Type has changed
|
||||
oldType !== newType
|
||||
&& prevState.source !== ""
|
||||
// Was a valid source previously
|
||||
&& availableSourcesOld.indexOf(prevState.source!) > -1
|
||||
// And is not a valid source now
|
||||
&& availableSourcesNew.indexOf(this.state.source!) < 0
|
||||
) {
|
||||
// Clear the source
|
||||
this.setState({
|
||||
source: ""
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getLayersForSource(source: string) {
|
||||
const sourceObj = this.props.sources[source] || {};
|
||||
return sourceObj.layers || [];
|
||||
}
|
||||
|
||||
getSources(type: LayerSpecification["type"]) {
|
||||
|
||||
switch(type) {
|
||||
case 'background':
|
||||
return [];
|
||||
case 'hillshade':
|
||||
case 'color-relief':
|
||||
return Object.entries(this.props.sources).filter(([_, v]) => v.type === 'raster-dem').map(([k, _]) => k);
|
||||
case 'raster':
|
||||
return Object.entries(this.props.sources).filter(([_, v]) => v.type === 'raster').map(([k, _]) => k);
|
||||
case 'heatmap':
|
||||
case 'circle':
|
||||
case 'fill':
|
||||
case 'fill-extrusion':
|
||||
case 'line':
|
||||
case 'symbol':
|
||||
return Object.entries(this.props.sources).filter(([_, v]) => v.type === 'vector' || v.type === 'geojson').map(([k, _]) => k);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
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}
|
||||
onOpenToggle={this.props.onOpenToggle}
|
||||
title={t('Add Layer')}
|
||||
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, error: null })
|
||||
}}
|
||||
/>
|
||||
<FieldType
|
||||
value={this.state.type}
|
||||
wdKey="add-layer.layer-type"
|
||||
onChange={(v: LayerSpecification["type"]) => this.setState({ type: v })}
|
||||
/>
|
||||
{this.state.type !== 'background' &&
|
||||
<FieldSource
|
||||
sourceIds={sources}
|
||||
wdKey="add-layer.layer-source-block"
|
||||
value={this.state.source}
|
||||
onChange={(v: string) => this.setState({ source: v })}
|
||||
/>
|
||||
}
|
||||
{!NON_SOURCE_LAYERS.includes(this.state.type) &&
|
||||
<FieldSourceLayer
|
||||
sourceLayerIds={layers}
|
||||
value={this.state['source-layer']}
|
||||
onChange={(v: string) => this.setState({ 'source-layer': v })}
|
||||
/>
|
||||
}
|
||||
<InputButton
|
||||
className="maputnik-add-layer-button"
|
||||
onClick={this.addLayer}
|
||||
data-wd-key="add-layer"
|
||||
>
|
||||
{t("Add Layer")}
|
||||
</InputButton>
|
||||
</div>
|
||||
</Modal>
|
||||
}
|
||||
}
|
||||
|
||||
const ModalAdd = withTranslation()(ModalAddInternal);
|
||||
export default ModalAdd;
|
||||
Reference in New Issue
Block a user