mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-10 03:27:57 +00:00
refac
This commit is contained in:
parent
24ee1cb168
commit
dc1203d34c
3 changed files with 24 additions and 17 deletions
|
|
@ -16,7 +16,7 @@
|
|||
let locale = '';
|
||||
let meta: { i18n?: Record<string, Record<string, string>>; [key: string]: any } = {};
|
||||
import { user } from '$lib/stores';
|
||||
import { slugify } from '$lib/utils';
|
||||
import { slugify, parseFrontmatter, formatSkillName } from '$lib/utils';
|
||||
import Spinner from '$lib/components/common/Spinner.svelte';
|
||||
import { updateSkillAccessGrants } from '$lib/apis/skills';
|
||||
import { goto, beforeNavigate } from '$app/navigation';
|
||||
|
|
@ -221,6 +221,12 @@
|
|||
|
||||
let accessGrants: any[] = [];
|
||||
let showAccessControlModal = false;
|
||||
const handleContentChange = (path: string, content: string) => {
|
||||
if (edit || path !== 'SKILL.md') return;
|
||||
const fields = parseFrontmatter(content);
|
||||
if (!name && typeof fields.name === 'string') name = formatSkillName(fields.name);
|
||||
if (!description && typeof fields.description === 'string') description = fields.description;
|
||||
};
|
||||
$: if (!edit && !clone && name) {
|
||||
id = slugify(name);
|
||||
}
|
||||
|
|
@ -454,6 +460,7 @@
|
|||
bind:dirty={fileDirty}
|
||||
initialPath={new URLSearchParams(location.search).get('path') || 'SKILL.md'}
|
||||
onSave={submitHandler}
|
||||
onContentChange={handleContentChange}
|
||||
canExport={edit &&
|
||||
($user?.role === 'admin' || $user?.permissions?.workspace?.skills_export)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
export let reloadKey = 0;
|
||||
export let initialPath = 'SKILL.md';
|
||||
export let onSave: () => Promise<void> = async () => {};
|
||||
export let onContentChange: (path: string, content: string) => void = () => {};
|
||||
const i18n = getContext<any>('i18n');
|
||||
type Draft = SkillFileSummary & {
|
||||
sourcePath?: string;
|
||||
|
|
@ -139,6 +140,7 @@
|
|||
if (loadedPath && codeEditor) value = codeEditor.getValue();
|
||||
const file = files.find((f) => f.path === loadedPath);
|
||||
if (file && !readOnly && value !== loadedValue) {
|
||||
onContentChange(loadedPath, value);
|
||||
file.content = value;
|
||||
file.changed = true;
|
||||
file.size = new TextEncoder().encode(value).length;
|
||||
|
|
@ -158,7 +160,10 @@
|
|||
};
|
||||
};
|
||||
$: if (!$mobile) showFileDrawer = false;
|
||||
$: if (loadedPath && value !== loadedValue && !readOnly) dirty = true;
|
||||
$: if (loadedPath && value !== loadedValue && !readOnly) {
|
||||
dirty = true;
|
||||
onContentChange(loadedPath, value);
|
||||
}
|
||||
const blobFor = async (file: Draft) => {
|
||||
if (file.content !== undefined)
|
||||
return new Blob([
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { Writable } from 'svelte/store';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import sha256 from 'js-sha256';
|
||||
import { parse as parseYaml } from 'yaml';
|
||||
import DOMPurify, { type UponSanitizeAttributeHookEvent } from 'dompurify';
|
||||
import { WEBUI_BASE_URL } from '$lib/constants';
|
||||
import type { FileNavOpenRequest } from '$lib/stores';
|
||||
|
|
@ -2465,22 +2466,16 @@ export const getCodeBlockContents = (content: string): object => {
|
|||
}))
|
||||
};
|
||||
};
|
||||
export const parseFrontmatter = (content) => {
|
||||
const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
|
||||
if (match) {
|
||||
const frontmatter = {};
|
||||
match[1].split('\n').forEach((line) => {
|
||||
const [key, ...value] = line.split(':');
|
||||
if (key && value) {
|
||||
frontmatter[key.trim()] = value
|
||||
.join(':')
|
||||
.trim()
|
||||
.replace(/^["']|["']$/g, '');
|
||||
}
|
||||
});
|
||||
return frontmatter;
|
||||
export const parseFrontmatter = (content: string): Record<string, unknown> => {
|
||||
const match = content.match(/^\uFEFF?---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/);
|
||||
if (!match) return {};
|
||||
try {
|
||||
const fields = parseYaml(match[1]);
|
||||
return fields && typeof fields === 'object' && !Array.isArray(fields) ? fields : {};
|
||||
} catch {
|
||||
// Incomplete frontmatter is normal while typing.
|
||||
return {};
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
export const formatSkillName = (name) => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue