From 30550d9190ef5e70d9c765b5d15a074b76848167 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Sun, 28 Sep 2025 13:42:10 +0000
Subject: [PATCH] Feat: Add warning for conflicting group permissions
This change introduces a visual warning in the group settings page. The warning appears when an admin attempts to disable a permission for a group that is already enabled in the default 'user' group. This is necessary because permissions are additive, and disabling a permission in a specific group will not revoke it if it's enabled in the default group.
To achieve this, the following changes were made:
- A new `PermissionSwitch.svelte` component was created to encapsulate the permission switch and its warning logic, avoiding redundant code.
- The `Groups.svelte` component was updated to correctly fetch the default user group's permissions.
- The `Permissions.svelte` component was refactored to use the new `PermissionSwitch.svelte` component, making the code cleaner and more maintainable.
---
src/lib/components/admin/Users/Groups.svelte | 62 +-
.../admin/Users/Groups/EditGroupModal.svelte | 3 +-
.../admin/Users/Groups/GroupItem.svelte | 2 +
.../Users/Groups/PermissionSwitch.svelte | 38 ++
.../admin/Users/Groups/Permissions.svelte | 552 ++++++------------
src/lib/components/common/Warning.svelte | 9 +
.../icons/ExclamationTriangle.svelte | 26 +
7 files changed, 274 insertions(+), 418 deletions(-)
create mode 100644 src/lib/components/admin/Users/Groups/PermissionSwitch.svelte
create mode 100644 src/lib/components/common/Warning.svelte
create mode 100644 src/lib/components/icons/ExclamationTriangle.svelte
diff --git a/src/lib/components/admin/Users/Groups.svelte b/src/lib/components/admin/Users/Groups.svelte
index cc57536f83..2e8255eae8 100644
--- a/src/lib/components/admin/Users/Groups.svelte
+++ b/src/lib/components/admin/Users/Groups.svelte
@@ -24,11 +24,7 @@
import GroupItem from './Groups/GroupItem.svelte';
import AddGroupModal from './Groups/AddGroupModal.svelte';
import { createNewGroup, getGroups } from '$lib/apis/groups';
- import {
- getUserDefaultPermissions,
- getAllUsers,
- updateUserDefaultPermissions
- } from '$lib/apis/users';
+ import { getAllUsers, updateUserDefaultPermissions } from '$lib/apis/users';
const i18n = getContext('i18n');
@@ -51,54 +47,20 @@
});
let search = '';
- let defaultPermissions = {
- workspace: {
- models: false,
- knowledge: false,
- prompts: false,
- tools: false
- },
- sharing: {
- public_models: false,
- public_knowledge: false,
- public_prompts: false,
- public_tools: false
- },
- chat: {
- controls: true,
- valves: true,
- system_prompt: true,
- params: true,
- file_upload: true,
- delete: true,
- delete_message: true,
- continue_response: true,
- regenerate_response: true,
- rate_response: true,
- edit: true,
- share: true,
- export: true,
- stt: true,
- tts: true,
- call: true,
- multiple_models: true,
- temporary: true,
- temporary_enforced: false
- },
- features: {
- direct_tool_servers: false,
- web_search: true,
- image_generation: true,
- code_interpreter: true,
- notes: true
- }
- };
+ let defaultPermissions = {};
let showCreateGroupModal = false;
let showDefaultPermissionsModal = false;
const setGroups = async () => {
- groups = await getGroups(localStorage.token);
+ const allGroups = await getGroups(localStorage.token);
+ const userGroup = allGroups.find((g) => g.name.toLowerCase() === 'user');
+
+ if (userGroup) {
+ defaultPermissions = userGroup.permissions;
+ }
+
+ groups = allGroups.filter((g) => g.name.toLowerCase() !== 'user');
};
const addGroupHandler = async (group) => {
@@ -146,8 +108,6 @@
}
await setGroups();
- defaultPermissions = await getUserDefaultPermissions(localStorage.token);
-
loaded = true;
});
@@ -226,7 +186,7 @@
{#each filteredGroups as group}
-
+
{/each}
diff --git a/src/lib/components/admin/Users/Groups/EditGroupModal.svelte b/src/lib/components/admin/Users/Groups/EditGroupModal.svelte
index 151735e3d1..1225a3dcf4 100644
--- a/src/lib/components/admin/Users/Groups/EditGroupModal.svelte
+++ b/src/lib/components/admin/Users/Groups/EditGroupModal.svelte
@@ -21,6 +21,7 @@
export let users = [];
export let group = null;
+ export let defaultPermissions = {};
export let custom = true;
@@ -230,7 +231,7 @@
{#if selectedTab == 'general'}
{:else if selectedTab == 'permissions'}
-
+
{:else if selectedTab == 'users'}
{/if}
diff --git a/src/lib/components/admin/Users/Groups/GroupItem.svelte b/src/lib/components/admin/Users/Groups/GroupItem.svelte
index 7a208f84a6..a16ab6560e 100644
--- a/src/lib/components/admin/Users/Groups/GroupItem.svelte
+++ b/src/lib/components/admin/Users/Groups/GroupItem.svelte
@@ -17,6 +17,7 @@
name: 'Admins',
user_ids: [1, 2, 3]
};
+ export let defaultPermissions = {};
export let setGroups = () => {};
@@ -59,6 +60,7 @@
edit
{users}
{group}
+ {defaultPermissions}
onSubmit={updateHandler}
onDelete={deleteHandler}
/>
diff --git a/src/lib/components/admin/Users/Groups/PermissionSwitch.svelte b/src/lib/components/admin/Users/Groups/PermissionSwitch.svelte
new file mode 100644
index 0000000000..71958d1059
--- /dev/null
+++ b/src/lib/components/admin/Users/Groups/PermissionSwitch.svelte
@@ -0,0 +1,38 @@
+
+
+
+ {#if tooltip}
+
+
+ {label}
+
+
+
+ {:else}
+
+ {/if}
+ {#if defaultState && !state}
+
+
+
+ {/if}
+
\ No newline at end of file
diff --git a/src/lib/components/admin/Users/Groups/Permissions.svelte b/src/lib/components/admin/Users/Groups/Permissions.svelte
index b7f7c3093f..3663960d86 100644
--- a/src/lib/components/admin/Users/Groups/Permissions.svelte
+++ b/src/lib/components/admin/Users/Groups/Permissions.svelte
@@ -2,11 +2,11 @@
import { getContext, onMount } from 'svelte';
const i18n = getContext('i18n');
- import Switch from '$lib/components/common/Switch.svelte';
import Tooltip from '$lib/components/common/Tooltip.svelte';
+ import PermissionSwitch from './PermissionSwitch.svelte';
// Default values for permissions
- const defaultPermissions = {
+ const DEFAULT_PERMISSIONS = {
workspace: {
models: false,
knowledge: false,
@@ -51,10 +51,11 @@
};
export let permissions = {};
+ export let defaultPermissions = {};
// Reactive statement to ensure all fields are present in `permissions`
$: {
- permissions = fillMissingProperties(permissions, defaultPermissions);
+ permissions = fillMissingProperties(permissions, DEFAULT_PERMISSIONS);
}
function fillMissingProperties(obj: any, defaults: any) {
@@ -69,398 +70,217 @@
}
onMount(() => {
- permissions = fillMissingProperties(permissions, defaultPermissions);
+ permissions = fillMissingProperties(permissions, DEFAULT_PERMISSIONS);
});
-
-
-
+
{$i18n.t('Workspace Permissions')}
-
-
-
- {$i18n.t('Models Access')}
-
-
-
-
-
-
- {$i18n.t('Knowledge Access')}
-
-
-
-
-
-
- {$i18n.t('Prompts Access')}
-
-
-
-
-
-
+
+
+
+
-
- {$i18n.t('Tools Access')}
-
-
-
+ />
-
+
{$i18n.t('Sharing Permissions')}
-
-
-
- {$i18n.t('Models Public Sharing')}
-
-
-
-
-
-
- {$i18n.t('Knowledge Public Sharing')}
-
-
-
-
-
-
- {$i18n.t('Prompts Public Sharing')}
-
-
-
-
-
-
- {$i18n.t('Tools Public Sharing')}
-
-
-
-
-
-
- {$i18n.t('Notes Public Sharing')}
-
-
+
-
+
{$i18n.t('Chat Permissions')}
+
+
+
-
-
- {$i18n.t('Allow File Upload')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Chat Controls')}
-
-
-
-
-
- {#if permissions.chat.controls}
-
-
- {$i18n.t('Allow Chat Valves')}
+ {#if permissions.chat.controls}
+
+ {/if}
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- {$i18n.t('Allow Chat System Prompt')}
+ {#if permissions.chat.temporary}
+
-
-
-
-
-
-
- {$i18n.t('Allow Chat Params')}
-
-
-
-
- {/if}
-
-
-
- {$i18n.t('Allow Chat Edit')}
-
-
-
+ {/if}
-
-
-
- {$i18n.t('Allow Chat Delete')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Delete Messages')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Continue Response')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Regenerate Response')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Rate Response')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Chat Share')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Chat Export')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Speech to Text')}
-
-
-
-
-
-
- {$i18n.t('Allow Text to Speech')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Call')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Multiple Models in Chat')}
-
-
-
-
-
-
-
- {$i18n.t('Allow Temporary Chat')}
-
-
-
-
-
- {#if permissions.chat.temporary}
-
-
- {$i18n.t('Enforce Temporary Chat')}
-
-
-
-
- {/if}
-
+
{$i18n.t('Features Permissions')}
-
-
-
- {$i18n.t('Direct Tool Servers')}
-
-
-
-
-
-
-
- {$i18n.t('Web Search')}
-
-
-
-
-
-
-
- {$i18n.t('Image Generation')}
-
-
-
-
-
-
-
- {$i18n.t('Code Interpreter')}
-
-
-
-
-
-
-
- {$i18n.t('Notes')}
-
-
-
+
-
+
\ No newline at end of file
diff --git a/src/lib/components/common/Warning.svelte b/src/lib/components/common/Warning.svelte
new file mode 100644
index 0000000000..85f60ff851
--- /dev/null
+++ b/src/lib/components/common/Warning.svelte
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/src/lib/components/icons/ExclamationTriangle.svelte b/src/lib/components/icons/ExclamationTriangle.svelte
new file mode 100644
index 0000000000..256e4a7be4
--- /dev/null
+++ b/src/lib/components/icons/ExclamationTriangle.svelte
@@ -0,0 +1,26 @@
+
+
+
+
+
\ No newline at end of file