permission additional content

This commit is contained in:
Julian Krauser 2025-03-28 11:25:06 +01:00
parent 8a28dcd535
commit b6fc8de978
4 changed files with 57 additions and 8 deletions

View file

@ -2,12 +2,7 @@
<div class="grow flex flex-col gap-2 overflow-hidden">
<div v-if="useSearch" class="relative self-end flex flex-row items-center gap-2">
<Spinner v-if="deferingSearch" />
<input
type="text"
class="!max-w-64 !w-64 rounded-md shadow-sm relative block px-3 py-2 pr-5 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
placeholder="Suche"
v-model="searchString"
/>
<input type="text" class="!max-w-64 !w-64" placeholder="Suche" v-model="searchString" />
<XMarkIcon
class="absolute h-4 stroke-2 right-2 top-1/2 -translate-y-1/2 cursor-pointer z-10"
@click="searchString = ''"

View file

@ -68,6 +68,31 @@
</div>
</div>
</div>
<div
v-if="sectionsAndModules.additional"
class="flex flex-col gap-2 h-fit w-full border border-primary rounded-md"
:class="isAdmin && !disableEdit ? ' pointer-events-none opacity-60 bg-gray-100' : ''"
>
<div class="bg-primary p-2 text-white flex flex-row justify-between items-center">
<p>weitere Berechtigungen</p>
</div>
<div
v-for="add in permissionStructure.additional"
:key="add.key"
class="p-1 px-2 flex flex-row justify-between items-center"
>
<p>{{ add.name }}</p>
<div class="self-end flex flex-row items-center gap-2">
<input
:type="add.type"
class="max-w-64 sm:w-64"
:value="_canValue(permissionUpdate, add.key, add.emptyIfAdmin)"
@input="(e) => changeValue(add.key, (e.target as HTMLInputElement).value)"
/>
<XMarkIcon class="h-4 stroke-2 cursor-pointer" @click="clearValue(add.key)" />
</div>
</div>
</div>
<div v-if="!disableEdit" class="flex flex-row gap-2 self-end pt-4">
<button primary-outline class="!w-fit" @click="reset" :disabled="canSaveOrReset">verwerfen</button>
<button primary class="!w-fit" @click="submit" :disabled="status == 'loading' || canSaveOrReset">
@ -92,7 +117,7 @@ import type {
} from "@/types/permissionTypes";
import { sectionsAndModules, permissionSections, permissionTypes } from "@/types/permissionTypes";
import { mapState, mapActions } from "pinia";
import { EyeIcon, PencilIcon, PlusIcon, TrashIcon } from "@heroicons/vue/24/outline";
import { EyeIcon, PencilIcon, PlusIcon, TrashIcon, XMarkIcon } from "@heroicons/vue/24/outline";
import { useAbilityStore } from "@/stores/ability";
import cloneDeep from "lodash.clonedeep";
import isEqual from "lodash.isequal";
@ -132,7 +157,7 @@ export default defineComponent({
};
},
computed: {
...mapState(useAbilityStore, ["_can"]),
...mapState(useAbilityStore, ["_can", "_canValue"]),
canSaveOrReset(): boolean {
return isEqual(this.permissions, this.permissionUpdate);
},
@ -186,6 +211,15 @@ export default defineComponent({
this.permissionUpdate[section]![modul] = permissions;
}
},
changeValue(key: string, value: string) {
if (this.permissionUpdate.additional == undefined) {
this.permissionUpdate.additional = {};
}
this.permissionUpdate.additional![key] = value;
},
clearValue(key: string) {
delete this.permissionUpdate?.additional?.[key];
},
reset() {
this.permissionUpdate = cloneDeep(this.permissions);
this.isAdmin = this.permissions.admin ?? false;

View file

@ -71,6 +71,12 @@ export const useAbilityStore = defineStore("ability", {
return true;
return false;
},
_canValue:
() =>
(permissions: PermissionObject, key: string, emptyIfAdmin: boolean = false): string => {
if (emptyIfAdmin && permissions.admin) return "";
return permissions?.additional?.[key] ?? "";
},
},
actions: {
setAbility(permissions: PermissionObject, isOwner: boolean) {

View file

@ -9,6 +9,7 @@ export type PermissionString =
| `${PermissionSection}.${PermissionModule}.*` // für alle Berechtigungen in einem Modul
| `${PermissionSection}.${PermissionType}` // für spezifische Berechtigungen in einem Abschnitt
| `${PermissionSection}.*` // für alle Berechtigungen in einem Abschnitt
| `additional.${string}.${string}` // additional
| "*"; // für Admin
export type PermissionObject = {
@ -17,10 +18,19 @@ export type PermissionObject = {
} & { all?: Array<PermissionType> | "*" };
} & {
admin?: boolean;
} & {
additional?: { [key: string]: string };
};
export type SectionsAndModulesObject = {
[section in PermissionSection]: Array<PermissionModule>;
} & {
additional?: Array<{
key: string;
name: string;
type: "number" | "string";
emptyIfAdmin: boolean;
}>;
};
export const permissionSections: Array<PermissionSection> = ["operation", "configuration", "management"];
@ -39,4 +49,8 @@ export const sectionsAndModules: SectionsAndModulesObject = {
operation: ["mission"],
configuration: ["force", "vehicle", "equipment"],
management: ["user", "role", "backup", "import"],
additional: [
{ key: "maxVisInDays", name: "max Sichtbarkeit in Tagen", type: "number", emptyIfAdmin: true },
{ key: "maxVisByMissions", name: "max Sichtbarkeit an Einsätzen", type: "number", emptyIfAdmin: true },
],
};