diff --git a/app/components/layout/AppNavbar.vue b/app/components/layout/AppNavbar.vue index ee6985b..8fb0ed8 100644 --- a/app/components/layout/AppNavbar.vue +++ b/app/components/layout/AppNavbar.vue @@ -186,9 +186,9 @@ Connecté en tant que
{{ activeProfileLabel }} -
  • - - Gestion des profils +
  • + + Administration
  • @@ -214,6 +214,7 @@ import { computed } from 'vue' import { useRoute } from '#imports' import { useNavDropdown } from '~/composables/useNavDropdown' +import { usePermissions } from '~/composables/usePermissions' import { useProfileSession } from '~/composables/useProfileSession' import IconLucideMenu from '~icons/lucide/menu' import IconLucideSettings from '~icons/lucide/settings' @@ -288,6 +289,7 @@ const navGroups: NavGroup[] = [ const route = useRoute() const { openDropdown, setDropdown, scheduleDropdownClose, toggleDropdown } = useNavDropdown() const { activeProfile } = useProfileSession() +const { isAdmin } = usePermissions() const isActive = (path: string) => { if (path === '/') { diff --git a/app/components/machine/MachineDetailHeader.vue b/app/components/machine/MachineDetailHeader.vue index 4f54a17..ab797e9 100644 --- a/app/components/machine/MachineDetailHeader.vue +++ b/app/components/machine/MachineDetailHeader.vue @@ -60,6 +60,8 @@ import IconLucideSquarePen from '~icons/lucide/square-pen' import IconLucideEye from '~icons/lucide/eye' import IconLucidePrinter from '~icons/lucide/printer' +const { canEdit } = usePermissions() + defineProps<{ title: string isDetailsView: boolean diff --git a/app/components/model-types/ManagementView.vue b/app/components/model-types/ManagementView.vue index 3b96f39..65788a7 100644 --- a/app/components/model-types/ManagementView.vue +++ b/app/components/model-types/ManagementView.vue @@ -16,6 +16,7 @@ :dir="dir" :loading="loading" :show-category-tabs="allowCategorySwitch" + :can-edit="canEdit" @update:category="onCategoryChange" @update:search="onSearchInput" @update:sort="onSortChange" @@ -30,6 +31,7 @@ :limit="limit" :offset="offset" :category="selectedCategory" + :can-edit="canEdit" @related="openRelatedModal" @edit="openEditPage" @delete="confirmDelete" @@ -169,6 +171,7 @@ let activeController: AbortController | null = null; const router = useRouter(); const { showError, showSuccess } = useToast(); const { get } = useApi(); +const { canEdit } = usePermissions(); const headingText = computed(() => props.heading); const descriptionText = computed( diff --git a/app/components/model-types/ModelTypeForm.vue b/app/components/model-types/ModelTypeForm.vue index a6ac478..108ac4b 100644 --- a/app/components/model-types/ModelTypeForm.vue +++ b/app/components/model-types/ModelTypeForm.vue @@ -29,7 +29,7 @@ class="select select-bordered w-full" name="category" required - :disabled="lockCategory" + :disabled="lockCategory || isReadonly" > @@ -134,7 +134,7 @@ - @@ -176,6 +176,7 @@ const props = withDefaults(defineProps<{ disableSubmitMessage?: string restrictedMode?: boolean restrictedModeMessage?: string + readonly?: boolean }>(), { initialData: null, saving: false, @@ -187,6 +188,7 @@ const props = withDefaults(defineProps<{ disableSubmitMessage: '', restrictedMode: false, restrictedModeMessage: '', + readonly: false, }) const emit = defineEmits<{ @@ -209,7 +211,8 @@ const disableSubmitMessage = computed(() => ? props.disableSubmitMessage : 'Cette catégorie ne peut pas être modifiée car des éléments y sont déjà liés.', ) -const restrictedMode = computed(() => props.restrictedMode === true) +const isReadonly = computed(() => props.readonly === true) +const restrictedMode = computed(() => props.restrictedMode === true || isReadonly.value) const restrictedModeMessage = computed(() => (props.restrictedModeMessage && props.restrictedModeMessage.trim()) ? props.restrictedModeMessage @@ -291,7 +294,7 @@ const resetForm = () => { } const submitLabel = computed(() => (props.mode === 'edit' ? 'Enregistrer' : 'Créer')) -const isSubmitDisabled = computed(() => saving.value || structureLoading.value || disableSubmit.value) +const isSubmitDisabled = computed(() => saving.value || structureLoading.value || disableSubmit.value || isReadonly.value) const validate = () => { errors.name = undefined @@ -308,6 +311,7 @@ const validate = () => { } const handleSubmit = () => { + if (isReadonly.value) return if (!validate()) { return } diff --git a/app/components/model-types/Table.vue b/app/components/model-types/Table.vue index f119901..53718cd 100644 --- a/app/components/model-types/Table.vue +++ b/app/components/model-types/Table.vue @@ -49,7 +49,7 @@ Liés - @@ -88,7 +88,7 @@ Liés - @@ -146,6 +146,7 @@ const props = defineProps<{ limit: number; offset: number; category?: ModelCategory; + canEdit?: boolean; }>(); const emit = defineEmits<{ diff --git a/app/components/model-types/Toolbar.vue b/app/components/model-types/Toolbar.vue index be6f6a5..362e542 100644 --- a/app/components/model-types/Toolbar.vue +++ b/app/components/model-types/Toolbar.vue @@ -83,13 +83,14 @@ import type { ModelCategory } from '~/services/modelTypes'; type SortField = 'name' | 'createdAt'; type SortDirection = 'asc' | 'desc'; -const props = defineProps<{ +const props = defineProps<{ category: ModelCategory; search: string; sort: SortField; dir: SortDirection; loading?: boolean; showCategoryTabs?: boolean; + canEdit?: boolean; }>(); const emit = defineEmits<{ diff --git a/app/components/sites/SiteCard.vue b/app/components/sites/SiteCard.vue index 413d067..d2c426b 100644 --- a/app/components/sites/SiteCard.vue +++ b/app/components/sites/SiteCard.vue @@ -37,9 +37,9 @@
    -
    @@ -55,6 +55,8 @@ import IconLucidePhone from '~icons/lucide/phone' import IconLucideUser from '~icons/lucide/user' import { formatPhone } from '~/utils/formatters/phone' +const { canEdit } = usePermissions() + const props = defineProps({ site: { type: Object, diff --git a/app/components/sites/SiteContactFormFields.vue b/app/components/sites/SiteContactFormFields.vue index 7465fb2..9217d0f 100644 --- a/app/components/sites/SiteContactFormFields.vue +++ b/app/components/sites/SiteContactFormFields.vue @@ -9,11 +9,12 @@ type="text" placeholder="Nom et prénom" class="input input-bordered" + :disabled="disabled" required /> - +
    @@ -38,6 +40,7 @@ type="text" placeholder="Code postal" class="input input-bordered" + :disabled="disabled" required /> @@ -51,6 +54,7 @@ type="text" placeholder="Ville" class="input input-bordered" + :disabled="disabled" required /> @@ -77,6 +81,10 @@ const props = defineProps({ type: Object as PropType, required: true, }, + disabled: { + type: Boolean, + default: false, + }, }) const form = toRef(props, 'form') diff --git a/app/components/sites/SiteCreateModal.vue b/app/components/sites/SiteCreateModal.vue index 9b50ee6..8e7173b 100644 --- a/app/components/sites/SiteCreateModal.vue +++ b/app/components/sites/SiteCreateModal.vue @@ -12,17 +12,18 @@ type="text" placeholder="Ex: Usine principale" class="input input-bordered" + :disabled="disabled" required /> - + @@ -53,6 +54,10 @@ const props = defineProps({ site: { type: Object as PropType, required: true + }, + disabled: { + type: Boolean, + default: false } }) diff --git a/app/components/sites/SiteEditModal.vue b/app/components/sites/SiteEditModal.vue index 224addb..12319cd 100644 --- a/app/components/sites/SiteEditModal.vue +++ b/app/components/sites/SiteEditModal.vue @@ -2,7 +2,7 @@ @@ -100,7 +100,7 @@ @@ -118,7 +118,7 @@ step="0.01" min="0" class="input input-bordered input-sm md:input-md" - :disabled="saving" + :disabled="!canEdit || saving" placeholder="Valeur indicatrice" > @@ -277,7 +277,7 @@ type="text" class="input input-bordered input-sm md:input-md" :required="field.required" - :disabled="saving" + :disabled="!canEdit || saving" > @@ -347,7 +347,7 @@ {{ selectedFiles.length }} document{{ selectedFiles.length > 1 ? 's' : '' }} prêt{{ selectedFiles.length > 1 ? 's' : '' }} à être ajouté{{ selectedFiles.length > 1 ? 's' : '' }} -
    +
    @@ -73,7 +73,7 @@
    @@ -90,7 +90,7 @@ step="0.01" min="0" class="input input-bordered input-sm md:input-md" - :disabled="submitting || !selectedType" + :disabled="!canEdit || submitting || !selectedType" placeholder="Valeur indicatrice" > @@ -244,7 +244,7 @@ type="text" class="input input-bordered input-sm md:input-md" :required="field.required" - :disabled="submitting" + :disabled="!canEdit || submitting" > @@ -314,7 +314,7 @@ {{ selectedDocuments.length }} document{{ selectedDocuments.length > 1 ? 's' : '' }} prêt{{ selectedDocuments.length > 1 ? 's' : '' }} à être ajouté{{ selectedDocuments.length > 1 ? 's' : '' }} -
    +
    (typeof route.query.typeId === 'string' ? route.query.typeId : '') const selectedTypeId = ref(initialTypeId.value) @@ -755,6 +756,7 @@ const requiredCustomFieldsFilled = computed(() => ) const canSubmit = computed(() => Boolean( + canEdit.value && selectedType.value && creationForm.name && requiredCustomFieldsFilled.value && diff --git a/app/pages/constructeurs.vue b/app/pages/constructeurs.vue index 5239785..0bfd49c 100644 --- a/app/pages/constructeurs.vue +++ b/app/pages/constructeurs.vue @@ -9,7 +9,7 @@ Gérez les fournisseurs et leurs coordonnées.

    - @@ -73,9 +73,9 @@
    -
    @@ -90,22 +90,22 @@