This commit is contained in:
Timothy Jaeryang Baek
2026-07-15 01:59:56 -04:00
parent 581f2f36f4
commit fb2ea27295
5 changed files with 138 additions and 83 deletions
+55 -16
View File
@@ -14,6 +14,7 @@
getBaseModels,
toggleModelById,
updateModelById,
updateModelAccessGrants,
importModels
} from '$lib/apis/models';
import { copyToClipboard } from '$lib/utils';
@@ -82,6 +83,18 @@
);
};
const isSharedModel = (model) => (model?.access_grants ?? []).length > 0 && !isPublicModel(model);
const modelAccessBadge = (model) => {
if (isPublicModel(model)) {
return { type: 'success', content: $i18n.t('Public') };
}
if (isSharedModel(model)) {
return { type: 'info', content: $i18n.t('Shared') };
}
return { type: 'muted', content: $i18n.t('Private') };
};
$: if (models) {
filteredModels = models
.filter((m) => searchValue === '' || m.name.toLowerCase().includes(searchValue.toLowerCase()))
@@ -297,6 +310,43 @@
);
};
const toggleModelPrivacyHandler = async (model) => {
const nextAccessGrants = isPublicModel(model)
? []
: [
...(model?.access_grants ?? []),
{
principal_type: 'user',
principal_id: '*',
permission: 'read'
}
];
const res = await updateModelAccessGrants(
localStorage.token,
model.id,
model.name,
nextAccessGrants
).catch(() => null);
if (res) {
models = models.map((m) =>
m.id === model.id ? { ...m, access_grants: res.access_grants ?? nextAccessGrants } : m
);
_models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
toast.success(
isPublicModel({ access_grants: nextAccessGrants })
? $i18n.t('Model is now public')
: $i18n.t('Model is now private')
);
}
};
const copyLinkHandler = async (model) => {
const baseUrl = window.location.origin;
const res = await copyToClipboard(`${baseUrl}/?model=${encodeURIComponent(model.id)}`);
@@ -662,22 +712,8 @@
</span>
<Badge
type={(model?.access_grants ?? []).some(
(g) =>
g.principal_type === 'user' &&
g.principal_id === '*' &&
g.permission === 'read'
)
? 'success'
: 'muted'}
content={(model?.access_grants ?? []).some(
(g) =>
g.principal_type === 'user' &&
g.principal_id === '*' &&
g.permission === 'read'
)
? $i18n.t('Public')
: $i18n.t('Private')}
type={modelAccessBadge(model).type}
content={modelAccessBadge(model).content}
/>
</div>
</Tooltip>
@@ -734,6 +770,9 @@
hideHandler={() => {
hideModelHandler(model);
}}
privacyHandler={() => {
toggleModelPrivacyHandler(model);
}}
pinModelHandler={() => {
pinModelHandler(model.id);
}}
@@ -14,6 +14,8 @@
import ArrowUpCircle from '$lib/components/icons/ArrowUpCircle.svelte';
import Pin from '$lib/components/icons/Pin.svelte';
import PinSlash from '$lib/components/icons/PinSlash.svelte';
import GlobeAlt from '$lib/components/icons/GlobeAlt.svelte';
import LockClosed from '$lib/components/icons/LockClosed.svelte';
import { config, settings } from '$lib/stores';
import Link from '$lib/components/icons/Link.svelte';
@@ -25,6 +27,7 @@
export let exportHandler: Function;
export let hideHandler: Function;
export let privacyHandler: Function;
export let pinModelHandler: Function;
export let copyLinkHandler: Function;
export let cloneHandler: Function;
@@ -32,6 +35,11 @@
export let onClose: Function;
let show = false;
const isPublicModel = (model) =>
(model?.access_grants ?? []).some(
(g) => g.principal_type === 'user' && g.principal_id === '*' && g.permission === 'read'
);
</script>
<Dropdown
@@ -100,6 +108,27 @@
</div>
</button>
<button
class="select-none flex w-full gap-2 items-center h-[1.6875rem] px-2 text-[13px] font-normal cursor-pointer hover:bg-gray-50/40 dark:hover:bg-gray-800/40 rounded-xl"
on:click={() => {
privacyHandler();
}}
>
{#if isPublicModel(model)}
<LockClosed className="size-3.5" />
{:else}
<GlobeAlt className="size-3.5" />
{/if}
<div class="flex items-center">
{#if isPublicModel(model)}
{$i18n.t('Make Private')}
{:else}
{$i18n.t('Make Public')}
{/if}
</div>
</button>
<button
class="select-none flex w-full gap-2 items-center h-[1.6875rem] px-2 text-[13px] font-normal cursor-pointer hover:bg-gray-50/40 dark:hover:bg-gray-800/40 rounded-xl"
on:click={() => {