diff --git a/MapStore2 b/MapStore2 index 307918e..8026a5f 160000 --- a/MapStore2 +++ b/MapStore2 @@ -1 +1 @@ -Subproject commit 307918e97587c7497795578ce2eddf491dcecb36 +Subproject commit 8026a5f02cc258bbc0a663ba393822d8805bece7 diff --git a/build/extension/commons.js b/build/extension/commons.js index 9a3b7c8..56fe53f 100644 --- a/build/extension/commons.js +++ b/build/extension/commons.js @@ -1,4 +1,6 @@ const path = require("path"); +const NormalModuleReplacementPlugin = require("webpack/lib/NormalModuleReplacementPlugin"); + // common configuration between production and development for webpack module.exports = { @@ -10,7 +12,11 @@ module.exports = { destination: path.join(__dirname, '..', '..', "dist"), // to compile properly also mapstore dependencies alias: { + "@mapstore/patcher": path.resolve(__dirname, '..', '..', "node_modules", "@mapstore", "patcher"), "@mapstore": path.resolve(__dirname, '..', '..', "MapStore2", "web", "client"), "@js": path.resolve(__dirname, '..', '..', "js") - } + }, + plugins: [ + new NormalModuleReplacementPlugin(/^cesium\/index\.css$/, path.join(__dirname, "..", "..", "node_modules", "cesium/Build/Cesium/Widgets/widgets.css")) + ] }; diff --git a/build/extension/module.app.webpack.config.js b/build/extension/module.app.webpack.config.js index b497509..4ad4cde 100644 --- a/build/extension/module.app.webpack.config.js +++ b/build/extension/module.app.webpack.config.js @@ -5,18 +5,18 @@ const webpackConfig = require("../../webpack.config"); const { name } = require('../../config'); // emulate the extension root directory -webpackConfig.devServer.proxy["/extension/"] = { +webpackConfig.devServer.proxy["/extensions/"] = { target: "http://localhost:8082" }; // emulate the extensions.json webpackConfig.devServer.before = function(app) { - app.get("/extensions.json", function(req, res) { + app.get("/extensions/extensions.json", function(req, res) { res.json({ [name]: { - "bundle": "extension/index.js", - "translations": "extension/translations" + "bundle": "index.js", + "translations": "translations" } }); }); -}, +}; module.exports = webpackConfig; diff --git a/build/extension/prod-webpack.config.js b/build/extension/prod-webpack.config.js index 9057fed..4971b53 100644 --- a/build/extension/prod-webpack.config.js +++ b/build/extension/prod-webpack.config.js @@ -5,7 +5,7 @@ const createExtensionWebpackConfig = require('../../MapStore2/build/createExtens const CopyPlugin = require('copy-webpack-plugin'); const ZipPlugin = require('zip-webpack-plugin'); const {name} = require('../../config'); -const commons = require('./commons'); +const { plugins: commonsPlugins, ...commons} = require('./commons'); // the build configuration for production allow to create the final zip file, compressed accordingly const plugins = [ @@ -22,7 +22,8 @@ const plugins = [ // other files have to be placed in the root, with the same name return path.basename(assetPath); } - }) + }), + ...commonsPlugins ]; // Temporary TODO: Has to be updated in createExtensionWebpackConfig diff --git a/build/extension/webpack.config.js b/build/extension/webpack.config.js index c746774..4b5319a 100644 --- a/build/extension/webpack.config.js +++ b/build/extension/webpack.config.js @@ -2,7 +2,7 @@ const createExtensionWebpackConfig = require('../../MapStore2/build/createExtensionWebpackConfig'); const { name } = require('../../config'); -const commons = require('./commons'); +const { plugins: commonsPlugins, ...commons } = require('./commons'); const webpackConfig = createExtensionWebpackConfig({ prod: false, name, @@ -10,11 +10,12 @@ const webpackConfig = createExtensionWebpackConfig({ overrides: { // serve translations (and index.json) devServer: { - publicPath: "/extension/", + publicPath: "/extensions/", contentBase: './assets', - contentBasePublicPath: '/extension/' + contentBasePublicPath: '/extensions/' } - } + }, + plugins: [ ...commonsPlugins ] }); module.exports = webpackConfig; diff --git a/config.json b/configs/config.json similarity index 100% rename from config.json rename to configs/config.json diff --git a/localConfig.json b/configs/localConfig.json similarity index 99% rename from localConfig.json rename to configs/localConfig.json index f81f0e9..1a7b8d7 100644 --- a/localConfig.json +++ b/configs/localConfig.json @@ -481,7 +481,7 @@ "declineUrl" : "http://www.google.com" } }, - "OmniBar", "Login", "Save", "SaveAs", "BurgerMenu", "Expander", "Undo", "Redo", "FullScreen", "GlobeViewSwitcher", "SearchServicesConfig", "SearchByBookmark", "WidgetsBuilder", "Widgets", + "OmniBar", "Login", "Save", "SaveAs", "SidebarMenu", "Expander", "Undo", "Redo", "FullScreen", "GlobeViewSwitcher", "SearchServicesConfig", "SearchByBookmark", "WidgetsBuilder", "Widgets", "WidgetsTray", "Timeline", "Playback", diff --git a/index.html b/index.html index 74a17ec..17a5e80 100644 --- a/index.html +++ b/index.html @@ -15,7 +15,7 @@ left: 0; bottom: 0; right: 0; - overflow: show; + overflow: visible; margin: auto; display: flex; align-items: center; @@ -92,10 +92,6 @@ - - - -
diff --git a/js/app.jsx b/js/app.jsx index 4174723..1a95fef 100644 --- a/js/app.jsx +++ b/js/app.jsx @@ -24,7 +24,6 @@ ConfigUtils.setConfigProp('themePrefix', 'MapStoreExtension'); * * ConfigUtils.setLocalConfigurationFile('localConfig.json'); */ -ConfigUtils.setLocalConfigurationFile('localConfig.json'); /** * Use a custom application configuration file with: diff --git a/js/extension/epics/__tests__/urbanisme-test.js b/js/extension/epics/__tests__/urbanisme-test.js index 340dac4..910fcac 100644 --- a/js/extension/epics/__tests__/urbanisme-test.js +++ b/js/extension/epics/__tests__/urbanisme-test.js @@ -8,8 +8,8 @@ import expect from 'expect'; import { testEpic, addTimeoutEpic } from '@mapstore/epics/__tests__/epicTestUtils'; -import { toggleControl, TOGGLE_CONTROL, setControlProperty } from '@mapstore/actions/controls'; -import { clickOnMap } from '@mapstore/actions/map'; +import { toggleControl, TOGGLE_CONTROL } from '@mapstore/actions/controls'; +import {clickOnMap, registerEventListener} from '@mapstore/actions/map'; import { PURGE_MAPINFO_RESULTS, TOGGLE_MAPINFO_STATE, loadFeatureInfo } from '@mapstore/actions/mapInfo'; import { @@ -17,11 +17,12 @@ import { toggleLandPlanningEpic, cleanUpUrbanismeEpic, clickOnMapEventEpic, - deactivateOnMeasureEnabledEpic, getFeatureInfoEpic, onClosePanelEpic, onToogleToolEpic, - updateAdditionalLayerEpic, highlightFeatureEpic + updateAdditionalLayerEpic, + highlightFeatureEpic, + tearDownUrbanismeOnDrawToolActive } from '../urbanisme'; import { setUp, @@ -99,16 +100,16 @@ describe('Urbanisme EPICS', () => { it('toggleLandPlanningEpic when Urbanisme tool enabled', (done) => { const state = { - controls: { urbanisme: { enabled: true }, measure: {enabled: true}}, + controls: { urbanisme: { enabled: true }}, urbanisme: { config: { cadastreWMSURL: "/cadastreWMSURL"}}, mapInfo: {enabled: true} }; testEpic( toggleLandPlanningEpic, - 4, + 3, toggleControl('urbanisme', null), actions => { - expect(actions.length).toBe(4); + expect(actions.length).toBe(3); actions.map(action=> { switch (action.type) { case UPDATE_ADDITIONAL_LAYER: @@ -226,35 +227,17 @@ describe('Urbanisme EPICS', () => { state); }); - it('cleanUpUrbanismeEpic opening annotation when urbanisme plugin is opened', (done) => { - const state = { controls: { urbanisme: { enabled: true}, annotations: { enabled: true}}}; - testEpic( - cleanUpUrbanismeEpic, - 1, - toggleControl("annotations"), - actions => { - expect(actions.length).toBe(1); - actions.map(action=>{ - switch (action.type) { - case TOGGLE_CONTROL: - break; - default: - expect(true).toBe(false); - } - }); - done(); - }, - state); - }); - - it('closeOnMeasureEnabledEpic close when urbanisme plugin when measurement is opened', (done) => { - const state = { controls: { measure: { enabled: true}, urbanisme: { enabled: true}}}; + it('tearDownUrbanismeOnDrawToolActive toggle off urbanisme tool when measurement is opened', (done) => { + const state = { + controls: { measure: { enabled: true}, urbanisme: { enabled: true}}, + urbanisme: { activeTool: "ADS"} + }; testEpic( - deactivateOnMeasureEnabledEpic, - 3, - setControlProperty("measure", "enabled", true), + tearDownUrbanismeOnDrawToolActive, + 2, + registerEventListener('click', 'measure'), actions => { - expect(actions.length).toBe(3); + expect(actions.length).toBe(2); actions.map(action=>{ switch (action.type) { case TOGGLE_TOOL: @@ -263,8 +246,6 @@ describe('Urbanisme EPICS', () => { case TOGGLE_VIEWER_PANEL: expect(action.enabled).toBe(false); break; - case PURGE_MAPINFO_RESULTS: - break; default: expect(true).toBe(false); } @@ -300,7 +281,7 @@ describe('Urbanisme EPICS', () => { mockAxios.onGet(`${CADASTRAPP_URL}/getParcelle`).reply(200, [{parcelle: "parcelle", ccopre: "ccopre", ccosec: "ccosec", dnupla: "dnupla", dnvoiri: "dnvoiri", cconvo: "cconvo", dvoilib: "dvoilib", dcntpa: "dcntpa"}]); mockAxios.onGet(`${URBANISMEAPP_URL}/renseignUrba`).reply(200, {libelles: [{libelle: "Test"}]}); - mockAxios.onGet(`${CADASTRAPP_URL}/getFIC`, ).reply((config)=>{ + mockAxios.onGet(`${CADASTRAPP_URL}/getFIC` ).reply((config)=>{ if (config.params.onglet === 0) return [200, [{surfc: "surfc"}]]; return [200, [{comptecommunal: "codeProprio"}]]; }); @@ -347,7 +328,7 @@ describe('Urbanisme EPICS', () => { mockAxios.onGet(`${CADASTRAPP_URL}/getCommune`).reply(200, []); mockAxios.onGet(`${CADASTRAPP_URL}/getParcelle`).reply(200, []); mockAxios.onGet(`${URBANISMEAPP_URL}/renseignUrba`).reply(200, {}); - mockAxios.onGet(`${CADASTRAPP_URL}/getFIC`, ).reply((config)=>{ + mockAxios.onGet(`${CADASTRAPP_URL}/getFIC` ).reply((config)=>{ if (config.params.onglet === 0) return [200, []]; return [200, []]; }); @@ -440,10 +421,10 @@ describe('Urbanisme EPICS', () => { }; testEpic( onToogleToolEpic, - 4, + 3, toggleUrbanismeTool('NRU'), actions => { - expect(actions.length).toBe(4); + expect(actions.length).toBe(3); actions.map(action=>{ switch (action.type) { case URBANISME_RESET_FEATURE_HIGHLIGHT: @@ -454,9 +435,6 @@ describe('Urbanisme EPICS', () => { case TOGGLE_VIEWER_PANEL: expect(action.enabled).toBe(false); break; - case TOGGLE_CONTROL: - expect(action.control).toBe("measure"); - break; default: expect(true).toBe(false); } diff --git a/js/extension/epics/urbanisme.js b/js/extension/epics/urbanisme.js index 87f93ab..80c5658 100644 --- a/js/extension/epics/urbanisme.js +++ b/js/extension/epics/urbanisme.js @@ -10,10 +10,11 @@ import * as Rx from "rxjs"; import {get, isEmpty, omit} from "lodash"; import uuid from 'uuid'; -import {SET_CONTROL_PROPERTY, TOGGLE_CONTROL, toggleControl} from "@mapstore/actions/controls"; -import {ANNOTATIONS} from "@mapstore/utils/AnnotationsUtils"; +import { + TOGGLE_CONTROL +} from "@mapstore/actions/controls"; import {error} from "@mapstore/actions/notifications"; -import {CLICK_ON_MAP} from "@mapstore/actions/map"; +import {CLICK_ON_MAP, registerEventListener, unRegisterEventListener} from "@mapstore/actions/map"; import {removeAdditionalLayer, updateAdditionalLayer} from '@mapstore/actions/additionallayers'; import { closeIdentify, @@ -35,7 +36,6 @@ import { import {localConfigSelector} from '@mapstore/selectors/localConfig'; import proj4 from 'proj4'; -import {createControlEnabledSelector, measureSelector} from "@mapstore/selectors/controls"; import {wrapStartStop} from "@mapstore/observables/epics"; import { @@ -98,13 +98,14 @@ import { mapTriggerSelector, showMarkerSelector } from "@mapstore/selectors/mapInfo"; -import {styleFeatures} from "@js/extension/utils/UrbanismeUtils"; +import {styleFeatures} from "../utils/UrbanismeUtils"; import {resolutionsSelector} from "@mapstore/selectors/map"; import { registerHook, RESOLUTION_HOOK } from "@mapstore/utils/MapUtils"; - +import {shutdownToolOnAnotherToolDrawing} from "@mapstore/utils/ControlUtils"; +import {setAPIURL} from "@js/extension/api"; /** * Ensures that config for the urbanisme tool is fetched and loaded * @memberof epics.urbanisme @@ -112,9 +113,10 @@ import { * @return {observable} */ export const setUpPluginEpic = (action$, store) => - action$.ofType(SET_UP).switchMap(() => { + action$.ofType(SET_UP).switchMap((action) => { const state = store.getState(); const isConfigLoaded = configLoadSelector(state); + setAPIURL(action.initConfig); // adds projections from localConfig.json // The extension do not see the state proj4 of MapStore (can not reproject in custom CRS as mapstore does) // so they have to be registered again in the extension. @@ -141,10 +143,10 @@ export const setUpPluginEpic = (action$, store) => loading(false, 'configLoading'), e => { console.log(e); // eslint-disable-line no-console - return Rx.Observable.of(error({ + return Rx.Observable.from([error({ title: "Error", message: "Unable to setup urbanisme app" - }), loading(false, 'configLoading')); + }), loading(false, 'configLoading')]); } ) @@ -167,7 +169,6 @@ export const toggleLandPlanningEpic = (action$, store) => const {cadastreWMSURL: url, layer: name = DEFAULT_URBANISME_LAYER} = configSelector(state) || {}; const enabled = urbanimseControlSelector(state); const mapInfoEnabled = get(state, "mapInfo.enabled"); - const isMeasureEnabled = measureSelector(state); const mapHoverTrigger = mapTriggerSelector(state); if (enabled) { return Rx.Observable.from([ @@ -196,7 +197,6 @@ export const toggleLandPlanningEpic = (action$, store) => }) ]).concat([ ...(mapInfoEnabled ? [toggleMapInfoState()] : []), - ...(isMeasureEnabled ? [toggleControl("measure")] : []), ...(mapHoverTrigger === 'hover' ? [setMapTrigger("click")] : []) ]); } @@ -204,8 +204,7 @@ export const toggleLandPlanningEpic = (action$, store) => return !isEmpty(layer) ? Rx.Observable.from([ removeAdditionalLayer({id: URBANISME_RASTER_LAYER_ID, owner: URBANISME_OWNER}), - removeAdditionalLayer({id: URBANISME_VECTOR_LAYER_ID, owner: URBANISME_OWNER}), - purgeMapInfoResults() + removeAdditionalLayer({id: URBANISME_VECTOR_LAYER_ID, owner: URBANISME_OWNER}) ]).concat(!mapInfoEnabled ? [toggleMapInfoState()] : []) : Rx.Observable.empty(); }); @@ -231,6 +230,7 @@ export const clickOnMapEventEpic = (action$, {getState}) => ? Rx.Observable.of(toggleUrbanismeTool(null)) : Rx.Observable.empty(); } + return !isEmpty(activeTool) && !isPrinting ? Rx.Observable.of( featureInfoClick(point, layer), @@ -251,13 +251,7 @@ export const cleanUpUrbanismeEpic = (action$, {getState}) => .ofType(TOGGLE_CONTROL) .filter(({control}) => { const isUrbanismeEnabled = urbanimseControlSelector(getState()); - const isAnnotationsEnabled = createControlEnabledSelector(ANNOTATIONS)( - getState() - ); - return ( - (control === CONTROL_NAME && !isUrbanismeEnabled) || - (control === ANNOTATIONS && isAnnotationsEnabled && isUrbanismeEnabled) - ); + return control === CONTROL_NAME && !isUrbanismeEnabled; }) .switchMap(({control}) => { const state = getState(); @@ -271,34 +265,26 @@ export const cleanUpUrbanismeEpic = (action$, {getState}) => setAttributes(null), resetFeatureHighlight() ]); - } else if (control === ANNOTATIONS) { - observable$ = Rx.Observable.of(toggleControl(CONTROL_NAME)); } return observable$; }); /** - * Ensures that the urbanisme plugin is deactivated when measurement tool is activated - * @memberof epics.urbanisme - * @param {observable} action$ manages `SET_CONTROL_PROPERTY` - * @return {observable} + * Toggle urbanisme tool off when one of the drawing tools takes control + * @param action$ + * @param store + * @returns {Observable