diff --git a/src/App.vue b/src/App.vue index 026d0174c8217b044e22c2aa1f5ff57457976664..964cfd77ac5e2480361fb249dc59952ae2d3d255 100644 --- a/src/App.vue +++ b/src/App.vue @@ -10,7 +10,10 @@ <header class="header-menu"> <div class="menu container"> <div class="ui inverted icon menu"> - <router-link to="/" class="header item"> + <router-link + :to="isSharedProject ? '' : '/'" + :class="['header item', {disable: isSharedProject}]" + > <img class="ui mini right spaced image" :src="logo" /> <span class="desktop"> {{ APPLICATION_NAME }} @@ -117,7 +120,7 @@ </div> <div class="desktop flex push-right-desktop"> - <router-link v-if="user" to="/my_account/" class="item"> + <router-link v-if="user" :to="{name: 'my_account'}" class="item"> {{ userFullname || user.username || "Utilisateur inconnu" }} </router-link> <div @@ -161,7 +164,8 @@ > <i class="close icon" @click="DISCARD_MESSAGE(message)"></i> <div class="header"> - <i class="info circle icon"></i> Informations + <i class="info circle icon"></i> + Informations </div> <ul class="list"> {{ @@ -184,8 +188,8 @@ <footer> <div class="ui compact text menu"> - <router-link to="/mentions/" class="item">Mentions légales</router-link> - <router-link to="/aide/" class="item">Aide</router-link> + <router-link :to="{name: 'mentions'}" class="item">Mentions légales</router-link> + <router-link :to="{name: 'aide'}" class="item">Aide</router-link> <p class="item">Version {{ PACKAGE_VERSION }}</p> </div> </footer> @@ -246,6 +250,9 @@ export default { ? true : false; }, + isSharedProject() { + return this.$route.path.includes('projet-partage'); + } }, methods: { @@ -424,4 +431,10 @@ footer { } </style> - \ No newline at end of file + + <style scoped> + .disable:hover { + cursor: default !important; + background-color: #373636 !important; + } + </style> \ No newline at end of file diff --git a/src/components/feature/FeatureExtraForm.vue b/src/components/feature/FeatureExtraForm.vue index c0deb2df754b5d0e73b1142a52c8d45d54e639c7..3171439c2262ff1711068dcad8abc6d2d2b21c8e 100644 --- a/src/components/feature/FeatureExtraForm.vue +++ b/src/components/feature/FeatureExtraForm.vue @@ -34,6 +34,7 @@ <div v-frag v-else-if="field.field_type === 'boolean'"> <div class="ui checkbox"> <input + class="hidden" type="checkbox" :checked="field.value" :name="field.name" diff --git a/src/components/project/ProjectMappingContextLayer.vue b/src/components/project/ProjectMappingContextLayer.vue index 567d47ab2a9d226110ddd3b4574467c24247e24e..cfd82b70d16a14d08c4138848a515550dba02966 100644 --- a/src/components/project/ProjectMappingContextLayer.vue +++ b/src/components/project/ProjectMappingContextLayer.vue @@ -39,7 +39,7 @@ @click="updateLayer({ ...layer, queryable: !layer.queryable })" class="ui checkbox" > - <input type="checkbox" v-model="layer.queryable" name="queryable" /> + <input class="hidden" type="checkbox" v-model="layer.queryable" name="queryable" /> <label for="queryable"> Requêtable</label> </div> <!-- {{ form.queryable.errors }} --> diff --git a/src/router/index.js b/src/router/index.js index ab603a745eef79c6de3269be2f61f017c08eb4e8..f335b9e01be58a26d80966e245a9a7895ee048c7 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -4,6 +4,11 @@ import Index from '../views/Index.vue' Vue.use(VueRouter) +let projectBase = "projet" +if (window.location.pathname.includes("projet-partage")) { + projectBase = "projet-partage" +} + const routes = [ { path: '/', @@ -19,17 +24,17 @@ const routes = [ component: () => import(/* webpackChunkName: "login" */'../views/registration/Login.vue') }, { - path: '/my_account/', + path: `${projectBase === 'projet' ? '': '/' + projectBase}/my_account/`, name: 'my_account', component: () => import('../views/My_account.vue') }, { - path: '/mentions/', + path: `${projectBase === 'projet' ? '': '/' + projectBase}/mentions/`, name: 'mentions', component: () => import('../views/flatpages/with_right_menu.vue') }, { - path: '/aide/', + path: `${projectBase === 'projet' ? '': '/' + projectBase}/aide/`, name: 'aide', component: () => import('../views/flatpages/Default.vue') }, @@ -40,13 +45,13 @@ const routes = [ component: () => import('../views/project/Project_edit.vue') }, { - path: '/projet/:slug', + path: `/${projectBase}/:slug`, name: 'project_detail', props: true, component: () => import('../views/project/Project_detail.vue'), }, { - path: '/projet/:slug/editer', + path: `/${projectBase}/:slug/editer`, name: 'project_edit', component: () => import('../views/project/Project_edit.vue') }, @@ -61,65 +66,65 @@ const routes = [ component: () => import('../views/project/Project_edit.vue') }, { - path: '/projet/:slug/administration-carte/', + path: `/${projectBase}/:slug/administration-carte/`, name: 'project_mapping', component: () => import('../views/project/Project_mapping.vue') }, { - path: '/projet/:slug/membres/', + path: `/${projectBase}/:slug/membres/`, name: 'project_members', component: () => import('../views/project/Project_members.vue') }, // * FEATURE TYPE { - path: '/projet/:slug/type-signalement/ajouter/', + path: `/${projectBase}/:slug/type-signalement/ajouter/`, name: 'ajouter-type-signalement', props: true, component: () => import('../views/feature_type/Feature_type_edit.vue') }, { - path: '/projet/:slug/type-signalement/ajouter/create_from/:slug_type_signal', + path: `/${projectBase}/:slug/type-signalement/ajouter/create_from/:slug_type_signal`, name: 'dupliquer-type-signalement', component: () => import('../views/feature_type/Feature_type_edit.vue') }, { - path: '/projet/:slug/type-signalement/:feature_type_slug/', + path: `/${projectBase}/:slug/type-signalement/:feature_type_slug/`, name: 'details-type-signalement', component: () => import('../views/feature_type/Feature_type_detail.vue') }, { - path: '/projet/:slug/type-signalement/:slug_type_signal/editer/', + path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/editer/`, name: 'editer-type-signalement', component: () => import('../views/feature_type/Feature_type_edit.vue') }, { - path: '/projet/:slug/type-signalement/:slug_type_signal/symbologie/', + path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/symbologie/`, name: 'editer-symbologie-signalement', component: () => import('../views/feature_type/Feature_type_symbology.vue') }, // * FEATURE { - path: '/projet/:slug/signalement/lister/', + path: `/${projectBase}/:slug/signalement/lister/`, name: 'liste-signalements', component: () => import('../views/feature/Feature_list.vue') }, { - path: '/projet/:slug/type-signalement/:slug_type_signal/signalement/ajouter/', + path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/signalement/ajouter/`, name: 'ajouter-signalement', component: () => import('../views/feature/Feature_edit.vue') }, { - path: '/projet/:slug/type-signalement/:slug_type_signal/signalement/:slug_signal', + path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/signalement/:slug_signal`, name: 'details-signalement', component: () => import('../views/feature/Feature_detail.vue') }, { - path: '/projet/:slug/type-signalement/:slug_type_signal/offline', + path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/offline`, name: 'offline-signalement', component: () => import('../views/feature/Feature_offline.vue') }, { - path: '/projet/:slug/type-signalement/:slug_type_signal/signalement/:slug_signal/editer/', + path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/signalement/:slug_signal/editer/`, name: 'editer-signalement', component: () => import('../views/feature/Feature_edit.vue') }, diff --git a/src/store/index.js b/src/store/index.js index 101367d988c51875c904b37e99ad13701c204bb6..a6c2008102fb6e5ace554cbc6339f6303893e276 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -135,6 +135,7 @@ export default new Vuex.Store({ getters: { project: state => state.projects.find((project) => project.slug === state.project_slug), permissions: state => state.user_permissions ? state.user_permissions[state.project_slug] : noPermissions, + // TODO: utiliser et créer point api depuis ProjectTypeListView lors du passage à la pagination des projets project_types: state => state.projects.filter(projet => projet.is_project_type), project_user: state => state.projects.filter(projet => projet.creator === state.user.id), }, diff --git a/src/views/feature_type/Feature_type_edit.vue b/src/views/feature_type/Feature_type_edit.vue index c01b58538f9adec34edc21ffef3ce1eefc959298..823914679f737ce657ffa3fc09024a00b0e0216f 100644 --- a/src/views/feature_type/Feature_type_edit.vue +++ b/src/views/feature_type/Feature_type_edit.vue @@ -80,11 +80,13 @@ <div class="field"> <div class="ui checkbox"> <input + class="hidden" + :id="form.title_optional.html_name" :name="form.title_optional.html_name" v-model="form.title_optional.value" type="checkbox" /> - <label>{{ form.title_optional.label }}</label> + <label :for="form.title_optional.html_name">{{ form.title_optional.label }}</label> </div> </div> diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue index f03b8eeffd99d2d0180f2b302f7ebe4607ae6510..a0cd446abded78b8bc41a6cc956d65f3ee7fa81b 100644 --- a/src/views/project/Project_detail.vue +++ b/src/views/project/Project_detail.vue @@ -3,9 +3,6 @@ <div v-frag v-if="permissions && permissions.can_view_project && project"> <div id="message" class="fullwidth"> <div v-if="tempMessage" class="ui positive message"> - <!-- <i class="close icon"></i> --> - <!-- <div class="header">You are eligible for a reward</div> --> - <p><i class="check icon"></i> {{ tempMessage }}</p> </div> </div> @@ -48,74 +45,99 @@ >{{ project.nb_published_features_comments }} </div> </div> - <div class="ten wide column"> - <h1 class="ui header"> - <div class="content"> - {{ project.title }} - <div v-if="arraysOffline.length > 0"> - {{ arraysOffline.length }} modification<span v-if="arraysOffline.length>1">s</span> en attente + <div class="ten wide column important-flex space-between"> + <div> + <h1 class="ui header"> + {{ project.title }} + </h1> + <div class="ui hidden divider"></div> + <div class="sub header"> + {{ project.description }} + </div> + </div> + + <div class="content flex flex-column-right"> + <div class="flex flex-column-right"> + <div class="ui icon right compact buttons flex-column-right"> + <div> + <a + v-if=" + user && + permissions && + permissions.can_view_project && + isOffline() !== true + " + id="subscribe-button" + class="ui button button-hover-green" + data-tooltip="S'abonner au projet" + data-position="top center" + data-variation="mini" + @click="modalType = 'subscribe'" + > + <i class="inverted grey envelope icon"></i> + </a> + <router-link + v-if=" + permissions && + permissions.can_update_project && + isOffline() !== true + " + :to="{ name: 'project_edit', params: { slug: project.slug } }" + class="ui button button-hover-orange" + data-tooltip="Modifier le projet" + data-position="top center" + data-variation="mini" + > + <i class="inverted grey pencil alternate icon"></i> + </router-link> + <a + v-if=" + user_permissions && + user_permissions[project.slug] && + user_permissions[project.slug].is_project_administrator && + isOffline() !== true + " + id="delete-button" + class="ui button button-hover-red" + data-tooltip="Supprimer le projet" + data-position="top center" + data-variation="mini" + @click="modalType = 'deleteProject'" + > + <i class="inverted grey trash icon"></i> + </a> + </div> <button - :disabled="isOffline()" - @click="sendOfflineFeatures()" - class="ui fluid teal icon button" + v-if="user && user.is_administrator && !isSharedProject && project.generate_share_link" + class="ui teal left labeled icon button" + @click="copyLink" > - <i class="upload icon"></i> Envoyer au serveur + <i class="left icon share square"></i> + Copier le lien de partage </button> </div> - <div class="ui icon right floated compact buttons"> - <a - v-if=" - user && - permissions && - permissions.can_view_project && - isOffline() !== true - " - id="subscribe-button" - class="ui button button-hover-green" - data-tooltip="S'abonner au projet" - data-position="top center" - data-variation="mini" - @click="modalType = 'subscribe'" - > - <i class="inverted grey envelope icon"></i> - </a> - <router-link - v-if=" - permissions && - permissions.can_update_project && - isOffline() !== true - " - :to="{ name: 'project_edit', params: { slug: project.slug } }" - class="ui button button-hover-orange" - data-tooltip="Modifier le projet" - data-position="top center" - data-variation="mini" - > - <i class="inverted grey pencil alternate icon"></i> - </router-link> - <a - v-if=" - user_permissions && - user_permissions[project.slug] && - user_permissions[project.slug].is_project_administrator && - isOffline() !== true - " - id="delete-button" - class="ui button button-hover-red" - data-tooltip="Supprimer le projet" - data-position="top center" - data-variation="mini" - @click="modalType = 'deleteProject'" - > - <i class="inverted grey trash icon"></i> - </a> - </div> - <div class="ui hidden divider"></div> - <div class="sub header"> - {{ project.description }} + <div v-if="confirmMsg"> + <div class="ui positive tiny-margin message"> + <span> + Le lien a été copié dans le presse-papier + </span> + + <i class="close icon" @click="confirmMsg = ''" /> + </div> </div> </div> - </h1> + </div> + </div> + <div v-if="arraysOffline.length > 0"> + {{ arraysOffline.length }} modification<span v-if="arraysOffline.length>1">s</span> en attente + <button + :disabled="isOffline()" + @click="sendOfflineFeatures()" + class="ui fluid labeled teal icon button" + > + <i class="upload icon"></i> + Envoyer au serveur + </button> </div> </div> @@ -704,6 +726,7 @@ export default { importMessage: null, arraysOffline: [], arraysOfflineErrors: [], + confirmMsg: false, geojsonImport: [], fileToImport: { name: "", size: 0 }, slug: this.$route.params.slug, @@ -749,6 +772,9 @@ export default { }, fileSize() { return fileConvertSizeToMo(this.fileToImport.size); + }, + isSharedProject() { + return this.$route.path.includes('projet-partage'); } }, @@ -834,7 +860,10 @@ export default { return "?ver=" + Math.random(); }, getRouteUrl(url) { - return "/" + url.replace(this.$store.state.configuration.BASE_URL, ""); // remove duplicate /geocontrib + if (this.isSharedProject) { + url = url.replace("projet", "projet-partage") + } + return url.replace(this.$store.state.configuration.BASE_URL, ""); //* remove duplicate /geocontrib }, isOffline() { return navigator.onLine === false; @@ -847,6 +876,17 @@ export default { return false; }, + copyLink() { + const sharedLink = window.location.href.replace("projet", "projet-partage"); + navigator.clipboard.writeText(sharedLink).then(()=> { + console.log("success") + this.confirmMsg = true; + }, () => { + console.log("failed") + } + ) + }, + retrieveProjectInfo() { this.GET_PROJECT_INFO(this.slug) .then(() => { @@ -1115,7 +1155,6 @@ export default { /* // ! missing style in semantic.min.css, je ne comprends pas comment... */ .ui.right.floated.button { float: right; - margin: 0 0 0 1em; } .feature-type-container { @@ -1158,6 +1197,14 @@ export default { .text-left { text-align: left !important; } +.space-between { + justify-content: space-between; +} + +.flex-column-right { + flex-direction: column !important; + align-items: flex-end; +} .import-message { width: fit-content; @@ -1167,6 +1214,9 @@ export default { </style> <style scoped> +.ui.button, .ui.button .button, .tiny-margin { + margin: 0.1rem 0 0.1rem 0.1rem !important; +} .alert { color: red; } diff --git a/src/views/project/Project_edit.vue b/src/views/project/Project_edit.vue index 5aed3f7d69d9175da7fb9aa3fb84d954ec500821..715b5c8cbe2492ca7e17d8a1c745c2d631221038 100644 --- a/src/views/project/Project_edit.vue +++ b/src/views/project/Project_edit.vue @@ -158,6 +158,7 @@ <div class="field"> <div class="ui checkbox"> <input + class="hidden" type="checkbox" v-model="form.moderation" name="moderation" @@ -165,12 +166,12 @@ /> <label for="moderation">Modération</label> </div> - <!-- {{ form.moderation.errors }} --> </div> <div class="field"> <div class="ui checkbox"> <input + class="hidden" type="checkbox" v-model="form.is_project_type" name="is_project_type" @@ -178,7 +179,19 @@ /> <label for="is_project_type">Est un projet type</label> </div> - <!-- {{ form.is_project_type.errors }} --> + </div> + + <div class="field"> + <div class="ui checkbox"> + <input + class="hidden" + type="checkbox" + v-model="form.generate_share_link" + name="generate_share_link" + id="generate_share_link" + /> + <label for="generate_share_link">Génération d'un lien de partage externe</label> + </div> </div> <div class="ui divider"></div> @@ -196,12 +209,6 @@ import Dropdown from "@/components/Dropdown.vue"; import { mapState, mapGetters } from "vuex"; -// axios.defaults.headers.common["X-CSRFToken"] = ((name) => { -// var re = new RegExp(name + "=([^;]+)"); -// var value = re.exec(document.cookie); -// return value !== null ? unescape(value[1]) : null; -// })("csrftoken"); - export default { name: "Project_edit", @@ -244,6 +251,7 @@ export default { nb_published_features_comments: 0, nb_contributors: 0, is_project_type: false, + generate_share_link: false, }, thumbnailFileSrc: "", }; @@ -449,6 +457,7 @@ export default { archive_feature: this.form.archive_feature, delete_feature: this.form.delete_feature, is_project_type: this.form.is_project_type, + generate_share_link: this.form.generate_share_link, moderation: this.form.moderation, }; let url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/`;