import { atom } from "jotai"; import { LatLngBoundsExpression } from "leaflet"; type LayerSettings = { visible: boolean; opacity: number; zIndex: number; }; export type WMSLayerConfig = { type: "wms"; url?: string; layers?: string; format?: string; transparent?: boolean; bounds?: LatLngBoundsExpression | null; }; export type Source = { id: number | string; source: string; }; export type LayerMode = "basic" | "choropleth"; export type ActiveLayer = { id: string; name: string; source: Source; settings: LayerSettings; layer: WMSLayerConfig; mode?: LayerMode; }; export const activeLayersAtom = atom([]); export const addLayerAtom = atom(null, (get, set, layer: Omit) => { set(activeLayersAtom, [ ...get(activeLayersAtom), { ...layer, settings: { visible: true, opacity: 1, zIndex: get(activeLayersAtom).length + 1, }, }, ]); }); export const toggleLayerAtom = atom(null, (get, set, layerId: string) => { set(activeLayersAtom, (prev) => prev.map((layer) => layer.id === layerId ? { ...layer, settings: { ...layer.settings, visible: !layer.settings.visible }, } : layer ) ); }); export const removeLayerAtom = atom(null, (get, set, layerId: string) => { set(activeLayersAtom, (prev) => prev.filter((layer) => layer.id !== layerId)); }); export const setLayerOpacityAtom = atom(null, (get, set, { layerId, opacity }: { layerId: string; opacity: number }) => { set(activeLayersAtom, (prev) => prev.map((layer) => (layer.id === layerId ? { ...layer, settings: { ...layer.settings, opacity } } : layer))); }); export const reorderLayersAtom = atom(null, (get, set, { fromIndex, toIndex }: { fromIndex: number; toIndex: number }) => { const layers = [...get(activeLayersAtom)]; const [moved] = layers.splice(fromIndex, 1); layers.splice(toIndex, 0, moved); const updated = layers.map((layer, index) => ({ ...layer, settings: { ...layer.settings, zIndex: index + 1, }, })); set(activeLayersAtom, updated); }); export const enableAllLayersAtom = atom(null, (get, set) => { set(activeLayersAtom, (prev) => prev.map((layer) => ({ ...layer, settings: { ...layer.settings, visible: true }, })) ); }); export const disableAllLayersAtom = atom(null, (get, set) => { set(activeLayersAtom, (prev) => prev.map((layer) => ({ ...layer, settings: { ...layer.settings, visible: false }, })) ); }); export const toggleAllLayersAtom = atom(null, (get, set) => { const allVisible = get(activeLayersAtom).every((layer) => layer.settings.visible); set(activeLayersAtom, (prev) => prev.map((layer) => ({ ...layer, settings: { ...layer.settings, visible: !allVisible }, })) ); }); export const allLayersVisibleAtom = atom((get) => get(activeLayersAtom).every((layer) => layer.settings.visible)); export const anyLayersVisibleAtom = atom((get) => get(activeLayersAtom).some((layer) => layer.settings.visible)); export const removeAllLayersAtom = atom(null, (get, set) => { set(activeLayersAtom, []); // Clear all layers from the activeLayersAtom }); export const setLayerModeAtom = atom(null, (get, set, { layerId, mode }: { layerId: string; mode: LayerMode }) => { set(activeLayersAtom, (prev) => prev.map((layer) => (layer.id === layerId ? { ...layer, mode } : layer))); });