* wip: server_tools * feat: Integrate with `/tools` endpoint * feat: Builtin + MCP + JSON Schema Tools WIP * refactor * displayName -> display_name * snake_case everywhere * rm redundant field * feat: Improvements * chore: update webui build output * refactor: Updates after server updates * chore: update webui build output * change arg to --tools all * feat: UI improvements * chore: update webui build output * add readme mention * llama-gen-docs * chore: update webui build output * chore: update webui build output * chore: update webui build output * feat: Reorganize settings sections * feat: Separate dialogs for MCP Servers Settings and Import/Export * feat: WIP * feat: WIP * feat: WIP * feat: WIP * feat: WIP * feat: WIP * WIP on allozaur/20677-webui-server-tools * feat: UI improvements * chore: Update package lock * chore: Run `npm audit fix` * feat: UI WIP * feat: UI * refactor: Desktop Icon Strip DRY * feat: Cleaner rendering and transition for ChatScreen * feat: UI improvements * feat: UI improvement * feat: Remove MCP Server "enable" switch from Tools submenu * chore: Run `npm audit fix` * feat: WIP * feat: Logic improvements * refactor: Cleanup * refactor: DRY * test: Fix Chat Sidebar UI Tests * chore: Update package lock * refactor: Cleanup * feat: Chat Message Action Card with Continue and Permission flow implementations * feat: Add agentic steering messages, draft messages and improve chat UX * fix: Search results UI * test: Fix unit test * feat: UI/UX improvements * refactor: Simplify `useToolsPanel` access in components * feat: Implement Processing Info Context API * feat: Implement 'Go back to chat' functionality for settings * feat: Enhance MCP Server management in Chat Form Attachments * style: Minor UI and branding adjustments * chore: Update webui static build output * chore: Formatting, linting & type checks * feat: Draft messages logic * feat: UI improvements * feat: Steering Messages improvements * refactor: Cleanup * refactor: Cleanup * feat: Improve UI * refactor: Settings navigation hook * refactor: DRY code * refactor: DRY ChatMessageUser UI components * refactor: Desktop Icon Strip DRY * refactor: Tools & permissions * fix: Navigation condition * refactor: Cleanup * refactor: Cleanup * refactor: Cleanup * fix: preserve reasoning_content in agentic flow --------- Co-authored-by: Xuan Son Nguyen <son@huggingface.co>
82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
import { IsMobile } from '$lib/hooks/is-mobile.svelte.js';
|
|
import { getContext, setContext } from 'svelte';
|
|
import { SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_MIN_WIDTH } from './constants.js';
|
|
|
|
type Getter<T> = () => T;
|
|
|
|
export type SidebarStateProps = {
|
|
/**
|
|
* A getter function that returns the current open state of the sidebar.
|
|
* We use a getter function here to support `bind:open` on the `Sidebar.Provider`
|
|
* component.
|
|
*/
|
|
open: Getter<boolean>;
|
|
|
|
/**
|
|
* A function that sets the open state of the sidebar. To support `bind:open`, we need
|
|
* a source of truth for changing the open state to ensure it will be synced throughout
|
|
* the sub-components and any `bind:` references.
|
|
*/
|
|
setOpen: (open: boolean) => void;
|
|
};
|
|
|
|
class SidebarState {
|
|
readonly props: SidebarStateProps;
|
|
open = $derived.by(() => this.props.open());
|
|
openMobile = $state(false);
|
|
sidebarWidth = $state(SIDEBAR_MIN_WIDTH);
|
|
isResizing = $state(false);
|
|
setOpen: SidebarStateProps['setOpen'];
|
|
#isMobile: IsMobile;
|
|
state = $derived.by(() => (this.open ? 'expanded' : 'collapsed'));
|
|
|
|
constructor(props: SidebarStateProps) {
|
|
this.setOpen = props.setOpen;
|
|
this.#isMobile = new IsMobile();
|
|
this.props = props;
|
|
}
|
|
|
|
// Convenience getter for checking if the sidebar is mobile
|
|
// without this, we would need to use `sidebar.isMobile.current` everywhere
|
|
get isMobile() {
|
|
return this.#isMobile.current;
|
|
}
|
|
|
|
// Event handler to apply to the `<svelte:window>`
|
|
handleShortcutKeydown = (e: KeyboardEvent) => {
|
|
if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
|
|
e.preventDefault();
|
|
this.toggle();
|
|
}
|
|
};
|
|
|
|
setOpenMobile = (value: boolean) => {
|
|
this.openMobile = value;
|
|
};
|
|
|
|
toggle = () => {
|
|
this.setOpen(!this.open);
|
|
};
|
|
}
|
|
|
|
const SYMBOL_KEY = 'scn-sidebar';
|
|
|
|
/**
|
|
* Instantiates a new `SidebarState` instance and sets it in the context.
|
|
*
|
|
* @param props The constructor props for the `SidebarState` class.
|
|
* @returns The `SidebarState` instance.
|
|
*/
|
|
export function setSidebar(props: SidebarStateProps): SidebarState {
|
|
return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props));
|
|
}
|
|
|
|
/**
|
|
* Retrieves the `SidebarState` instance from the context. This is a class instance,
|
|
* so you cannot destructure it.
|
|
* @returns The `SidebarState` instance.
|
|
*/
|
|
export function useSidebar(): SidebarState {
|
|
return getContext(Symbol.for(SYMBOL_KEY));
|
|
}
|