diff --git a/src/components/AddLayerModal/index.less b/src/components/AddLayerModal/index.less new file mode 100644 index 000000000..51d2c812a --- /dev/null +++ b/src/components/AddLayerModal/index.less @@ -0,0 +1,7 @@ +.add-layer-modal { + + .ant-table-cell { + padding: 0.2rem; + } + +} diff --git a/src/components/AddLayerModal/index.spec.tsx b/src/components/AddLayerModal/index.spec.tsx new file mode 100644 index 000000000..fcc14cfa8 --- /dev/null +++ b/src/components/AddLayerModal/index.spec.tsx @@ -0,0 +1,9 @@ +import AddLayerModal from './index'; + +describe('', () => { + + it('is defined', () => { + expect(AddLayerModal).not.toBeUndefined(); + }); + +}); diff --git a/src/components/AddLayerModal/index.tsx b/src/components/AddLayerModal/index.tsx new file mode 100644 index 000000000..e2ac0d70d --- /dev/null +++ b/src/components/AddLayerModal/index.tsx @@ -0,0 +1,183 @@ +import React, { + useState +} from 'react'; + +import { + Button, + Input, + Modal, + ModalProps, + notification, + Table +} from 'antd'; + +import { + getUid +} from 'ol'; +import OlLayerGroup from 'ol/layer/Group'; + +import { + useTranslation +} from 'react-i18next'; + +import { + CapabilitiesUtil, + MapUtil +} from '@terrestris/ol-util'; +import { + WMSLayer +} from '@terrestris/ol-util/dist/types'; + +import { + useMap +} from '@terrestris/react-geo/dist/Hook/useMap'; + +import useAppDispatch from '../../hooks/useAppDispatch'; +import useAppSelector from '../../hooks/useAppSelector'; +import { + hide +} from '../../store/addLayerModal'; +import { + unsetSelectedKey +} from '../../store/toolMenu'; + +import './index.less'; + +export type AddLayerModalProps = {} & Partial; + +export const AddLayerModal: React.FC = ({ + ...restProps +}): JSX.Element => { + const [loading, setLoading] = useState(false); + const [layers, setLayers] = useState([]); + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [url, setUrl] = useState( + 'https://sgx.geodatenzentrum.de/wms_topplus_open?request=GetCapabilities&service=wms' + ); + + const isModalVisible = useAppSelector(state => state.addLayerModal.visible); + + const dispatch = useAppDispatch(); + + const map = useMap(); + + const { + t + } = useTranslation(); + + const getCapabilities = async (capabilitiesUrl: string) => { + try { + setLoading(true); + + const capabilities = await CapabilitiesUtil.getWmsCapabilities(capabilitiesUrl); + const externalLayers = CapabilitiesUtil.getLayersFromWmsCapabilities(capabilities, 'Title'); + + setLayers(externalLayers); + } catch (error) { + notification.error({ + message: t('AddLayerModal.errorMessage'), + description: t('AddLayerModal.errorDescription') + }); + } finally { + setLoading(false); + } + }; + + const closeModal = () => { + setSelectedRowKeys([]); + setLayers([]); + dispatch(hide()); + dispatch(unsetSelectedKey('addLayer')); + }; + + const onAddSelected = () => { + const layersToAdd = layers.filter(layer => selectedRowKeys.includes(getUid(layer))); + addLayers(layersToAdd); + }; + + const onAddAll = () => { + addLayers(layers); + }; + + const addLayers = (layersToAdd: WMSLayer[]) => { + if (!map) { + return; + } + + const targetFolderName = t('AddLayerModal.externalWmsFolder'); + let targetGroup = MapUtil.getLayerByName(map, targetFolderName) as OlLayerGroup; + if (!targetGroup) { + targetGroup = new OlLayerGroup(); + targetGroup.set('name', targetFolderName); + const existingGroups = map.getLayerGroup().getLayers(); + existingGroups.insertAt(existingGroups?.getLength() || 0, targetGroup); + } + + layersToAdd.forEach(layerToAdd => { + if (!targetGroup.getLayers().getArray().includes(layerToAdd)) { + layerToAdd.set('isExternalLayer', true); + targetGroup.getLayers().push(layerToAdd); + } + }); + + targetGroup.set('hideInLayerTree', targetGroup.getLayers().getLength() < 1); + + closeModal(); + }; + + return ( + + {t('AddLayerModal.addSelectedLayers')} + , + + ]} + {...restProps} + > + { + setUrl(event.target.value); + }} + onSearch={getCapabilities} + enterButton={true} + /> + { + return record.get('title'); + } + } + ]} + rowKey={(record: any) => getUid(record)} + rowSelection={{ + selectedRowKeys, + onChange: setSelectedRowKeys + }} + pagination={false} + dataSource={layers} + /> + + ); +}; + +export default AddLayerModal; diff --git a/src/components/ApplicationInfo/index.spec.tsx b/src/components/ApplicationInfo/index.spec.tsx new file mode 100644 index 000000000..69e665449 --- /dev/null +++ b/src/components/ApplicationInfo/index.spec.tsx @@ -0,0 +1,9 @@ +import ApplicationInfo from './index'; + +describe('', () => { + + it('is defined', () => { + expect(ApplicationInfo).not.toBeUndefined(); + }); + +}); diff --git a/src/components/BasicMapComponent/index.spec.tsx b/src/components/BasicMapComponent/index.spec.tsx new file mode 100644 index 000000000..7f539e78f --- /dev/null +++ b/src/components/BasicMapComponent/index.spec.tsx @@ -0,0 +1,9 @@ +import BasicMapComponent from './index'; + +describe('', () => { + + it('is defined', () => { + expect(BasicMapComponent).not.toBeUndefined(); + }); + +}); diff --git a/src/components/BasicNominatimSearch/index.spec.tsx b/src/components/BasicNominatimSearch/index.spec.tsx new file mode 100644 index 000000000..24412e659 --- /dev/null +++ b/src/components/BasicNominatimSearch/index.spec.tsx @@ -0,0 +1,9 @@ +import BasicNominatimSearch from './index'; + +describe('', () => { + + it('is defined', () => { + expect(BasicNominatimSearch).not.toBeUndefined(); + }); + +}); diff --git a/src/components/Footer/index.spec.tsx b/src/components/Footer/index.spec.tsx new file mode 100644 index 000000000..2d36eb4c1 --- /dev/null +++ b/src/components/Footer/index.spec.tsx @@ -0,0 +1,9 @@ +import Footer from './index'; + +describe('
', () => { + + it('is defined', () => { + expect(Footer).not.toBeUndefined(); + }); + +}); diff --git a/src/components/Header/index.spec.tsx b/src/components/Header/index.spec.tsx new file mode 100644 index 000000000..b160eb3e2 --- /dev/null +++ b/src/components/Header/index.spec.tsx @@ -0,0 +1,9 @@ +import Header from './index'; + +describe('
', () => { + + it('is defined', () => { + expect(Header).not.toBeUndefined(); + }); + +}); diff --git a/src/components/LanguageSelector/index.spec.tsx b/src/components/LanguageSelector/index.spec.tsx new file mode 100644 index 000000000..712f2942e --- /dev/null +++ b/src/components/LanguageSelector/index.spec.tsx @@ -0,0 +1,9 @@ +import LanguageSelector from './index'; + +describe('', () => { + + it('is defined', () => { + expect(LanguageSelector).not.toBeUndefined(); + }); + +}); diff --git a/src/components/Permalink/index.spec.tsx b/src/components/Permalink/index.spec.tsx new file mode 100644 index 000000000..618b59727 --- /dev/null +++ b/src/components/Permalink/index.spec.tsx @@ -0,0 +1,9 @@ +import Permalink from './index'; + +describe('', () => { + + it('is defined', () => { + expect(Permalink).not.toBeUndefined(); + }); + +}); diff --git a/src/components/PrintForm/CustomFieldInput/index.spec.tsx b/src/components/PrintForm/CustomFieldInput/index.spec.tsx new file mode 100644 index 000000000..ce270487f --- /dev/null +++ b/src/components/PrintForm/CustomFieldInput/index.spec.tsx @@ -0,0 +1,9 @@ +import CustomFieldInput from './index'; + +describe('', () => { + + it('is defined', () => { + expect(CustomFieldInput).not.toBeUndefined(); + }); + +}); diff --git a/src/components/PrintForm/LayoutSelect/index.spec.tsx b/src/components/PrintForm/LayoutSelect/index.spec.tsx new file mode 100644 index 000000000..196fc63c3 --- /dev/null +++ b/src/components/PrintForm/LayoutSelect/index.spec.tsx @@ -0,0 +1,9 @@ +import LayoutSelect from './index'; + +describe('', () => { + + it('is defined', () => { + expect(LayoutSelect).not.toBeUndefined(); + }); + +}); diff --git a/src/components/PrintForm/OutputFormatSelect/index.spec.tsx b/src/components/PrintForm/OutputFormatSelect/index.spec.tsx new file mode 100644 index 000000000..787ac14ff --- /dev/null +++ b/src/components/PrintForm/OutputFormatSelect/index.spec.tsx @@ -0,0 +1,9 @@ +import OutputFormatSelect from './index'; + +describe('', () => { + + it('is defined', () => { + expect(OutputFormatSelect).not.toBeUndefined(); + }); + +}); diff --git a/src/components/PrintForm/ResolutionSelect/index.spec.tsx b/src/components/PrintForm/ResolutionSelect/index.spec.tsx new file mode 100644 index 000000000..a42a297cf --- /dev/null +++ b/src/components/PrintForm/ResolutionSelect/index.spec.tsx @@ -0,0 +1,9 @@ +import ResolutionSelect from './index'; + +describe('', () => { + + it('is defined', () => { + expect(ResolutionSelect).not.toBeUndefined(); + }); + +}); diff --git a/src/components/PrintForm/index.spec.tsx b/src/components/PrintForm/index.spec.tsx new file mode 100644 index 000000000..829cedf9d --- /dev/null +++ b/src/components/PrintForm/index.spec.tsx @@ -0,0 +1,9 @@ +import PrintForm from './index'; + +describe('', () => { + + it('is defined', () => { + expect(PrintForm).not.toBeUndefined(); + }); + +}); diff --git a/src/components/ToolMenu/Draw/index.spec.tsx b/src/components/ToolMenu/Draw/index.spec.tsx new file mode 100644 index 000000000..d33c48ec3 --- /dev/null +++ b/src/components/ToolMenu/Draw/index.spec.tsx @@ -0,0 +1,155 @@ +// import TestUtil from '../../Util/TestUtil'; + +import Draw from './index'; + +describe('', () => { + + it('is defined', () => { + expect(Draw).not.toBeUndefined(); + }); + +}); +// it('can be rendered', () => { +// const wrapper = TestUtil.mountComponent(Panel); +// expect(wrapper).not.toBeUndefined(); +// }); + +// it('passes props to Rnd', () => { +// const wrapper = TestUtil.mountComponent(Panel, { +// className: 'podolski', +// fc: 'koeln' +// }); +// const rnd = wrapper.find('Rnd').getElements()[0]; +// expect(rnd.props.className).toContain('podolski'); +// expect(rnd.props.fc).toBe('koeln'); +// }); + +// describe('#onKeyDown', () => { + +// const wrapper = TestUtil.mountComponent(Panel); + +// // Mock a DOM to play around +// document.body.className = 'react-geo-panel'; + +// const element = wrapper.instance()._rnd.getSelfElement(); + +// it('is defined', () => { +// expect(wrapper.instance().onKeyDown).not.toBeUndefined(); +// }); + +// it('calls onEscape method if provided in props', () => { +// const mockEvt = { +// key: 'invalid_key' +// }; + +// wrapper.setProps({ +// onEscape: jest.fn() +// }); + +// const onEscSpy = jest.spyOn(wrapper.props(), 'onEscape'); +// const focusSpy = jest.spyOn(element, 'focus'); + +// wrapper.instance().onKeyDown(mockEvt); +// expect(onEscSpy).toHaveBeenCalledTimes(0); +// expect(focusSpy).toHaveBeenCalledTimes(0); + +// // call once again with valid key and onEscape function +// mockEvt.key = 'Escape'; + +// wrapper.instance().onKeyDown(mockEvt); +// expect(onEscSpy).toHaveBeenCalledTimes(1); +// expect(focusSpy).toHaveBeenCalledTimes(1); +// expect(element.className).toContain(document.activeElement.className); + +// onEscSpy.mockRestore(); +// focusSpy.mockRestore(); +// }); +// }); + +// describe('#toggleCollapse', () => { +// const wrapper = TestUtil.mountComponent(Panel); + +// it('is defined', () => { +// expect(wrapper.instance().toggleCollapse).not.toBeUndefined(); +// }); + +// it('inverts the collapsed property on the state', () => { +// const oldState = wrapper.state(); +// wrapper.instance().toggleCollapse(); +// const newState = wrapper.state(); +// expect(oldState.collapsed).toBe(!newState.collapsed); +// }); +// }); + +// describe('#onResize', () => { +// const wrapper = TestUtil.mountComponent(Panel); + +// it('is defined', () => { +// expect(wrapper.instance().onResize).not.toBeUndefined(); +// }); + +// it('sets resizing on the state to true', () => { +// wrapper.instance().onResize(null, null, {clientHeight: 1337}); +// expect(wrapper.state().height).toBe(1337); +// }); + +// it('calls corresponding function "onResize" of props if defined', () => { +// const onResizeMock = jest.fn(); +// const wrapperWithMockedFunction = TestUtil.mountComponent(Panel, { +// onResize: onResizeMock +// }); +// expect(wrapperWithMockedFunction.instance().onResizeStop).not.toBeUndefined(); +// wrapperWithMockedFunction.instance().onResize(null, null, {clientHeight: 4711}); +// expect(onResizeMock.mock.calls).toHaveLength(1); +// }); +// }); + +// describe('#onResizeStart', () => { +// const wrapper = TestUtil.mountComponent(Panel); + +// it('is defined', () => { +// expect(wrapper.instance().onResizeStart).not.toBeUndefined(); +// }); + +// it('sets resizing on the state to true', () => { +// wrapper.instance().onResizeStart(); +// const state = wrapper.state(); +// expect(state.resizing).toBe(true); +// }); + +// it('calls corresponding function "onResizeStart" of props if defined', () => { +// const onResizeStartMock = jest.fn(); +// const wrapperWithMockedFunction = TestUtil.mountComponent(Panel, { +// onResizeStart: onResizeStartMock +// }); +// expect(wrapperWithMockedFunction.instance().onResizeStart).not.toBeUndefined(); +// wrapperWithMockedFunction.instance().onResizeStart(); +// expect(onResizeStartMock.mock.calls).toHaveLength(1); +// }); +// }); + +// describe('#onResizeStop', () => { +// const wrapper = TestUtil.mountComponent(Panel); + +// it('is defined', () => { +// expect(wrapper.instance().onResizeStop).not.toBeUndefined(); +// }); + +// it('sets the el size on the state', () => { +// wrapper.instance().onResizeStop(); +// const state = wrapper.state(); +// expect(state.resizing).toBe(false); +// }); + +// it('calls corresponding function "onResizeStop" of props if defined', () => { +// const onResizeStopMock = jest.fn(); +// const wrapperWithMockedFunction = TestUtil.mountComponent(Panel, { +// onResizeStop: onResizeStopMock +// }); +// expect(wrapperWithMockedFunction.instance().onResizeStop).not.toBeUndefined(); +// wrapperWithMockedFunction.instance().onResizeStop(); +// expect(onResizeStopMock.mock.calls).toHaveLength(1); +// }); +// }); + +// }); diff --git a/src/components/ToolMenu/FeatureInfo/FeaturePropertyGrid/index.spec.tsx b/src/components/ToolMenu/FeatureInfo/FeaturePropertyGrid/index.spec.tsx new file mode 100644 index 000000000..effdc5f2b --- /dev/null +++ b/src/components/ToolMenu/FeatureInfo/FeaturePropertyGrid/index.spec.tsx @@ -0,0 +1,9 @@ +import FeaturePropertyGrid from './index'; + +describe('', () => { + + it('is defined', () => { + expect(FeaturePropertyGrid).not.toBeUndefined(); + }); + +}); diff --git a/src/components/ToolMenu/FeatureInfo/index.spec.tsx b/src/components/ToolMenu/FeatureInfo/index.spec.tsx new file mode 100644 index 000000000..098b412a2 --- /dev/null +++ b/src/components/ToolMenu/FeatureInfo/index.spec.tsx @@ -0,0 +1,9 @@ +import FeatureInfo from './index'; + +describe('', () => { + + it('is defined', () => { + expect(FeatureInfo).not.toBeUndefined(); + }); + +}); diff --git a/src/components/ToolMenu/LayerTree/LayerTreeContextMenu/index.spec.tsx b/src/components/ToolMenu/LayerTree/LayerTreeContextMenu/index.spec.tsx new file mode 100644 index 000000000..fc397be2f --- /dev/null +++ b/src/components/ToolMenu/LayerTree/LayerTreeContextMenu/index.spec.tsx @@ -0,0 +1,9 @@ +import LayerTreeContextMenu from './index'; + +describe('', () => { + + it('is defined', () => { + expect(LayerTreeContextMenu).not.toBeUndefined(); + }); + +}); diff --git a/src/components/ToolMenu/LayerTree/index.spec.tsx b/src/components/ToolMenu/LayerTree/index.spec.tsx new file mode 100644 index 000000000..057b40e55 --- /dev/null +++ b/src/components/ToolMenu/LayerTree/index.spec.tsx @@ -0,0 +1,9 @@ +import LayerTree from './index'; + +describe('', () => { + + it('is defined', () => { + expect(LayerTree).not.toBeUndefined(); + }); + +}); diff --git a/src/components/ToolMenu/Measure/index.spec.tsx b/src/components/ToolMenu/Measure/index.spec.tsx new file mode 100644 index 000000000..3d116beb5 --- /dev/null +++ b/src/components/ToolMenu/Measure/index.spec.tsx @@ -0,0 +1,9 @@ +import Measure from './index'; + +describe('', () => { + + it('is defined', () => { + expect(Measure).not.toBeUndefined(); + }); + +}); diff --git a/src/components/ToolMenu/index.spec.tsx b/src/components/ToolMenu/index.spec.tsx new file mode 100644 index 000000000..4f38e8c5c --- /dev/null +++ b/src/components/ToolMenu/index.spec.tsx @@ -0,0 +1,9 @@ +import ToolMenu from './index'; + +describe('', () => { + + it('is defined', () => { + expect(ToolMenu).not.toBeUndefined(); + }); + +}); diff --git a/src/components/UserMenu/index.spec.tsx b/src/components/UserMenu/index.spec.tsx new file mode 100644 index 000000000..bcc5e3226 --- /dev/null +++ b/src/components/UserMenu/index.spec.tsx @@ -0,0 +1,9 @@ +import UserMenu from './index'; + +describe('', () => { + + it('is defined', () => { + expect(UserMenu).not.toBeUndefined(); + }); + +});