|
@@ -19,21 +19,29 @@
|
|
|
|
|
|
|
|
<q-list v-if="!loading" separator class="col scroll">
|
|
<q-list v-if="!loading" separator class="col scroll">
|
|
|
<q-item
|
|
<q-item
|
|
|
- v-for="item in roots"
|
|
|
|
|
- :key="item.id"
|
|
|
|
|
|
|
+ v-for="item in menus"
|
|
|
|
|
+ :key="item.scope"
|
|
|
clickable
|
|
clickable
|
|
|
- :active="selectedId === item.id"
|
|
|
|
|
|
|
+ :active="selectedScope === item.scope"
|
|
|
active-class="bg-blue-1 text-primary"
|
|
active-class="bg-blue-1 text-primary"
|
|
|
- @click="selectedId = item.id"
|
|
|
|
|
|
|
+ @click="selectedScope = item.scope"
|
|
|
>
|
|
>
|
|
|
<q-item-section avatar>
|
|
<q-item-section avatar>
|
|
|
- <q-icon :name="iconFor(item.scope)" color="dark" />
|
|
|
|
|
|
|
+ <q-icon :name="item.icon" color="dark" />
|
|
|
</q-item-section>
|
|
</q-item-section>
|
|
|
|
|
|
|
|
<q-item-section>
|
|
<q-item-section>
|
|
|
- <q-item-label>{{ item.description }}</q-item-label>
|
|
|
|
|
|
|
+ <q-item-label>
|
|
|
|
|
+ {{ item.label }}
|
|
|
|
|
+ <q-icon
|
|
|
|
|
+ v-if="item.children?.length"
|
|
|
|
|
+ name="mdi-chevron-right"
|
|
|
|
|
+ size="16px"
|
|
|
|
|
+ class="q-ml-xs"
|
|
|
|
|
+ />
|
|
|
|
|
+ </q-item-label>
|
|
|
<q-item-label caption>
|
|
<q-item-label caption>
|
|
|
- <PermissionLevelBadges :bits="bitsById[item.id]" />
|
|
|
|
|
|
|
+ <PermissionLevelBadges :bits="bitsFor(item.scope)" />
|
|
|
</q-item-label>
|
|
</q-item-label>
|
|
|
</q-item-section>
|
|
</q-item-section>
|
|
|
|
|
|
|
@@ -48,9 +56,8 @@
|
|
|
>
|
|
>
|
|
|
<q-tooltip>Editar permissões</q-tooltip>
|
|
<q-tooltip>Editar permissões</q-tooltip>
|
|
|
<PermissionLevelMenu
|
|
<PermissionLevelMenu
|
|
|
- :bits="bitsById[item.id]"
|
|
|
|
|
- :available-bits="item.available_bits"
|
|
|
|
|
- @update:bits="(value) => (bitsById[item.id] = value)"
|
|
|
|
|
|
|
+ :bits="bitsFor(item.scope)"
|
|
|
|
|
+ @update:bits="(value) => setBits(item.scope, value)"
|
|
|
/>
|
|
/>
|
|
|
</q-btn>
|
|
</q-btn>
|
|
|
</q-item-section>
|
|
</q-item-section>
|
|
@@ -83,16 +90,20 @@
|
|
|
>
|
|
>
|
|
|
<div>Nenhuma subcategoria</div>
|
|
<div>Nenhuma subcategoria</div>
|
|
|
<div class="text-caption">
|
|
<div class="text-caption">
|
|
|
- O menu "{{ selected.description }}" não possui subcategorias.
|
|
|
|
|
|
|
+ O menu "{{ selected.label }}" não possui subcategorias.
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<q-list v-else separator class="col scroll">
|
|
<q-list v-else separator class="col scroll">
|
|
|
- <q-item v-for="child in children" :key="child.id">
|
|
|
|
|
|
|
+ <q-item v-for="child in children" :key="child.scope">
|
|
|
|
|
+ <q-item-section avatar>
|
|
|
|
|
+ <q-icon :name="child.icon" color="dark" />
|
|
|
|
|
+ </q-item-section>
|
|
|
|
|
+
|
|
|
<q-item-section>
|
|
<q-item-section>
|
|
|
- <q-item-label>{{ child.description }}</q-item-label>
|
|
|
|
|
|
|
+ <q-item-label>{{ child.label }}</q-item-label>
|
|
|
<q-item-label caption>
|
|
<q-item-label caption>
|
|
|
- <PermissionLevelBadges :bits="bitsById[child.id]" />
|
|
|
|
|
|
|
+ <PermissionLevelBadges :bits="bitsFor(child.scope)" />
|
|
|
</q-item-label>
|
|
</q-item-label>
|
|
|
</q-item-section>
|
|
</q-item-section>
|
|
|
|
|
|
|
@@ -106,9 +117,8 @@
|
|
|
>
|
|
>
|
|
|
<q-tooltip>Editar permissões</q-tooltip>
|
|
<q-tooltip>Editar permissões</q-tooltip>
|
|
|
<PermissionLevelMenu
|
|
<PermissionLevelMenu
|
|
|
- :bits="bitsById[child.id]"
|
|
|
|
|
- :available-bits="child.available_bits"
|
|
|
|
|
- @update:bits="(value) => (bitsById[child.id] = value)"
|
|
|
|
|
|
|
+ :bits="bitsFor(child.scope)"
|
|
|
|
|
+ @update:bits="(value) => setBits(child.scope, value)"
|
|
|
/>
|
|
/>
|
|
|
</q-btn>
|
|
</q-btn>
|
|
|
</q-item-section>
|
|
</q-item-section>
|
|
@@ -121,7 +131,12 @@
|
|
|
<q-separator />
|
|
<q-separator />
|
|
|
|
|
|
|
|
<q-card-actions align="right">
|
|
<q-card-actions align="right">
|
|
|
- <q-btn label="Cancelar" color="primary" outline @click="onDialogCancel" />
|
|
|
|
|
|
|
+ <q-btn
|
|
|
|
|
+ label="Cancelar"
|
|
|
|
|
+ color="primary"
|
|
|
|
|
+ outline
|
|
|
|
|
+ @click="onDialogCancel"
|
|
|
|
|
+ />
|
|
|
<q-btn
|
|
<q-btn
|
|
|
label="Salvar"
|
|
label="Salvar"
|
|
|
color="primary"
|
|
color="primary"
|
|
@@ -144,7 +159,7 @@ import {
|
|
|
getUserTypePermissions,
|
|
getUserTypePermissions,
|
|
|
updateUserTypePermissions,
|
|
updateUserTypePermissions,
|
|
|
} from "src/api/user_type";
|
|
} from "src/api/user_type";
|
|
|
-import { permissionScopeIcon } from "src/pages/permissions/permission_scopes";
|
|
|
|
|
|
|
+import { FRANCHISOR_PERMISSION_MENUS } from "src/pages/permissions/permission_menus";
|
|
|
|
|
|
|
|
const { group } = defineProps({
|
|
const { group } = defineProps({
|
|
|
group: {
|
|
group: {
|
|
@@ -160,32 +175,58 @@ const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
|
|
|
|
|
|
|
|
const loading = ref(false);
|
|
const loading = ref(false);
|
|
|
const saving = ref(false);
|
|
const saving = ref(false);
|
|
|
-const permissions = ref([]);
|
|
|
|
|
-const bitsById = ref({});
|
|
|
|
|
-const selectedId = ref(null);
|
|
|
|
|
|
|
+const selectedScope = ref(null);
|
|
|
|
|
|
|
|
-const roots = computed(() =>
|
|
|
|
|
- permissions.value.filter((p) => p.parent_id === null),
|
|
|
|
|
|
|
+// permission_id e bits atuais do grupo, indexados pelo scope do menu.
|
|
|
|
|
+const permissionIdByScope = ref({});
|
|
|
|
|
+const bitsByScope = ref({});
|
|
|
|
|
+
|
|
|
|
|
+const menus = computed(() =>
|
|
|
|
|
+ FRANCHISOR_PERMISSION_MENUS.filter(
|
|
|
|
|
+ (menu) => permissionIdByScope.value[menu.scope] !== undefined,
|
|
|
|
|
+ ),
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
const selected = computed(
|
|
const selected = computed(
|
|
|
- () => permissions.value.find((p) => p.id === selectedId.value) ?? null,
|
|
|
|
|
|
|
+ () => menus.value.find((menu) => menu.scope === selectedScope.value) ?? null,
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
const children = computed(() =>
|
|
const children = computed(() =>
|
|
|
- permissions.value.filter((p) => p.parent_id === selectedId.value),
|
|
|
|
|
|
|
+ (selected.value?.children ?? []).filter(
|
|
|
|
|
+ (child) => permissionIdByScope.value[child.scope] !== undefined,
|
|
|
|
|
+ ),
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
-const iconFor = (scope) => permissionScopeIcon(scope);
|
|
|
|
|
|
|
+const bitsFor = (scope) => bitsByScope.value[scope] ?? 0;
|
|
|
|
|
+
|
|
|
|
|
+const setBits = (scope, value) => {
|
|
|
|
|
+ bitsByScope.value[scope] = value;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const scopesInMenu = () =>
|
|
|
|
|
+ FRANCHISOR_PERMISSION_MENUS.flatMap((menu) => [
|
|
|
|
|
+ menu.scope,
|
|
|
|
|
+ ...(menu.children ?? []).map((child) => child.scope),
|
|
|
|
|
+ ]);
|
|
|
|
|
|
|
|
const fetchPermissions = async () => {
|
|
const fetchPermissions = async () => {
|
|
|
loading.value = true;
|
|
loading.value = true;
|
|
|
try {
|
|
try {
|
|
|
const payload = await getUserTypePermissions(group.slug);
|
|
const payload = await getUserTypePermissions(group.slug);
|
|
|
- permissions.value = payload.permissions;
|
|
|
|
|
- bitsById.value = Object.fromEntries(
|
|
|
|
|
- payload.permissions.map((p) => [p.id, p.bits]),
|
|
|
|
|
|
|
+ const byScope = Object.fromEntries(
|
|
|
|
|
+ payload.permissions.map((p) => [p.scope, p]),
|
|
|
);
|
|
);
|
|
|
|
|
+
|
|
|
|
|
+ permissionIdByScope.value = {};
|
|
|
|
|
+ bitsByScope.value = {};
|
|
|
|
|
+
|
|
|
|
|
+ for (const scope of scopesInMenu()) {
|
|
|
|
|
+ const permission = byScope[scope];
|
|
|
|
|
+ if (!permission) continue;
|
|
|
|
|
+
|
|
|
|
|
+ permissionIdByScope.value[scope] = permission.id;
|
|
|
|
|
+ bitsByScope.value[scope] = permission.bits;
|
|
|
|
|
+ }
|
|
|
} catch {
|
|
} catch {
|
|
|
Notify.create({
|
|
Notify.create({
|
|
|
message: "Não foi possível carregar as permissões do grupo.",
|
|
message: "Não foi possível carregar as permissões do grupo.",
|
|
@@ -201,9 +242,9 @@ const onSave = async () => {
|
|
|
try {
|
|
try {
|
|
|
await updateUserTypePermissions(
|
|
await updateUserTypePermissions(
|
|
|
group.slug,
|
|
group.slug,
|
|
|
- permissions.value.map((p) => ({
|
|
|
|
|
- permission_id: p.id,
|
|
|
|
|
- bits: bitsById.value[p.id] ?? 0,
|
|
|
|
|
|
|
+ Object.entries(permissionIdByScope.value).map(([scope, id]) => ({
|
|
|
|
|
+ permission_id: id,
|
|
|
|
|
+ bits: bitsByScope.value[scope] ?? 0,
|
|
|
})),
|
|
})),
|
|
|
);
|
|
);
|
|
|
Notify.create({ message: "Permissões atualizadas.", type: "positive" });
|
|
Notify.create({ message: "Permissões atualizadas.", type: "positive" });
|