@dignite/ng.site 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/fesm2022/{dignite-ng.site-content-editor.component-DA6FaJSU.mjs → dignite-ng.site-content-editor.component-DJEBh1ok.mjs} +2 -2
  2. package/fesm2022/{dignite-ng.site-content-editor.component-DA6FaJSU.mjs.map → dignite-ng.site-content-editor.component-DJEBh1ok.mjs.map} +1 -1
  3. package/fesm2022/{dignite-ng.site-content-types.component-Dnqe8A4t.mjs → dignite-ng.site-content-types.component-B3GpUeEa.mjs} +3 -3
  4. package/fesm2022/{dignite-ng.site-content-types.component-Dnqe8A4t.mjs.map → dignite-ng.site-content-types.component-B3GpUeEa.mjs.map} +1 -1
  5. package/fesm2022/{dignite-ng.site-contents.component-Ch5GYIHE.mjs → dignite-ng.site-contents.component-ht0WYCSN.mjs} +3 -3
  6. package/fesm2022/{dignite-ng.site-contents.component-Ch5GYIHE.mjs.map → dignite-ng.site-contents.component-ht0WYCSN.mjs.map} +1 -1
  7. package/fesm2022/{dignite-ng.site-dignite-ng.site-BMcNABSG.mjs → dignite-ng.site-dignite-ng.site-CJVw2UzZ.mjs} +145 -29
  8. package/fesm2022/dignite-ng.site-dignite-ng.site-CJVw2UzZ.mjs.map +1 -0
  9. package/fesm2022/{dignite-ng.site-fields.component-BaK27N9k.mjs → dignite-ng.site-fields.component-DpKMPRz3.mjs} +4 -4
  10. package/fesm2022/{dignite-ng.site-fields.component-BaK27N9k.mjs.map → dignite-ng.site-fields.component-DpKMPRz3.mjs.map} +1 -1
  11. package/fesm2022/{dignite-ng.site-pages.component-BwGyK7jw.mjs → dignite-ng.site-pages.component-Dc3kz6EW.mjs} +3 -3
  12. package/fesm2022/{dignite-ng.site-pages.component-BwGyK7jw.mjs.map → dignite-ng.site-pages.component-Dc3kz6EW.mjs.map} +1 -1
  13. package/fesm2022/dignite-ng.site-setting-management.mjs +77 -4
  14. package/fesm2022/dignite-ng.site-setting-management.mjs.map +1 -1
  15. package/fesm2022/dignite-ng.site-theme-workbench.component-HoSTVRBM.mjs +1283 -0
  16. package/fesm2022/dignite-ng.site-theme-workbench.component-HoSTVRBM.mjs.map +1 -0
  17. package/fesm2022/dignite-ng.site.mjs +1 -1
  18. package/package.json +1 -1
  19. package/types/dignite-ng.site-setting-management.d.ts +34 -4
  20. package/types/dignite-ng.site.d.ts +173 -89
  21. package/fesm2022/dignite-ng.site-dignite-ng.site-BMcNABSG.mjs.map +0 -1
  22. package/fesm2022/dignite-ng.site-theme-workbench.component-CA47DnTj.mjs +0 -1206
  23. package/fesm2022/dignite-ng.site-theme-workbench.component-CA47DnTj.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dignite-ng.site-theme-workbench.component-HoSTVRBM.mjs","sources":["../../../projects/site/src/lib/components/theme/code-editor.component.ts","../../../projects/site/src/lib/components/theme/theme-workbench.helpers.ts","../../../projects/site/src/lib/components/theme/theme-workbench.component.ts","../../../projects/site/src/lib/components/theme/theme-workbench.component.html"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n OnDestroy,\n effect,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { css } from '@codemirror/lang-css';\nimport { html } from '@codemirror/lang-html';\nimport { javascript } from '@codemirror/lang-javascript';\nimport { Compartment, EditorState, Extension } from '@codemirror/state';\nimport { EditorView } from '@codemirror/view';\nimport { basicSetup } from 'codemirror';\nimport type { ThemeEditorLanguage } from './theme-workbench.helpers';\n\n/**\n * A code editor over CodeMirror 6, used for the files of a theme.\n *\n * A template is highlighted as HTML, not Scriban: it is an HTML document with Scriban's `{{ }}` in it, and there is\n * no Scriban grammar for CodeMirror, so the `{{ }}` parts are not highlighted - only the markup around them. A static\n * file is highlighted by its extension ({@link language}).\n *\n * {@link documentKey} names the file being edited. When it changes, the editor starts a new editing state for the new\n * file, so undo never reaches into another file. While it stays the same, the document is owned by CodeMirror as the\n * user types; {@link value} only matters when it differs from the document (the file was reloaded, say), in which\n * case the whole document is replaced. A value the editor itself just emitted therefore comes back as a no-op.\n */\n@Component({\n selector: 'site-code-editor',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: '<div #host></div>',\n styles: ':host { display: block; }',\n})\nexport class CodeEditorComponent implements AfterViewInit, OnDestroy {\n readonly value = input('');\n readonly readonly = input(false);\n readonly language = input<ThemeEditorLanguage>('html');\n readonly documentKey = input<string | undefined>(undefined);\n readonly valueChange = output<string>();\n\n private readonly host = viewChild.required<ElementRef<HTMLElement>>('host');\n private readonly readOnlyCompartment = new Compartment();\n private readonly languageCompartment = new Compartment();\n private currentKey: string | undefined;\n\n // A signal, so the effects below run again once the view exists - it is created in ngAfterViewInit, after\n // their first run.\n private readonly view = signal<EditorView | undefined>(undefined);\n\n constructor() {\n effect(() => {\n const view = this.view();\n const key = this.documentKey();\n const value = this.value();\n\n if (!view) {\n return;\n }\n\n if (key !== this.currentKey) {\n this.currentKey = key;\n view.setState(this.createState(value));\n return;\n }\n\n if (value !== view.state.doc.toString()) {\n view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: value } });\n }\n });\n\n effect(() => {\n const view = this.view();\n const readonly = this.readonly();\n const language = this.language();\n\n view?.dispatch({\n effects: [\n this.readOnlyCompartment.reconfigure(readOnlyExtensions(readonly)),\n this.languageCompartment.reconfigure(languageExtension(language)),\n ],\n });\n });\n }\n\n ngAfterViewInit(): void {\n this.currentKey = this.documentKey();\n this.view.set(new EditorView({ parent: this.host().nativeElement, state: this.createState(this.value()) }));\n }\n\n private createState(doc: string): EditorState {\n return EditorState.create({\n doc,\n extensions: [\n basicSetup,\n this.languageCompartment.of(languageExtension(this.language())),\n EditorView.lineWrapping,\n EDITOR_THEME,\n this.readOnlyCompartment.of(readOnlyExtensions(this.readonly())),\n EditorView.updateListener.of(update => {\n if (update.docChanged) {\n this.valueChange.emit(update.state.doc.toString());\n }\n }),\n ],\n });\n }\n\n ngOnDestroy(): void {\n this.view()?.destroy();\n }\n\n /** Puts the cursor at a 1-based line and column and scrolls it into view. Out-of-range values are clamped. */\n goTo(line: number, column: number): void {\n const view = this.view();\n if (!view) {\n return;\n }\n\n const doc = view.state.doc;\n const target = doc.line(Math.min(Math.max(Math.trunc(line) || 1, 1), doc.lines));\n const position = Math.min(target.from + Math.max(Math.trunc(column) - 1, 0), target.to);\n\n view.dispatch({\n selection: { anchor: position },\n effects: EditorView.scrollIntoView(position, { y: 'center' }),\n });\n view.focus();\n }\n\n /**\n * Replaces the selection (or inserts at the cursor) with `text`, puts the cursor after it and focuses the editor. It\n * is an ordinary transaction, so {@link valueChange} fires exactly as it does for typing. A read-only editor is left\n * alone.\n */\n insert(text: string): void {\n const view = this.view();\n if (!view || this.readonly()) {\n return;\n }\n\n view.dispatch(view.state.update(view.state.replaceSelection(text), { scrollIntoView: true, userEvent: 'input' }));\n view.focus();\n }\n}\n\nfunction readOnlyExtensions(readonly: boolean) {\n return [EditorState.readOnly.of(readonly), EditorView.editable.of(!readonly)];\n}\n\nfunction languageExtension(language: ThemeEditorLanguage): Extension {\n switch (language) {\n case 'html':\n return html();\n case 'css':\n return css();\n case 'javascript':\n return javascript();\n default:\n return [];\n }\n}\n\n// The editor sits inside a Bootstrap card, so it inherits the card's colors rather than reading the body's:\n// in LeptonX Lite's dim theme --bs-body-bg is dark while the card stays light, and an editor painted with the\n// body tokens came out as a black box on a white card. Only the chrome (border, gutter, active line) reads\n// theme variables, with Bootstrap's light values as fallbacks.\nconst EDITOR_THEME = EditorView.theme({\n // The page that hosts the editor may size it: --site-code-editor-height fixes its height, and without it the\n // editor grows with its text up to --site-code-editor-max-height.\n '&': {\n height: 'var(--site-code-editor-height, auto)',\n minHeight: '24rem',\n maxHeight: 'var(--site-code-editor-max-height, 75vh)',\n border: '1px solid var(--bs-border-color, #dee2e6)',\n borderRadius: 'var(--bs-border-radius, 0.375rem)',\n backgroundColor: 'transparent',\n },\n '&.cm-focused': {\n outline: 'none',\n borderColor: 'var(--bs-primary, #0d6efd)',\n },\n '.cm-scroller': {\n minHeight: '24rem',\n fontFamily: 'var(--bs-font-monospace, monospace)',\n },\n '.cm-gutters': {\n backgroundColor: 'transparent',\n color: 'inherit',\n opacity: '0.6',\n border: 'none',\n borderRight: '1px solid var(--bs-border-color, #dee2e6)',\n },\n '.cm-activeLine, .cm-activeLineGutter': {\n backgroundColor: 'rgba(128, 128, 128, 0.12)',\n },\n});\n","import type { SiteThemeFileSummaryDto } from '../../proxy/dignite/site/admin/themes/models';\nimport type { FieldDto } from '../../proxy/dignite/site/fields/models';\nimport type { PageDto } from '../../proxy/dignite/site/pages/models';\nimport { SiteThemeFileStatus } from '../../proxy/dignite/site/themes/site-theme-file-status.enum';\n\n/** Mirrors `SiteThemeConsts.PathPattern` (`src/Dignite.Site.Domain.Shared/Themes/SiteThemeConsts.cs`). */\nexport const THEME_PATH_PATTERN =\n /^(?:[A-Za-z0-9_][A-Za-z0-9_-]*\\/)*[A-Za-z0-9_][A-Za-z0-9_-]*(?:\\.[A-Za-z0-9_-]+)*$/;\n\n/** Mirrors `SiteThemeConsts.MaxPathLength`. */\nexport const THEME_MAX_PATH_LENGTH = 256;\n\n/** Mirrors the default `SiteThemeConsts.AssetExtensions`; a host may allow more, which the server then accepts. */\nexport const THEME_ASSET_EXTENSIONS = [\n 'css', 'js', 'mjs', 'json', 'map', 'txt', 'svg', 'xml', 'webmanifest', 'ics', 'csv',\n];\n\n/** The path as the server stores it: trimmed, without a leading slash. */\nexport function normalizeThemePath(path: string): string {\n return (path ?? '').trim().replace(/^\\/+/, '');\n}\n\n/** The extension of the last segment, without the dot, or null - the server's `SiteThemePaths.GetExtension`. */\nexport function extensionOf(path: string): string | null {\n const name = path.slice(path.lastIndexOf('/') + 1);\n const dot = name.lastIndexOf('.');\n return dot <= 0 || dot === name.length - 1 ? null : name.slice(dot + 1).toLowerCase();\n}\n\n/**\n * Whether `name` is a language the browser knows, spelled the way it spells it (`ja`, `zh-Hans`; not `zh-hans`) -\n * the server's check for the extension of a language version, which it makes with the runtime's cultures.\n */\nfunction isLanguageName(name: string): boolean {\n if (!/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/.test(name)) {\n return false;\n }\n\n try {\n return (\n Intl.getCanonicalLocales(name)[0] === name &&\n new Intl.DisplayNames(['en'], { type: 'language', fallback: 'none' }).of(name) !== undefined\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Whether the path names the version of a template for one language - `blog/post.ja` is the Japanese version of\n * `blog/post` - which is a template, not a static file: the last segment has exactly one dot, followed by a language\n * that is not a static file's extension. Mirrors the server's `SiteThemePaths.TryGetLanguageVersion`.\n */\nexport function isLanguageVersionPath(path: string): boolean {\n const name = path.slice(path.lastIndexOf('/') + 1);\n const dot = name.indexOf('.');\n if (dot <= 0 || dot !== name.lastIndexOf('.') || dot === name.length - 1) {\n return false;\n }\n\n const extension = name.slice(dot + 1);\n return !THEME_ASSET_EXTENSIONS.includes(extension.toLowerCase()) && isLanguageName(extension);\n}\n\n/** Whether the path names a static file (its last segment has an extension) rather than a Scriban template. */\nexport function isAssetPath(path: string): boolean {\n return extensionOf(path) !== null && !isLanguageVersionPath(path);\n}\n\n/**\n * Why a path cannot be saved, as a localization key, or null when it can. The server decides in the end (a host may\n * allow more extensions); this only spares a round trip for the common mistakes.\n */\nexport function themePathProblem(path: string): string | null {\n const normalized = normalizeThemePath(path);\n if (!normalized || normalized.length > THEME_MAX_PATH_LENGTH || !THEME_PATH_PATTERN.test(normalized)) {\n return 'Site::ThemePathInvalid';\n }\n\n const extension = extensionOf(normalized);\n if (extension !== null && !THEME_ASSET_EXTENSIONS.includes(extension) && !isLanguageVersionPath(normalized)) {\n return 'Site::ThemePathExtensionNotAllowed';\n }\n\n return null;\n}\n\n/** The language the code editor highlights a file in, by its extension. */\nexport type ThemeEditorLanguage = 'html' | 'css' | 'javascript' | 'text';\n\nexport function languageOf(path: string): ThemeEditorLanguage {\n if (isLanguageVersionPath(path)) {\n return 'html';\n }\n\n switch (extensionOf(path)) {\n case null:\n case 'svg':\n case 'xml':\n return 'html';\n case 'css':\n return 'css';\n case 'js':\n case 'mjs':\n case 'json':\n case 'map':\n case 'webmanifest':\n return 'javascript';\n default:\n return 'text';\n }\n}\n\nconst LAYOUT_SKELETON = `<!DOCTYPE html>\n<html lang=\"{{ culture }}\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>{{ head?.meta_title ?? page.display_name }}</title>\n {{ site_head }}\n</head>\n<body>\n{{ body }}\n</body>\n</html>\n`;\n\nconst PAGE_SKELETON = `<h1>{{ page.display_name }}</h1>\n{{ if content }}\n {{ for field in field_list }}\n <section>\n <h2>{{ field.display_name }}</h2>\n {{ render_field field.name }}\n </section>\n {{ end }}\n{{ else }}\n {{ list = contents { max: 20 } }}\n <ul>\n {{ for item in list.items }}\n <li><a href=\"{{ item.url }}\">{{ item.slug }}</a></li>\n {{ end }}\n </ul>\n{{ end }}\n`;\n\nconst PARTIAL_SKELETON = `<div>\n {{ page.display_name }}\n</div>\n`;\n\n/**\n * What a new file starts with, guessed from the suggested conventions only - it is a starting point, not a type: a\n * static file starts empty, a file under `layouts/` as a layout, a name starting with `_` as a partial, anything else\n * as a page template.\n */\nexport function skeletonFor(path: string): string {\n const normalized = normalizeThemePath(path);\n const name = normalized.slice(normalized.lastIndexOf('/') + 1);\n\n if (isAssetPath(normalized)) {\n return '';\n }\n\n if (normalized.startsWith('layouts/')) {\n return LAYOUT_SKELETON;\n }\n\n return name.startsWith('_') ? PARTIAL_SKELETON : PAGE_SKELETON;\n}\n\n/** A folder or a file of the tree on the left. */\nexport interface ThemeTreeNode {\n /** The folder's path (`blog`, `blog/archive`) or the file's. */\n path: string;\n /** The last segment. */\n name: string;\n isFolder: boolean;\n isAsset: boolean;\n status: SiteThemeFileStatus;\n children: ThemeTreeNode[];\n /** For a folder: whether something under it differs from the live release. */\n hasChanges: boolean;\n}\n\n/**\n * The working copy's files as a tree: folders first, then files, each by name, ordinally. A folder exists only because\n * a file is in it - the theme has no empty folders.\n */\nexport function buildThemeTree(files: SiteThemeFileSummaryDto[]): ThemeTreeNode[] {\n const root: ThemeTreeNode = {\n path: '', name: '', isFolder: true, isAsset: false, status: SiteThemeFileStatus.Unchanged, children: [], hasChanges: false,\n };\n\n for (const file of files) {\n const segments = (file.path ?? '').split('/');\n let folder = root;\n\n segments.slice(0, -1).forEach((segment, index) => {\n const path = segments.slice(0, index + 1).join('/');\n let child = folder.children.find(node => node.isFolder && node.path === path);\n if (!child) {\n child = {\n path, name: segment, isFolder: true, isAsset: false, status: SiteThemeFileStatus.Unchanged, children: [], hasChanges: false,\n };\n folder.children.push(child);\n }\n\n folder = child;\n });\n\n folder.children.push({\n path: file.path ?? '',\n name: segments[segments.length - 1],\n isFolder: false,\n isAsset: file.isAsset,\n status: file.status,\n children: [],\n hasChanges: file.status !== SiteThemeFileStatus.Unchanged,\n });\n }\n\n sortAndMark(root);\n return root.children;\n}\n\nfunction sortAndMark(folder: ThemeTreeNode): boolean {\n folder.children.sort((a, b) =>\n a.isFolder !== b.isFolder ? (a.isFolder ? -1 : 1) : a.name < b.name ? -1 : a.name > b.name ? 1 : 0);\n\n let changed = false;\n for (const child of folder.children) {\n if (child.isFolder) {\n child.hasChanges = sortAndMark(child);\n }\n\n changed ||= child.hasChanges;\n }\n\n return changed;\n}\n\n/** Every folder on the way to `path`, outermost first: `blog`, `blog/archive` for `blog/archive/post`. */\nexport function foldersOf(path: string): string[] {\n const segments = path.split('/');\n return segments.slice(0, -1).map((_, index) => segments.slice(0, index + 1).join('/'));\n}\n\n/** The part of an HTTP error response the workbench reads: ABP's `{ error: { code, message, details } }` body. */\nexport interface ApiErrorResponse {\n status?: number;\n message?: string;\n error?: {\n error?: {\n code?: string;\n message?: string;\n details?: string;\n validationErrors?: { message?: string }[];\n };\n };\n}\n\n/** The message of an ABP error response, with its validation details. */\nexport function errorMessageOf(response: ApiErrorResponse | undefined): string {\n const error = response?.error?.error;\n const details = (error?.validationErrors ?? []).map(entry => entry.message).filter(Boolean);\n\n return [error?.message ?? response?.message, ...details].filter(Boolean).join('\\n');\n}\n\n/** The theme path a page's `Template` renders through - the site's resolution: a trailing `.cshtml` is dropped. */\nexport function pageTemplatePath(template: string): string {\n const name = (template ?? '').trim();\n return normalizeThemePath(name.toLowerCase().endsWith('.cshtml') ? name.slice(0, -'.cshtml'.length) : name);\n}\n\n/** The field type of a page's SEO block: edited in its own panel and written by `site_head`, never by hand. */\nconst SEO_FIELD_TYPE = 'Seo';\n\n/** A field name Scriban can read as a member (`content.fields.title`); anything else needs the indexer form. */\nconst SCRIBAN_MEMBER_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * The Scriban that prints a field of the current content. Plain values are read straight off `content.fields`; a date\n * is formatted; everything composite or rich (editor text, matrix, table, a linked content, files) goes through\n * `render_field`, which knows how to draw it. A name that is not a plain identifier (it may hold a hyphen) is read with\n * the indexer, the only form Scriban parses for it.\n */\nexport function snippetFor(fieldTypeName: string, name: string): string {\n const member = SCRIBAN_MEMBER_NAME.test(name) ? `content.fields.${name}` : `content.fields[\"${name}\"]`;\n\n switch (fieldTypeName) {\n case 'Text':\n case 'Number':\n case 'Boolean':\n case 'Select':\n case 'Tree':\n return `{{ ${member} }}`;\n case 'DateTime':\n return `{{ ${member} | date.to_string \"%Y-%m-%d\" }}`;\n default:\n return `{{ render_field \"${name}\" }}`;\n }\n}\n\n/** One field in the sidebar: what the author sees and the snippet a click inserts. */\nexport interface ThemeField {\n name: string;\n displayName: string;\n fieldTypeName: string;\n snippet: string;\n}\n\n/** The fields of one content type of a page, in the order the content type arranges them. */\nexport interface ThemeFieldGroup {\n id: string;\n displayName: string;\n fields: ThemeField[];\n}\n\n/**\n * One group per content type of `page`, its fields in arrangement order, named as the content type names them, without\n * the SEO block; a content type left with no field is left out. Empty until both the page and the field library are\n * there.\n */\nexport function fieldGroupsFor(page: PageDto | undefined, library: FieldDto[] | undefined): ThemeFieldGroup[] {\n if (!page || !library) {\n return [];\n }\n\n const fieldsById = new Map(library.map(field => [field.id, field] as const));\n\n return (page.contentTypes ?? [])\n .map(contentType => ({\n id: contentType.id ?? contentType.name ?? '',\n displayName: contentType.displayName || contentType.name || '',\n fields: [...(contentType.fields ?? [])]\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n .flatMap(arranged => {\n const field = fieldsById.get(arranged.fieldId ?? '');\n if (!field?.name || field.fieldTypeName === SEO_FIELD_TYPE) {\n return [];\n }\n\n const fieldTypeName = field.fieldTypeName ?? '';\n return [\n {\n name: field.name,\n displayName: arranged.displayName || field.displayName || field.name,\n fieldTypeName,\n snippet: snippetFor(fieldTypeName, field.name),\n },\n ];\n }),\n }))\n .filter(group => group.fields.length > 0);\n}\n","import { CoreModule, LocalizationService, PermissionService } from '@abp/ng.core';\nimport { Confirmation, ConfirmationService, ThemeSharedModule, ToasterService } from '@abp/ng.theme.shared';\nimport {\n ChangeDetectionStrategy,\n Component,\n HostListener,\n OnInit,\n computed,\n effect,\n inject,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { forkJoin } from 'rxjs';\nimport type { PageDto } from '../../proxy/dignite/site/pages/models';\nimport { FieldAdminService } from '../../proxy/dignite/site/admin/fields/field-admin.service';\nimport { PageAdminService } from '../../proxy/dignite/site/admin/pages/page-admin.service';\nimport type { FieldDto } from '../../proxy/dignite/site/fields/models';\nimport { SiteThemeAdminService } from '../../proxy/dignite/site/admin/themes/site-theme-admin.service';\nimport { SiteThemeTransferAdminService } from '../../proxy/dignite/site/admin/themes/site-theme-transfer-admin.service';\nimport type {\n SiteReleaseDto,\n SiteThemeCheckDto,\n SiteThemeDto,\n SiteThemeFileDto,\n SiteThemeFileSummaryDto,\n SiteThemeFileUsagesDto,\n SiteThemeImportResultDto,\n SiteThemeIssueDto,\n SiteThemeSyntaxErrorDto,\n} from '../../proxy/dignite/site/admin/themes/models';\nimport { SiteThemeUsageKindDto } from '../../proxy/dignite/site/admin/themes/site-theme-usage-kind-dto.enum';\nimport { SiteThemeFileStatus } from '../../proxy/dignite/site/themes/site-theme-file-status.enum';\nimport { SiteThemeIssueSeverity } from '../../proxy/dignite/site/themes/site-theme-issue-severity.enum';\nimport { eSitePolicyNames } from '../../enums/policy-names';\nimport { CodeEditorComponent } from './code-editor.component';\nimport {\n ApiErrorResponse,\n ThemeTreeNode,\n buildThemeTree,\n ThemeField,\n errorMessageOf,\n fieldGroupsFor,\n foldersOf,\n isAssetPath,\n languageOf,\n normalizeThemePath,\n pageTemplatePath,\n skeletonFor,\n themePathProblem,\n} from './theme-workbench.helpers';\n\n/** `Site:090003`: the working copy changed since the check the publish was based on. */\nconst CHANGED_SINCE_CHECK = 'Site:090003';\n\n/**\n * A file open in a tab: what the editor shows, and what was last saved, to tell whether it has unsaved changes.\n * A file only looked at is not `pinned`: opening another file replaces its tab. One that was edited, or created, is,\n * and stays until it is closed.\n */\nexport interface ThemeOpenFile {\n path: string;\n isAsset: boolean;\n body: string;\n savedBody: string;\n pinned: boolean;\n concurrencyStamp?: string;\n syntaxErrors: SiteThemeSyntaxErrorDto[];\n}\n\n/** A page the template in front renders. */\nexport interface ThemeTemplatePage {\n id: string;\n name: string;\n}\n\n/** A row of the tree as the template renders it: a node and how deep it is. */\ninterface ThemeTreeRow {\n node: ThemeTreeNode;\n depth: number;\n}\n\n/**\n * The theme workbench: the working copy's files in a tree on the left, open files in an editor in the middle, the\n * check on the right, and publishing, the release history and the theme's settings above.\n *\n * Saving writes one file of the working copy in place and changes nothing on the site; publishing freezes the whole\n * working copy into a release and makes it live. See the Scriban Templates page of the documentation for the model.\n *\n * Deliberately no `<form (ngSubmit)>` around the editor: ABP's `FormSubmitDirective` (pulled in by `CoreModule`)\n * submits a form on every Enter keyup that does not come from a `<textarea>`, and CodeMirror is a contenteditable.\n */\n@Component({\n selector: 'site-theme-workbench',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './theme-workbench.component.html',\n imports: [CoreModule, ThemeSharedModule, FormsModule, CodeEditorComponent],\n // The three columns are sized to the viewport, so that the page itself does not scroll: the editor keeps one\n // height whichever file is open, and the tree and the findings scroll inside their columns. The rem offsets are\n // what the LeptonX layout, the header card and the column headers take above and below them.\n styles: `\n :host {\n --site-code-editor-height: max(24rem, calc(100vh - 25rem));\n --site-code-editor-max-height: none;\n }\n\n .theme-tree {\n max-height: max(20rem, calc(100vh - 21rem));\n overflow-y: auto;\n }\n\n .theme-tree-row {\n display: flex;\n align-items: center;\n width: 100%;\n padding-right: 0.25rem;\n border-radius: var(--bs-border-radius-sm, 0.25rem);\n }\n\n .theme-tree-main {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n flex: 1 1 auto;\n min-width: 0;\n border: none;\n background: transparent;\n text-align: start;\n padding: 0.15rem 0;\n color: inherit;\n white-space: nowrap;\n }\n\n .theme-tree-row:hover {\n background-color: rgba(128, 128, 128, 0.12);\n }\n\n /* The \"more\" button shows on the row that is pointed at, focused or has its menu open - and always on a touch screen. */\n .theme-tree-more {\n flex: 0 0 auto;\n border: none;\n background: transparent;\n color: inherit;\n padding: 0.1rem 0.4rem;\n opacity: 0;\n }\n\n .theme-tree-row:hover .theme-tree-more,\n .theme-tree-row:focus-within .theme-tree-more,\n .theme-tree-more.open {\n opacity: 1;\n }\n\n @media (hover: none) {\n .theme-tree-more {\n opacity: 1;\n }\n }\n\n .theme-tree-row.active {\n background-color: rgba(var(--bs-primary-rgb, 13, 110, 253), 0.15);\n }\n\n .theme-tree-row .name {\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1 1 auto;\n }\n\n .theme-tree-row.deleted .name {\n text-decoration: line-through;\n opacity: 0.6;\n }\n\n .theme-tab {\n white-space: nowrap;\n }\n\n .theme-field-snippet {\n white-space: pre-wrap;\n word-break: break-all;\n }\n\n .theme-tabs {\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .theme-issues {\n max-height: max(20rem, calc(100vh - 17rem));\n overflow-y: auto;\n }\n\n /* The fields scroll inside their own box, so that the check below them stays in reach. */\n .theme-fields {\n max-height: max(10rem, 38vh);\n overflow-y: auto;\n }\n `,\n})\nexport class ThemeWorkbenchComponent implements OnInit {\n private readonly themeService = inject(SiteThemeAdminService);\n private readonly transferService = inject(SiteThemeTransferAdminService);\n private readonly pageService = inject(PageAdminService);\n private readonly fieldService = inject(FieldAdminService);\n private readonly permission = inject(PermissionService);\n private readonly confirmation = inject(ConfirmationService);\n private readonly toaster = inject(ToasterService);\n private readonly localization = inject(LocalizationService);\n\n readonly statuses = SiteThemeFileStatus;\n readonly severities = SiteThemeIssueSeverity;\n\n readonly canExport = this.permission.getGrantedPolicy(eSitePolicyNames.Themes);\n readonly canEdit = this.permission.getGrantedPolicy(eSitePolicyNames.ThemesEdit);\n readonly canPublish = this.permission.getGrantedPolicy(eSitePolicyNames.ThemesPublish);\n\n private readonly editor = viewChild(CodeEditorComponent);\n\n // State that changes in an HTTP callback is a signal, not a plain field: the host layout's ancestors are OnPush,\n // and a plain-field write in a response callback never marks them for check.\n readonly isLoading = signal(true);\n readonly isBusy = signal(false);\n readonly theme = signal<SiteThemeDto | undefined>(undefined);\n readonly files = signal<SiteThemeFileSummaryDto[]>([]);\n readonly collapsed = signal<ReadonlySet<string>>(new Set());\n readonly openFiles = signal<ThemeOpenFile[]>([]);\n readonly activePath = signal<string | undefined>(undefined);\n readonly check = signal<SiteThemeCheckDto | undefined>(undefined);\n readonly isChecking = signal(false);\n\n readonly tree = computed(() => buildThemeTree(this.files()));\n\n /** The tree flattened into the rows the template shows, folders that are collapsed left closed. */\n readonly treeRows = computed(() => {\n const rows: ThemeTreeRow[] = [];\n const collapsed = this.collapsed();\n\n const walk = (nodes: ThemeTreeNode[], depth: number) => {\n for (const node of nodes) {\n rows.push({ node, depth });\n if (node.isFolder && !collapsed.has(node.path)) {\n walk(node.children, depth + 1);\n }\n }\n };\n\n walk(this.tree(), 0);\n return rows;\n });\n\n readonly activeFile = computed(() => this.openFiles().find(file => file.path === this.activePath()));\n\n /** Whether the file in front can be the default layout: the last check lists it among the layouts. */\n readonly isLayoutInFront = computed(() => {\n const path = this.activePath();\n return !!path && (this.check()?.layouts ?? []).includes(path);\n });\n\n /** Whether the file in front already is the default layout. */\n readonly isDefaultLayoutInFront = computed(() => {\n const path = this.activePath();\n return !!path && path === this.theme()?.defaultLayout;\n });\n\n readonly hasUnsavedFiles = computed(() => this.openFiles().some(file => isDirty(file)));\n\n readonly errorCount = computed(() => this.issuesOf(SiteThemeIssueSeverity.Error).length);\n readonly warningCount = computed(() => this.issuesOf(SiteThemeIssueSeverity.Warning).length);\n\n // Dialogs.\n readonly isNewFileOpen = signal(false);\n readonly newFilePath = signal('');\n readonly newFileError = signal<string | null>(null);\n\n readonly isRenameOpen = signal(false);\n readonly renameFrom = signal('');\n readonly renameTo = signal('');\n readonly renameUpdatesReferences = signal(true);\n readonly renameError = signal<string | null>(null);\n\n readonly isPublishOpen = signal(false);\n readonly publishCheck = signal<SiteThemeCheckDto | undefined>(undefined);\n readonly publishComment = signal('');\n readonly publishError = signal<string | null>(null);\n\n readonly isImportOpen = signal(false);\n readonly importFile = signal<File | null>(null);\n /** Merge (false) or replace (true): whether the working copy loses the files the package does not have. */\n readonly importReplace = signal(false);\n readonly importResult = signal<SiteThemeImportResultDto | undefined>(undefined);\n\n readonly isReleasesOpen = signal(false);\n readonly releases = signal<SiteReleaseDto[]>([]);\n\n /** The \"more\" menu of a file in the tree: the file, and where it opens (fixed, so the tree's scrolling does not clip it). */\n readonly rowMenu = signal<{ path: string; top: number; right: number } | null>(null);\n\n /** The site's pages, to find those the template in front renders; empty without the Pages permission. */\n readonly pages = signal<PageDto[]>([]);\n\n /** The active pages whose template is the file in front. */\n readonly templatePages = computed<ThemeTemplatePage[]>(() => {\n const path = this.activePath();\n if (!path || isAssetPath(path)) {\n return [];\n }\n\n return this.pages()\n .filter(page => page.isActive && pageTemplatePath(page.template) === path)\n .map(page => ({ id: page.id ?? '', name: page.displayName || page.name }));\n });\n\n // The field sidebar.\n\n /** The page the author picked to list the fields of; the first page of the template in front otherwise. */\n readonly chosenFieldsPageId = signal<string | undefined>(undefined);\n /** Pages read in full, with their content types, by id; null for one that could not be read. */\n private readonly pageDetails = signal<ReadonlyMap<string, PageDto | null>>(new Map());\n /** The field library, read once; undefined until then, empty when it could not be read (no Fields permission). */\n private readonly fieldLibrary = signal<FieldDto[] | undefined>(undefined);\n private fieldLibraryRequested = false;\n private readonly requestedPageIds = new Set<string>();\n\n /** Whether the fields show: the file in front is the template of a page. The check shows whatever the file. */\n readonly showsFields = computed(() => this.templatePages().length > 0);\n\n readonly fieldsPageId = computed(() => {\n const ids = this.templatePages().map(page => page.id);\n const chosen = this.chosenFieldsPageId();\n return chosen && ids.includes(chosen) ? chosen : ids[0];\n });\n\n readonly fieldGroups = computed(() => {\n const id = this.fieldsPageId();\n return fieldGroupsFor((id && this.pageDetails().get(id)) || undefined, this.fieldLibrary());\n });\n\n readonly isLoadingFields = computed(() => {\n const id = this.fieldsPageId();\n return this.fieldLibrary() === undefined || (!!id && !this.pageDetails().has(id));\n });\n\n constructor() {\n // Reads what the sidebar lists when it is shown: the library once, each page once.\n effect(() => {\n if (!this.showsFields()) {\n return;\n }\n\n const id = this.fieldsPageId();\n untracked(() => {\n this.ensureFieldLibrary();\n if (id) {\n this.ensurePageDetail(id);\n }\n });\n });\n }\n\n ngOnInit(): void {\n forkJoin([this.themeService.get(), this.themeService.getFiles()]).subscribe({\n next: ([theme, files]) => {\n this.theme.set(theme);\n this.files.set(files.items ?? []);\n this.isLoading.set(false);\n this.runCheck();\n },\n error: () => this.isLoading.set(false),\n });\n\n if (this.permission.getGrantedPolicy(eSitePolicyNames.Pages)) {\n this.pageService.getList({}).subscribe(result => this.pages.set(result.items ?? []));\n }\n }\n\n /** Inserts a field's snippet into the file in front, at the cursor. */\n insertField(field: ThemeField): void {\n this.editor()?.insert(field.snippet);\n }\n\n private ensureFieldLibrary(): void {\n if (this.fieldLibraryRequested) {\n return;\n }\n\n this.fieldLibraryRequested = true;\n // skipHandleError: without the Fields permission the sidebar says it has nothing to list; no toast.\n this.fieldService.getList({}, { skipHandleError: true }).subscribe({\n next: result => this.fieldLibrary.set(result.items ?? []),\n error: () => this.fieldLibrary.set([]),\n });\n }\n\n private ensurePageDetail(id: string): void {\n if (this.requestedPageIds.has(id)) {\n return;\n }\n\n this.requestedPageIds.add(id);\n this.pageService.get(id, { skipHandleError: true }).subscribe({\n next: page => this.pageDetails.update(details => new Map(details).set(id, page)),\n error: () => this.pageDetails.update(details => new Map(details).set(id, null)),\n });\n }\n\n /** Opens the \"more\" menu of a file under its button, or closes it when it is already open for that file. */\n toggleRowMenu(event: MouseEvent, path: string): void {\n // Not on to the document listener below, which would close the menu at once.\n event.stopPropagation();\n if (this.rowMenu()?.path === path) {\n this.rowMenu.set(null);\n return;\n }\n\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\n this.rowMenu.set({ path, top: rect.bottom, right: window.innerWidth - rect.right });\n }\n\n /** Closes the \"more\" menu on a click anywhere, on Escape, and when the tree scrolls from under it. */\n @HostListener('document:click')\n @HostListener('document:keydown.escape')\n closeRowMenu(): void {\n if (this.rowMenu()) {\n this.rowMenu.set(null);\n }\n }\n\n renameFromMenu(): void {\n const path = this.rowMenu()?.path;\n this.rowMenu.set(null);\n if (path) {\n this.openRename(path);\n }\n }\n\n deleteFromMenu(): void {\n const path = this.rowMenu()?.path;\n this.rowMenu.set(null);\n if (path) {\n this.deleteFile(path);\n }\n }\n\n /** Asks before leaving the page while a file has unsaved changes. */\n @HostListener('window:beforeunload', ['$event'])\n onBeforeUnload(event: BeforeUnloadEvent): void {\n if (this.hasUnsavedFiles()) {\n event.preventDefault();\n }\n }\n\n /** Ctrl+S / Cmd+S saves the file in front, instead of the browser's \"save page\". */\n onEditorKeydown(event: KeyboardEvent): void {\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') {\n event.preventDefault();\n this.save();\n }\n }\n\n isDirty(file: ThemeOpenFile): boolean {\n return isDirty(file);\n }\n\n statusKey(status: SiteThemeFileStatus): string | null {\n switch (status) {\n case SiteThemeFileStatus.Modified:\n return 'Site::ThemeFileStatus:Modified';\n case SiteThemeFileStatus.Added:\n return 'Site::ThemeFileStatus:Added';\n case SiteThemeFileStatus.Deleted:\n return 'Site::ThemeFileStatus:Deleted';\n default:\n return null;\n }\n }\n\n /** Whether the working copy's default layout is not the one the live release froze. */\n defaultLayoutChanged(check: SiteThemeCheckDto | undefined): boolean {\n return !!check?.liveReleaseNumber && (check.defaultLayout ?? '') !== (check.liveDefaultLayout ?? '');\n }\n\n issuesOf(severity: SiteThemeIssueSeverity): SiteThemeIssueDto[] {\n return (this.check()?.issues ?? []).filter(issue => issue.severity === severity);\n }\n\n toggleFolder(path: string): void {\n const next = new Set(this.collapsed());\n if (next.has(path)) {\n next.delete(path);\n } else {\n next.add(path);\n }\n\n this.collapsed.set(next);\n }\n\n select(node: ThemeTreeNode): void {\n if (node.isFolder) {\n this.toggleFolder(node.path);\n } else if (node.status !== SiteThemeFileStatus.Deleted) {\n this.openFile(node.path);\n }\n }\n\n openFile(path: string, then?: () => void): void {\n this.expandTo(path);\n\n if (this.openFiles().some(file => file.path === path)) {\n this.activePath.set(path);\n then?.();\n return;\n }\n\n this.themeService.getFile(path).subscribe(file => {\n // The tabs of files that were only looked at give way to this one.\n this.openFiles.update(files => [...files.filter(f => f.pinned || isDirty(f)), toOpenFile(file)]);\n this.activePath.set(file.path);\n // After the editor has taken the new document.\n setTimeout(() => then?.());\n });\n }\n\n closeFile(path: string): void {\n const file = this.openFiles().find(f => f.path === path);\n if (!file) {\n return;\n }\n\n const close = () => {\n const files = this.openFiles();\n const index = files.findIndex(f => f.path === path);\n const remaining = files.filter(f => f.path !== path);\n this.openFiles.set(remaining);\n\n if (this.activePath() === path) {\n this.activePath.set(remaining[Math.min(index, remaining.length - 1)]?.path);\n }\n };\n\n if (!isDirty(file)) {\n close();\n return;\n }\n\n this.confirmation\n .warn('Site::CloseUnsavedConfirm', 'AbpUi::AreYouSure', { messageLocalizationParams: [path] })\n .subscribe(status => {\n if (status === Confirmation.Status.confirm) {\n close();\n }\n });\n }\n\n onEdit(body: string): void {\n const path = this.activePath();\n this.openFiles.update(files =>\n files.map(file => (file.path === path ? { ...file, body, pinned: file.pinned || body !== file.savedBody } : file)));\n }\n\n save(overwrite = false): void {\n const file = this.activeFile();\n if (!file || !this.canEdit || this.isBusy()) {\n return;\n }\n\n this.isBusy.set(true);\n this.themeService\n .saveFile(\n { path: file.path, body: file.body, concurrencyStamp: overwrite ? undefined : file.concurrencyStamp },\n { skipHandleError: true },\n )\n .subscribe({\n next: saved => {\n this.isBusy.set(false);\n this.replaceOpenFile(file.path, {\n ...toOpenFile(saved),\n body: this.bodyOf(file.path) ?? saved.body ?? '',\n pinned: true,\n });\n this.toaster.success('Site::ThemeFileSaved');\n this.refreshFiles();\n this.runCheck();\n },\n error: (response: ApiErrorResponse) => {\n this.isBusy.set(false);\n if (response.status === 409) {\n this.resolveConflict(file.path);\n return;\n }\n\n this.toaster.error(errorMessageOf(response) || 'AbpUi::DefaultErrorMessage');\n },\n });\n }\n\n /** Someone saved the file after it was opened: overwrite their version with this one, or load theirs. */\n private resolveConflict(path: string): void {\n this.confirmation\n .warn('Site::SaveConflictConfirm', 'AbpUi::AreYouSure', {\n messageLocalizationParams: [path],\n yesText: 'Site::Overwrite',\n cancelText: 'Site::ReloadFile',\n })\n .subscribe(status => {\n // Closing the dialog (Esc, the close button) decides neither: the edits stay, unsaved.\n if (status === Confirmation.Status.confirm) {\n this.save(true);\n } else if (status === Confirmation.Status.reject) {\n this.reloadFile(path);\n }\n });\n }\n\n private reloadFile(path: string): void {\n this.themeService.getFile(path).subscribe(file => {\n this.replaceOpenFile(path, toOpenFile(file));\n this.toaster.info('Site::ThemeFileReloaded', undefined, { messageLocalizationParams: [path] });\n });\n }\n\n goToIssue(issue: SiteThemeIssueDto): void {\n if (!issue.path) {\n return;\n }\n\n const line = issue.line;\n const column = issue.column ?? 1;\n this.openFile(issue.path, () => {\n if (line) {\n this.editor()?.goTo(line, column);\n }\n });\n }\n\n goToSyntaxError(error: SiteThemeSyntaxErrorDto): void {\n this.editor()?.goTo(error.line, error.column);\n }\n\n /** The number of the check asked for last: only its answer counts, so an older one arriving late cannot overwrite it. */\n private checkSequence = 0;\n /** Callbacks waiting for the answer of the check asked for last, including those of checks it took over from. */\n private pendingAfter: ((check: SiteThemeCheckDto) => void)[] = [];\n\n /**\n * Asks for the check of the working copy as it is saved now. Checks run after every change, so one can be asked for\n * while another is still on its way; only the last one counts - the working copy it read is the newest. `after`\n * runs with that answer, also when a later check took this one's place.\n */\n runCheck(after?: (check: SiteThemeCheckDto) => void): void {\n const sequence = ++this.checkSequence;\n if (after) {\n this.pendingAfter.push(after);\n }\n\n this.isChecking.set(true);\n this.themeService.check().subscribe({\n next: check => {\n if (sequence !== this.checkSequence) {\n return;\n }\n\n this.check.set(check);\n this.isChecking.set(false);\n const callbacks = this.pendingAfter;\n this.pendingAfter = [];\n callbacks.forEach(callback => callback(check));\n },\n error: () => {\n if (sequence === this.checkSequence) {\n this.isChecking.set(false);\n this.pendingAfter = [];\n }\n },\n });\n }\n\n // New file.\n\n openNewFile(folder?: string): void {\n this.newFilePath.set(folder ? folder + '/' : '');\n this.newFileError.set(null);\n this.isNewFileOpen.set(true);\n }\n\n createFile(): void {\n const path = normalizeThemePath(this.newFilePath());\n const problem = themePathProblem(path);\n if (problem) {\n this.newFileError.set(this.localization.instant(problem));\n return;\n }\n\n if (this.files().some(file => file.path === path && file.status !== SiteThemeFileStatus.Deleted)) {\n this.newFileError.set(this.localization.instant('Site::ThemeFileExists', path));\n return;\n }\n\n this.isBusy.set(true);\n this.themeService.saveFile({ path, body: skeletonFor(path) }, { skipHandleError: true }).subscribe({\n next: saved => {\n this.isBusy.set(false);\n this.isNewFileOpen.set(false);\n this.refreshFiles();\n this.runCheck();\n this.openFiles.update(files => [...files.filter(f => f.path !== saved.path), { ...toOpenFile(saved), pinned: true }]);\n this.activePath.set(saved.path);\n this.expandTo(saved.path ?? '');\n },\n error: (response: ApiErrorResponse) => {\n this.isBusy.set(false);\n this.newFileError.set(errorMessageOf(response));\n },\n });\n }\n\n // Rename.\n\n openRename(path: string): void {\n this.renameFrom.set(path);\n this.renameTo.set(path);\n this.renameUpdatesReferences.set(true);\n this.renameError.set(null);\n this.isRenameOpen.set(true);\n }\n\n rename(): void {\n const from = this.renameFrom();\n const to = normalizeThemePath(this.renameTo());\n const problem = themePathProblem(to);\n if (problem) {\n this.renameError.set(this.localization.instant(problem));\n return;\n }\n\n if (this.openFiles().some(file => isDirty(file) && file.path === from)) {\n this.renameError.set(this.localization.instant('Site::SaveBeforeRename'));\n return;\n }\n\n this.isBusy.set(true);\n this.themeService\n .renameFile({ path: from, newPath: to, updateReferences: this.renameUpdatesReferences() }, { skipHandleError: true })\n .subscribe({\n next: result => {\n this.isBusy.set(false);\n this.isRenameOpen.set(false);\n\n // The renamed file keeps its tab, under its new path; files whose references were rewritten are reloaded\n // when they have no unsaved changes of their own.\n this.openFiles.update(files =>\n files.map(file => (file.path === from ? { ...toOpenFile(result.file), pinned: file.pinned } : file)));\n if (this.activePath() === from) {\n this.activePath.set(result.file.path);\n }\n\n for (const path of result.updatedPaths ?? []) {\n const open = this.openFiles().find(file => file.path === path);\n if (open && !isDirty(open) && path !== result.file.path) {\n this.reloadFile(path);\n }\n }\n\n this.toaster.success('Site::ThemeFileRenamed', undefined, {\n messageLocalizationParams: [String(result.updatedPaths?.length ?? 0)],\n });\n if (result.pagesStillUsingOldPath?.length) {\n this.toaster.warn('Site::RenamePagesStillUsing', undefined, {\n messageLocalizationParams: [result.pagesStillUsingOldPath.join(', ')],\n });\n }\n\n this.refreshTheme();\n this.refreshFiles();\n this.runCheck();\n },\n error: (response: ApiErrorResponse) => {\n this.isBusy.set(false);\n this.renameError.set(errorMessageOf(response));\n },\n });\n }\n\n // Delete.\n\n deleteFile(path: string): void {\n this.themeService.getFileUsages(path).subscribe(usages => {\n const users = describeUsages(usages, kind => this.localization.instant('Site::ThemeUsage:' + SiteThemeUsageKindDto[kind]));\n const confirm$ = users\n ? this.confirmation.warn('Site::DeleteThemeFileUsedConfirm', 'AbpUi::AreYouSure', {\n messageLocalizationParams: [path, users],\n })\n : this.confirmation.warn('Site::DeleteThemeFileConfirm', 'AbpUi::AreYouSure', {\n messageLocalizationParams: [path],\n });\n\n confirm$.subscribe(status => {\n if (status !== Confirmation.Status.confirm) {\n return;\n }\n\n this.themeService.deleteFile(path).subscribe(() => {\n this.openFiles.update(files => files.filter(file => file.path !== path));\n if (this.activePath() === path) {\n this.activePath.set(this.openFiles()[0]?.path);\n }\n\n this.toaster.success('AbpUi::DeletedSuccessfully');\n this.refreshFiles();\n this.runCheck();\n });\n });\n });\n }\n\n // Preview.\n\n /**\n * Opens the site's home page in a new tab with the working copy as saved, or with a release, for this browser only;\n * the author follows the site's links from there. The tab is opened inside the click, so the browser lets it\n * through, and pointed at the signed link once it arrives; it gets no handle on this page, since the theme's scripts\n * run in it.\n */\n openPreview(releaseId?: string): void {\n const tab = window.open('', '_blank');\n if (!tab) {\n this.toaster.warn('Site::PreviewPopupBlocked');\n return;\n }\n\n tab.opener = null;\n if (!releaseId && this.hasUnsavedFiles()) {\n this.toaster.info('Site::PreviewUnsavedNotShown');\n }\n\n this.themeService.getPreviewLink(undefined, releaseId).subscribe({\n next: link => tab.location.replace(link.url!),\n // The error itself is shown by the default handler.\n error: () => tab.close(),\n });\n }\n\n // Publish.\n\n openPublish(): void {\n this.publishComment.set('');\n this.publishError.set(null);\n this.publishCheck.set(undefined);\n this.isPublishOpen.set(true);\n this.runCheck(check => this.publishCheck.set(check));\n }\n\n /** Enter in the comment publishes, unless it only confirms a word in an input method (Chinese, Japanese). */\n publishOnEnter(event: Event): void {\n if (!(event as KeyboardEvent).isComposing) {\n this.publish();\n }\n }\n\n publish(): void {\n const check = this.publishCheck();\n if (!check?.fingerprint || check.hasErrors || !check.hasChanges || this.isBusy()) {\n return;\n }\n\n this.isBusy.set(true);\n this.themeService\n .publish({ fingerprint: check.fingerprint, comment: this.publishComment() || undefined }, { skipHandleError: true })\n .subscribe({\n next: release => {\n this.isBusy.set(false);\n this.isPublishOpen.set(false);\n this.toaster.success('Site::ThemePublished', undefined, { messageLocalizationParams: [String(release.number)] });\n this.refreshTheme();\n this.refreshFiles();\n this.runCheck();\n },\n error: (response: ApiErrorResponse) => {\n this.isBusy.set(false);\n this.publishError.set(errorMessageOf(response));\n if (response.error?.error?.code === CHANGED_SINCE_CHECK) {\n // Show what is there now; the author publishes again from the fresh check.\n this.runCheck(fresh => this.publishCheck.set(fresh));\n }\n },\n });\n }\n\n // Export and import.\n\n /** Downloads the working copy as a zip package, or a release's when one is given. */\n exportTheme(release?: SiteReleaseDto): void {\n if (release && !release.id) {\n return;\n }\n\n // Named here as the server names it: a Content-Disposition header is not readable across origins.\n this.transferService.export(release?.id).subscribe(blob =>\n downloadBlob(blob, release ? `theme-release-${release.number}.zip` : 'theme-working-copy.zip'),\n );\n }\n\n openImport(): void {\n this.importFile.set(null);\n this.importReplace.set(false);\n this.importResult.set(undefined);\n this.isImportOpen.set(true);\n }\n\n onImportFileChange(event: Event): void {\n this.importFile.set((event.target as HTMLInputElement).files?.[0] ?? null);\n this.importResult.set(undefined);\n }\n\n /**\n * Writes the package into the working copy; nothing goes live. A package with any invalid entry is refused whole,\n * and ABP's error handler shows the problems. The result stays in the dialog, as the author reads what changed.\n */\n importTheme(): void {\n const file = this.importFile();\n if (!file || !this.canEdit || this.isBusy()) {\n return;\n }\n\n const body = new FormData();\n body.append('File', file, file.name);\n body.append('Replace', String(this.importReplace()));\n\n this.isBusy.set(true);\n this.transferService.import(body).subscribe({\n next: result => {\n this.isBusy.set(false);\n this.importResult.set(result);\n\n // Tabs of files the package touched would show what is no longer there; those with unsaved edits stay.\n const touched = new Set([...result.added, ...result.modified, ...result.deleted]);\n this.openFiles.update(files => files.filter(open => !touched.has(open.path) || isDirty(open)));\n if (!this.openFiles().some(open => open.path === this.activePath())) {\n this.activePath.set(this.openFiles()[0]?.path);\n }\n\n this.refreshTheme();\n this.refreshFiles();\n this.runCheck();\n },\n error: () => this.isBusy.set(false),\n });\n }\n\n /** The files with syntax errors in an import result, with their errors; empty when there are none. */\n syntaxErrorsOf(result: SiteThemeImportResultDto): { path: string; errors: SiteThemeSyntaxErrorDto[] }[] {\n return Object.entries(result.syntaxErrors ?? {})\n .filter(([, errors]) => errors.length > 0)\n .map(([path, errors]) => ({ path, errors }));\n }\n\n // Releases.\n\n openReleases(): void {\n this.isReleasesOpen.set(true);\n this.loadReleases();\n }\n\n private loadReleases(): void {\n this.themeService.getReleases().subscribe(result => this.releases.set(result.items ?? []));\n }\n\n makeLive(release: SiteReleaseDto): void {\n this.confirmation\n .warn('Site::MakeReleaseLiveConfirm', 'AbpUi::AreYouSure', { messageLocalizationParams: [String(release.number)] })\n .subscribe(status => {\n if (status !== Confirmation.Status.confirm || !release.id) {\n return;\n }\n\n this.themeService.setLiveRelease(release.id).subscribe(() => {\n this.toaster.success('Site::ReleaseMadeLive', undefined, { messageLocalizationParams: [String(release.number)] });\n this.loadReleases();\n this.refreshTheme();\n this.refreshFiles();\n this.runCheck();\n });\n });\n }\n\n restore(release: SiteReleaseDto): void {\n this.confirmation\n .warn('Site::RestoreReleaseConfirm', 'AbpUi::AreYouSure', { messageLocalizationParams: [String(release.number)] })\n .subscribe(status => {\n if (status !== Confirmation.Status.confirm || !release.id) {\n return;\n }\n\n this.themeService.restoreRelease(release.id).subscribe(() => {\n // Every open file may have changed; open tabs would show what is no longer there.\n this.openFiles.set([]);\n this.activePath.set(undefined);\n this.isReleasesOpen.set(false);\n this.toaster.success('Site::ReleaseRestored', undefined, { messageLocalizationParams: [String(release.number)] });\n this.refreshTheme();\n this.refreshFiles();\n this.runCheck();\n });\n });\n }\n\n // Default layout.\n\n /**\n * Makes the file in front the default layout, from its own toolbar: it is offered only for a file the check lists as\n * a layout, and the server judges again, from what is saved - what it writes and calls, through what it includes.\n */\n setAsDefaultLayout(): void {\n const path = this.activePath();\n if (!path || this.isBusy() || this.isDefaultLayoutInFront()) {\n return;\n }\n\n this.isBusy.set(true);\n this.themeService\n .update({ defaultLayout: path, concurrencyStamp: this.theme()?.concurrencyStamp }, { skipHandleError: true })\n .subscribe({\n next: theme => {\n this.isBusy.set(false);\n this.theme.set(theme);\n this.toaster.success('Site::DefaultLayoutSet', undefined, { messageLocalizationParams: [path] });\n this.runCheck();\n },\n error: (response: ApiErrorResponse) => {\n this.isBusy.set(false);\n this.toaster.error(errorMessageOf(response) || 'AbpUi::DefaultErrorMessage');\n },\n });\n }\n\n languageOf(path: string) {\n return languageOf(path);\n }\n\n private refreshTheme(): void {\n this.themeService.get().subscribe(theme => this.theme.set(theme));\n }\n\n private refreshFiles(): void {\n this.themeService.getFiles().subscribe(files => this.files.set(files.items ?? []));\n }\n\n private replaceOpenFile(path: string, file: ThemeOpenFile): void {\n this.openFiles.update(files => files.map(f => (f.path === path ? { ...file, pinned: file.pinned || f.pinned } : f)));\n }\n\n private bodyOf(path: string): string | undefined {\n return this.openFiles().find(file => file.path === path)?.body;\n }\n\n private expandTo(path: string): void {\n const folders = foldersOf(path);\n if (folders.some(folder => this.collapsed().has(folder))) {\n const next = new Set(this.collapsed());\n folders.forEach(folder => next.delete(folder));\n this.collapsed.set(next);\n }\n }\n}\n\n/** Saves a blob to disk through a link click; the object address is released once the click has been handled. */\nfunction downloadBlob(blob: Blob, fileName: string): void {\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = fileName;\n document.body.appendChild(link);\n link.click();\n link.remove();\n setTimeout(() => URL.revokeObjectURL(url));\n}\n\nfunction isDirty(file: ThemeOpenFile): boolean {\n return file.body !== file.savedBody;\n}\n\nfunction toOpenFile(file: SiteThemeFileDto): ThemeOpenFile {\n return {\n path: file.path ?? '',\n isAsset: file.isAsset,\n body: file.body ?? '',\n savedBody: file.body ?? '',\n pinned: false,\n concurrencyStamp: file.concurrencyStamp,\n syntaxErrors: file.syntaxErrors ?? [],\n };\n}\n\n/** Who uses a file, in words: `Events (include), about (page)`; empty when nothing does. */\nexport function describeUsages(\n usages: SiteThemeFileUsagesDto,\n kindName: (kind: SiteThemeUsageKindDto) => string,\n): string {\n return (usages.usages ?? [])\n .map(usage => `${usage.pageName ?? usage.sourcePath ?? ''} (${kindName(usage.kind)})`.trim())\n .join(', ');\n}\n","@if (isLoading()) {\n <div class=\"text-center py-5\">\n <span class=\"spinner-border\" role=\"status\"></span>\n </div>\n} @else {\n <!-- Toolbar: the default layout, and the actions on the theme as a whole. The live release is marked in the history. -->\n <div class=\"card mb-3\">\n <div class=\"card-body d-flex flex-wrap align-items-center gap-2\">\n <div class=\"me-auto\">\n <h5 class=\"mb-0\">{{ 'Site::Theme' | abpLocalization }}</h5>\n <small class=\"text-muted\">\n {{ 'Site::DefaultLayout' | abpLocalization }}:\n <code>{{ theme()?.defaultLayout || ('Site::NoDefaultLayout' | abpLocalization) }}</code>\n </small>\n </div>\n <!-- Preview of the theme as a whole: the site's home page, from which the author follows the links. -->\n <button\n type=\"button\"\n class=\"btn btn-outline-secondary\"\n [title]=\"'Site::PreviewThemeHint' | abpLocalization\"\n (click)=\"openPreview()\"\n >\n <i class=\"fa fa-eye me-1\"></i>{{ 'Site::PreviewTheme' | abpLocalization }}\n </button>\n @if (canExport) {\n <button\n type=\"button\"\n class=\"btn btn-outline-secondary\"\n [title]=\"'Site::ExportThemeHint' | abpLocalization\"\n (click)=\"exportTheme()\"\n >\n <i class=\"fa fa-download me-1\"></i>{{ 'Site::ExportTheme' | abpLocalization }}\n </button>\n }\n @if (canEdit) {\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"openImport()\">\n <i class=\"fa fa-file-import me-1\"></i>{{ 'Site::ImportTheme' | abpLocalization }}\n </button>\n }\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"openReleases()\">\n <i class=\"fa fa-history me-1\"></i>{{ 'Site::Releases' | abpLocalization }}\n </button>\n @if (canPublish) {\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"openPublish()\">\n <i class=\"fa fa-upload me-1\"></i>{{ 'Site::PublishTheme' | abpLocalization }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"row g-3\">\n <!-- Left: the working copy's files. -->\n <div class=\"col-lg-3\">\n <div class=\"card h-100\">\n <div class=\"card-body\">\n <div class=\"d-flex align-items-center mb-2\">\n <h6 class=\"mb-0 me-auto\">{{ 'Site::ThemeFiles' | abpLocalization }}</h6>\n @if (canEdit) {\n <button\n type=\"button\"\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"openNewFile()\"\n [title]=\"'Site::NewThemeFile' | abpLocalization\"\n >\n <i class=\"fa fa-plus\"></i>\n </button>\n }\n </div>\n <div class=\"theme-tree\" role=\"tree\" (scroll)=\"closeRowMenu()\">\n @for (row of treeRows(); track row.node.path + row.node.isFolder) {\n <div\n class=\"theme-tree-row\"\n [class.active]=\"!row.node.isFolder && row.node.path === activePath()\"\n [class.deleted]=\"row.node.status === statuses.Deleted\"\n [style.padding-left.rem]=\"0.25 + row.depth * 1\"\n >\n <button\n type=\"button\"\n class=\"theme-tree-main\"\n role=\"treeitem\"\n [title]=\"row.node.path\"\n (click)=\"select(row.node)\"\n >\n @if (row.node.isFolder) {\n <i class=\"fa fa-fw\" [class.fa-folder]=\"collapsed().has(row.node.path)\" [class.fa-folder-open]=\"!collapsed().has(row.node.path)\"></i>\n } @else {\n <i class=\"fa fa-fw\" [class.fa-file-code]=\"row.node.isAsset\" [class.fa-file-lines]=\"!row.node.isAsset\"></i>\n }\n <span class=\"name\">{{ row.node.name }}</span>\n @if (!row.node.isFolder && statusKey(row.node.status); as key) {\n <span\n class=\"badge\"\n [class.text-bg-warning]=\"row.node.status === statuses.Modified\"\n [class.text-bg-success]=\"row.node.status === statuses.Added\"\n [class.text-bg-secondary]=\"row.node.status === statuses.Deleted\"\n [title]=\"key | abpLocalization\"\n >{{ (key + ':Short') | abpLocalization }}</span>\n } @else if (row.node.isFolder && row.node.hasChanges) {\n <span class=\"text-warning\" [title]=\"'Site::ThemeFolderHasChanges' | abpLocalization\">•</span>\n }\n </button>\n <!-- Renaming and deleting are rare: behind a \"more\" button on the file, not in the editor's way. -->\n @if (canEdit && !row.node.isFolder && row.node.status !== statuses.Deleted) {\n <button\n type=\"button\"\n class=\"theme-tree-more\"\n [class.open]=\"rowMenu()?.path === row.node.path\"\n [attr.aria-label]=\"'Site::MoreActions' | abpLocalization\"\n [attr.aria-expanded]=\"rowMenu()?.path === row.node.path\"\n [title]=\"'Site::MoreActions' | abpLocalization\"\n (click)=\"toggleRowMenu($event, row.node.path)\"\n >\n <i class=\"fa fa-ellipsis-vertical\"></i>\n </button>\n }\n </div>\n } @empty {\n <p class=\"text-muted small mb-0\">{{ 'Site::ThemeNoFiles' | abpLocalization }}</p>\n }\n </div>\n </div>\n </div>\n </div>\n\n <!-- Middle: the open files. -->\n <div class=\"col-lg-6\">\n <div class=\"card h-100\">\n <div class=\"card-body\">\n @if (openFiles().length > 0) {\n <ul class=\"nav nav-tabs mb-2 flex-nowrap theme-tabs\">\n @for (file of openFiles(); track file.path) {\n <li class=\"nav-item\">\n <a\n href=\"javascript:void(0)\"\n class=\"nav-link theme-tab\"\n [class.active]=\"file.path === activePath()\"\n [class.fst-italic]=\"!file.pinned && !isDirty(file)\"\n [title]=\"file.path\"\n (click)=\"activePath.set(file.path)\"\n >\n {{ file.path.split('/').pop() }}@if (isDirty(file)) { <span class=\"text-warning\" [title]=\"'Site::UnsavedChanges' | abpLocalization\">●</span> }\n <button\n type=\"button\"\n class=\"btn-close btn-sm ms-1 align-middle\"\n style=\"font-size: 0.6rem\"\n [attr.aria-label]=\"'AbpUi::Close' | abpLocalization\"\n (click)=\"$event.stopPropagation(); closeFile(file.path)\"\n ></button>\n </a>\n </li>\n }\n </ul>\n\n @if (activeFile(); as file) {\n <div class=\"d-flex flex-wrap align-items-center gap-2 mb-2\">\n <code class=\"me-auto\">{{ file.path }}</code>\n @if (canEdit) {\n <!-- Only for a file the check lists as a layout; there is nothing to do when it already is the default. -->\n @if (isLayoutInFront()) {\n <button\n type=\"button\"\n class=\"btn btn-sm btn-outline-secondary\"\n [disabled]=\"isDefaultLayoutInFront() || isBusy()\"\n [title]=\"(isDefaultLayoutInFront() ? 'Site::IsDefaultLayoutHint' : 'Site::SetAsDefaultLayoutHint') | abpLocalization\"\n (click)=\"setAsDefaultLayout()\"\n >\n <i class=\"fa fa-star me-1\"></i>{{ 'Site::SetAsDefaultLayout' | abpLocalization }}\n </button>\n }\n <button\n type=\"button\"\n class=\"btn btn-sm btn-primary\"\n [disabled]=\"!isDirty(file) || isBusy()\"\n [title]=\"'Site::SaveShortcut' | abpLocalization\"\n (click)=\"save()\"\n >\n @if (isBusy()) {\n <span class=\"spinner-border spinner-border-sm me-1\" role=\"status\"></span>\n } @else {\n <i class=\"fa fa-save me-1\"></i>\n }\n {{ 'AbpUi::Save' | abpLocalization }}\n </button>\n }\n </div>\n\n <div (keydown)=\"onEditorKeydown($event)\">\n <site-code-editor\n [documentKey]=\"file.path\"\n [value]=\"file.body\"\n [language]=\"languageOf(file.path)\"\n [readonly]=\"!canEdit\"\n (valueChange)=\"onEdit($event)\"\n ></site-code-editor>\n </div>\n\n @if (file.syntaxErrors.length > 0) {\n <div class=\"alert alert-danger mt-2 mb-0\" role=\"alert\">\n <strong class=\"d-block mb-1\">{{ 'Site::ThemeSyntaxErrors' | abpLocalization }}</strong>\n <ul class=\"list-unstyled mb-0\">\n @for (error of file.syntaxErrors; track $index) {\n <li>\n <!-- A button, not a link: it moves the editor's cursor, it does not navigate. -->\n <button type=\"button\" class=\"btn btn-link btn-sm p-0 align-baseline\" (click)=\"goToSyntaxError(error)\">\n {{ error.line }}:{{ error.column }}\n </button>\n {{ error.message }}\n </li>\n }\n </ul>\n </div>\n }\n }\n } @else {\n <p class=\"text-muted mb-0\">{{ 'Site::ThemeNoFileOpen' | abpLocalization }}</p>\n }\n </div>\n </div>\n </div>\n\n <!-- Right: the fields of a page the template in front renders, when it is one; the check below it, always. -->\n <div class=\"col-lg-3\">\n <div class=\"card h-100\">\n <div class=\"card-body theme-issues\">\n @if (showsFields()) {\n <h6>{{ 'Site::ThemeFields' | abpLocalization }}</h6>\n <div class=\"theme-fields\">\n @if (templatePages().length > 1) {\n <label class=\"form-label small mb-1\" for=\"site-theme-fields-page\">{{ 'Site::ThemeFieldsPage' | abpLocalization }}</label>\n <select\n id=\"site-theme-fields-page\"\n class=\"form-select form-select-sm mb-2\"\n [ngModel]=\"fieldsPageId()\"\n (ngModelChange)=\"chosenFieldsPageId.set($event)\"\n >\n @for (page of templatePages(); track page.id) {\n <option [value]=\"page.id\">{{ page.name }}</option>\n }\n </select>\n } @else {\n <p class=\"small fw-bold mb-1\">{{ 'Site::ThemeFieldsOfPage' | abpLocalization: templatePages()[0].name }}</p>\n }\n <p class=\"small text-muted mb-2\">\n {{ (canEdit ? 'Site::ThemeFieldsHint' : 'Site::ThemeFieldsReadOnlyHint') | abpLocalization }}\n </p>\n @if (isLoadingFields()) {\n <div class=\"text-center py-3\"><span class=\"spinner-border spinner-border-sm\" role=\"status\"></span></div>\n } @else {\n @for (group of fieldGroups(); track group.id) {\n <div class=\"small fw-bold mb-1\">{{ group.displayName }}</div>\n <ul class=\"list-unstyled small mb-3\">\n @for (field of group.fields; track field.name) {\n <li class=\"mb-2\">\n <button\n type=\"button\"\n class=\"btn btn-link btn-sm p-0 align-baseline text-start\"\n [disabled]=\"!canEdit\"\n (click)=\"insertField(field)\"\n >\n {{ field.displayName }}\n </button>\n <span class=\"text-muted ms-1\">{{ field.fieldTypeName }}</span>\n <br />\n <code class=\"theme-field-snippet\">{{ field.snippet }}</code>\n </li>\n }\n </ul>\n } @empty {\n <p class=\"small text-muted mb-0\">{{ 'Site::ThemeFieldsNone' | abpLocalization }}</p>\n }\n }\n </div>\n <hr class=\"my-3\" />\n }\n\n <!-- The check: runs by itself after every change; the button asks for the result as it is now, for what\n happened elsewhere (another author, an AI over MCP, the Pages screen). -->\n <div class=\"d-flex align-items-center mb-2\">\n <h6 class=\"mb-0 me-auto\">{{ 'Site::ThemeCheck' | abpLocalization }}</h6>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"runCheck()\" [disabled]=\"isChecking()\">\n @if (isChecking()) {\n <span class=\"spinner-border spinner-border-sm me-1\" role=\"status\"></span>\n } @else {\n <i class=\"fa fa-stethoscope me-1\"></i>\n }\n {{ 'Site::CheckTheme' | abpLocalization }}\n </button>\n </div>\n @if (check(); as current) {\n @if (current.issues.length === 0) {\n <p class=\"text-success small mb-2\"><i class=\"fa fa-check me-1\"></i>{{ 'Site::ThemeCheckClean' | abpLocalization }}</p>\n }\n @for (group of [severities.Error, severities.Warning]; track group) {\n @if (issuesOf(group).length > 0) {\n <div class=\"small fw-bold mb-1\" [class.text-danger]=\"group === severities.Error\" [class.text-warning]=\"group === severities.Warning\">\n {{ (group === severities.Error ? 'Site::ThemeErrors' : 'Site::ThemeWarnings') | abpLocalization }}\n ({{ issuesOf(group).length }})\n </div>\n <ul class=\"list-unstyled small mb-3\">\n @for (issue of issuesOf(group); track $index) {\n <li class=\"mb-2\">\n @if (issue.path) {\n <button type=\"button\" class=\"btn btn-link btn-sm p-0 align-baseline\" (click)=\"goToIssue(issue)\">\n {{ issue.path }}@if (issue.line) {:{{ issue.line }}}\n </button>\n <br />\n }\n {{ issue.message }}\n </li>\n }\n </ul>\n }\n }\n <p class=\"small text-muted mb-0\">\n @if (current.changes.length > 0) {\n {{ 'Site::ThemeUnpublishedChanges' | abpLocalization: current.changes.length.toString() }}\n }\n @if (defaultLayoutChanged(current)) {\n {{ 'Site::ThemeDefaultLayoutUnpublished' | abpLocalization: (current.liveDefaultLayout || ('Site::NoDefaultLayout' | abpLocalization)) }}\n }\n @if (!current.hasChanges) {\n {{ 'Site::ThemeNoUnpublishedChanges' | abpLocalization }}\n }\n </p>\n } @else {\n <p class=\"text-muted small mb-0\">{{ 'Site::ThemeCheckNotRun' | abpLocalization }}</p>\n }\n </div>\n </div>\n </div>\n </div>\n}\n\n<!-- The \"more\" menu of a file in the tree. Fixed, under its button: the tree scrolls and would clip it. -->\n@if (rowMenu(); as menu) {\n <div\n class=\"dropdown-menu show\"\n style=\"position: fixed\"\n [style.top.px]=\"menu.top\"\n [style.right.px]=\"menu.right\"\n (click)=\"$event.stopPropagation()\"\n >\n <button type=\"button\" class=\"dropdown-item\" (click)=\"renameFromMenu()\">\n <i class=\"fa fa-i-cursor fa-fw me-1\"></i>{{ 'Site::RenameThemeFile' | abpLocalization }}\n </button>\n <button type=\"button\" class=\"dropdown-item text-danger\" (click)=\"deleteFromMenu()\">\n <i class=\"fa fa-trash fa-fw me-1\"></i>{{ 'AbpUi::Delete' | abpLocalization }}\n </button>\n </div>\n}\n\n<!-- New file. -->\n<abp-modal [visible]=\"isNewFileOpen()\" (visibleChange)=\"isNewFileOpen.set($event)\" [busy]=\"isBusy()\">\n <ng-template #abpHeader>\n <h3>{{ 'Site::NewThemeFile' | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n <label class=\"form-label\" for=\"site-theme-new-path\">{{ 'Site::ThemeFilePath' | abpLocalization }}</label>\n <input\n id=\"site-theme-new-path\"\n type=\"text\"\n class=\"form-control\"\n autocomplete=\"off\"\n [ngModel]=\"newFilePath()\"\n (ngModelChange)=\"newFilePath.set($event); newFileError.set(null)\"\n (keydown.enter)=\"createFile()\"\n />\n <small class=\"form-text text-muted\">{{ 'Site::ThemeFilePathHint' | abpLocalization }}</small>\n @if (newFileError(); as message) {\n <div class=\"alert alert-danger mt-2 mb-0\" style=\"white-space: pre-line\">{{ message }}</div>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>{{ 'AbpUi::Cancel' | abpLocalization }}</button>\n <abp-button iconClass=\"fa fa-check\" [loading]=\"isBusy()\" (click)=\"createFile()\">\n {{ 'Site::CreateThemeFile' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n\n<!-- Rename. -->\n<abp-modal [visible]=\"isRenameOpen()\" (visibleChange)=\"isRenameOpen.set($event)\" [busy]=\"isBusy()\">\n <ng-template #abpHeader>\n <h3>{{ 'Site::RenameThemeFile' | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n <p class=\"mb-2\"><code>{{ renameFrom() }}</code></p>\n <label class=\"form-label\" for=\"site-theme-rename-path\">{{ 'Site::ThemeFileNewPath' | abpLocalization }}</label>\n <input\n id=\"site-theme-rename-path\"\n type=\"text\"\n class=\"form-control\"\n autocomplete=\"off\"\n [ngModel]=\"renameTo()\"\n (ngModelChange)=\"renameTo.set($event); renameError.set(null)\"\n (keydown.enter)=\"rename()\"\n />\n <div class=\"form-check mt-2\">\n <input\n id=\"site-theme-rename-references\"\n type=\"checkbox\"\n class=\"form-check-input\"\n [ngModel]=\"renameUpdatesReferences()\"\n (ngModelChange)=\"renameUpdatesReferences.set($event)\"\n />\n <label class=\"form-check-label\" for=\"site-theme-rename-references\">\n {{ 'Site::ThemeRenameUpdateReferences' | abpLocalization }}\n </label>\n </div>\n @if (renameError(); as message) {\n <div class=\"alert alert-danger mt-2 mb-0\" style=\"white-space: pre-line\">{{ message }}</div>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>{{ 'AbpUi::Cancel' | abpLocalization }}</button>\n <abp-button iconClass=\"fa fa-check\" [loading]=\"isBusy()\" (click)=\"rename()\">\n {{ 'Site::RenameThemeFile' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n\n<!-- Publish. -->\n<abp-modal [visible]=\"isPublishOpen()\" (visibleChange)=\"isPublishOpen.set($event)\" [busy]=\"isBusy()\" [options]=\"{ size: 'lg' }\">\n <ng-template #abpHeader>\n <h3>{{ 'Site::PublishThemeTitle' | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n @if (publishCheck(); as current) {\n @if (current.hasErrors) {\n <div class=\"alert alert-danger\">\n <strong class=\"d-block mb-1\">{{ 'Site::PublishThemeHasErrors' | abpLocalization }}</strong>\n <ul class=\"mb-0\">\n @for (issue of current.issues; track $index) {\n @if (issue.severity === severities.Error) {\n <li>\n @if (issue.path) { <code>{{ issue.path }}@if (issue.line) {:{{ issue.line }}}</code> }\n {{ issue.message }}\n </li>\n }\n }\n </ul>\n </div>\n } @else if (!current.hasChanges) {\n <div class=\"alert alert-info\">{{ 'Site::PublishThemeNoChanges' | abpLocalization }}</div>\n } @else {\n <h6>{{ 'Site::PublishThemeChanges' | abpLocalization }}</h6>\n <ul class=\"list-unstyled small mb-3\">\n @for (change of current.changes; track change.path) {\n <li>\n <span\n class=\"badge me-1\"\n [class.text-bg-warning]=\"change.status === statuses.Modified\"\n [class.text-bg-success]=\"change.status === statuses.Added\"\n [class.text-bg-secondary]=\"change.status === statuses.Deleted\"\n >{{ statusKey(change.status)! | abpLocalization }}</span>\n <code>{{ change.path }}</code>\n </li>\n }\n @if (defaultLayoutChanged(current)) {\n <li>\n <span class=\"badge text-bg-warning me-1\">{{ 'Site::ThemeFileStatus:Modified' | abpLocalization }}</span>\n {{ 'Site::DefaultLayout' | abpLocalization }}:\n <code>{{ current.liveDefaultLayout || ('Site::NoDefaultLayout' | abpLocalization) }}</code>\n →\n <code>{{ current.defaultLayout || ('Site::NoDefaultLayout' | abpLocalization) }}</code>\n </li>\n }\n </ul>\n @if (warningCount() > 0) {\n <p class=\"small text-warning\">{{ 'Site::PublishThemeWarnings' | abpLocalization: warningCount().toString() }}</p>\n }\n <label class=\"form-label\" for=\"site-theme-publish-comment\">{{ 'Site::ReleaseComment' | abpLocalization }}</label>\n <input\n id=\"site-theme-publish-comment\"\n type=\"text\"\n class=\"form-control\"\n autocomplete=\"off\"\n maxlength=\"256\"\n [placeholder]=\"'Site::ReleaseCommentPlaceholder' | abpLocalization\"\n [ngModel]=\"publishComment()\"\n (ngModelChange)=\"publishComment.set($event)\"\n (keydown.enter)=\"publishOnEnter($event)\"\n />\n }\n @if (publishError(); as message) {\n <div class=\"alert alert-danger mt-2 mb-0\" style=\"white-space: pre-line\">{{ message }}</div>\n }\n } @else {\n <div class=\"text-center py-3\"><span class=\"spinner-border\" role=\"status\"></span></div>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>{{ 'AbpUi::Cancel' | abpLocalization }}</button>\n <abp-button\n iconClass=\"fa fa-upload\"\n [loading]=\"isBusy()\"\n [disabled]=\"!publishCheck() || publishCheck()!.hasErrors || !publishCheck()!.hasChanges\"\n (click)=\"publish()\"\n >\n {{ 'Site::PublishTheme' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n\n<!-- Import. -->\n<abp-modal [visible]=\"isImportOpen()\" (visibleChange)=\"isImportOpen.set($event)\" [busy]=\"isBusy()\" [options]=\"{ size: 'lg' }\">\n <ng-template #abpHeader>\n <h3>{{ 'Site::ImportTheme' | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n @if (importResult(); as result) {\n <div class=\"alert alert-success\">{{ 'Site::ImportThemeDone' | abpLocalization }}</div>\n @if (result.defaultLayoutSet) {\n <p>{{ 'Site::ImportThemeDefaultLayoutSet' | abpLocalization }}</p>\n }\n @if (result.added.length) {\n <h6 class=\"mb-1\">{{ 'Site::ImportThemeAdded' | abpLocalization: result.added.length.toString() }}</h6>\n <ul class=\"mb-3\">\n @for (path of result.added; track path) {\n <li><code>{{ path }}</code></li>\n }\n </ul>\n }\n @if (result.modified.length) {\n <h6 class=\"mb-1\">{{ 'Site::ImportThemeModified' | abpLocalization: result.modified.length.toString() }}</h6>\n <ul class=\"mb-3\">\n @for (path of result.modified; track path) {\n <li><code>{{ path }}</code></li>\n }\n </ul>\n }\n @if (result.deleted.length) {\n <h6 class=\"mb-1\">{{ 'Site::ImportThemeDeleted' | abpLocalization: result.deleted.length.toString() }}</h6>\n <ul class=\"mb-3\">\n @for (path of result.deleted; track path) {\n <li><code>{{ path }}</code></li>\n }\n </ul>\n }\n <p class=\"text-muted mb-3\">{{ 'Site::ImportThemeUnchanged' | abpLocalization: result.unchanged.length.toString() }}</p>\n @let withErrors = syntaxErrorsOf(result);\n @if (withErrors.length) {\n <h6 class=\"mb-1 text-danger\">{{ 'Site::ImportThemeSyntaxErrors' | abpLocalization }}</h6>\n <ul class=\"mb-0\">\n @for (item of withErrors; track item.path) {\n <li>\n <code>{{ item.path }}</code>\n <ul>\n @for (error of item.errors; track $index) {\n <li>{{ error.line }}:{{ error.column }} {{ error.message }}</li>\n }\n </ul>\n </li>\n }\n </ul>\n }\n } @else {\n <p class=\"text-muted\">{{ 'Site::ImportThemeHint' | abpLocalization }}</p>\n <div class=\"mb-3\">\n <label class=\"form-label\" for=\"site-theme-import-file\">{{ 'Site::ImportThemeFile' | abpLocalization }}</label>\n <input\n id=\"site-theme-import-file\"\n type=\"file\"\n class=\"form-control\"\n accept=\".zip,application/zip\"\n (change)=\"onImportFileChange($event)\"\n />\n </div>\n <div class=\"form-check mb-2\">\n <input\n id=\"site-theme-import-merge\"\n type=\"radio\"\n class=\"form-check-input\"\n name=\"site-theme-import-mode\"\n [checked]=\"!importReplace()\"\n (change)=\"importReplace.set(false)\"\n />\n <label class=\"form-check-label\" for=\"site-theme-import-merge\">{{ 'Site::ImportThemeMerge' | abpLocalization }}</label>\n <small class=\"form-text text-muted d-block\">{{ 'Site::ImportThemeMergeHint' | abpLocalization }}</small>\n </div>\n <div class=\"form-check\">\n <input\n id=\"site-theme-import-replace\"\n type=\"radio\"\n class=\"form-check-input\"\n name=\"site-theme-import-mode\"\n [checked]=\"importReplace()\"\n (change)=\"importReplace.set(true)\"\n />\n <label class=\"form-check-label\" for=\"site-theme-import-replace\">{{ 'Site::ImportThemeReplace' | abpLocalization }}</label>\n <small class=\"form-text text-muted d-block\">{{ 'Site::ImportThemeReplaceHint' | abpLocalization }}</small>\n </div>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>\n {{ (importResult() ? 'AbpUi::Close' : 'AbpUi::Cancel') | abpLocalization }}\n </button>\n @if (!importResult()) {\n <abp-button iconClass=\"fa fa-file-import\" [loading]=\"isBusy()\" [disabled]=\"!importFile()\" (click)=\"importTheme()\">\n {{ 'Site::ImportTheme' | abpLocalization }}\n </abp-button>\n }\n </ng-template>\n</abp-modal>\n\n<!-- Releases. -->\n<abp-modal [visible]=\"isReleasesOpen()\" (visibleChange)=\"isReleasesOpen.set($event)\" [options]=\"{ size: 'xl' }\">\n <ng-template #abpHeader>\n <h3>{{ 'Site::Releases' | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n <!-- The comment takes the room and wraps; the other columns keep their words on one line. -->\n <div class=\"table-responsive\">\n <table class=\"table table-sm align-middle mb-0\">\n <thead>\n <tr>\n <th class=\"text-nowrap\">#</th>\n <th class=\"w-100\">{{ 'Site::ReleaseComment' | abpLocalization }}</th>\n <th class=\"text-nowrap\">{{ 'Site::ReleaseChangedFiles' | abpLocalization }}</th>\n <th class=\"text-nowrap\">{{ 'Site::ReleaseTime' | abpLocalization }}</th>\n <th class=\"text-end text-nowrap\">{{ 'AbpUi::Actions' | abpLocalization }}</th>\n </tr>\n </thead>\n <tbody>\n @for (release of releases(); track release.id) {\n <tr>\n <td class=\"text-nowrap\">\n {{ release.number }}\n @if (release.isLive) {\n <span class=\"badge text-bg-success ms-1\">{{ 'Site::ReleaseLive' | abpLocalization }}</span>\n }\n </td>\n <td>{{ release.comment }}</td>\n <td class=\"text-nowrap\">{{ release.changedFileCount }}</td>\n <td class=\"text-nowrap\">{{ release.creationTime | date: 'short' }}</td>\n <td class=\"text-end text-nowrap\">\n <button\n type=\"button\"\n class=\"btn btn-sm btn-outline-secondary me-1\"\n [title]=\"'Site::PreviewReleaseHint' | abpLocalization\"\n (click)=\"openPreview(release.id)\"\n >\n <i class=\"fa fa-eye me-1\"></i>{{ 'Site::PreviewTheme' | abpLocalization }}\n </button>\n @if (canExport) {\n <button\n type=\"button\"\n class=\"btn btn-sm btn-outline-secondary me-1\"\n [title]=\"'Site::ExportReleaseHint' | abpLocalization\"\n (click)=\"exportTheme(release)\"\n >\n <i class=\"fa fa-download me-1\"></i>{{ 'Site::ExportTheme' | abpLocalization }}\n </button>\n }\n @if (canPublish && !release.isLive) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary me-1\" (click)=\"makeLive(release)\">\n {{ 'Site::MakeReleaseLive' | abpLocalization }}\n </button>\n }\n @if (canEdit) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"restore(release)\">\n {{ 'Site::RestoreRelease' | abpLocalization }}\n </button>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td colspan=\"5\" class=\"text-muted\">{{ 'Site::NothingPublished' | abpLocalization }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>{{ 'AbpUi::Close' | abpLocalization }}</button>\n </ng-template>\n</abp-modal>\n"],"names":["i3"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export { l as CONTENT_FIELD_TYPE, m as CONTENT_FIELD_TYPE_NAME, n as ContentConfigComponent, o as ContentConfiguration, p as ContentControlComponent, b as ContentListStateService, a as ContentQueryService, q as ContentViewComponent, r as Dignite, s as FILE_FIELD_CONFIGURATION_NAMES, t as FILE_FIELD_TYPE, u as FILE_FIELD_TYPE_NAME, v as FileConfigComponent, w as FileControlComponent, x as FileDirectoryTreeComponent, y as FileFieldConfiguration, z as FileModalComponent, A as FilePickerComponent, B as FilePreviewComponent, D as FileUploadComponent, E as FileViewComponent, G as FormatFileSizePipe, I as IMAGE_TYPE_OPTIONS, M as MY_FILES_NODE_KEY, O as ObjectUrlService, H as SEO_FIELD_TYPE, J as SEO_FIELD_TYPE_NAME, K as SITE_FILE_CONTAINER_NAMES, L as SITE_FILE_PATH, N as SITE_IMAGES_CONTAINER_NAME, Q as SITE_ROUTES, R as SeoConfigComponent, T as SeoConfiguration, U as SeoControlComponent, V as SeoViewComponent, W as SiteCKEditorUploadProvider, X as SiteFileUrlService, S as SiteReferenceDataService, Y as ValidatorsService, Z as Volo, _ as absoluteFileUrl, e as eSitePolicyNames, $ as isMyFilesNode, a0 as isSiteFileUrl, a1 as relativeFileUrl, a2 as siteCKEditorConfigContributor, a3 as siteCKEditorDisplayContributor, a4 as sizedFileUrl, a5 as toContentListParams } from './dignite-ng.site-dignite-ng.site-BMcNABSG.mjs';
1
+ export { m as CONTENT_FIELD_TYPE, n as CONTENT_FIELD_TYPE_NAME, o as ContentConfigComponent, p as ContentConfiguration, q as ContentControlComponent, b as ContentListStateService, a as ContentQueryService, r as ContentViewComponent, s as Dignite, t as FILE_FIELD_CONFIGURATION_NAMES, u as FILE_FIELD_TYPE, v as FILE_FIELD_TYPE_NAME, w as FileConfigComponent, x as FileControlComponent, y as FileDirectoryTreeComponent, z as FileFieldConfiguration, A as FileModalComponent, B as FilePickerComponent, D as FilePreviewComponent, E as FileUploadComponent, G as FileViewComponent, H as FormatFileSizePipe, I as IMAGE_TYPE_OPTIONS, M as MY_FILES_NODE_KEY, O as OG_IMAGE_CONTAINER_NAME, J as OG_IMAGE_HEIGHT, K as OG_IMAGE_WIDTH, L as ObjectUrlService, N as SEO_FIELD_TYPE, Q as SEO_FIELD_TYPE_NAME, R as SITE_FILE_CONTAINER_NAMES, T as SITE_FILE_PATH, U as SITE_IMAGES_CONTAINER_NAME, V as SITE_ROUTES, W as SeoConfigComponent, X as SeoConfiguration, Y as SeoControlComponent, Z as SeoViewComponent, _ as SiteCKEditorUploadProvider, $ as SiteFileUrlService, S as SiteReferenceDataService, a0 as ValidatorsService, a1 as Volo, a2 as absoluteFileUrl, e as eSitePolicyNames, a3 as isMyFilesNode, a4 as isSiteFileUrl, a5 as relativeFileUrl, a6 as siteCKEditorConfigContributor, a7 as siteCKEditorDisplayContributor, a8 as sizedFileUrl, a9 as toContentListParams } from './dignite-ng.site-dignite-ng.site-CJVw2UzZ.mjs';
2
2
  //# sourceMappingURL=dignite-ng.site.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dignite/ng.site",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "homepage": "https://github.com/dignite-projects/site",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { eSitePolicyNames } from '@dignite/ng.site';
2
+ import { eSitePolicyNames, Dignite } from '@dignite/ng.site';
3
3
 
4
4
  /**
5
5
  * The languages the site serves, as a tab of Setting Management's page: the whole ordered list: the first is the default, whose pages have no language
@@ -31,11 +31,41 @@ declare class LanguagesSettingComponent {
31
31
 
32
32
  /** The name of the tab: a localization key of the `Site` resource, which the tab strip localizes. */
33
33
  declare const SITE_LANGUAGES_SETTING_TAB_NAME = "Site::Languages";
34
+ declare const SITE_SEO_SETTING_TAB_NAME = "Site::Seo";
34
35
  declare function configureSiteSettingTabs(): void;
35
36
  /**
36
- * Adds the site's languages to Setting Management's page as a tab. Next to `provideSettingManagementConfig()` in the
37
- * application's configuration: the page is that module's, and an application that does not use it does not use this.
37
+ * Adds the site's languages and SEO settings to Setting Management's page as tabs. Next to
38
+ * `provideSettingManagementConfig()` in the application's configuration: the page is that module's, and an
39
+ * application that does not use it does not use this.
38
40
  */
39
41
  declare function provideSiteSettingTabs(): _angular_core.EnvironmentProviders;
40
42
 
41
- export { LanguagesSettingComponent, SITE_LANGUAGES_SETTING_TAB_NAME, configureSiteSettingTabs, provideSiteSettingTabs };
43
+ /**
44
+ * The site's SEO settings, as a tab of Setting Management's page. For now the default share image: the one a page
45
+ * without a share image of its own is shared with. It is picked from the file library the way a page's own share
46
+ * image is (the `images` container); an address someone stored by other means shows and can be replaced or removed the
47
+ * same way. The server stores what it is given, and empty clears it. Without the update permission the tab only shows.
48
+ */
49
+ declare class SeoSettingComponent {
50
+ private readonly service;
51
+ private readonly toaster;
52
+ readonly policies: typeof eSitePolicyNames;
53
+ readonly imageContainerName = "images";
54
+ readonly imageWidth = 1200;
55
+ readonly imageHeight = 630;
56
+ readonly image: _angular_core.WritableSignal<string>;
57
+ readonly saved: _angular_core.WritableSignal<string>;
58
+ readonly pickerOpen: _angular_core.WritableSignal<boolean>;
59
+ readonly saving: _angular_core.WritableSignal<boolean>;
60
+ readonly isDirty: _angular_core.Signal<boolean>;
61
+ constructor();
62
+ load(): void;
63
+ onPicked(files: Dignite.Site.Admin.Files.FileDescriptorDto[]): void;
64
+ removeImage(): void;
65
+ save(): void;
66
+ private show;
67
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SeoSettingComponent, never>;
68
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SeoSettingComponent, "site-seo-setting", never, {}, {}, never, never, true, never>;
69
+ }
70
+
71
+ export { LanguagesSettingComponent, SITE_LANGUAGES_SETTING_TAB_NAME, SITE_SEO_SETTING_TAB_NAME, SeoSettingComponent, configureSiteSettingTabs, provideSiteSettingTabs };