refac
This commit is contained in:
1 parent
3316ba76aa
commit
5424ac5891
4 files changed
+130
-87
No files matched your search
@@ -18,36 +18,49 @@
|
||||
export let actions: Action[] = [];
|
||||
export let selectedActionIds: string[] = [];
|
||||
|
||||
$: selectableActions = actions.filter((action) => !action.is_global);
|
||||
$: selectedActions = actions.filter(
|
||||
(action) => action.is_global || selectedActionIds.includes(action.id)
|
||||
);
|
||||
$: availableActions = actions.filter(
|
||||
(action) => !action.is_global && !selectedActionIds.includes(action.id)
|
||||
);
|
||||
|
||||
const selectAction = (action: Action) => {
|
||||
selectedActionIds = [...selectedActionIds, action.id];
|
||||
const toggleAction = (action: Action) => {
|
||||
selectedActionIds = selectedActionIds.includes(action.id)
|
||||
? selectedActionIds.filter((id) => id !== action.id)
|
||||
: [...selectedActionIds, action.id];
|
||||
};
|
||||
</script>
|
||||
|
||||
{#if actions.length > 0}
|
||||
<div>
|
||||
<div class="flex w-full justify-between mb-1">
|
||||
<div class="flex w-full items-center gap-2 mb-1">
|
||||
<div class=" self-center text-xs text-gray-500">{$i18n.t('Actions')}</div>
|
||||
|
||||
{#if selectableActions.length > 0}
|
||||
<TypeaheadSelector
|
||||
id="model-actions-selector"
|
||||
items={selectableActions.map((action) => ({
|
||||
...action,
|
||||
description: action.meta?.description
|
||||
}))}
|
||||
selectedIds={selectedActionIds}
|
||||
placeholder={$i18n.t('Search actions')}
|
||||
triggerLabel={$i18n.t('Select Action')}
|
||||
emptyLabel={$i18n.t('No actions found')}
|
||||
variant="dropdown"
|
||||
on:select={(e) => {
|
||||
toggleAction(e.detail);
|
||||
}}
|
||||
on:enableall={(e) => {
|
||||
selectedActionIds = [
|
||||
...new Set([...selectedActionIds, ...e.detail.map((action) => action.id)])
|
||||
];
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<TypeaheadSelector
|
||||
id="model-actions-selector"
|
||||
items={availableActions}
|
||||
className="w-48 max-w-full"
|
||||
placeholder={$i18n.t('Search actions')}
|
||||
on:select={(e) => {
|
||||
selectAction(e.detail);
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class=" flex items-center flex-wrap">
|
||||
<div class=" flex items-center flex-wrap mt-1">
|
||||
{#each selectedActions as action, actionIdx}
|
||||
<div class=" flex items-center gap-2 mr-3">
|
||||
<div class="self-center flex items-center">
|
||||
@@ -71,5 +84,9 @@
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" text-xs dark:text-gray-700">
|
||||
{$i18n.t('To select actions here, add them to the "Functions" workspace first.')}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -18,34 +18,45 @@
|
||||
export let selectedFilterIds: string[] = [];
|
||||
|
||||
$: selectedFilters = filters.filter((filter) => selectedFilterIds.includes(filter.id));
|
||||
$: availableFilters = filters.filter((filter) => !selectedFilterIds.includes(filter.id));
|
||||
|
||||
const selectFilter = (filter: Filter) => {
|
||||
selectedFilterIds = [...selectedFilterIds, filter.id];
|
||||
const toggleFilter = (filter: Filter) => {
|
||||
selectedFilterIds = selectedFilterIds.includes(filter.id)
|
||||
? selectedFilterIds.filter((id) => id !== filter.id)
|
||||
: [...selectedFilterIds, filter.id];
|
||||
};
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div class="flex w-full justify-between mb-1">
|
||||
<div class="flex w-full items-center gap-2 mb-1">
|
||||
<div class=" self-center text-xs text-gray-500">{$i18n.t('Default Filters')}</div>
|
||||
|
||||
{#if filters.length > 0}
|
||||
<TypeaheadSelector
|
||||
id="model-default-filters-selector"
|
||||
items={filters.map((filter) => ({
|
||||
...filter,
|
||||
description: filter.meta?.description
|
||||
}))}
|
||||
selectedIds={selectedFilterIds}
|
||||
placeholder={$i18n.t('Search filters')}
|
||||
triggerLabel={$i18n.t('Select Filter')}
|
||||
emptyLabel={$i18n.t('No filters found')}
|
||||
variant="dropdown"
|
||||
on:select={(e) => {
|
||||
toggleFilter(e.detail);
|
||||
}}
|
||||
on:enableall={(e) => {
|
||||
selectedFilterIds = [
|
||||
...new Set([...selectedFilterIds, ...e.detail.map((filter) => filter.id)])
|
||||
];
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
{#if filters.length > 0}
|
||||
<TypeaheadSelector
|
||||
id="model-default-filters-selector"
|
||||
items={availableFilters.map((filter) => ({
|
||||
...filter,
|
||||
description: filter.meta?.description
|
||||
}))}
|
||||
className="w-48 max-w-full"
|
||||
placeholder={$i18n.t('Search filters')}
|
||||
on:select={(e) => {
|
||||
selectFilter(e.detail);
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class=" flex items-center flex-wrap">
|
||||
<div class=" flex items-center flex-wrap mt-1">
|
||||
{#each selectedFilters as filter}
|
||||
{@const isSelected = selectedFilterIds.includes(filter.id)}
|
||||
<div class=" flex items-center gap-2 mr-3">
|
||||
@@ -74,4 +85,8 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class=" text-xs dark:text-gray-700">
|
||||
{$i18n.t('To select default filters here, enable toggleable filters for this model first.')}
|
||||
</div>
|
||||
</div>
|
||||
@@ -18,40 +18,50 @@
|
||||
export let filters: Filter[] = [];
|
||||
export let selectedFilterIds: string[] = [];
|
||||
|
||||
$: selectableFilters = filters.filter((filter) => !filter.is_global);
|
||||
$: selectedFilters = filters.filter(
|
||||
(filter) => filter.is_global || selectedFilterIds.includes(filter.id)
|
||||
);
|
||||
$: availableFilters = filters.filter(
|
||||
(filter) => !filter.is_global && !selectedFilterIds.includes(filter.id)
|
||||
);
|
||||
|
||||
const selectFilter = (filter: Filter) => {
|
||||
selectedFilterIds = [...selectedFilterIds, filter.id];
|
||||
const toggleFilter = (filter: Filter) => {
|
||||
selectedFilterIds = selectedFilterIds.includes(filter.id)
|
||||
? selectedFilterIds.filter((id) => id !== filter.id)
|
||||
: [...selectedFilterIds, filter.id];
|
||||
};
|
||||
</script>
|
||||
|
||||
{#if filters.length > 0}
|
||||
<div>
|
||||
<div class="flex w-full justify-between mb-1">
|
||||
<div class="flex w-full items-center gap-2 mb-1">
|
||||
<div class=" self-center text-xs text-gray-500">{$i18n.t('Filters')}</div>
|
||||
|
||||
{#if selectableFilters.length > 0}
|
||||
<TypeaheadSelector
|
||||
id="model-filters-selector"
|
||||
items={selectableFilters.map((filter) => ({
|
||||
...filter,
|
||||
description: filter.meta?.description
|
||||
}))}
|
||||
selectedIds={selectedFilterIds}
|
||||
placeholder={$i18n.t('Search filters')}
|
||||
triggerLabel={$i18n.t('Select Filter')}
|
||||
emptyLabel={$i18n.t('No filters found')}
|
||||
variant="dropdown"
|
||||
on:select={(e) => {
|
||||
toggleFilter(e.detail);
|
||||
}}
|
||||
on:enableall={(e) => {
|
||||
selectedFilterIds = [
|
||||
...new Set([...selectedFilterIds, ...e.detail.map((filter) => filter.id)])
|
||||
];
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- TODO: Filter order matters -->
|
||||
<div class="flex flex-col">
|
||||
<TypeaheadSelector
|
||||
id="model-filters-selector"
|
||||
items={availableFilters.map((filter) => ({
|
||||
...filter,
|
||||
description: filter.meta?.description
|
||||
}))}
|
||||
className="w-48 max-w-full"
|
||||
placeholder={$i18n.t('Search filters')}
|
||||
on:select={(e) => {
|
||||
selectFilter(e.detail);
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class=" flex items-center flex-wrap">
|
||||
<div class=" flex items-center flex-wrap mt-1">
|
||||
{#each selectedFilters as filter}
|
||||
{@const isSelected = filter.is_global || selectedFilterIds.includes(filter.id)}
|
||||
<div class=" flex items-center gap-2 mr-3">
|
||||
@@ -82,5 +92,9 @@
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" text-xs dark:text-gray-700">
|
||||
{$i18n.t('To select filters here, add them to the "Functions" workspace first.')}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -3,6 +3,7 @@
|
||||
import { saveAs } from 'file-saver';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import Plus from '$lib/components/icons/Plus.svelte';
|
||||
import XMark from '$lib/components/icons/XMark.svelte';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
@@ -26,13 +27,13 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class=" space-y-3">
|
||||
<div class="flex w-full justify-between mb-1.5">
|
||||
<div class=" self-center text-xs flex-1 shrink-0 w-full">
|
||||
<div class="space-y-2">
|
||||
<div class="mb-1 flex h-6 w-full items-center justify-between">
|
||||
<div class="min-w-0 flex-1 self-center text-xs text-gray-500 dark:text-gray-400">
|
||||
{$i18n.t('Default Prompt Suggestions')}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end gap-2">
|
||||
<div class="flex shrink-0 items-center justify-end gap-1.5">
|
||||
<input
|
||||
id="prompt-suggestions-import-input"
|
||||
type="file"
|
||||
@@ -75,7 +76,7 @@
|
||||
/>
|
||||
|
||||
<button
|
||||
class="flex text-xs items-center space-x-1 py-1 rounded-xl bg-transparent dark:text-gray-200 transition"
|
||||
class="flex items-center rounded-xl bg-transparent px-1 py-0.5 text-xs text-gray-500 transition hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
const input = document.getElementById('prompt-suggestions-import-input');
|
||||
@@ -84,14 +85,14 @@
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div class=" self-center font-normal line-clamp-1">
|
||||
<div class="line-clamp-1 self-center font-normal">
|
||||
{$i18n.t('Import')}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{#if promptSuggestions.length}
|
||||
<button
|
||||
class="flex text-xs items-center space-x-1 py-1 rounded-xl bg-transparent dark:text-gray-200 transition"
|
||||
class="flex items-center rounded-xl bg-transparent px-1 py-0.5 text-xs text-gray-500 transition hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
|
||||
type="button"
|
||||
on:click={async () => {
|
||||
let blob = new Blob([JSON.stringify(promptSuggestions)], {
|
||||
@@ -100,89 +101,85 @@
|
||||
saveAs(blob, `prompt-suggestions-export-${Date.now()}.json`);
|
||||
}}
|
||||
>
|
||||
<div class=" self-center font-normal line-clamp-1">
|
||||
<div class="line-clamp-1 self-center font-normal">
|
||||
{$i18n.t('Export')}
|
||||
</div>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
class=" px-1.5 rounded-xl transition font-normal text-sm flex items-center"
|
||||
class="flex size-6 items-center justify-center text-gray-500 transition hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
|
||||
type="button"
|
||||
aria-label={$i18n.t('Add prompt suggestion')}
|
||||
on:click={() => {
|
||||
if (promptSuggestions.length === 0 || promptSuggestions.at(-1).content !== '') {
|
||||
promptSuggestions = [...promptSuggestions, { content: '', title: ['', ''] }];
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Plus className="size-3" strokeWidth="2.5" />
|
||||
<Plus className="size-3.5" strokeWidth="2.25" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if _promptSuggestions.length > 0}
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-col gap-1.5">
|
||||
{#each _promptSuggestions as prompt, promptIdx}
|
||||
<div
|
||||
class=" flex border rounded-2xl border-gray-100/30 dark:border-gray-850/30 bg-transparent p-2"
|
||||
class="flex gap-1 rounded-lg border border-gray-100/40 bg-transparent px-2 py-1 dark:border-gray-850/50"
|
||||
>
|
||||
<div class="flex flex-col md:flex-row w-full gap-1 md:gap-2 px-2">
|
||||
<div class="gap-0.5 min-w-60">
|
||||
<div class="flex min-w-0 flex-1 flex-col gap-0.5">
|
||||
<div class="grid min-w-0 gap-1 md:grid-cols-2 md:gap-1.5">
|
||||
<Tooltip content={$i18n.t('e.g. Tell me a fun fact')} placement="top-start">
|
||||
<input
|
||||
class="text-sm w-full bg-transparent outline-hidden"
|
||||
class="w-full bg-transparent text-[13px] leading-5 text-gray-700 outline-hidden placeholder:text-gray-300 dark:text-gray-200 dark:placeholder:text-gray-700"
|
||||
placeholder={$i18n.t('Title')}
|
||||
aria-label={$i18n.t('Title')}
|
||||
bind:value={prompt.title[0]}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content={$i18n.t('e.g. about the Roman Empire')} placement="top-start">
|
||||
<input
|
||||
class="text-sm w-full bg-transparent outline-hidden text-gray-600 dark:text-gray-400"
|
||||
class="w-full bg-transparent text-[13px] leading-5 text-gray-500 outline-hidden placeholder:text-gray-300 dark:text-gray-500 dark:placeholder:text-gray-700"
|
||||
placeholder={$i18n.t('Subtitle')}
|
||||
aria-label={$i18n.t('Subtitle')}
|
||||
bind:value={prompt.title[1]}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<Tooltip
|
||||
className="w-full self-center items-center flex"
|
||||
className="flex min-w-0"
|
||||
content={$i18n.t('e.g. Tell me a fun fact about the Roman Empire')}
|
||||
placement="top-start"
|
||||
>
|
||||
<textarea
|
||||
class="text-sm w-full bg-transparent outline-hidden resize-none"
|
||||
placeholder={$i18n.t('Prompt')}
|
||||
rows="2"
|
||||
class="min-h-5 w-full resize-none bg-transparent text-[13px] leading-5 text-gray-700 outline-hidden placeholder:text-gray-300 dark:text-gray-200 dark:placeholder:text-gray-700"
|
||||
placeholder={$i18n.t('Content')}
|
||||
aria-label={$i18n.t('Content')}
|
||||
rows="1"
|
||||
bind:value={prompt.content}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="p-1 self-start"
|
||||
class="flex size-6 shrink-0 items-center justify-center text-gray-400 opacity-70 transition hover:text-gray-700 hover:opacity-100 dark:text-gray-600 dark:hover:text-gray-300"
|
||||
type="button"
|
||||
aria-label={$i18n.t('Remove prompt suggestion')}
|
||||
on:click={() => {
|
||||
promptSuggestions.splice(promptIdx, 1);
|
||||
promptSuggestions = promptSuggestions;
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
class="w-4 h-4"
|
||||
>
|
||||
<path
|
||||
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
|
||||
/>
|
||||
</svg>
|
||||
<XMark className="size-3.5" />
|
||||
</button>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-xs text-center w-full text-gray-500 mb-1.5">
|
||||
<div class="mb-1.5 w-full text-center text-xs text-gray-500 dark:text-gray-600">
|
||||
{$i18n.t('No suggestion prompts')}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in new issue
Block a user