From 9117bc0a6c22185c143c006bae210f4da17e85ce Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 16 Apr 2026 09:08:51 +0200 Subject: [PATCH 1/8] feat(frontend) : ERP-26 - sidebar entry + i18n keys for admin roles --- config/sidebar.php | 6 ++++++ frontend/i18n/locales/fr.json | 39 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/config/sidebar.php b/config/sidebar.php index 6c66a51..54018b8 100644 --- a/config/sidebar.php +++ b/config/sidebar.php @@ -32,6 +32,12 @@ return [ 'icon' => 'mdi:cog-outline', 'module' => 'core', ], + [ + 'label' => 'sidebar.core.roles', + 'to' => '/admin/roles', + 'icon' => 'mdi:shield-account-outline', + 'module' => 'core', + ], [ 'label' => 'sidebar.general.logout', 'to' => '/logout', diff --git a/frontend/i18n/locales/fr.json b/frontend/i18n/locales/fr.json index de5013c..eaf2273 100644 --- a/frontend/i18n/locales/fr.json +++ b/frontend/i18n/locales/fr.json @@ -22,6 +22,9 @@ "commercial": { "section": "Commercial", "suppliers": "Répertoire fournisseurs" + }, + "core": { + "roles": "Gestion des roles" } }, "dashboard": { @@ -56,5 +59,41 @@ "auth": { "logout": "Deconnexion reussie" } + }, + "admin": { + "roles": { + "title": "Gestion des roles", + "newRole": "Nouveau role", + "editRole": "Modifier le role", + "createRole": "Creer un role", + "noRoles": "Aucun role configure", + "table": { + "label": "Libelle", + "code": "Code", + "permissions": "Permissions", + "system": "Systeme", + "actions": "Actions" + }, + "form": { + "label": "Libelle", + "code": "Code", + "description": "Description", + "permissions": "Permissions" + }, + "delete": { + "title": "Supprimer le role", + "message": "Etes-vous sur de vouloir supprimer le role \"{label}\" ? Cette action est irreversible.", + "systemTooltip": "Role systeme non supprimable" + }, + "toast": { + "created": "Role cree avec succes", + "updated": "Role mis a jour avec succes", + "deleted": "Role supprime avec succes" + }, + "permissions": { + "selectAll": "Tout selectionner", + "noPermissions": "Aucune permission disponible" + } + } } } -- 2.39.5 From 44c73b6551e54719d75c0e61c28d4aeab3a19ee2 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 16 Apr 2026 09:10:58 +0200 Subject: [PATCH 2/8] feat(frontend) : ERP-26 - PermissionGroup component --- .../core/components/PermissionGroup.vue | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 frontend/modules/core/components/PermissionGroup.vue diff --git a/frontend/modules/core/components/PermissionGroup.vue b/frontend/modules/core/components/PermissionGroup.vue new file mode 100644 index 0000000..1288a22 --- /dev/null +++ b/frontend/modules/core/components/PermissionGroup.vue @@ -0,0 +1,72 @@ + + + -- 2.39.5 From 84f91428bcaea6aed88602236052635a1c741c0e Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 16 Apr 2026 09:16:08 +0200 Subject: [PATCH 3/8] feat(frontend) : ERP-26 - RoleDeleteModal component Co-Authored-By: Claude Opus 4.6 (1M context) --- .../core/components/RoleDeleteModal.vue | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 frontend/modules/core/components/RoleDeleteModal.vue diff --git a/frontend/modules/core/components/RoleDeleteModal.vue b/frontend/modules/core/components/RoleDeleteModal.vue new file mode 100644 index 0000000..5f611bd --- /dev/null +++ b/frontend/modules/core/components/RoleDeleteModal.vue @@ -0,0 +1,69 @@ + + + + + -- 2.39.5 From 2cb5a7a0b0aa86c335e1cd295abb7602a685e834 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 16 Apr 2026 09:18:07 +0200 Subject: [PATCH 4/8] feat(frontend) : ERP-26 - RoleDrawer component (create/edit with permissions) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../modules/core/components/RoleDrawer.vue | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 frontend/modules/core/components/RoleDrawer.vue diff --git a/frontend/modules/core/components/RoleDrawer.vue b/frontend/modules/core/components/RoleDrawer.vue new file mode 100644 index 0000000..ebd38e4 --- /dev/null +++ b/frontend/modules/core/components/RoleDrawer.vue @@ -0,0 +1,218 @@ + + + -- 2.39.5 From 6e0c875bd71d8eebd30a1b99f29ee452b6e29c95 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 16 Apr 2026 09:20:10 +0200 Subject: [PATCH 5/8] feat(frontend) : ERP-26 - admin roles page with table, drawer, delete modal Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/modules/core/pages/admin/roles.vue | 184 ++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 frontend/modules/core/pages/admin/roles.vue diff --git a/frontend/modules/core/pages/admin/roles.vue b/frontend/modules/core/pages/admin/roles.vue new file mode 100644 index 0000000..86d747c --- /dev/null +++ b/frontend/modules/core/pages/admin/roles.vue @@ -0,0 +1,184 @@ + + + -- 2.39.5 From 6101bd85ceb537130c15a38f31048fe8a4deee0d Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 16 Apr 2026 09:21:50 +0200 Subject: [PATCH 6/8] build(frontend) : ERP-26 - bump @malio/layer-ui to ^1.3.0 (DataTable) Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/package-lock.json | 79 +++++++++++++++++--------------------- frontend/package.json | 2 +- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9fc364f..6695e2e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,7 +7,7 @@ "name": "coltura-frontend", "hasInstallScript": true, "dependencies": { - "@malio/layer-ui": "^1.2.3", + "@malio/layer-ui": "^1.3.0", "@nuxt/icon": "^2.2.1", "@nuxtjs/i18n": "^10.2.3", "@nuxtjs/tailwindcss": "^6.14.0", @@ -83,7 +83,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -581,6 +580,27 @@ "integrity": "sha512-/B8YJGPzaYq1NbsQmwgP8EZqg40NpTw4ZB3suuI0TplbxKHeK94jeaawLmVhCv+YwUnOpiWEz9U6SeThku/8JQ==", "license": "MIT" }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", @@ -1819,9 +1839,9 @@ "license": "MIT" }, "node_modules/@malio/layer-ui": { - "version": "1.2.3", - "resolved": "https://gitea.malio.fr/api/packages/MALIO-DEV/npm/%40malio%2Flayer-ui/-/1.2.3/layer-ui-1.2.3.tgz", - "integrity": "sha512-5nRnBzRkXfs3PfKwKl6sH2ikrmSK7lTifcd0TX1QZP3rFRVRTgcT6mrsrpsbR9PwI27OeCNm0X6d0Ii92Rq7Yg==", + "version": "1.3.0", + "resolved": "https://gitea.malio.fr/api/packages/MALIO-DEV/npm/%40malio%2Flayer-ui/-/1.3.0/layer-ui-1.3.0.tgz", + "integrity": "sha512-Gs4pnlWTWrhoF3QQKxYBu4IxN65O9B4bls7s+ONm05qvI2Y2x7N4VNFGjWvT+rNQ4BzHFCxSCzN4V3o6p0Q7uw==", "dependencies": { "@nuxt/icon": "^2.2.1", "@nuxtjs/tailwindcss": "^6.14.0", @@ -2166,7 +2186,6 @@ "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-4.4.2.tgz", "integrity": "sha512-5+IPRNX2CjkBhuWUwz0hBuLqiaJPRoKzQ+SvcdrQDbAyE+VDeFt74VpSFr5/R0ujrK4b+XnSHUJWdS72w6hsog==", "license": "MIT", - "peer": true, "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", @@ -2269,7 +2288,6 @@ "resolved": "https://registry.npmjs.org/@nuxt/schema/-/schema-4.4.2.tgz", "integrity": "sha512-/q6C7Qhiricgi+PKR7ovBnJlKTL0memCbA1CzRT+itCW/oeYzUfeMdQ35mGntlBoyRPNrMXbzuSUhfDbSCU57w==", "license": "MIT", - "peer": true, "dependencies": { "@vue/shared": "^3.5.30", "defu": "^6.1.4", @@ -4610,7 +4628,6 @@ "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.19.0" } @@ -4673,7 +4690,6 @@ "integrity": "sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.58.2", "@typescript-eslint/types": "8.58.2", @@ -4818,7 +4834,6 @@ "integrity": "sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.58.2", @@ -5454,7 +5469,6 @@ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.32.tgz", "integrity": "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg==", "license": "MIT", - "peer": true, "dependencies": { "@babel/parser": "^7.29.2", "@vue/compiler-core": "3.5.32", @@ -5698,7 +5712,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6086,7 +6099,6 @@ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "license": "Apache-2.0", - "peer": true, "peerDependencies": { "bare-abort-controller": "*" }, @@ -6284,7 +6296,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", @@ -6399,7 +6410,6 @@ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -6594,8 +6604,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/citty/-/citty-0.2.2.tgz", "integrity": "sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/clean-regexp": { "version": "1.0.0", @@ -6671,17 +6680,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, - "node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "devOptional": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=14" - } - }, "node_modules/comment-parser": { "version": "1.4.6", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.6.tgz", @@ -7449,6 +7447,16 @@ "balanced-match": "^1.0.0" } }, + "node_modules/editorconfig/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/editorconfig/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -7649,7 +7657,6 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -8808,7 +8815,6 @@ "integrity": "sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", @@ -11199,7 +11205,6 @@ "resolved": "https://registry.npmjs.org/nuxt/-/nuxt-4.4.2.tgz", "integrity": "sha512-iWVFpr/YEqVU/CenqIHMnIkvb2HE/9f+q8oxZ+pj2et+60NljGRClCgnmbvGPdmNFE0F1bEhoBCYfqbDOCim3Q==", "license": "MIT", - "peer": true, "dependencies": { "@dxup/nuxt": "^0.4.0", "@nuxt/cli": "^3.34.0", @@ -12258,7 +12263,6 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "license": "MIT", - "peer": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -12310,7 +12314,6 @@ "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.112.0.tgz", "integrity": "sha512-7rQ3QdJwobMQLMZwQaPuPYMEF2fDRZwf51lZ//V+bA37nejjKW5ifMHbbCwvA889Y4RLhT+/wLJpPRhAoBaZYw==", "license": "MIT", - "peer": true, "dependencies": { "@oxc-project/types": "^0.112.0" }, @@ -12577,7 +12580,6 @@ "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.4.tgz", "integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==", "license": "MIT", - "peer": true, "dependencies": { "@vue/devtools-api": "^7.7.7" }, @@ -12656,7 +12658,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -13200,7 +13201,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -13820,7 +13820,6 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -14718,7 +14717,6 @@ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", "license": "MIT", - "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -15374,7 +15372,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "napi-postinstall": "^0.3.0" }, @@ -15641,7 +15638,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -16560,7 +16556,6 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.32.tgz", "integrity": "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==", "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/compiler-sfc": "3.5.32", @@ -16605,7 +16600,6 @@ "integrity": "sha512-Vxi9pJdbN3ZnVGLODVtZ7y4Y2kzAAE2Cm0CZ3ZDRvydVYxZ6VrnBhLikBsRS+dpwj4Jv4UCv21PTEwF5rQ9WXg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "debug": "^4.4.0", "eslint-scope": "^8.2.0 || ^9.0.0", @@ -16642,7 +16636,6 @@ "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.3.1.tgz", "integrity": "sha512-azq8fhVnCwJAw0iXW7i44h9P+Bj+snNuevBAaJ9bxn0I3YVsRU3deVFPNnTfZ2uxVJefGp83JUmL68ddCPw5Pw==", "license": "MIT", - "peer": true, "dependencies": { "@intlify/core-base": "11.3.1", "@intlify/devtools-types": "11.3.1", diff --git a/frontend/package.json b/frontend/package.json index 618ed7a..5d025f4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,7 +15,7 @@ "test:watch": "vitest" }, "dependencies": { - "@malio/layer-ui": "^1.2.3", + "@malio/layer-ui": "^1.3.0", "@nuxt/icon": "^2.2.1", "@nuxtjs/i18n": "^10.2.3", "@nuxtjs/tailwindcss": "^6.14.0", -- 2.39.5 From 07d53cdf8cc3d91feb421e57e38d3d481ead75aa Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 16 Apr 2026 09:30:49 +0200 Subject: [PATCH 7/8] fix(frontend) : ERP-26 - fix Hydra response format (member not hydra:member) and IRI permissions Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/modules/core/components/RoleDrawer.vue | 16 +++++++++++----- frontend/modules/core/pages/admin/roles.vue | 6 +++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/frontend/modules/core/components/RoleDrawer.vue b/frontend/modules/core/components/RoleDrawer.vue index ebd38e4..a774fbf 100644 --- a/frontend/modules/core/components/RoleDrawer.vue +++ b/frontend/modules/core/components/RoleDrawer.vue @@ -84,7 +84,7 @@ interface Role { label: string description: string | null isSystem: boolean - permissions: Permission[] + permissions: (Permission | string)[] } interface PermissionModule { @@ -134,12 +134,12 @@ const permissionsByModule = computed(() => { // Charger les permissions au montage async function loadPermissions() { - const data = await api.get<{ 'hydra:member': Permission[] }>( + const data = await api.get<{ member: Permission[] }>( '/permissions', { 'orphan': false, itemsPerPage: 200 }, { toast: false }, ) - allPermissions.value = data['hydra:member'] + allPermissions.value = data.member } // Remplir le formulaire quand le role change @@ -148,7 +148,13 @@ watch(() => props.role, (role) => { form.value.label = role.label form.value.code = role.code form.value.description = role.description || '' - selectedPermissionIds.value = new Set(role.permissions.map(p => p.id)) + selectedPermissionIds.value = new Set(role.permissions.map(p => { + // L'API peut retourner des objets Permission ou des IRIs string + if (typeof p === 'string') { + return Number(p.split('/').pop()) + } + return p.id + })) } else { form.value.label = '' form.value.code = '' @@ -196,7 +202,7 @@ async function handleSave() { label: form.value.label, code: form.value.code, description: form.value.description || null, - permissions: Array.from(selectedPermissionIds.value).map(id => ({ id })), + permissions: Array.from(selectedPermissionIds.value).map(id => `/api/permissions/${id}`), } if (isEditMode.value && props.role) { diff --git a/frontend/modules/core/pages/admin/roles.vue b/frontend/modules/core/pages/admin/roles.vue index 86d747c..e0e6e05 100644 --- a/frontend/modules/core/pages/admin/roles.vue +++ b/frontend/modules/core/pages/admin/roles.vue @@ -111,7 +111,7 @@ interface Role { label: string description: string | null isSystem: boolean - permissions: Permission[] + permissions: (Permission | string)[] } const { t } = useI18n() @@ -132,12 +132,12 @@ const deleting = ref(false) async function loadRoles() { loading.value = true try { - const data = await api.get<{ 'hydra:member': Role[] }>( + const data = await api.get<{ member: Role[] }>( '/roles', {}, { toast: false }, ) - roles.value = data['hydra:member'] + roles.value = data.member } finally { loading.value = false } -- 2.39.5 From 3fe44e4de2c61c24c805819bcbbd26f00534a61e Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 16 Apr 2026 09:32:54 +0200 Subject: [PATCH 8/8] refactor(frontend) : ERP-26 - migrate roles table to MalioDataTable component Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/modules/core/pages/admin/roles.vue | 137 +++++++++++--------- 1 file changed, 73 insertions(+), 64 deletions(-) diff --git a/frontend/modules/core/pages/admin/roles.vue b/frontend/modules/core/pages/admin/roles.vue index e0e6e05..ec81460 100644 --- a/frontend/modules/core/pages/admin/roles.vue +++ b/frontend/modules/core/pages/admin/roles.vue @@ -14,70 +14,49 @@ -
- - - - - - - - - - - - - - - - - - - -
{{ t('admin.roles.table.label') }}{{ t('admin.roles.table.code') }}{{ t('admin.roles.table.permissions') }}{{ t('admin.roles.table.system') }}{{ t('admin.roles.table.actions') }}
- {{ role.label }} - - {{ role.code }} - - {{ role.permissions.length }} - - - {{ t('admin.roles.table.system') }} - - -
- - -
-
- - -
- -

{{ t('admin.roles.noRoles') }}

-
-
+ + + + + + ([]) const loading = ref(false) + +const columns = [ + { key: 'label', label: t('admin.roles.table.label') }, + { key: 'code', label: t('admin.roles.table.code') }, + { key: 'permissions', label: t('admin.roles.table.permissions') }, + { key: 'system', label: t('admin.roles.table.system') }, + { key: 'actions', label: t('admin.roles.table.actions') }, +] + +// Transformer les roles en items compatibles MalioDataTable +const roleItems = computed(() => + roles.value.map(role => ({ + id: role.id, + label: role.label, + code: role.code, + permissions: role.permissions.length, + isSystem: role.isSystem, + system: '', // colonne geree par le slot + actions: '', // colonne geree par le slot + })) +) + +function getRoleById(id: number): Role | undefined { + return roles.value.find(r => r.id === id) +} + +function onRowClick(item: Record) { + const role = getRoleById(item.id as number) + if (role) openEditDrawer(role) +} const drawerOpen = ref(false) const selectedRole = ref(null) const deleteModalOpen = ref(false) -- 2.39.5