mirror of
https://github.com/open-webui/open-webui
synced 2025-05-31 11:00:49 +00:00
refac
This commit is contained in:
parent
dff85c733d
commit
b80ec76435
@ -739,12 +739,12 @@ DEFAULT_USER_ROLE = PersistentConfig(
|
|||||||
os.getenv("DEFAULT_USER_ROLE", "pending"),
|
os.getenv("DEFAULT_USER_ROLE", "pending"),
|
||||||
)
|
)
|
||||||
|
|
||||||
USER_PERMISSIONS_CHAT_DELETION = (
|
USER_PERMISSIONS_CHAT_DELETE = (
|
||||||
os.environ.get("USER_PERMISSIONS_CHAT_DELETION", "True").lower() == "true"
|
os.environ.get("USER_PERMISSIONS_CHAT_DELETE", "True").lower() == "true"
|
||||||
)
|
)
|
||||||
|
|
||||||
USER_PERMISSIONS_CHAT_EDITING = (
|
USER_PERMISSIONS_CHAT_EDIT = (
|
||||||
os.environ.get("USER_PERMISSIONS_CHAT_EDITING", "True").lower() == "true"
|
os.environ.get("USER_PERMISSIONS_CHAT_EDIT", "True").lower() == "true"
|
||||||
)
|
)
|
||||||
|
|
||||||
USER_PERMISSIONS_CHAT_TEMPORARY = (
|
USER_PERMISSIONS_CHAT_TEMPORARY = (
|
||||||
@ -753,11 +753,11 @@ USER_PERMISSIONS_CHAT_TEMPORARY = (
|
|||||||
|
|
||||||
USER_PERMISSIONS = PersistentConfig(
|
USER_PERMISSIONS = PersistentConfig(
|
||||||
"USER_PERMISSIONS",
|
"USER_PERMISSIONS",
|
||||||
"ui.user_permissions",
|
"user.permissions",
|
||||||
{
|
{
|
||||||
"chat": {
|
"chat": {
|
||||||
"deletion": USER_PERMISSIONS_CHAT_DELETION,
|
"deletion": USER_PERMISSIONS_CHAT_DELETE,
|
||||||
"editing": USER_PERMISSIONS_CHAT_EDITING,
|
"editing": USER_PERMISSIONS_CHAT_EDIT,
|
||||||
"temporary": USER_PERMISSIONS_CHAT_TEMPORARY,
|
"temporary": USER_PERMISSIONS_CHAT_TEMPORARY,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -785,18 +785,6 @@ DEFAULT_ARENA_MODEL = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
ENABLE_MODEL_FILTER = PersistentConfig(
|
|
||||||
"ENABLE_MODEL_FILTER",
|
|
||||||
"model_filter.enable",
|
|
||||||
os.environ.get("ENABLE_MODEL_FILTER", "False").lower() == "true",
|
|
||||||
)
|
|
||||||
MODEL_FILTER_LIST = os.environ.get("MODEL_FILTER_LIST", "")
|
|
||||||
MODEL_FILTER_LIST = PersistentConfig(
|
|
||||||
"MODEL_FILTER_LIST",
|
|
||||||
"model_filter.list",
|
|
||||||
[model.strip() for model in MODEL_FILTER_LIST.split(";")],
|
|
||||||
)
|
|
||||||
|
|
||||||
WEBHOOK_URL = PersistentConfig(
|
WEBHOOK_URL = PersistentConfig(
|
||||||
"WEBHOOK_URL", "webhook_url", os.environ.get("WEBHOOK_URL", "")
|
"WEBHOOK_URL", "webhook_url", os.environ.get("WEBHOOK_URL", "")
|
||||||
)
|
)
|
||||||
|
@ -70,13 +70,11 @@ from open_webui.config import (
|
|||||||
DEFAULT_LOCALE,
|
DEFAULT_LOCALE,
|
||||||
ENABLE_ADMIN_CHAT_ACCESS,
|
ENABLE_ADMIN_CHAT_ACCESS,
|
||||||
ENABLE_ADMIN_EXPORT,
|
ENABLE_ADMIN_EXPORT,
|
||||||
ENABLE_MODEL_FILTER,
|
|
||||||
ENABLE_OLLAMA_API,
|
ENABLE_OLLAMA_API,
|
||||||
ENABLE_OPENAI_API,
|
ENABLE_OPENAI_API,
|
||||||
ENABLE_TAGS_GENERATION,
|
ENABLE_TAGS_GENERATION,
|
||||||
ENV,
|
ENV,
|
||||||
FRONTEND_BUILD_DIR,
|
FRONTEND_BUILD_DIR,
|
||||||
MODEL_FILTER_LIST,
|
|
||||||
OAUTH_PROVIDERS,
|
OAUTH_PROVIDERS,
|
||||||
ENABLE_SEARCH_QUERY,
|
ENABLE_SEARCH_QUERY,
|
||||||
SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE,
|
SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE,
|
||||||
@ -194,9 +192,6 @@ app.state.config = AppConfig()
|
|||||||
app.state.config.ENABLE_OPENAI_API = ENABLE_OPENAI_API
|
app.state.config.ENABLE_OPENAI_API = ENABLE_OPENAI_API
|
||||||
app.state.config.ENABLE_OLLAMA_API = ENABLE_OLLAMA_API
|
app.state.config.ENABLE_OLLAMA_API = ENABLE_OLLAMA_API
|
||||||
|
|
||||||
app.state.config.ENABLE_MODEL_FILTER = ENABLE_MODEL_FILTER
|
|
||||||
app.state.config.MODEL_FILTER_LIST = MODEL_FILTER_LIST
|
|
||||||
|
|
||||||
app.state.config.WEBHOOK_URL = WEBHOOK_URL
|
app.state.config.WEBHOOK_URL = WEBHOOK_URL
|
||||||
|
|
||||||
app.state.config.TASK_MODEL = TASK_MODEL
|
app.state.config.TASK_MODEL = TASK_MODEL
|
||||||
|
@ -48,69 +48,38 @@
|
|||||||
let showCreateGroupModal = false;
|
let showCreateGroupModal = false;
|
||||||
let showDefaultPermissionsModal = false;
|
let showDefaultPermissionsModal = false;
|
||||||
|
|
||||||
|
const setGroups = async () => {
|
||||||
|
groups = await getGroups(localStorage.token);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addGroupHandler = async (group) => {
|
||||||
|
const res = await createNewGroup(localStorage.token, group).catch((error) => {
|
||||||
|
toast.error(error);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
toast.success($i18n.t('Group created successfully'));
|
||||||
|
groups = await getGroups(localStorage.token);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateDefaultPermissionsHandler = async (permissions) => {
|
||||||
|
console.log(permissions);
|
||||||
|
};
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
if ($user?.role !== 'admin') {
|
if ($user?.role !== 'admin') {
|
||||||
await goto('/');
|
await goto('/');
|
||||||
} else {
|
} else {
|
||||||
groups = await getGroups(localStorage.token);
|
await setGroups();
|
||||||
|
|
||||||
// [
|
|
||||||
// {
|
|
||||||
// id: '1',
|
|
||||||
// name: 'Group A',
|
|
||||||
// description: 'Group A description',
|
|
||||||
// permissions: {
|
|
||||||
// model: {
|
|
||||||
// enable_filter: false, // boolean
|
|
||||||
// ids: [], // array of strings
|
|
||||||
// default_id: null // null or string
|
|
||||||
// },
|
|
||||||
// workspace: {
|
|
||||||
// models: false, // boolean
|
|
||||||
// knowledge: false, // boolean
|
|
||||||
// prompts: false // boolean
|
|
||||||
// },
|
|
||||||
// chat: {
|
|
||||||
// delete: true, // boolean
|
|
||||||
// edit: true, // boolean
|
|
||||||
// temporary: true // boolean
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// user_ids: ['1', '2', '3'], // array of strings
|
|
||||||
// admin_ids: ['1'] // array of strings
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: '2',
|
|
||||||
// name: 'Moderators',
|
|
||||||
// description: 'Moderators description',
|
|
||||||
// permissions: {
|
|
||||||
// model: {
|
|
||||||
// enable_filter: false, // boolean
|
|
||||||
// ids: [], // array of strings
|
|
||||||
// default_id: null // null or string
|
|
||||||
// },
|
|
||||||
// workspace: {
|
|
||||||
// models: false, // boolean
|
|
||||||
// knowledge: false, // boolean
|
|
||||||
// prompts: false // boolean
|
|
||||||
// },
|
|
||||||
// chat: {
|
|
||||||
// delete: true, // boolean
|
|
||||||
// edit: true, // boolean
|
|
||||||
// temporary: true // boolean
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// user_ids: ['1', '5', '6'], // array of strings
|
|
||||||
// admin_ids: ['1'] // array of strings
|
|
||||||
// }
|
|
||||||
// ];
|
|
||||||
}
|
}
|
||||||
loaded = true;
|
loaded = true;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if loaded}
|
{#if loaded}
|
||||||
<AddGroupModal bind:show={showCreateGroupModal} />
|
<AddGroupModal bind:show={showCreateGroupModal} onSubmit={addGroupHandler} />
|
||||||
<div class="mt-0.5 mb-2 gap-1 flex flex-col md:flex-row justify-between">
|
<div class="mt-0.5 mb-2 gap-1 flex flex-col md:flex-row justify-between">
|
||||||
<div class="flex md:self-center text-lg font-medium px-0.5">
|
<div class="flex md:self-center text-lg font-medium px-0.5">
|
||||||
{$i18n.t('Groups')}
|
{$i18n.t('Groups')}
|
||||||
@ -196,7 +165,7 @@
|
|||||||
|
|
||||||
{#each filteredGroups as group}
|
{#each filteredGroups as group}
|
||||||
<div class="my-2">
|
<div class="my-2">
|
||||||
<GroupItem {group} {users} />
|
<GroupItem {group} {users} {setGroups} />
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
@ -204,7 +173,12 @@
|
|||||||
|
|
||||||
<hr class="mb-2 border-gray-50 dark:border-gray-850" />
|
<hr class="mb-2 border-gray-50 dark:border-gray-850" />
|
||||||
|
|
||||||
<GroupModal bind:show={showDefaultPermissionsModal} tabs={['permissions']} custom={false} />
|
<GroupModal
|
||||||
|
bind:show={showDefaultPermissionsModal}
|
||||||
|
tabs={['permissions']}
|
||||||
|
custom={false}
|
||||||
|
onSubmit={updateDefaultPermissionsHandler}
|
||||||
|
/>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="flex items-center justify-between rounded-lg w-full transition pt-1"
|
class="flex items-center justify-between rounded-lg w-full transition pt-1"
|
||||||
|
@ -4,16 +4,9 @@
|
|||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
import Modal from '$lib/components/common/Modal.svelte';
|
import Modal from '$lib/components/common/Modal.svelte';
|
||||||
import Plus from '$lib/components/icons/Plus.svelte';
|
|
||||||
import Minus from '$lib/components/icons/Minus.svelte';
|
|
||||||
import PencilSolid from '$lib/components/icons/PencilSolid.svelte';
|
|
||||||
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
|
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
|
||||||
import Switch from '$lib/components/common/Switch.svelte';
|
|
||||||
import Display from './Display.svelte';
|
import Display from './Display.svelte';
|
||||||
import Permissions from './Permissions.svelte';
|
import Permissions from './Permissions.svelte';
|
||||||
import Users from './Users.svelte';
|
import Users from './Users.svelte';
|
||||||
import UsersSolid from '$lib/components/icons/UsersSolid.svelte';
|
|
||||||
import UserPlusSolid from '$lib/components/icons/UserPlusSolid.svelte';
|
import UserPlusSolid from '$lib/components/icons/UserPlusSolid.svelte';
|
||||||
import WrenchSolid from '$lib/components/icons/WrenchSolid.svelte';
|
import WrenchSolid from '$lib/components/icons/WrenchSolid.svelte';
|
||||||
|
|
||||||
@ -31,15 +24,25 @@
|
|||||||
export let tabs = ['general', 'permissions', 'users'];
|
export let tabs = ['general', 'permissions', 'users'];
|
||||||
|
|
||||||
let selectedTab = 'general';
|
let selectedTab = 'general';
|
||||||
|
let loading = false;
|
||||||
|
|
||||||
let name = '';
|
let name = '';
|
||||||
let description = '';
|
let description = '';
|
||||||
|
|
||||||
let permissions = {};
|
let permissions = {
|
||||||
|
workspace: {
|
||||||
|
models: false,
|
||||||
|
knowledge: false,
|
||||||
|
prompts: false,
|
||||||
|
tools: false
|
||||||
|
},
|
||||||
|
chat: {
|
||||||
|
delete: true,
|
||||||
|
edit: true,
|
||||||
|
temporary: true
|
||||||
|
}
|
||||||
|
};
|
||||||
let userIds = [];
|
let userIds = [];
|
||||||
let adminIds = [];
|
|
||||||
|
|
||||||
let loading = false;
|
|
||||||
|
|
||||||
const submitHandler = async () => {
|
const submitHandler = async () => {
|
||||||
loading = true;
|
loading = true;
|
||||||
@ -65,7 +68,19 @@
|
|||||||
if (group) {
|
if (group) {
|
||||||
name = group.name;
|
name = group.name;
|
||||||
description = group.description;
|
description = group.description;
|
||||||
permissions = group?.permissions ?? {};
|
permissions = group?.permissions ?? {
|
||||||
|
workspace: {
|
||||||
|
models: false,
|
||||||
|
knowledge: false,
|
||||||
|
prompts: false,
|
||||||
|
tools: false
|
||||||
|
},
|
||||||
|
chat: {
|
||||||
|
delete: true,
|
||||||
|
edit: true,
|
||||||
|
temporary: true
|
||||||
|
}
|
||||||
|
};
|
||||||
userIds = group?.user_ids ?? [];
|
userIds = group?.user_ids ?? [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -200,9 +215,9 @@
|
|||||||
{#if selectedTab == 'general'}
|
{#if selectedTab == 'general'}
|
||||||
<Display bind:name bind:description />
|
<Display bind:name bind:description />
|
||||||
{:else if selectedTab == 'permissions'}
|
{:else if selectedTab == 'permissions'}
|
||||||
<Permissions bind:permissions {custom} />
|
<Permissions bind:permissions />
|
||||||
{:else if selectedTab == 'users'}
|
{:else if selectedTab == 'users'}
|
||||||
<Users bind:userIds bind:adminIds {users} />
|
<Users bind:userIds {users} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { toast } from 'svelte-sonner';
|
||||||
|
import { getContext } from 'svelte';
|
||||||
|
|
||||||
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
|
import { deleteGroupById, updateGroupById } from '$lib/apis/groups';
|
||||||
|
|
||||||
import Pencil from '$lib/components/icons/Pencil.svelte';
|
import Pencil from '$lib/components/icons/Pencil.svelte';
|
||||||
import User from '$lib/components/icons/User.svelte';
|
import User from '$lib/components/icons/User.svelte';
|
||||||
|
|
||||||
import UserCircleSolid from '$lib/components/icons/UserCircleSolid.svelte';
|
import UserCircleSolid from '$lib/components/icons/UserCircleSolid.svelte';
|
||||||
import GroupModal from './EditGroupModal.svelte';
|
import GroupModal from './EditGroupModal.svelte';
|
||||||
|
|
||||||
@ -11,10 +17,43 @@
|
|||||||
user_ids: [1, 2, 3]
|
user_ids: [1, 2, 3]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export let setGroups = () => {};
|
||||||
|
|
||||||
let showEdit = false;
|
let showEdit = false;
|
||||||
|
|
||||||
|
const updateHandler = async (_group) => {
|
||||||
|
const res = await updateGroupById(localStorage.token, group.id, _group).catch((error) => {
|
||||||
|
toast.error(error);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
toast.success($i18n.t('Group updated successfully'));
|
||||||
|
setGroups();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteHandler = async () => {
|
||||||
|
const res = await deleteGroupById(localStorage.token, group.id).catch((error) => {
|
||||||
|
toast.error(error);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
toast.success($i18n.t('Group deleted successfully'));
|
||||||
|
setGroups();
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<GroupModal bind:show={showEdit} edit {group} {users} />
|
<GroupModal
|
||||||
|
bind:show={showEdit}
|
||||||
|
edit
|
||||||
|
{users}
|
||||||
|
{group}
|
||||||
|
onSubmit={updateHandler}
|
||||||
|
onDelete={deleteHandler}
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="flex items-center gap-3 justify-between px-1 text-xs w-full transition">
|
<div class="flex items-center gap-3 justify-between px-1 text-xs w-full transition">
|
||||||
<div class="flex items-center gap-1.5 w-full font-medium">
|
<div class="flex items-center gap-1.5 w-full font-medium">
|
||||||
|
@ -3,34 +3,25 @@
|
|||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
import Switch from '$lib/components/common/Switch.svelte';
|
import Switch from '$lib/components/common/Switch.svelte';
|
||||||
import { models } from '$lib/stores';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
import Minus from '$lib/components/icons/Minus.svelte';
|
|
||||||
import Plus from '$lib/components/icons/Plus.svelte';
|
|
||||||
|
|
||||||
export let permissions = {};
|
export let permissions = {
|
||||||
export let custom = true;
|
workspace: {
|
||||||
|
models: false,
|
||||||
let defaultModelId = '';
|
knowledge: false,
|
||||||
|
prompts: false,
|
||||||
let selectedModelId = '';
|
tools: false
|
||||||
|
},
|
||||||
let filterEnabled = false;
|
chat: {
|
||||||
let filterMode = 'include';
|
delete: true,
|
||||||
let filterModelIds = [];
|
edit: true,
|
||||||
|
temporary: true
|
||||||
let workspaceModelsAccess = false;
|
}
|
||||||
let workspaceKnowledgeAccess = false;
|
};
|
||||||
let workspacePromptsAccess = false;
|
|
||||||
let workspaceToolsAccess = false;
|
|
||||||
let workspaceFunctionsAccess = false;
|
|
||||||
|
|
||||||
let chatDeletion = true;
|
|
||||||
let chatEdit = true;
|
|
||||||
let chatTemporary = true;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<!-- <div>
|
||||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('Model Permissions')}</div>
|
<div class=" mb-2 text-sm font-medium">{$i18n.t('Model Permissions')}</div>
|
||||||
|
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
@ -130,52 +121,46 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class=" border-gray-50 dark:border-gray-850 my-2" />
|
<hr class=" border-gray-50 dark:border-gray-850 my-2" /> -->
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('Workspace Permissions')}</div>
|
<div class=" mb-2 text-sm font-medium">{$i18n.t('Workspace Permissions')}</div>
|
||||||
|
|
||||||
<div class=" flex w-full justify-between my-2 pr-2">
|
<div class=" flex w-full justify-between my-2 pr-2">
|
||||||
<div class=" self-center text-xs font-medium">
|
<div class=" self-center text-xs font-medium">
|
||||||
{#if custom}
|
|
||||||
{$i18n.t('Admins')}:
|
|
||||||
{/if}
|
|
||||||
{$i18n.t('Models Access')}
|
{$i18n.t('Models Access')}
|
||||||
</div>
|
</div>
|
||||||
<Switch bind:state={workspaceModelsAccess} />
|
<Switch bind:state={permissions.workspace.models} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=" flex w-full justify-between my-2 pr-2">
|
<div class=" flex w-full justify-between my-2 pr-2">
|
||||||
<div class=" self-center text-xs font-medium">
|
<div class=" self-center text-xs font-medium">
|
||||||
{#if custom}
|
|
||||||
{$i18n.t('Admins')}:
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{$i18n.t('Knowledge Access')}
|
{$i18n.t('Knowledge Access')}
|
||||||
</div>
|
</div>
|
||||||
<Switch bind:state={workspaceKnowledgeAccess} />
|
<Switch bind:state={permissions.workspace.knowledge} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=" flex w-full justify-between my-2 pr-2">
|
<div class=" flex w-full justify-between my-2 pr-2">
|
||||||
<div class=" self-center text-xs font-medium">
|
<div class=" self-center text-xs font-medium">
|
||||||
{#if custom}
|
|
||||||
{$i18n.t('Admins')}:
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{$i18n.t('Prompts Access')}
|
{$i18n.t('Prompts Access')}
|
||||||
</div>
|
</div>
|
||||||
<Switch bind:state={workspacePromptsAccess} />
|
<Switch bind:state={permissions.workspace.prompts} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <div class=" flex w-full justify-between my-2 pr-2">
|
<div class=" ">
|
||||||
<div class=" self-center text-xs font-medium">{$i18n.t('Allow Tools Access')}</div>
|
<Tooltip
|
||||||
<Switch bind:state={workspaceToolsAccess} />
|
className=" flex w-full justify-between my-2 pr-2"
|
||||||
|
content={$i18n.t(
|
||||||
|
'Warning: Enabling this will allow users to upload arbitrary code on the server.'
|
||||||
|
)}
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
|
<div class=" self-center text-xs font-medium">
|
||||||
|
{$i18n.t('Tools Access')}
|
||||||
|
</div>
|
||||||
|
<Switch bind:state={permissions.workspace.tools} />
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=" flex w-full justify-between my-2 pr-2">
|
|
||||||
<div class=" self-center text-xs font-medium">{$i18n.t('Allow Functions Access')}</div>
|
|
||||||
<Switch bind:state={workspaceFunctionsAccess} />
|
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class=" border-gray-50 dark:border-gray-850 my-2" />
|
<hr class=" border-gray-50 dark:border-gray-850 my-2" />
|
||||||
@ -185,35 +170,26 @@
|
|||||||
|
|
||||||
<div class=" flex w-full justify-between my-2 pr-2">
|
<div class=" flex w-full justify-between my-2 pr-2">
|
||||||
<div class=" self-center text-xs font-medium">
|
<div class=" self-center text-xs font-medium">
|
||||||
{#if custom}
|
{$i18n.t('Allow Chat Delete')}
|
||||||
{$i18n.t('Members')}:
|
|
||||||
{/if}
|
|
||||||
{$i18n.t('Allow Chat Deletion')}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Switch bind:state={chatDeletion} />
|
<Switch bind:state={permissions.chat.delete} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=" flex w-full justify-between my-2 pr-2">
|
<div class=" flex w-full justify-between my-2 pr-2">
|
||||||
<div class=" self-center text-xs font-medium">
|
<div class=" self-center text-xs font-medium">
|
||||||
{#if custom}
|
{$i18n.t('Allow Chat Edit')}
|
||||||
{$i18n.t('Members')}:
|
|
||||||
{/if}
|
|
||||||
{$i18n.t('Allow Chat Editing')}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Switch bind:state={chatEdit} />
|
<Switch bind:state={permissions.chat.edit} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=" flex w-full justify-between my-2 pr-2">
|
<div class=" flex w-full justify-between my-2 pr-2">
|
||||||
<div class=" self-center text-xs font-medium">
|
<div class=" self-center text-xs font-medium">
|
||||||
{#if custom}
|
|
||||||
{$i18n.t('Members')}:
|
|
||||||
{/if}
|
|
||||||
{$i18n.t('Allow Temporary Chat')}
|
{$i18n.t('Allow Temporary Chat')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Switch bind:state={chatTemporary} />
|
<Switch bind:state={permissions.chat.temporary} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
export let users = [];
|
export let users = [];
|
||||||
export let userIds = [];
|
export let userIds = [];
|
||||||
export let adminIds = [];
|
|
||||||
|
|
||||||
let filteredUsers = [];
|
let filteredUsers = [];
|
||||||
|
|
||||||
@ -30,16 +29,10 @@
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const aIsAdmin = adminIds.includes(a.id);
|
|
||||||
const bIsAdmin = adminIds.includes(b.id);
|
|
||||||
const aUserIndex = userIds.indexOf(a.id);
|
const aUserIndex = userIds.indexOf(a.id);
|
||||||
const bUserIndex = userIds.indexOf(b.id);
|
const bUserIndex = userIds.indexOf(b.id);
|
||||||
|
|
||||||
// Admin users should come first
|
// Compare based on userIds or fall back to alphabetical order
|
||||||
if (aIsAdmin && !bIsAdmin) return -1; // Place 'a' first if it's admin
|
|
||||||
if (!aIsAdmin && bIsAdmin) return 1; // Place 'b' first if it's admin
|
|
||||||
|
|
||||||
// Neither are admin, compare based on userIds or fall back to alphabetical order
|
|
||||||
if (aUserIndex !== -1 && bUserIndex === -1) return -1; // 'a' has valid userId -> prioritize
|
if (aUserIndex !== -1 && bUserIndex === -1) return -1; // 'a' has valid userId -> prioritize
|
||||||
if (bUserIndex !== -1 && aUserIndex === -1) return 1; // 'b' has valid userId -> prioritize
|
if (bUserIndex !== -1 && aUserIndex === -1) return 1; // 'b' has valid userId -> prioritize
|
||||||
|
|
||||||
@ -114,20 +107,7 @@
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
{#if userIds.includes(user.id)}
|
{#if userIds.includes(user.id)}
|
||||||
<button
|
<Badge type="success" content="member" />
|
||||||
on:click={() => {
|
|
||||||
adminIds = adminIds.includes(user.id)
|
|
||||||
? adminIds.filter((id) => id !== user.id)
|
|
||||||
: [...adminIds, user.id];
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
{#if adminIds.includes(user.id)}
|
|
||||||
<Badge type="info" content="admin" />
|
|
||||||
{:else}
|
|
||||||
<Badge type="success" content="member" />
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user