diff --git a/frontend/src/components/permissions/ChannelPermissionsDialog.vue b/frontend/src/components/permissions/ChannelPermissionsDialog.vue
new file mode 100644
index 0000000..7912d0a
--- /dev/null
+++ b/frontend/src/components/permissions/ChannelPermissionsDialog.vue
@@ -0,0 +1,133 @@
+
+
+
+
+
+ Permissions — {{ channel?.name || 'Canal' }}
+
+ {{ error }}
+
+ Rôles
+ Membres
+
+
+ {{ targetName }}
+
+
+ Réinitialiser les permissions directes
+
+
+ Fermer
+
+
+
diff --git a/frontend/src/composables/usePermissions.ts b/frontend/src/composables/usePermissions.ts
index eeecf69..df2b47b 100644
--- a/frontend/src/composables/usePermissions.ts
+++ b/frontend/src/composables/usePermissions.ts
@@ -22,10 +22,11 @@ export function usePermissions() {
async function parseResponse(response: Response): Promise {
if (!response.ok) {
const error = await response.json().catch(() => null)
-
- throw new Error(
+ const exception = new Error(
error?.message || 'Erreur lors de la gestion des permissions',
- )
+ ) as Error & { status?: number }
+ exception.status = response.status
+ throw exception
}
if (response.status === 204) {
@@ -232,4 +233,4 @@ export function usePermissions() {
setChannelRolePermission,
removeChannelRolePermission,
}
-}
\ No newline at end of file
+}
diff --git a/frontend/src/pages/server/index.vue b/frontend/src/pages/server/index.vue
index f623182..8d1884a 100644
--- a/frontend/src/pages/server/index.vue
+++ b/frontend/src/pages/server/index.vue
@@ -9,6 +9,8 @@ import CreateCategoryDialog from '@/components/category/CreateCategoryDialog.vue
import {type MenuItem, useContextMenu} from '@/composables/useContextMenu'
import {useUserStore} from "@/stores/user.ts";
import {useServerStore} from "@/stores/server.ts";
+import ChannelPermissionsDialog from '@/components/permissions/ChannelPermissionsDialog.vue'
+import {useAuthStore} from '@/stores/auth'
const props = defineProps<{
serverId: string
@@ -22,6 +24,9 @@ const userStore = useUserStore()
const serverStore = useServerStore()
const {currentTree} = storeToRefs(serverStore)
const {openContextMenu} = useContextMenu()
+const authStore = useAuthStore()
+const showPermissionsDialog = ref(false)
+const selectedChannel = ref(null)
const loadServerData = async (targetServerId: string) => {
@@ -111,6 +116,14 @@ async function deleteChannel(channelId: string) {
function onChannelContextMenu(event: MouseEvent, channel: any) {
const menuItems: MenuItem[] = [
+ ...(authStore.isAdmin ? [{
+ label: 'Gérer les permissions',
+ icon: 'mdi-shield-key',
+ action: () => {
+ selectedChannel.value = channel
+ showPermissionsDialog.value = true
+ },
+ }] : []),
{
label: 'Marquer comme lu',
icon: 'mdi-check',
@@ -194,6 +207,12 @@ function onChannelContextMenu(event: MouseEvent, channel: any) {
@created="refreshServerTree"
/>
+
+
diff --git a/src/routes/user/handlers.rs b/src/routes/user/handlers.rs
index f6af161..4a808fe 100644
--- a/src/routes/user/handlers.rs
+++ b/src/routes/user/handlers.rs
@@ -2,10 +2,11 @@ use crate::core::state::AppState;
use crate::http::context::Superuser;
use crate::http::error::HTTPError;
use crate::domain::dto::user::{CreateUserRequest, UpdateUserRequest, UserResponse};
+use crate::domain::dto::user::UserQueryParams;
use crate::routes::user::mapper;
use axum::{
Json,
- extract::{Path, State},
+ extract::{Path, Query, State},
http::StatusCode,
};
use uuid::Uuid;
@@ -28,8 +29,11 @@ use uuid::Uuid;
pub async fn get_all(
_admin: Superuser,
State(state): State,
+ Query(filters): Query,
) -> Result>, HTTPError> {
- let users = state.repositories.user.get_all().await?;
+ let users = state.repositories.user.filter(crate::repositories::types::UserFilter {
+ server_id: filters.server_id,
+ }).await?;
Ok(Json(
users
.into_iter()