diff --git a/public/config/config.json b/public/config/config.json index d6c92bb107b707af411e52c4ad03907900fdad77..9651190e5aa2d349aead14b9d85304d92d6f2356 100644 --- a/public/config/config.json +++ b/public/config/config.json @@ -9,6 +9,7 @@ "VUE_APP_LOGO_PATH":"/geocontrib/img/logo-neogeo-circle.png", "VUE_APP_DJANGO_BASE":"http://localhost:8010", "VUE_APP_DJANGO_API_BASE":"http://localhost:8010/api/", + "VUE_APP_RELOAD_INTERVAL": 15000, "VUE_APP_DISABLE_LOGIN_BUTTON":false, "VUE_APP_LOGIN_URL":"", "DEFAULT_BASE_MAP":{ diff --git a/src/components/ImportTask.vue b/src/components/ImportTask.vue index 8d35b287054a1921f8aaa80aa57042e1fd99a743..693df72ea8f4d5af0308f219582ccd5022f4bcf4 100644 --- a/src/components/ImportTask.vue +++ b/src/components/ImportTask.vue @@ -99,9 +99,9 @@ export default { methods: { fetchImports() { this.$store.dispatch( - "feature_type/GET_IMPORTS", - this.$route.params.feature_type_slug - ); + "feature_type/GET_IMPORTS", { + feature_type: this.$route.params.feature_type_slug + }); this.$store.dispatch('feature/GET_PROJECT_FEATURES', { project_slug: this.$route.params.slug }) diff --git a/src/store/index.js b/src/store/index.js index 650578b9818713a06fc71faec3288001597663fb..f3ff33c6acfdc5c150fb01ef3efc8fd1ab35d31e 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -8,7 +8,20 @@ import map from "./modules/map" Vue.use(Vuex); -const noPermissions = { "can_view_project": true, "can_create_project": false, "can_update_project": false, "can_view_feature": true, "can_view_archived_feature": true, "can_create_feature": false, "can_update_feature": false, "can_delete_feature": false, "can_publish_feature": false, "can_create_feature_type": false, "can_view_feature_type": true, "is_project_administrator": false } +const noPermissions = { + can_view_project: true, + can_create_project: false, + can_update_project: false, + can_view_feature: true, + can_view_archived_feature: true, + can_create_feature: false, + can_update_feature: false, + can_delete_feature: false, + can_publish_feature: false, + can_create_feature_type: false, + can_view_feature_type: true, + is_project_administrator: false +}; export default new Vuex.Store({ modules: { @@ -33,7 +46,8 @@ export default new Vuex.Store({ isLoading: false, message: "En cours de chargement" }, - cancellableSearchRequest: [] + cancellableSearchRequest: [], + reloadIntervalId: null }, mutations: { @@ -98,13 +112,21 @@ export default new Vuex.Store({ message: "En cours de chargement" }; }, + SET_CANCELLABLE_SEARCH_REQUEST(state, payload) { state.cancellableSearchRequest.push(payload); }, - RESET_CANCELLABLE_SEARCH_REQUEST(state) { state.cancellableSearchRequest = []; }, + + SET_RELOAD_INTERVAL_ID(state, payload) { + state.reloadIntervalId = payload; + }, + CLEAR_RELOAD_INTERVAL_ID(state) { + clearInterval(state.reloadIntervalId); + state.reloadIntervalId = null; + } }, getters: { diff --git a/src/store/modules/feature_type.js b/src/store/modules/feature_type.js index 612c4140631d3e8990f056d995417a9bf0bdb12f..be5ecdd25fcf3fe74535df151ea50a42eef5d1e5 100644 --- a/src/store/modules/feature_type.js +++ b/src/store/modules/feature_type.js @@ -160,7 +160,6 @@ const feature_type = { }, SEND_FEATURES_FROM_GEOJSON({ state, dispatch }, payload) { - console.log(payload); const { feature_type_slug } = payload; if (state.fileToImport.size > 0) { @@ -178,7 +177,9 @@ const feature_type = { }) .then((response) => { if (response && response.status === 200) { - dispatch("GET_IMPORTS", feature_type_slug); + dispatch("GET_IMPORTS", { + feature_type: feature_type_slug + }); } return response }) @@ -188,11 +189,14 @@ const feature_type = { } }, - GET_IMPORTS({ commit }, feature_type) { - let url = - this.state.configuration.VUE_APP_DJANGO_API_BASE + - "import-tasks?feature_type_slug=" + - feature_type; + GET_IMPORTS({ commit }, { project_slug, feature_type }) { + let url = `${this.state.configuration.VUE_APP_DJANGO_API_BASE}import-tasks`; + if (project_slug) { + url = url.concat('', `${url.includes('?') ? '&' : '?'}project_slug=${project_slug}`); + } + if (feature_type) { + url = url.concat('', `${url.includes('?') ? '&' : '?'}feature_type_slug=${feature_type}`); + } axios .get(url) .then((response) => { diff --git a/src/views/feature_type/Feature_type_detail.vue b/src/views/feature_type/Feature_type_detail.vue index ae9f110d5f192ae078a0456b0bed9a6ff9764fb7..e6a15e7802a0bceff60dbcb729fc0cdd8ea772b2 100644 --- a/src/views/feature_type/Feature_type_detail.vue +++ b/src/views/feature_type/Feature_type_detail.vue @@ -282,7 +282,9 @@ export default { toggleShowImport() { this.showImport = !this.showImport; if (this.showImport) { - this.$store.dispatch("feature_type/GET_IMPORTS", this.structure.slug); + this.$store.dispatch("feature_type/GET_IMPORTS", { + feature_type: this.structure.slug + }); } }, @@ -396,7 +398,9 @@ export default { 'structure'(newValue){ console.log(newValue) if (newValue){ - this.$store.dispatch("feature_type/GET_IMPORTS", this.structure.slug); + this.$store.dispatch("feature_type/GET_IMPORTS", { + feature_type: this.structure.slug + }); } } }, @@ -404,9 +408,6 @@ export default { if (!this.project) { this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug); } - // if (this.structure) { - // this.$store.dispatch("feature_type/GET_IMPORTS", this.structure.slug); - // } this.setCurrentFeatureTypeSlug(); // .then(res => resolve(res)) // .catch(err => reject(err)); diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue index cf87d50e56980912ecd3737fd11667eae63c8470..c9cdf37492d9cd3f5b01b0f40b0e2bcb368562d7 100644 --- a/src/views/project/Project_detail.vue +++ b/src/views/project/Project_detail.vue @@ -154,7 +154,7 @@ {{ type.title }} </router-link> <!-- {% if project and feature_types and - permissions|lookup:'can_create_feature' %} --> + permissions|lookup:'can_create_feature' %} --> <!-- // ? should we get type.is_editable ? --> <!-- v-if=" project && @@ -162,110 +162,128 @@ type.is_editable " --> <div class="middle aligned content"> - <router-link - v-if=" - project && permissions && permissions.can_create_feature - " - :to="{ - name: 'ajouter-signalement', - params: { slug_type_signal: type.slug }, - }" - class=" - ui - compact - small - icon - right - floated - button button-hover-green - " - data-tooltip="Ajouter un signalement" - data-position="left center" - data-variation="mini" - > - <i class="ui plus icon"></i> - </router-link> - <router-link - :to="{ - name: 'dupliquer-type-signalement', - params: { slug_type_signal: type.slug }, - }" - v-if=" - project && - permissions && - permissions.can_create_feature_type && - isOffline() !== true - " - class=" - ui - compact - small - icon - right - floated - button button-hover-green - " - data-tooltip="Dupliquer un type de signalement" - data-position="left center" - data-variation="mini" - > - <i class="inverted grey copy alternate icon"></i> - </router-link> - <router-link - :to="{ - name: 'editer-type-signalement', - params: { slug_type_signal: type.slug }, - }" - v-if=" - project && - type.is_editable && - permissions && - permissions.can_create_feature_type && - isOffline() !== true - " - class=" - ui - compact - small - icon - right - floated - button button-hover-green - " - data-tooltip="Éditer le type de signalement" - data-position="left center" - data-variation="mini" - > - <i class="inverted grey pencil alternate icon"></i> - </router-link> - <router-link - :to="{ - name: 'editer-symbologie-signalement', - params: { slug_type_signal: type.slug }, - }" - v-if=" - project && - type.is_editable && - type.geom_type === 'point' && - permissions && - permissions.can_create_feature_type && - isOffline() != true - " - class=" - ui - compact - small - icon - right - floated - button button-hover-green - " - data-tooltip="Éditer la symbologie du type de signalement" - data-position="left center" - data-variation="mini" - > - <i class="inverted grey paint brush alternate icon"></i> - </router-link> + <router-link + v-if=" + project && permissions && permissions.can_create_feature + " + :to="{ + name: 'ajouter-signalement', + params: { slug_type_signal: type.slug }, + }" + class=" + ui + compact + small + icon + right + floated + button button-hover-green + " + data-tooltip="Ajouter un signalement" + data-position="left center" + data-variation="mini" + > + <i class="ui plus icon"></i> + </router-link> + <router-link + :to="{ + name: 'dupliquer-type-signalement', + params: { slug_type_signal: type.slug }, + }" + v-if=" + project && + permissions && + permissions.can_create_feature_type && + isOffline() !== true + " + class=" + ui + compact + small + icon + right + floated + button button-hover-green + " + data-tooltip="Dupliquer un type de signalement" + data-position="left center" + data-variation="mini" + > + <i class="inverted grey copy alternate icon"></i> + </router-link> + <router-link + :to="{ + name: 'editer-type-signalement', + params: { slug_type_signal: type.slug }, + }" + v-if=" + project && + type.is_editable && + permissions && + permissions.can_create_feature_type && + isOffline() !== true && + !( + importFeatureTypeData.find(el => el.feature_type_title === type.slug) && + importFeatureTypeData.find(el => el.feature_type_title === type.slug).status === 'pending' + ) + " + class=" + ui + compact + small + icon + right + floated + button button-hover-green + " + data-tooltip="Éditer le type de signalement" + data-position="left center" + data-variation="mini" + > + <i class="inverted grey pencil alternate icon"></i> + </router-link> + <router-link + :to="{ + name: 'editer-symbologie-signalement', + params: { slug_type_signal: type.slug }, + }" + v-if=" + project && + type.is_editable && + type.geom_type === 'point' && + permissions && + permissions.can_create_feature_type && + isOffline() != true && + !( + importFeatureTypeData.find(el => el.feature_type_title === type.slug) && + importFeatureTypeData.find(el => el.feature_type_title === type.slug).status === 'pending' + ) + " + class=" + ui + compact + small + icon + right + floated + button button-hover-green + " + data-tooltip="Éditer la symbologie du type de signalement" + data-position="left center" + data-variation="mini" + > + <i class="inverted grey paint brush alternate icon"></i> + </router-link> + <div + v-if=" + importFeatureTypeData.find(el => el.feature_type_title === type.slug) && + importFeatureTypeData.find(el => el.feature_type_title === type.slug).status === 'pending' + " + class="import-message" + > + <i class="info circle icon" /> + Import en cours + </div> </div> </div> </div> @@ -549,7 +567,7 @@ <script> import frag from "vue-frag"; import { mapUtil } from "@/assets/js/map-util.js"; -import { mapGetters, mapState } from "vuex"; +import { mapGetters, mapState, mapActions, mapMutations } from "vuex"; import projectAPI from "@/services/project-api"; import featureAPI from "@/services/feature-api"; @@ -579,6 +597,7 @@ export default { data() { return { infoMessage: "", + importMessage: null, arraysOffline: [], geojsonImport: [], fileToImport: { name: "", size: 0 }, @@ -593,10 +612,22 @@ export default { }, computed: { - ...mapGetters(["project", "permissions"]), - ...mapState("feature_type", ["feature_types"]), - ...mapState("feature", ["features"]), - ...mapState(["last_comments", "user"]), + ...mapGetters([ + 'project', + 'permissions' + ]), + ...mapState('feature_type', [ + 'feature_types', + 'importFeatureTypeData' + ]), + ...mapState('feature', [ + 'features' + ]), + ...mapState([ + 'last_comments', + 'user', + 'reloadIntervalId' + ]), DJANGO_BASE_URL() { return this.$store.state.configuration.VUE_APP_DJANGO_BASE; }, @@ -605,7 +636,48 @@ export default { } }, + watch: { + feature_types: { + deep: true, + handler(newValue, oldValue) { + if (newValue && newValue !== oldValue) { + this.GET_IMPORTS({ + project_slug: this.$route.params.slug + }); + } + } + }, + + importFeatureTypeData: { + deep: true, + handler(newValue) { + if (newValue && newValue.some(el => el.status === 'pending') && !this.reloadIntervalId) { + this.SET_RELOAD_INTERVAL_ID(setInterval(() => { + this.GET_IMPORTS({ + project_slug: this.$route.params.slug + }); + }, this.$store.state.configuration.VUE_APP_RELOAD_INTERVAL)); + } else if (newValue && !newValue.some(el => el.status === 'pending')) { + this.CLEAR_RELOAD_INTERVAL_ID(); + } + } + } + }, + methods: { + ...mapMutations([ + 'SET_RELOAD_INTERVAL_ID', + 'CLEAR_RELOAD_INTERVAL_ID' + ]), + ...mapActions([ + 'GET_PROJECT_INFO' + ]), + ...mapActions('feature_type', [ + 'GET_IMPORTS' + ]), + ...mapActions('feature', [ + 'GET_PROJECT_FEATURES' + ]), refreshId() { return "?ver=" + Math.random(); }, @@ -786,18 +858,24 @@ export default { }, mounted() { - this.$store.dispatch("GET_PROJECT_INFO", this.slug).then(() => { - this.featureTypeLoading = false; - setTimeout(this.initMap, 1000); - }); - this.$store - .dispatch("feature/GET_PROJECT_FEATURES", { - project_slug: this.slug, - ordering: '-created_on', - limit: 5 + this.GET_PROJECT_INFO(this.slug) + .then(() => { + this.featureTypeLoading = false; + setTimeout(this.initMap, 1000); }) + .catch(() => { + this.featureTypeLoading = false; + }); + this.GET_PROJECT_FEATURES({ + project_slug: this.slug, + ordering: '-created_on', + limit: 5 + }) .then(() => { this.featuresLoading = false; + }) + .catch(() => { + this.featuresLoading = false; }); if (this.message) { @@ -869,4 +947,10 @@ export default { .text-left { text-align: left !important; } + +.import-message { + width: fit-content; + line-height: 2em; + color: teal; +} </style>