浏览代码

feat(students): implement permission checks for adding, editing, and deleting student-related items

ebagabee 1 周之前
父节点
当前提交
3c2b04054e

+ 14 - 1
src/pages/students/StudentPage.vue

@@ -49,7 +49,7 @@
         descricao="Alunos"
         :feminino="false"
         no-api-call
-        add-item
+        :add-item="canAdd"
         :loading="isLoading"
         @on-add-item="onAddStudent"
       >
@@ -73,6 +73,7 @@
           <q-td auto-width>
             <q-item-section class="no-wrap" style="flex-direction: row">
               <q-btn
+                v-if="canEdit"
                 outline
                 icon="mdi-account-edit-outline"
                 style="width: 36px"
@@ -80,6 +81,7 @@
                 @click.prevent.stop="onEditStudent(row)"
               />
               <q-btn
+                v-if="canDelete"
                 outline
                 icon="mdi-trash-can-outline"
                 style="width: 36px"
@@ -102,6 +104,7 @@ import DefaultTable from "src/components/defaults/DefaultTable.vue";
 import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
 import { getStudents, deleteStudent } from "src/api/student";
 import { userStore } from "src/stores/user";
+import { permissionStore } from "src/stores/permission";
 
 const AddEditStudentDialog = defineAsyncComponent(
   () => import("src/pages/students/components/AddEditStudentDialog.vue"),
@@ -113,6 +116,16 @@ const EditStudentDialog = defineAsyncComponent(
 
 const $q = useQuasar();
 const store = userStore();
+const permissions = permissionStore();
+const canAdd = computed(() =>
+  permissions.getAccess("franchisee_students", "add"),
+);
+const canEdit = computed(() =>
+  permissions.getAccess("franchisee_students", "edit"),
+);
+const canDelete = computed(() =>
+  permissions.getAccess("franchisee_students", "delete"),
+);
 
 const rows = ref([]);
 const isLoading = ref(false);

+ 9 - 2
src/pages/students/tabs/ContractTab.vue

@@ -15,7 +15,7 @@
       descricao="contratos"
       :feminino="false"
       no-api-call
-      add-item
+      :add-item="canAdd"
       :show-search-field="false"
       @on-add-item="handleAdd"
     >
@@ -36,12 +36,14 @@
         <q-td align="center">
           <q-item-section class="no-wrap" style="flex-direction: row; gap: 4px">
             <q-btn
+              v-if="canEdit"
               outline
               icon="mdi-pencil-outline"
               style="width: 36px"
               @click.prevent.stop="handleEdit(row)"
             />
             <q-btn
+              v-if="canEdit"
               outline
               icon="mdi-paperclip"
               style="width: 36px"
@@ -49,6 +51,7 @@
               @click.prevent.stop="triggerFileInput(row)"
             />
             <q-btn
+              v-if="canEdit"
               outline
               icon="mdi-dots-vertical"
               style="width: 36px"
@@ -92,7 +95,7 @@
 </template>
 
 <script setup>
-import { ref, onMounted } from "vue";
+import { computed, ref, onMounted } from "vue";
 import { useQuasar } from "quasar";
 import DefaultTable from "src/components/defaults/DefaultTable.vue";
 import AddEditContractDialog from "src/pages/students/components/AddEditContractDialog.vue";
@@ -104,6 +107,7 @@ import {
   cancelContract,
   reactivateContract,
 } from "src/api/studentContract";
+import { permissionStore } from "src/stores/permission";
 
 const props = defineProps({
   student: {
@@ -113,6 +117,9 @@ const props = defineProps({
 });
 
 const $q = useQuasar();
+const permissions = permissionStore();
+const canAdd = computed(() => permissions.getAccess("franchisee_students", "add"));
+const canEdit = computed(() => permissions.getAccess("franchisee_students", "edit"));
 const rows = ref([]);
 const fileInputRef = ref(null);
 const uploadingId = ref(null);

+ 9 - 3
src/pages/students/tabs/MediaTab.vue

@@ -4,7 +4,7 @@
       v-model:rows="rows"
       :columns="columns"
       no-api-call
-      add-item
+      :add-item="canAdd"
       :show-search-field="false"
       hide-no-data-label
       @on-add-item="openAddDialog"
@@ -37,7 +37,7 @@
           @click.stop="openFile(row.file_url)"
         />
         <q-btn
-          v-if="row.type !== 'contract'"
+          v-if="canEdit && row.type !== 'contract'"
           flat
           round
           dense
@@ -46,6 +46,7 @@
           @click.stop="openEditDialog(row)"
         />
         <q-btn
+          v-if="canDelete"
           flat
           round
           dense
@@ -58,18 +59,23 @@
 </template>
 
 <script setup>
-import { ref, onMounted } from "vue";
+import { computed, ref, onMounted } from "vue";
 import { useQuasar } from "quasar";
 import DefaultTable from "src/components/defaults/DefaultTable.vue";
 import AddStudentMediaDialog from "src/pages/students/components/AddStudentMediaDialog.vue";
 import EditStudentMediaDialog from "src/pages/students/components/EditStudentMediaDialog.vue";
 import { getStudentMedias, deleteStudentMedia } from "src/api/student_media";
+import { permissionStore } from "src/stores/permission";
 
 const props = defineProps({
   studentId: { type: Number, required: true },
 });
 
 const $q = useQuasar();
+const permissions = permissionStore();
+const canAdd = computed(() => permissions.getAccess("franchisee_students", "add"));
+const canEdit = computed(() => permissions.getAccess("franchisee_students", "edit"));
+const canDelete = computed(() => permissions.getAccess("franchisee_students", "delete"));
 const rows = ref([]);
 
 const columns = [

+ 9 - 2
src/pages/students/tabs/ResponsibleTab.vue

@@ -7,7 +7,7 @@
       descricao="responsáveis"
       :feminino="true"
       no-api-call
-      add-item
+      :add-item="canAdd"
       :show-search-field="false"
       @on-add-item="handleAdd"
     >
@@ -15,12 +15,14 @@
         <q-td align="center">
           <q-item-section class="no-wrap" style="flex-direction: row; gap: 4px">
             <q-btn
+              v-if="canEdit"
               outline
               icon="mdi-pencil-outline"
               style="width: 36px"
               @click.prevent.stop="handleEdit(row)"
             />
             <q-btn
+              v-if="canDelete"
               outline
               icon="mdi-trash-can-outline"
               style="width: 36px"
@@ -34,7 +36,7 @@
 </template>
 
 <script setup>
-import { ref, onMounted } from "vue";
+import { computed, ref, onMounted } from "vue";
 import { useQuasar } from "quasar";
 import DefaultTable from "src/components/defaults/DefaultTable.vue";
 import ResponsibleDialog from "src/pages/students/components/ResponsibleDialog.vue";
@@ -42,6 +44,7 @@ import {
   getStudentResponsible,
   deleteStudentResponsible,
 } from "src/api/studentResponsible";
+import { permissionStore } from "src/stores/permission";
 
 const props = defineProps({
   studentId: {
@@ -51,6 +54,10 @@ const props = defineProps({
 });
 
 const $q = useQuasar();
+const permissions = permissionStore();
+const canAdd = computed(() => permissions.getAccess("franchisee_students", "add"));
+const canEdit = computed(() => permissions.getAccess("franchisee_students", "edit"));
+const canDelete = computed(() => permissions.getAccess("franchisee_students", "delete"));
 const rows = ref([]);
 
 const columns = ref([

+ 1 - 0
src/router/routes/config.route.js

@@ -21,6 +21,7 @@ export default [
     meta: {
       title: "Alunos",
       requireAuth: true,
+      requiredPermission: "franchisee_students",
       breadcrumbs: [
         {
           name: "StudentPage",

+ 2 - 1
src/stores/navigation.js

@@ -19,7 +19,8 @@ export const navigationStore = defineStore("navigation", () => {
       name: "StudentPage",
       icon: "mdi-account-outline",
       disable: false,
-      permission: true,
+      permission: false,
+      permissionScope: "franchisee_students",
     },
     {
       type: "single",