Przeglądaj źródła

feat(permissions): update permission scopes to franchisor_activities and enhance access controls across Kanban features

ebagabee 2 tygodni temu
rodzic
commit
2b0834f3f6

+ 11 - 2
src/pages/kanban/KanbanPage.vue

@@ -45,6 +45,7 @@
               style="font-size: 11px"
             />
             <q-btn
+              v-if="canAdd"
               flat
               round
               dense
@@ -60,7 +61,8 @@
         <draggable
           :list="columnMap[column.phase]"
           :data-phase="column.phase"
-          group="kanban"
+          :group="canEdit ? 'kanban' : { name: 'kanban', pull: false, put: false }"
+          :disabled="!canEdit"
           item-key="id"
           :animation="180"
           ghost-class="drag-ghost"
@@ -71,7 +73,9 @@
           <template #item="{ element }">
             <KanbanCard
               :card="element"
-              @edit="openDialog(element, column.phase)"
+              :can-edit="canEdit"
+              :can-delete="canDelete"
+              @edit="canEdit && openDialog(element, column.phase)"
               @delete="removeCard($event, column.phase)"
             />
           </template>
@@ -89,12 +93,17 @@ import draggable from "vuedraggable";
 import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
 import KanbanCard from "./components/KanbanCard.vue";
 import { getKanbans, reorderKanbans } from "src/api/kanban";
+import { permissionStore } from "src/stores/permission";
 
 const AddEditKanbanDialog = defineAsyncComponent(
   () => import("./components/AddEditKanbanDialog.vue"),
 );
 
 const $q = useQuasar();
+const permissions = permissionStore();
+const canAdd = permissions.getAccess("franchisor_activities", "add");
+const canEdit = permissions.getAccess("franchisor_activities", "edit");
+const canDelete = permissions.getAccess("franchisor_activities", "delete");
 const loading = ref(false);
 
 const columns = [

+ 11 - 1
src/pages/kanban/components/AddEditKanbanDialog.vue

@@ -99,6 +99,7 @@
             <div v-show="currentTab === 'comentarios'">
               <div class="flex justify-end q-mb-sm">
                 <q-btn
+                  v-if="canAdd"
                   color="primary"
                   icon="mdi-plus"
                   unelevated
@@ -123,6 +124,8 @@
                     :reply="reply.reply"
                     :created-at="reply.created_at"
                     :user-name="reply.user_name"
+                    :can-edit="canEdit"
+                    :can-delete="canDelete"
                     @edit="onEditComment(reply)"
                     @delete="onDeleteComment(reply)"
                   />
@@ -137,6 +140,7 @@
             <div v-show="currentTab === 'midias'">
               <div class="flex justify-end q-mb-sm">
                 <q-btn
+                  v-if="canAdd"
                   color="primary"
                   icon="mdi-upload-outline"
                   unelevated
@@ -170,6 +174,7 @@
                     :mime-type="media.mime_type"
                     :created-at="media.created_at"
                     :user-name="media.user_name"
+                    :can-delete="canDelete"
                     @delete="onDeleteMedia(media)"
                   />
                 </template>
@@ -182,7 +187,7 @@
 
           <q-card-actions align="right" class="q-px-md q-pb-md" style="flex-shrink: 0">
             <q-btn outline color="primary" label="Cancelar" @click="onDialogCancel" />
-            <q-btn color="primary" label="Salvar" type="submit" :loading="loading" />
+            <q-btn v-if="card?.id ? canEdit : canAdd" color="primary" label="Salvar" type="submit" :loading="loading" />
           </q-card-actions>
         </q-form>
       </q-card>
@@ -215,6 +220,7 @@ import {
   uploadKanbanMedia,
   deleteKanbanMedia,
 } from "src/api/kanban_media";
+import { permissionStore } from "src/stores/permission";
 
 defineEmits([...useDialogPluginComponent.emits]);
 
@@ -227,6 +233,10 @@ const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
   useDialogPluginComponent();
 
 const $q = useQuasar();
+const permissions = permissionStore();
+const canAdd = permissions.getAccess("franchisor_activities", "add");
+const canEdit = permissions.getAccess("franchisor_activities", "edit");
+const canDelete = permissions.getAccess("franchisor_activities", "delete");
 
 const formRef      = ref(null);
 const loading      = ref(false);

+ 7 - 3
src/pages/kanban/components/KanbanCard.vue

@@ -1,8 +1,9 @@
 <template>
   <q-card
-    class="kanban-card cursor-pointer"
+    class="kanban-card"
+    :class="{ 'cursor-pointer': canEdit }"
     :style="{ borderLeft: `4px solid ${phaseColor}` }"
-    @click="$emit('edit', card)"
+    @click="canEdit && $emit('edit', card)"
   >
     <!-- Header: Creator name + Priority badge + Delete button -->
     <div class="row items-center justify-between q-px-md q-pt-md">
@@ -17,6 +18,7 @@
           style="padding: 4px 8px; font-size: 11px"
         />
         <q-btn
+          v-if="canDelete"
           flat
           dense
           round
@@ -73,8 +75,10 @@ import { deleteKanban } from "src/api/kanban";
 
 const emit = defineEmits(["edit", "delete"]);
 
-const { card } = defineProps({
+const { card, canEdit, canDelete } = defineProps({
   card: { type: Object, required: true },
+  canEdit: { type: Boolean, default: false },
+  canDelete: { type: Boolean, default: false },
 });
 
 const $q = useQuasar();

+ 4 - 0
src/pages/kanban/components/KanbanCommentCard.vue

@@ -11,6 +11,7 @@
       </div>
       <div style="display: flex; gap: 4px; flex-shrink: 0">
         <q-btn
+          v-if="canEdit"
           flat
           dense
           round
@@ -20,6 +21,7 @@
           @click="$emit('edit')"
         />
         <q-btn
+          v-if="canDelete"
           flat
           dense
           round
@@ -37,6 +39,8 @@
 defineEmits(["edit", "delete"]);
 
 defineProps({
+  canEdit: { type: Boolean, default: false },
+  canDelete: { type: Boolean, default: false },
   reply: {
     type: String,
     required: true,

+ 2 - 0
src/pages/kanban/components/KanbanMediaCard.vue

@@ -37,6 +37,7 @@
           target="_blank"
         />
         <q-btn
+          v-if="canDelete"
           flat
           dense
           round
@@ -56,6 +57,7 @@ import { computed } from "vue";
 defineEmits(["delete"]);
 
 const props = defineProps({
+  canDelete: { type: Boolean, default: false },
   fileName:  { type: String, required: true },
   fileUrl:   { type: String, required: true },
   mimeType:  { type: String, default: null },

+ 1 - 1
src/pages/permissions/permission_menus.js

@@ -60,7 +60,7 @@ export const FRANCHISOR_PERMISSION_MENUS = Object.freeze([
     icon: "mdi-cash-multiple",
   },
   { scope: "franchisor_support", label: "Suporte", icon: "mdi-headset" },
-  { scope: "kanban", label: "Atividades", icon: "mdi-clipboard-list-outline" },
+  { scope: "franchisor_activities", label: "Atividades", icon: "mdi-clipboard-list-outline" },
   { scope: "config", label: "Cadastros", icon: "mdi-account-multiple-outline" },
   {
     scope: "config.user-type",

+ 1 - 1
src/router/routes/kanban.route.js

@@ -9,7 +9,7 @@ export default [
         translate: false,
       },
       requireAuth: true,
-      requiredPermission: "dashboard",
+      requiredPermission: "franchisor_activities",
       breadcrumbs: [
         {
           name: "KanbanPage",

+ 1 - 1
src/stores/navigation.js

@@ -113,7 +113,7 @@ export const navigationStore = defineStore("navigation", () => {
       icon: "mdi-clipboard-list-outline",
       disable: false,
       permission: false,
-      permissionScope: "dashboard",
+      permissionScope: "franchisor_activities",
     },
     {
       type: "single",