@dignite/ng.site 1.0.1 → 2.0.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.
- package/README.md +14 -0
- package/fesm2022/dignite-ng.site-config.mjs +10 -1
- package/fesm2022/dignite-ng.site-config.mjs.map +1 -1
- package/fesm2022/{dignite-ng.site-content-editor.component-iFWDeYJ9.mjs → dignite-ng.site-content-editor.component-DA6FaJSU.mjs} +2 -2
- package/fesm2022/{dignite-ng.site-content-editor.component-iFWDeYJ9.mjs.map → dignite-ng.site-content-editor.component-DA6FaJSU.mjs.map} +1 -1
- package/fesm2022/{dignite-ng.site-content-types.component-D2jMSSq6.mjs → dignite-ng.site-content-types.component-Dnqe8A4t.mjs} +27 -7
- package/fesm2022/dignite-ng.site-content-types.component-Dnqe8A4t.mjs.map +1 -0
- package/fesm2022/{dignite-ng.site-contents.component-DKuel8w-.mjs → dignite-ng.site-contents.component-Ch5GYIHE.mjs} +2 -2
- package/fesm2022/{dignite-ng.site-contents.component-DKuel8w-.mjs.map → dignite-ng.site-contents.component-Ch5GYIHE.mjs.map} +1 -1
- package/fesm2022/{dignite-ng.site-dignite-ng.site-CsKxqjY9.mjs → dignite-ng.site-dignite-ng.site-BMcNABSG.mjs} +283 -55
- package/fesm2022/dignite-ng.site-dignite-ng.site-BMcNABSG.mjs.map +1 -0
- package/fesm2022/{dignite-ng.site-fields.component-By_YyfIx.mjs → dignite-ng.site-fields.component-BaK27N9k.mjs} +5 -3
- package/fesm2022/dignite-ng.site-fields.component-BaK27N9k.mjs.map +1 -0
- package/fesm2022/{dignite-ng.site-pages.component-S9BEgC4W.mjs → dignite-ng.site-pages.component-BwGyK7jw.mjs} +28 -5
- package/fesm2022/dignite-ng.site-pages.component-BwGyK7jw.mjs.map +1 -0
- package/fesm2022/dignite-ng.site-setting-management.mjs +123 -0
- package/fesm2022/dignite-ng.site-setting-management.mjs.map +1 -0
- package/fesm2022/dignite-ng.site-theme-workbench.component-CA47DnTj.mjs +1206 -0
- package/fesm2022/dignite-ng.site-theme-workbench.component-CA47DnTj.mjs.map +1 -0
- package/fesm2022/dignite-ng.site.mjs +1 -1
- package/package.json +17 -1
- package/types/dignite-ng.site-config.d.ts +2 -1
- package/types/dignite-ng.site-setting-management.d.ts +41 -0
- package/types/dignite-ng.site.d.ts +386 -111
- package/fesm2022/dignite-ng.site-content-types.component-D2jMSSq6.mjs.map +0 -1
- package/fesm2022/dignite-ng.site-dignite-ng.site-CsKxqjY9.mjs.map +0 -1
- package/fesm2022/dignite-ng.site-fields.component-By_YyfIx.mjs.map +0 -1
- package/fesm2022/dignite-ng.site-pages.component-S9BEgC4W.mjs.map +0 -1
|
@@ -10,7 +10,7 @@ import * as i5 from 'ng-zorro-antd/auto-complete';
|
|
|
10
10
|
import { NzAutocompleteModule } from 'ng-zorro-antd/auto-complete';
|
|
11
11
|
import { switchMap, forkJoin, map } from 'rxjs';
|
|
12
12
|
import { FieldTypeResolver, FlexFieldConfigComponent } from '@dignite/ng.flex-fields';
|
|
13
|
-
import {
|
|
13
|
+
import { i as FieldAdminService, S as SiteReferenceDataService, e as eSitePolicyNames } from './dignite-ng.site-dignite-ng.site-BMcNABSG.mjs';
|
|
14
14
|
import * as i3 from '@ngx-validate/core';
|
|
15
15
|
|
|
16
16
|
const MAX_FIELD_NAME_LENGTH = 64;
|
|
@@ -221,8 +221,10 @@ class FieldsComponent {
|
|
|
221
221
|
});
|
|
222
222
|
}
|
|
223
223
|
delete(field) {
|
|
224
|
+
// Not the generic AbpUi::ItemWillBeDeletedMessage: deleting a field removes its value from every
|
|
225
|
+
// content, and this confirmation is the only place a person is told.
|
|
224
226
|
this.confirmation
|
|
225
|
-
.warn('
|
|
227
|
+
.warn('Site::DeleteFieldConfirmMessage', 'AbpUi::AreYouSure', {
|
|
226
228
|
messageLocalizationParams: [field.displayName ?? ''],
|
|
227
229
|
})
|
|
228
230
|
.subscribe((status) => {
|
|
@@ -406,4 +408,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImpor
|
|
|
406
408
|
}] } });
|
|
407
409
|
|
|
408
410
|
export { FieldsComponent };
|
|
409
|
-
//# sourceMappingURL=dignite-ng.site-fields.component-
|
|
411
|
+
//# sourceMappingURL=dignite-ng.site-fields.component-BaK27N9k.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dignite-ng.site-fields.component-BaK27N9k.mjs","sources":["../../../projects/site/src/lib/components/fields/fields.component.ts","../../../projects/site/src/lib/components/fields/fields.component.html"],"sourcesContent":["import { CoreModule, ListResultDto, PermissionDirective } from '@abp/ng.core';\nimport {\n Confirmation,\n ConfirmationService,\n ThemeSharedModule,\n ToasterService,\n} from '@abp/ng.theme.shared';\nimport {\n Component,\n ElementRef,\n ViewChild,\n computed,\n inject,\n signal,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { NzAutocompleteModule } from 'ng-zorro-antd/auto-complete';\nimport { Observable, forkJoin, map, switchMap } from 'rxjs';\nimport {\n FieldTypeDefinition,\n FieldTypeResolver,\n FlexFieldConfigComponent,\n} from '@dignite/ng.flex-fields';\nimport type { FlexFieldData } from '@dignite/ng.flex-fields';\nimport { FieldAdminService } from '../../proxy/dignite/site/admin/fields/field-admin.service';\nimport type { GetFieldListInput } from '../../proxy/dignite/site/admin/fields/models';\nimport type { FieldDto } from '../../proxy/dignite/site/fields/models';\nimport { eSitePolicyNames } from '../../enums/policy-names';\nimport { SiteReferenceDataService } from '../../services/site-reference-data.service';\n\nconst MAX_FIELD_NAME_LENGTH = 64;\nconst MAX_FIELD_DISPLAY_NAME_LENGTH = 128;\nconst MAX_GROUP_NAME_LENGTH = 64;\n\n/** Mirrors `IdentifierName.Pattern` (`src/Dignite.Site.Domain.Shared/IdentifierName.cs`). */\nconst NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;\n\n/**\n * localStorage key for per-group collapse state the user has explicitly chosen, keyed by group name\n * (`''` for Ungrouped - a real group name is never empty after {@link FieldsComponent.sections}\n * trims it). Groups absent here fall back to the built-in default.\n */\nconst GROUP_COLLAPSE_STATE_STORAGE_KEY = 'Dignite.Site.Fields.GroupCollapseState';\n\n/** One group heading plus the fields filed under it. */\ninterface FieldGroupSection {\n /** Null for the ungrouped fields, which sort last. */\n groupName: string | null;\n fields: FieldDto[];\n}\n\n/**\n * The tenant's field library, listed in one column with a heading per group.\n *\n * **Grouping is a label on the field, not an entity.** `Field.GroupName` is a plain string, so an\n * editor files a field under a new group by typing it - there is no \"create the group first\" step, and\n * a group stops existing when the last field leaves it.\n *\n * **No Required/Searchable here.** Unlike the flex-fields demo, whose `ProductFieldDto` carries those\n * flags on the definition, Site keeps them per *usage* on `ContentTypeFieldDto` - the same field can be\n * pulled into several content types with different settings (总体设计 §2.3). They are set in the\n * content type's field arrangement.\n */\n@Component({\n selector: 'site-fields',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './fields.component.html',\n imports: [\n CoreModule,\n ThemeSharedModule,\n ReactiveFormsModule,\n PermissionDirective,\n FlexFieldConfigComponent,\n NzAutocompleteModule,\n ],\n})\nexport class FieldsComponent {\n private readonly fieldService = inject(FieldAdminService);\n private readonly referenceData = inject(SiteReferenceDataService);\n private readonly fieldTypeResolver = inject(FieldTypeResolver);\n private readonly fb = inject(FormBuilder);\n private readonly confirmation = inject(ConfirmationService);\n private readonly toaster = inject(ToasterService);\n\n readonly policies = eSitePolicyNames;\n readonly fieldTypes: readonly FieldTypeDefinition[] = this.fieldTypeResolver.getAll();\n\n /**\n * The whole field library, unpaged - grouped display has no notion of \"current page\".\n *\n * State that changes in an HTTP callback (this, `knownGroupNames` and the modal flags below) is a\n * signal, not a plain field: the host layout's ancestors (`abp-router-outlet`, the LeptonX layouts)\n * are OnPush, and a plain-field write in a response callback never marks them for check, so the list\n * would stay empty until some unrelated event happened to.\n */\n readonly data = signal<ListResultDto<FieldDto>>({ items: [] });\n filters = {} as GetFieldListInput;\n\n /**\n * The whole field library, bucketed by group for rendering. Ungrouped goes last: it is the catch-all,\n * and leading with it would bury the named groups under whatever has not been filed yet.\n */\n readonly sections = computed<FieldGroupSection[]>(() => {\n const buckets = new Map<string, FieldDto[]>();\n const ungrouped: FieldDto[] = [];\n\n for (const field of this.data().items ?? []) {\n const groupName = field.groupName?.trim();\n if (!groupName) {\n ungrouped.push(field);\n continue;\n }\n const bucket = buckets.get(groupName);\n if (bucket) {\n bucket.push(field);\n } else {\n buckets.set(groupName, [field]);\n }\n }\n\n const sections: FieldGroupSection[] = [...buckets.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([groupName, fields]) => ({ groupName, fields }));\n\n if (ungrouped.length > 0) {\n sections.push({ groupName: null, fields: ungrouped });\n }\n\n return sections;\n });\n\n /** Every group name in use, for the editor's suggestion list. */\n readonly knownGroupNames = signal<string[]>([]);\n\n /**\n * Per-group collapse state the user has explicitly toggled, keyed by group name (`''` for\n * Ungrouped). Client-side only, persisted in localStorage. A group absent here uses the built-in\n * default: Ungrouped starts open (it is the catch-all, worth seeing at a glance), named groups\n * start closed.\n */\n private readonly groupCollapseOverrides = new Map<string, boolean>(this.loadGroupCollapseOverrides());\n\n /**\n * Backs the group `nz-autocomplete`. Filters `knownGroupNames` client-side against the form's current\n * text rather than a server round trip - the list is already loaded, and there is no separate id: a\n * group's key IS its name.\n */\n get filteredGroupNames(): string[] {\n const term = ((this.form?.get('groupName')?.value as string) ?? '').trim().toLowerCase();\n const names = this.knownGroupNames();\n return term ? names.filter(name => name.toLowerCase().includes(term)) : names;\n }\n\n readonly isModalOpen = signal(false);\n readonly isModalBusy = signal(false);\n editingField?: FieldDto;\n form?: FormGroup;\n selectedFieldData?: FlexFieldData;\n\n readonly isRenameModalOpen = signal(false);\n readonly isRenameModalBusy = signal(false);\n renamingField?: FieldDto;\n renameForm?: FormGroup;\n\n readonly isGroupModalOpen = signal(false);\n readonly isGroupModalBusy = signal(false);\n renamingGroupName?: string;\n groupForm?: FormGroup;\n\n @ViewChild('submitButton') submitButton?: ElementRef<HTMLButtonElement>;\n @ViewChild('renameSubmitButton') renameSubmitButton?: ElementRef<HTMLButtonElement>;\n @ViewChild('groupSubmitButton') groupSubmitButton?: ElementRef<HTMLButtonElement>;\n\n constructor() {\n this.search();\n this.loadKnownGroupNames();\n }\n\n /** Reloads the whole (unpaged) field library; {@link sections} re-buckets it by group. */\n search(): void {\n this.fieldService.getList({ filter: this.filters.filter }).subscribe(result => {\n this.data.set(result);\n });\n }\n\n toggleGroup(groupName: string | null): void {\n this.groupCollapseOverrides.set(groupName ?? '', !this.isGroupCollapsed(groupName));\n this.saveGroupCollapseOverrides();\n }\n\n isGroupCollapsed(groupName: string | null): boolean {\n return this.groupCollapseOverrides.get(groupName ?? '') ?? groupName !== null;\n }\n\n private loadGroupCollapseOverrides(): [string, boolean][] {\n try {\n const raw = localStorage.getItem(GROUP_COLLAPSE_STATE_STORAGE_KEY);\n return raw ? Object.entries(JSON.parse(raw) as Record<string, boolean>) : [];\n } catch {\n return [];\n }\n }\n\n private saveGroupCollapseOverrides(): void {\n localStorage.setItem(\n GROUP_COLLAPSE_STATE_STORAGE_KEY,\n JSON.stringify(Object.fromEntries(this.groupCollapseOverrides)),\n );\n }\n\n /**\n * Drawn from the shared reference cache rather than `data().items` directly, so it stays in sync with\n * whatever else on the page (or another component) last invalidated it.\n */\n private loadKnownGroupNames(): void {\n this.referenceData.getFieldsById().subscribe(fields => {\n this.knownGroupNames.set(\n [\n ...new Set(\n [...fields.values()]\n .map(field => field.groupName?.trim())\n .filter((name): name is string => !!name),\n ),\n ].sort((a, b) => a.localeCompare(b)),\n );\n });\n }\n\n private refreshLibrary(): void {\n this.referenceData.invalidateFields();\n this.loadKnownGroupNames();\n this.search();\n }\n\n /** Localization key for a field type's display name, for use with `| abpLocalization`. */\n displayNameKeyOf(fieldTypeName?: string): string {\n return (\n this.fieldTypes.find(type => type.name === fieldTypeName)?.displayNameKey ??\n fieldTypeName ??\n ''\n );\n }\n\n openCreate(): void {\n this.editingField = undefined;\n this.form = this.buildForm();\n this.isModalOpen.set(true);\n }\n\n openEdit(field: FieldDto): void {\n this.editingField = field;\n this.form = this.buildForm(field);\n this.isModalOpen.set(true);\n }\n\n closeModal(): void {\n this.isModalOpen.set(false);\n this.form = undefined;\n this.editingField = undefined;\n }\n\n save(): void {\n if (!this.form || this.form.invalid || this.isModalBusy()) {\n return;\n }\n\n this.isModalBusy.set(true);\n const value = this.form.getRawValue();\n const configuration = this.form.get('configuration')?.value ?? {};\n const groupName = (value.groupName as string)?.trim() || null;\n\n const request$ = this.editingField\n ? this.fieldService.update(this.editingField.id!, {\n displayName: value.displayName,\n fieldTypeName: value.fieldTypeName,\n description: value.description,\n configuration,\n groupName,\n })\n : this.fieldService.create({\n name: value.name,\n displayName: value.displayName,\n fieldTypeName: value.fieldTypeName,\n description: value.description,\n configuration,\n groupName,\n });\n\n request$.subscribe({\n next: () => {\n this.isModalBusy.set(false);\n this.closeModal();\n this.refreshLibrary();\n this.toaster.success('AbpUi::SavedSuccessfully');\n },\n error: () => this.isModalBusy.set(false),\n });\n }\n\n delete(field: FieldDto): void {\n // Not the generic AbpUi::ItemWillBeDeletedMessage: deleting a field removes its value from every\n // content, and this confirmation is the only place a person is told.\n this.confirmation\n .warn('Site::DeleteFieldConfirmMessage', 'AbpUi::AreYouSure', {\n messageLocalizationParams: [field.displayName ?? ''],\n })\n .subscribe((status: Confirmation.Status) => {\n if (status === Confirmation.Status.confirm) {\n // A platform preset answers Site:030002 here; the error handler surfaces the server's own\n // message, which already explains to remove it from an arrangement instead.\n this.fieldService.delete(field.id!).subscribe(() => {\n this.refreshLibrary();\n this.toaster.success('AbpUi::SuccessfullyDeleted');\n });\n }\n });\n }\n\n /**\n * Renaming is deliberately its own operation, not part of the edit form: `UpdateFieldDto` carries no\n * name, the server guards it with its own permission (`SiteAdmin.Fields.Rename`), and it rewrites the\n * stored value of every content using the field.\n */\n openRename(field: FieldDto): void {\n this.renamingField = field;\n this.renameForm = this.fb.group({\n newName: [\n field.name ?? '',\n [Validators.required, Validators.maxLength(MAX_FIELD_NAME_LENGTH), Validators.pattern(NAME_PATTERN)],\n ],\n });\n this.isRenameModalOpen.set(true);\n }\n\n closeRenameModal(): void {\n this.isRenameModalOpen.set(false);\n this.renameForm = undefined;\n this.renamingField = undefined;\n }\n\n saveRename(): void {\n if (!this.renameForm || this.renameForm.invalid || this.isRenameModalBusy()) {\n return;\n }\n\n this.isRenameModalBusy.set(true);\n\n this.fieldService.rename(this.renamingField!.id!, this.renameForm.getRawValue()).subscribe({\n next: () => {\n this.isRenameModalBusy.set(false);\n this.closeRenameModal();\n this.refreshLibrary();\n this.toaster.success('AbpUi::SavedSuccessfully');\n },\n error: () => this.isRenameModalBusy.set(false),\n });\n }\n\n /**\n * Group is a label, not an entity ({@link FieldGroupSection}), so \"editing\" one is a bulk rename of\n * `groupName` across every field that carries it - scoped to the whole library via a fresh fetch in\n * `fieldsInGroup`, not just `section.fields` (which reflects whatever the search box currently\n * filters `data().items` to).\n */\n openEditGroup(groupName: string): void {\n this.renamingGroupName = groupName;\n this.groupForm = this.fb.group({\n groupName: [groupName, [Validators.required, Validators.maxLength(MAX_GROUP_NAME_LENGTH)]],\n });\n this.isGroupModalOpen.set(true);\n }\n\n closeGroupModal(): void {\n this.isGroupModalOpen.set(false);\n this.groupForm = undefined;\n this.renamingGroupName = undefined;\n }\n\n saveGroupRename(): void {\n if (!this.groupForm || this.groupForm.invalid || this.isGroupModalBusy() || !this.renamingGroupName) {\n return;\n }\n\n const oldGroupName = this.renamingGroupName;\n const newGroupName = (this.groupForm.getRawValue().groupName as string).trim();\n\n if (newGroupName === oldGroupName) {\n this.closeGroupModal();\n return;\n }\n\n this.isGroupModalBusy.set(true);\n this.fieldsInGroup(oldGroupName)\n .pipe(\n switchMap(fields => forkJoin(fields.map(field => this.updateFieldGroupName(field, newGroupName)))),\n )\n .subscribe({\n next: () => {\n this.isGroupModalBusy.set(false);\n this.closeGroupModal();\n this.refreshLibrary();\n this.toaster.success('AbpUi::SavedSuccessfully');\n },\n error: () => this.isGroupModalBusy.set(false),\n });\n }\n\n /** Ungroups every field in the group - the group itself is only ever the fields that carry its name. */\n deleteGroup(groupName: string): void {\n this.fieldsInGroup(groupName).subscribe(fields => {\n this.confirmation\n .warn('Site::UngroupConfirmMessage', 'AbpUi::AreYouSure', {\n messageLocalizationParams: [String(fields.length), groupName],\n })\n .subscribe((status: Confirmation.Status) => {\n if (status === Confirmation.Status.confirm) {\n forkJoin(fields.map(field => this.updateFieldGroupName(field, null))).subscribe(() => {\n this.refreshLibrary();\n this.toaster.success('AbpUi::SuccessfullyDeleted');\n });\n }\n });\n });\n }\n\n /**\n * The group's full membership, library-wide - a fresh, unfiltered fetch so a rename/ungroup is never\n * scoped down by whatever the search box currently filters `data().items` to.\n */\n private fieldsInGroup(groupName: string): Observable<FieldDto[]> {\n return this.fieldService\n .getList({})\n .pipe(map(result => (result.items ?? []).filter(field => field.groupName === groupName)));\n }\n\n private updateFieldGroupName(field: FieldDto, groupName: string | null) {\n return this.fieldService.update(field.id!, {\n displayName: field.displayName!,\n fieldTypeName: field.fieldTypeName!,\n description: field.description,\n configuration: field.configuration,\n groupName,\n });\n }\n\n private buildForm(field?: FieldDto): FormGroup {\n this.selectedFieldData = field\n ? {\n id: field.id!,\n name: field.name!,\n displayName: field.displayName!,\n description: field.description ?? undefined,\n fieldTypeName: field.fieldTypeName!,\n configuration: (field.configuration ?? {}) as Record<string, unknown>,\n }\n : undefined;\n\n return this.fb.group({\n // Fixed after creation - renaming goes through `openRename`. Kept in the form (disabled) so the\n // modal can show what it is.\n name: [\n { value: field?.name ?? '', disabled: !!field },\n [Validators.required, Validators.maxLength(MAX_FIELD_NAME_LENGTH), Validators.pattern(NAME_PATTERN)],\n ],\n displayName: [\n field?.displayName ?? '',\n [Validators.required, Validators.maxLength(MAX_FIELD_DISPLAY_NAME_LENGTH)],\n ],\n description: [field?.description ?? ''],\n // Free text with a suggestion list rather than a closed dropdown: filing a field under a new\n // group is just typing its name.\n groupName: [field?.groupName ?? '', [Validators.maxLength(MAX_GROUP_NAME_LENGTH)]],\n // Also fixed after creation: changing the type would orphan every stored value. Still bound so\n // `ff-flex-field-config` can pick which configuration editor to render.\n fieldTypeName: [\n { value: field?.fieldTypeName ?? this.fieldTypes[0]?.name ?? '', disabled: !!field },\n Validators.required,\n ],\n });\n }\n}\n","<div class=\"card\">\n <div class=\"card-body\">\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <h5 class=\"mb-0\">{{ 'Site::Fields' | abpLocalization }}</h5>\n <button\n *abpPermission=\"policies.FieldsCreate\"\n type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"openCreate()\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::NewField' | abpLocalization }}\n </button>\n </div>\n\n <div class=\"row mb-3\">\n <div class=\"col-md-4\">\n <input\n type=\"text\"\n class=\"form-control\"\n [(ngModel)]=\"filters.filter\"\n (keyup.enter)=\"search()\"\n [placeholder]=\"'AbpUi::Search' | abpLocalization\"\n />\n </div>\n </div>\n\n <div class=\"table-responsive\">\n <table class=\"table align-middle mb-0\">\n <thead>\n <tr>\n <th>{{ 'Site::DisplayName:Field.DisplayName' | abpLocalization }}</th>\n <th>{{ 'Site::DisplayName:Field.Name' | abpLocalization }}</th>\n <th>{{ 'Site::DisplayName:Field.FieldTypeName' | abpLocalization }}</th>\n <th>{{ 'AbpUi::Actions' | abpLocalization }}</th>\n </tr>\n </thead>\n <tbody>\n @for (section of sections(); track section.groupName) {\n <tr class=\"table-light\">\n <th colspan=\"4\" class=\"fw-semibold\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <span style=\"cursor: pointer\" (click)=\"toggleGroup(section.groupName)\">\n <i\n class=\"fa me-2 text-muted\"\n [class.fa-chevron-down]=\"!isGroupCollapsed(section.groupName)\"\n [class.fa-chevron-right]=\"isGroupCollapsed(section.groupName)\"\n ></i>\n @if (section.groupName) {\n <i class=\"fa fa-folder me-1 text-muted\"></i>{{ section.groupName }}\n } @else {\n <i class=\"fa fa-folder-open me-1 text-muted\"></i>\n <span class=\"text-muted\">{{ 'Site::Ungrouped' | abpLocalization }}</span>\n }\n </span>\n @if (section.groupName) {\n <span>\n <button\n *abpPermission=\"policies.FieldsUpdate\"\n type=\"button\"\n class=\"btn btn-sm btn-light me-1\"\n (click)=\"openEditGroup(section.groupName!)\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button\n *abpPermission=\"policies.FieldsUpdate\"\n type=\"button\"\n class=\"btn btn-sm btn-light\"\n (click)=\"deleteGroup(section.groupName!)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </span>\n }\n </div>\n </th>\n </tr>\n @if (!isGroupCollapsed(section.groupName)) {\n @for (field of section.fields; track field.id) {\n <tr>\n <td>\n <div>{{ field.displayName }}</div>\n @if (field.description) {\n <small class=\"text-muted\">{{ field.description }}</small>\n }\n </td>\n <td>{{ field.name }}</td>\n <td>{{ displayNameKeyOf(field.fieldTypeName) | abpLocalization }}</td>\n <td class=\"text-nowrap text-end\">\n <button\n *abpPermission=\"policies.FieldsUpdate\"\n type=\"button\"\n class=\"btn btn-sm btn-light me-1\"\n (click)=\"openEdit(field)\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button\n *abpPermission=\"policies.FieldsRename\"\n type=\"button\"\n class=\"btn btn-sm btn-light me-1\"\n (click)=\"openRename(field)\"\n [title]=\"'Site::RenameField' | abpLocalization\"\n >\n <i class=\"fa fa-i-cursor\"></i>\n </button>\n <button\n *abpPermission=\"policies.FieldsDelete\"\n type=\"button\"\n class=\"btn btn-sm btn-light\"\n (click)=\"delete(field)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </td>\n </tr>\n }\n }\n } @empty {\n <tr>\n <td colspan=\"4\" class=\"text-muted\">\n {{ 'AbpUi::NoDataAvailableInDatatable' | abpLocalization }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n</div>\n\n<abp-modal\n [(visible)]=\"isModalOpen\"\n [busy]=\"isModalBusy()\"\n [options]=\"{ size: 'xl' }\"\n (disappear)=\"closeModal()\"\n>\n <ng-template #abpHeader>\n <h3>{{ (editingField ? 'Site::EditField' : 'Site::NewField') | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n @if (form) {\n <form [formGroup]=\"form\" (submit)=\"save()\">\n <button type=\"submit\" #submitButton style=\"display: none\"></button>\n\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Field.DisplayName' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"displayName\" />\n </div>\n\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Field.Name' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"name\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Field.Name' | abpLocalization }}\n </small>\n </div>\n\n <!-- Description sits high on purpose: it is product copy aimed at AI, which an MCP client\n reads to fill the field correctly (总体设计 §6.2.6), not an optional footnote. -->\n <div class=\"mb-3\">\n <label class=\"form-label fw-semibold\">\n {{ 'Site::DisplayName:Field.Description' | abpLocalization }}\n </label>\n <textarea class=\"form-control\" formControlName=\"description\" rows=\"3\"></textarea>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Field.Description' | abpLocalization }}\n </small>\n </div>\n\n <!-- Above the field type, and free text: filing under a new group is just typing its name. -->\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Field.Group' | abpLocalization }}</label>\n <input\n type=\"text\"\n class=\"form-control\"\n formControlName=\"groupName\"\n [nzAutocomplete]=\"groupNameAuto\"\n />\n <nz-autocomplete #groupNameAuto [nzDataSource]=\"filteredGroupNames\"></nz-autocomplete>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Field.Group' | abpLocalization }}\n </small>\n </div>\n\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Field.FieldTypeName' | abpLocalization }}</label>\n <select class=\"form-select\" formControlName=\"fieldTypeName\">\n @for (fieldType of fieldTypes; track fieldType.name) {\n <option [value]=\"fieldType.name\">{{ fieldType.displayNameKey | abpLocalization }}</option>\n }\n </select>\n @if (editingField) {\n <small class=\"form-text text-muted\">\n {{ 'Site::FieldTypeFixedAfterCreation' | abpLocalization }}\n </small>\n }\n </div>\n\n <hr />\n <h6>{{ 'Site::DisplayName:Field.Configuration' | abpLocalization }}</h6>\n\n <ff-flex-field-config\n [type]=\"form.getRawValue().fieldTypeName\"\n [selected]=\"selectedFieldData\"\n [form]=\"form\"\n ></ff-flex-field-config>\n </form>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>\n {{ 'AbpUi::Cancel' | abpLocalization }}\n </button>\n <abp-button\n iconClass=\"fa fa-check\"\n [disabled]=\"!form?.valid\"\n [loading]=\"isModalBusy()\"\n (click)=\"submitButton?.nativeElement?.click()\"\n >\n {{ 'AbpUi::Save' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n\n<abp-modal\n [(visible)]=\"isRenameModalOpen\"\n [busy]=\"isRenameModalBusy()\"\n (disappear)=\"closeRenameModal()\"\n>\n <ng-template #abpHeader>\n <h3>{{ 'Site::RenameField' | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n @if (renameForm) {\n <form [formGroup]=\"renameForm\" (submit)=\"saveRename()\">\n <button type=\"submit\" #renameSubmitButton style=\"display: none\"></button>\n\n <div class=\"alert alert-warning\">\n {{ 'Site::RenameFieldWarning' | abpLocalization }}\n </div>\n\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Field.NewName' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"newName\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Field.NewName' | abpLocalization }}\n </small>\n </div>\n </form>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>\n {{ 'AbpUi::Cancel' | abpLocalization }}\n </button>\n <abp-button\n iconClass=\"fa fa-check\"\n [disabled]=\"!renameForm?.valid\"\n [loading]=\"isRenameModalBusy()\"\n (click)=\"renameSubmitButton?.nativeElement?.click()\"\n >\n {{ 'AbpUi::Save' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n\n<abp-modal\n [(visible)]=\"isGroupModalOpen\"\n [busy]=\"isGroupModalBusy()\"\n (disappear)=\"closeGroupModal()\"\n>\n <ng-template #abpHeader>\n <h3>{{ 'Site::RenameGroup' | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n @if (groupForm) {\n <form [formGroup]=\"groupForm\" (submit)=\"saveGroupRename()\">\n <button type=\"submit\" #groupSubmitButton style=\"display: none\"></button>\n\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Group.NewName' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"groupName\" />\n </div>\n </form>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>\n {{ 'AbpUi::Cancel' | abpLocalization }}\n </button>\n <abp-button\n iconClass=\"fa fa-check\"\n [disabled]=\"!groupForm?.valid\"\n [loading]=\"isGroupModalBusy()\"\n (click)=\"groupSubmitButton?.nativeElement?.click()\"\n >\n {{ 'AbpUi::Save' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n"],"names":["i2","i3","i4"],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ import * as i2 from '@angular/router';
|
|
|
12
12
|
import { Router, RouterLink } from '@angular/router';
|
|
13
13
|
import * as i8 from 'ng-zorro-antd/tree-select';
|
|
14
14
|
import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select';
|
|
15
|
-
import { P as PageAdminService, e as eSitePolicyNames } from './dignite-ng.site-dignite-ng.site-
|
|
15
|
+
import { P as PageAdminService, g as SiteThemeAdminService, e as eSitePolicyNames, h as SiteThemeFileStatus } from './dignite-ng.site-dignite-ng.site-BMcNABSG.mjs';
|
|
16
16
|
import * as i1 from '@angular/common';
|
|
17
17
|
import * as i3 from '@ngx-validate/core';
|
|
18
18
|
|
|
@@ -37,6 +37,7 @@ class PagesComponent {
|
|
|
37
37
|
this.toaster = inject(ToasterService);
|
|
38
38
|
this.router = inject(Router);
|
|
39
39
|
this.permission = inject(PermissionService);
|
|
40
|
+
this.themeService = inject(SiteThemeAdminService);
|
|
40
41
|
this.policies = eSitePolicyNames;
|
|
41
42
|
/**
|
|
42
43
|
* The whole (filtered) result set, unpaged - the datatable paginates it client-side.
|
|
@@ -53,6 +54,9 @@ class PagesComponent {
|
|
|
53
54
|
...(ngDevMode ? [{ debugName: "isModalOpen" }] : /* istanbul ignore next */ []));
|
|
54
55
|
this.isModalBusy = signal(false, /* @ts-ignore */
|
|
55
56
|
...(ngDevMode ? [{ debugName: "isModalBusy" }] : /* istanbul ignore next */ []));
|
|
57
|
+
/** The theme's template paths, suggested under the Template input. */
|
|
58
|
+
this.templateOptions = signal([], /* @ts-ignore */
|
|
59
|
+
...(ngDevMode ? [{ debugName: "templateOptions" }] : /* istanbul ignore next */ []));
|
|
56
60
|
this.applyFilters();
|
|
57
61
|
}
|
|
58
62
|
/** Whether the tree-toggle template should render a toggle for this row at all. */
|
|
@@ -88,13 +92,30 @@ class PagesComponent {
|
|
|
88
92
|
openCreate() {
|
|
89
93
|
this.editingPage = undefined;
|
|
90
94
|
this.form = this.buildForm();
|
|
95
|
+
this.loadTemplateOptions();
|
|
91
96
|
this.isModalOpen.set(true);
|
|
92
97
|
}
|
|
93
98
|
openEdit(page) {
|
|
94
99
|
this.editingPage = page;
|
|
95
100
|
this.form = this.buildForm(page);
|
|
101
|
+
this.loadTemplateOptions();
|
|
96
102
|
this.isModalOpen.set(true);
|
|
97
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* The theme's templates, offered under the Template input. A suggestion list, not a choice: a page can name a
|
|
106
|
+
* Razor view instead. Skipped without the Themes permission, and quietly empty when the theme cannot be read.
|
|
107
|
+
*/
|
|
108
|
+
loadTemplateOptions() {
|
|
109
|
+
if (!this.permission.getGrantedPolicy(eSitePolicyNames.Themes)) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.themeService.getFiles({ skipHandleError: true }).subscribe({
|
|
113
|
+
next: files => this.templateOptions.set((files.items ?? [])
|
|
114
|
+
.filter(file => !file.isAsset && file.status !== SiteThemeFileStatus.Deleted)
|
|
115
|
+
.map(file => file.path ?? '')),
|
|
116
|
+
error: () => this.templateOptions.set([]),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
98
119
|
closeModal() {
|
|
99
120
|
this.isModalOpen.set(false);
|
|
100
121
|
this.form = undefined;
|
|
@@ -128,8 +149,10 @@ class PagesComponent {
|
|
|
128
149
|
});
|
|
129
150
|
}
|
|
130
151
|
delete(page) {
|
|
152
|
+
// Not the generic AbpUi::ItemWillBeDeletedMessage: deleting a page also deletes its content types and
|
|
153
|
+
// every content of those types, and this confirmation is the only place a person is told.
|
|
131
154
|
this.confirmation
|
|
132
|
-
.warn('
|
|
155
|
+
.warn('Site::DeletePageConfirmMessage', 'AbpUi::AreYouSure', {
|
|
133
156
|
messageLocalizationParams: [page.displayName ?? ''],
|
|
134
157
|
})
|
|
135
158
|
.subscribe((status) => {
|
|
@@ -213,7 +236,7 @@ class PagesComponent {
|
|
|
213
236
|
});
|
|
214
237
|
}
|
|
215
238
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: PagesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
216
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.2", type: PagesComponent, isStandalone: true, selector: "site-pages", viewQueries: [{ propertyName: "submitButton", first: true, predicate: ["submitButton"], descendants: true }], ngImport: i0, template: "<div class=\"card mb-3\">\n <div class=\"card-body\">\n <div class=\"row align-items-end g-2\">\n <div class=\"col-md-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.IsActive' | abpLocalization }}</label>\n <select class=\"form-select\" [(ngModel)]=\"filters.isActive\" (change)=\"applyFilters()\">\n <option [ngValue]=\"undefined\">--</option>\n <option [ngValue]=\"true\">{{ 'AbpUi::Yes' | abpLocalization }}</option>\n <option [ngValue]=\"false\">{{ 'AbpUi::No' | abpLocalization }}</option>\n </select>\n </div>\n <div class=\"col-md-5\">\n <label class=\"form-label\">{{ 'AbpUi::Search' | abpLocalization }}</label>\n <input\n type=\"text\"\n class=\"form-control\"\n [(ngModel)]=\"filters.filter\"\n (keyup.enter)=\"applyFilters()\"\n [placeholder]=\"'AbpUi::Search' | abpLocalization\"\n />\n </div>\n <div class=\"col-md-4\">\n <button type=\"button\" class=\"btn btn-primary me-2\" (click)=\"applyFilters()\">\n <i class=\"fa fa-search me-1\"></i>{{ 'AbpUi::Search' | abpLocalization }}\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"clearFilters()\">\n {{ 'AbpUi::Clear' | abpLocalization }}\n </button>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"card\">\n <div class=\"card-body\">\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <h5 class=\"mb-0\">{{ 'Site::Pages' | abpLocalization }}</h5>\n <button\n *abpPermission=\"policies.PagesCreate\"\n type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"openCreate()\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::NewPage' | abpLocalization }}\n </button>\n </div>\n\n <ngx-datatable\n class=\"material\"\n [rows]=\"data().items\"\n columnMode=\"flex\"\n [headerHeight]=\"42\"\n [footerHeight]=\"42\"\n rowHeight=\"auto\"\n treeFromRelation=\"parentId\"\n treeToRelation=\"id\"\n (treeAction)=\"onTreeAction($event)\"\n >\n <ngx-datatable-column\n prop=\"displayName\"\n [flexGrow]=\"2\"\n [isTreeColumn]=\"true\"\n [treeLevelIndent]=\"20\"\n [name]=\"'Site::DisplayName:Page.DisplayName' | abpLocalization\"\n >\n <ng-template\n let-row=\"row\"\n let-treeStatus=\"treeStatus\"\n let-onTreeAction=\"onTreeAction\"\n ngx-datatable-cell-template\n >\n @if (hasChildren(row)) {\n <button type=\"button\" class=\"page-tree-toggle\" (click)=\"onTreeAction()\">\n <i\n class=\"fa\"\n [ngClass]=\"treeStatus === 'collapsed' ? 'fa-caret-right' : 'fa-caret-down'\"\n ></i>\n </button>\n }\n {{ row.displayName }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n prop=\"name\"\n [flexGrow]=\"2\"\n [name]=\"'Site::DisplayName:Page.Name' | abpLocalization\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n prop=\"route\"\n [flexGrow]=\"2\"\n [name]=\"'Site::DisplayName:Page.Route' | abpLocalization\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n [flexGrow]=\"1\"\n [name]=\"'Site::DisplayName:Page.IsActive' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <i class=\"fa\" [ngClass]=\"row.isActive ? 'fa-check text-success' : 'fa-times text-muted'\"></i>\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column [flexGrow]=\"2\" [sortable]=\"false\" [name]=\"'AbpUi::Actions' | abpLocalization\">\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <a\n *abpPermission=\"policies.ContentTypes\"\n class=\"btn btn-sm btn-light me-1\"\n [routerLink]=\"['/site/pages', row.id, 'content-types']\"\n [title]=\"'Site::ContentTypes' | abpLocalization\"\n >\n <i class=\"fa fa-sitemap\"></i>\n </a>\n <button\n *abpPermission=\"policies.PagesUpdate\"\n type=\"button\"\n class=\"btn btn-sm btn-light me-1\"\n (click)=\"openEdit(row)\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button\n *abpPermission=\"policies.PagesDelete\"\n type=\"button\"\n class=\"btn btn-sm btn-light\"\n (click)=\"delete(row)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </ng-template>\n </ngx-datatable-column>\n </ngx-datatable>\n </div>\n</div>\n\n<abp-modal [(visible)]=\"isModalOpen\" [busy]=\"isModalBusy()\" (disappear)=\"closeModal()\">\n <ng-template #abpHeader>\n <h3>{{ (editingPage ? 'Site::EditPage' : 'Site::NewPage') | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n @if (form) {\n <form [formGroup]=\"form\" (submit)=\"save()\">\n <button type=\"submit\" #submitButton style=\"display: none\"></button>\n\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.DisplayName' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"displayName\" />\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Name' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"name\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Name' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Route' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"route\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Route' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Template' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"template\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Template' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.ParentId' | abpLocalization }}</label>\n <nz-tree-select\n class=\"form-select parent-picker-select\"\n formControlName=\"parentId\"\n [nzNodes]=\"parentTreeNodes\"\n nzAllowClear\n nzShowSearch\n nzDefaultExpandAll\n nzDropdownClassName=\"parent-picker-dropdown\"\n [nzPlaceHolder]=\"'Site::DisplayName:Page.ParentId' | abpLocalization\"\n ></nz-tree-select>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.ParentId' | abpLocalization }}\n </small>\n </div>\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"site-page-is-active\"\n formControlName=\"isActive\"\n />\n <label class=\"form-check-label\" for=\"site-page-is-active\">\n {{ 'Site::DisplayName:Page.IsActive' | abpLocalization }}\n </label>\n </div>\n </form>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>\n {{ 'AbpUi::Cancel' | abpLocalization }}\n </button>\n <abp-button\n iconClass=\"fa fa-check\"\n [disabled]=\"!form?.valid\"\n [loading]=\"isModalBusy()\"\n (click)=\"submitButton?.nativeElement?.click()\"\n >\n {{ 'AbpUi::Save' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n", styles: [":host ::ng-deep .datatable-tree-button{display:none}.page-tree-toggle{border:none;background:transparent;padding:0;width:16px;cursor:pointer;color:inherit}::ng-deep .parent-picker-select{width:100%}::ng-deep .parent-picker-select.ant-select{color:inherit!important;height:unset!important;font-size:unset!important;--bs-form-select-bg-img: unset !important}::ng-deep .parent-picker-select .ant-select-selector{background:transparent!important;border:none!important;padding:.475rem 1.25rem!important;box-shadow:none!important;height:auto!important}::ng-deep .parent-picker-select .ant-select-selection-placeholder{color:inherit!important}::ng-deep .parent-picker-select.form-select{padding:0!important}::ng-deep .parent-picker-dropdown.ant-select-dropdown{background:var(--lpx-content-bg, var(--bs-secondary-bg, #fff))!important}::ng-deep .parent-picker-dropdown .ant-select-tree-node-content-wrapper:hover{background-color:var(--bs-primary)!important;color:var(--bs-white)!important}::ng-deep .parent-picker-dropdown .ant-select-tree-node-content-wrapper.ant-select-tree-node-selected{background-color:var(--lpx-brand)!important;color:var(--bs-white)!important}::ng-deep .parent-picker-dropdown .ant-select-tree{color:var(--bs-body-color)!important;background-color:transparent!important}\n"], dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: i3.ValidationGroupDirective, selector: "[formGroup],[formGroupName]", exportAs: ["validationGroup"] }, { kind: "directive", type: i3.ValidationDirective, selector: "[formControl],[formControlName]", exportAs: ["validationDirective"] }, { kind: "directive", type: i4.PermissionDirective, selector: "[abpPermission]", inputs: ["abpPermission", "abpPermissionRunChangeDetection"] }, { kind: "ngmodule", type: ThemeSharedModule }, { kind: "component", type: i2$1.ButtonComponent, selector: "abp-button", inputs: ["buttonId", "buttonClass", "buttonType", "formName", "iconClass", "loading", "disabled", "attributes"], outputs: ["click", "focus", "blur", "abpClick", "abpFocus", "abpBlur"] }, { kind: "component", type: i2$1.ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }, { kind: "directive", type: i2$1.ModalCloseDirective, selector: "[abpClose]" }, { kind: "component", type: i6.DatatableComponent, selector: "ngx-datatable", inputs: ["targetMarkerTemplate", "rows", "groupRowsBy", "groupedRows", "columns", "selected", "scrollbarV", "scrollbarVDynamic", "scrollbarH", "rowHeight", "columnMode", "headerHeight", "footerHeight", "externalPaging", "externalSorting", "limit", "count", "offset", "loadingIndicator", "ghostLoadingIndicator", "selectionType", "reorderable", "swapColumns", "sortType", "sorts", "cssClasses", "messages", "rowClass", "selectCheck", "displayCheck", "groupExpansionDefault", "trackByProp", "selectAllRowsOnPage", "virtualization", "treeFromRelation", "treeToRelation", "summaryRow", "summaryHeight", "summaryPosition", "disableRowCheck", "rowDraggable", "enableClearingSortState", "rowIdentity"], outputs: ["scroll", "activate", "select", "sort", "page", "reorder", "resize", "tableContextmenu", "treeAction", "rowDragEvents"] }, { kind: "directive", type: i6.DataTableColumnDirective, selector: "ngx-datatable-column", inputs: ["name", "prop", "bindAsUnsafeHtml", "frozenLeft", "frozenRight", "flexGrow", "resizeable", "comparator", "pipe", "sortable", "draggable", "canAutoResize", "minWidth", "width", "maxWidth", "checkboxable", "headerCheckboxable", "headerClass", "cellClass", "isTreeColumn", "treeLevelIndent", "summaryFunc", "summaryTemplate", "cellTemplate", "headerTemplate", "treeToggleTemplate", "ghostCellTemplate"] }, { kind: "directive", type: i6.DataTableColumnCellDirective, selector: "[ngx-datatable-cell-template]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: NgxDatatableModule }, { kind: "ngmodule", type: NzTreeSelectModule }, { kind: "component", type: i8.NzTreeSelectComponent, selector: "nz-tree-select", inputs: ["nzId", "nzAllowClear", "nzShowExpand", "nzShowLine", "nzDropdownMatchSelectWidth", "nzCheckable", "nzHideUnMatched", "nzShowIcon", "nzShowSearch", "nzDisabled", "nzAsyncData", "nzMultiple", "nzDefaultExpandAll", "nzCheckStrictly", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualHeight", "nzExpandedIcon", "nzNotFoundContent", "nzNodes", "nzOpen", "nzSize", "nzVariant", "nzPlaceHolder", "nzDropdownStyle", "nzDropdownClassName", "nzBackdrop", "nzStatus", "nzPlacement", "nzExpandedKeys", "nzPrefix", "nzSuffixIcon", "nzDisplayWith", "nzMaxTagCount", "nzMaxTagPlaceholder", "nzTreeTemplate"], outputs: ["nzOpenChange", "nzCleared", "nzRemoved", "nzExpandChange", "nzTreeClick", "nzTreeCheckboxChange"], exportAs: ["nzTreeSelect"] }, { kind: "pipe", type: i4.LocalizationPipe, name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
239
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.2", type: PagesComponent, isStandalone: true, selector: "site-pages", viewQueries: [{ propertyName: "submitButton", first: true, predicate: ["submitButton"], descendants: true }], ngImport: i0, template: "<div class=\"card mb-3\">\n <div class=\"card-body\">\n <div class=\"row align-items-end g-2\">\n <div class=\"col-md-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.IsActive' | abpLocalization }}</label>\n <select class=\"form-select\" [(ngModel)]=\"filters.isActive\" (change)=\"applyFilters()\">\n <option [ngValue]=\"undefined\">--</option>\n <option [ngValue]=\"true\">{{ 'AbpUi::Yes' | abpLocalization }}</option>\n <option [ngValue]=\"false\">{{ 'AbpUi::No' | abpLocalization }}</option>\n </select>\n </div>\n <div class=\"col-md-5\">\n <label class=\"form-label\">{{ 'AbpUi::Search' | abpLocalization }}</label>\n <input\n type=\"text\"\n class=\"form-control\"\n [(ngModel)]=\"filters.filter\"\n (keyup.enter)=\"applyFilters()\"\n [placeholder]=\"'AbpUi::Search' | abpLocalization\"\n />\n </div>\n <div class=\"col-md-4\">\n <button type=\"button\" class=\"btn btn-primary me-2\" (click)=\"applyFilters()\">\n <i class=\"fa fa-search me-1\"></i>{{ 'AbpUi::Search' | abpLocalization }}\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"clearFilters()\">\n {{ 'AbpUi::Clear' | abpLocalization }}\n </button>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"card\">\n <div class=\"card-body\">\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <h5 class=\"mb-0\">{{ 'Site::Pages' | abpLocalization }}</h5>\n <button\n *abpPermission=\"policies.PagesCreate\"\n type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"openCreate()\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::NewPage' | abpLocalization }}\n </button>\n </div>\n\n <ngx-datatable\n class=\"material\"\n [rows]=\"data().items\"\n columnMode=\"flex\"\n [headerHeight]=\"42\"\n [footerHeight]=\"42\"\n rowHeight=\"auto\"\n treeFromRelation=\"parentId\"\n treeToRelation=\"id\"\n (treeAction)=\"onTreeAction($event)\"\n >\n <ngx-datatable-column\n prop=\"displayName\"\n [flexGrow]=\"2\"\n [isTreeColumn]=\"true\"\n [treeLevelIndent]=\"20\"\n [name]=\"'Site::DisplayName:Page.DisplayName' | abpLocalization\"\n >\n <ng-template\n let-row=\"row\"\n let-treeStatus=\"treeStatus\"\n let-onTreeAction=\"onTreeAction\"\n ngx-datatable-cell-template\n >\n @if (hasChildren(row)) {\n <button type=\"button\" class=\"page-tree-toggle\" (click)=\"onTreeAction()\">\n <i\n class=\"fa\"\n [ngClass]=\"treeStatus === 'collapsed' ? 'fa-caret-right' : 'fa-caret-down'\"\n ></i>\n </button>\n }\n {{ row.displayName }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n prop=\"name\"\n [flexGrow]=\"2\"\n [name]=\"'Site::DisplayName:Page.Name' | abpLocalization\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n prop=\"route\"\n [flexGrow]=\"2\"\n [name]=\"'Site::DisplayName:Page.Route' | abpLocalization\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n [flexGrow]=\"1\"\n [name]=\"'Site::DisplayName:Page.IsActive' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <i class=\"fa\" [ngClass]=\"row.isActive ? 'fa-check text-success' : 'fa-times text-muted'\"></i>\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column [flexGrow]=\"2\" [sortable]=\"false\" [name]=\"'AbpUi::Actions' | abpLocalization\">\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <a\n *abpPermission=\"policies.ContentTypes\"\n class=\"btn btn-sm btn-light me-1\"\n [routerLink]=\"['/site/pages', row.id, 'content-types']\"\n [title]=\"'Site::ContentTypes' | abpLocalization\"\n >\n <i class=\"fa fa-sitemap\"></i>\n </a>\n <button\n *abpPermission=\"policies.PagesUpdate\"\n type=\"button\"\n class=\"btn btn-sm btn-light me-1\"\n (click)=\"openEdit(row)\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button\n *abpPermission=\"policies.PagesDelete\"\n type=\"button\"\n class=\"btn btn-sm btn-light\"\n (click)=\"delete(row)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </ng-template>\n </ngx-datatable-column>\n </ngx-datatable>\n </div>\n</div>\n\n<abp-modal [(visible)]=\"isModalOpen\" [busy]=\"isModalBusy()\" (disappear)=\"closeModal()\">\n <ng-template #abpHeader>\n <h3>{{ (editingPage ? 'Site::EditPage' : 'Site::NewPage') | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n @if (form) {\n <form [formGroup]=\"form\" (submit)=\"save()\">\n <button type=\"submit\" #submitButton style=\"display: none\"></button>\n\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.DisplayName' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"displayName\" />\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Name' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"name\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Name' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Route' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"route\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Route' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Template' | abpLocalization }}</label>\n <input\n type=\"text\"\n class=\"form-control\"\n formControlName=\"template\"\n list=\"site-page-template-options\"\n autocomplete=\"off\"\n />\n <datalist id=\"site-page-template-options\">\n @for (path of templateOptions(); track path) {\n <option [value]=\"path\"></option>\n }\n </datalist>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Template' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.ParentId' | abpLocalization }}</label>\n <nz-tree-select\n class=\"form-select parent-picker-select\"\n formControlName=\"parentId\"\n [nzNodes]=\"parentTreeNodes\"\n nzAllowClear\n nzShowSearch\n nzDefaultExpandAll\n nzDropdownClassName=\"parent-picker-dropdown\"\n [nzPlaceHolder]=\"'Site::DisplayName:Page.ParentId' | abpLocalization\"\n ></nz-tree-select>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.ParentId' | abpLocalization }}\n </small>\n </div>\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"site-page-is-active\"\n formControlName=\"isActive\"\n />\n <label class=\"form-check-label\" for=\"site-page-is-active\">\n {{ 'Site::DisplayName:Page.IsActive' | abpLocalization }}\n </label>\n </div>\n </form>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>\n {{ 'AbpUi::Cancel' | abpLocalization }}\n </button>\n <abp-button\n iconClass=\"fa fa-check\"\n [disabled]=\"!form?.valid\"\n [loading]=\"isModalBusy()\"\n (click)=\"submitButton?.nativeElement?.click()\"\n >\n {{ 'AbpUi::Save' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n", styles: [":host ::ng-deep .datatable-tree-button{display:none}.page-tree-toggle{border:none;background:transparent;padding:0;width:16px;cursor:pointer;color:inherit}::ng-deep .parent-picker-select{width:100%}::ng-deep .parent-picker-select.ant-select{color:inherit!important;height:unset!important;font-size:unset!important;--bs-form-select-bg-img: unset !important}::ng-deep .parent-picker-select .ant-select-selector{background:transparent!important;border:none!important;padding:.475rem 1.25rem!important;box-shadow:none!important;height:auto!important}::ng-deep .parent-picker-select .ant-select-selection-placeholder{color:inherit!important}::ng-deep .parent-picker-select.form-select{padding:0!important}::ng-deep .parent-picker-dropdown.ant-select-dropdown{background:var(--lpx-content-bg, var(--bs-secondary-bg, #fff))!important}::ng-deep .parent-picker-dropdown .ant-select-tree-node-content-wrapper:hover{background-color:var(--bs-primary)!important;color:var(--bs-white)!important}::ng-deep .parent-picker-dropdown .ant-select-tree-node-content-wrapper.ant-select-tree-node-selected{background-color:var(--lpx-brand)!important;color:var(--bs-white)!important}::ng-deep .parent-picker-dropdown .ant-select-tree{color:var(--bs-body-color)!important;background-color:transparent!important}\n"], dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: i3.ValidationGroupDirective, selector: "[formGroup],[formGroupName]", exportAs: ["validationGroup"] }, { kind: "directive", type: i3.ValidationDirective, selector: "[formControl],[formControlName]", exportAs: ["validationDirective"] }, { kind: "directive", type: i4.PermissionDirective, selector: "[abpPermission]", inputs: ["abpPermission", "abpPermissionRunChangeDetection"] }, { kind: "ngmodule", type: ThemeSharedModule }, { kind: "component", type: i2$1.ButtonComponent, selector: "abp-button", inputs: ["buttonId", "buttonClass", "buttonType", "formName", "iconClass", "loading", "disabled", "attributes"], outputs: ["click", "focus", "blur", "abpClick", "abpFocus", "abpBlur"] }, { kind: "component", type: i2$1.ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }, { kind: "directive", type: i2$1.ModalCloseDirective, selector: "[abpClose]" }, { kind: "component", type: i6.DatatableComponent, selector: "ngx-datatable", inputs: ["targetMarkerTemplate", "rows", "groupRowsBy", "groupedRows", "columns", "selected", "scrollbarV", "scrollbarVDynamic", "scrollbarH", "rowHeight", "columnMode", "headerHeight", "footerHeight", "externalPaging", "externalSorting", "limit", "count", "offset", "loadingIndicator", "ghostLoadingIndicator", "selectionType", "reorderable", "swapColumns", "sortType", "sorts", "cssClasses", "messages", "rowClass", "selectCheck", "displayCheck", "groupExpansionDefault", "trackByProp", "selectAllRowsOnPage", "virtualization", "treeFromRelation", "treeToRelation", "summaryRow", "summaryHeight", "summaryPosition", "disableRowCheck", "rowDraggable", "enableClearingSortState", "rowIdentity"], outputs: ["scroll", "activate", "select", "sort", "page", "reorder", "resize", "tableContextmenu", "treeAction", "rowDragEvents"] }, { kind: "directive", type: i6.DataTableColumnDirective, selector: "ngx-datatable-column", inputs: ["name", "prop", "bindAsUnsafeHtml", "frozenLeft", "frozenRight", "flexGrow", "resizeable", "comparator", "pipe", "sortable", "draggable", "canAutoResize", "minWidth", "width", "maxWidth", "checkboxable", "headerCheckboxable", "headerClass", "cellClass", "isTreeColumn", "treeLevelIndent", "summaryFunc", "summaryTemplate", "cellTemplate", "headerTemplate", "treeToggleTemplate", "ghostCellTemplate"] }, { kind: "directive", type: i6.DataTableColumnCellDirective, selector: "[ngx-datatable-cell-template]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: NgxDatatableModule }, { kind: "ngmodule", type: NzTreeSelectModule }, { kind: "component", type: i8.NzTreeSelectComponent, selector: "nz-tree-select", inputs: ["nzId", "nzAllowClear", "nzShowExpand", "nzShowLine", "nzDropdownMatchSelectWidth", "nzCheckable", "nzHideUnMatched", "nzShowIcon", "nzShowSearch", "nzDisabled", "nzAsyncData", "nzMultiple", "nzDefaultExpandAll", "nzCheckStrictly", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualHeight", "nzExpandedIcon", "nzNotFoundContent", "nzNodes", "nzOpen", "nzSize", "nzVariant", "nzPlaceHolder", "nzDropdownStyle", "nzDropdownClassName", "nzBackdrop", "nzStatus", "nzPlacement", "nzExpandedKeys", "nzPrefix", "nzSuffixIcon", "nzDisplayWith", "nzMaxTagCount", "nzMaxTagPlaceholder", "nzTreeTemplate"], outputs: ["nzOpenChange", "nzCleared", "nzRemoved", "nzExpandChange", "nzTreeClick", "nzTreeCheckboxChange"], exportAs: ["nzTreeSelect"] }, { kind: "pipe", type: i4.LocalizationPipe, name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
217
240
|
}
|
|
218
241
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: PagesComponent, decorators: [{
|
|
219
242
|
type: Component,
|
|
@@ -225,11 +248,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImpor
|
|
|
225
248
|
NzTreeSelectModule,
|
|
226
249
|
PermissionDirective,
|
|
227
250
|
RouterLink,
|
|
228
|
-
], template: "<div class=\"card mb-3\">\n <div class=\"card-body\">\n <div class=\"row align-items-end g-2\">\n <div class=\"col-md-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.IsActive' | abpLocalization }}</label>\n <select class=\"form-select\" [(ngModel)]=\"filters.isActive\" (change)=\"applyFilters()\">\n <option [ngValue]=\"undefined\">--</option>\n <option [ngValue]=\"true\">{{ 'AbpUi::Yes' | abpLocalization }}</option>\n <option [ngValue]=\"false\">{{ 'AbpUi::No' | abpLocalization }}</option>\n </select>\n </div>\n <div class=\"col-md-5\">\n <label class=\"form-label\">{{ 'AbpUi::Search' | abpLocalization }}</label>\n <input\n type=\"text\"\n class=\"form-control\"\n [(ngModel)]=\"filters.filter\"\n (keyup.enter)=\"applyFilters()\"\n [placeholder]=\"'AbpUi::Search' | abpLocalization\"\n />\n </div>\n <div class=\"col-md-4\">\n <button type=\"button\" class=\"btn btn-primary me-2\" (click)=\"applyFilters()\">\n <i class=\"fa fa-search me-1\"></i>{{ 'AbpUi::Search' | abpLocalization }}\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"clearFilters()\">\n {{ 'AbpUi::Clear' | abpLocalization }}\n </button>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"card\">\n <div class=\"card-body\">\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <h5 class=\"mb-0\">{{ 'Site::Pages' | abpLocalization }}</h5>\n <button\n *abpPermission=\"policies.PagesCreate\"\n type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"openCreate()\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::NewPage' | abpLocalization }}\n </button>\n </div>\n\n <ngx-datatable\n class=\"material\"\n [rows]=\"data().items\"\n columnMode=\"flex\"\n [headerHeight]=\"42\"\n [footerHeight]=\"42\"\n rowHeight=\"auto\"\n treeFromRelation=\"parentId\"\n treeToRelation=\"id\"\n (treeAction)=\"onTreeAction($event)\"\n >\n <ngx-datatable-column\n prop=\"displayName\"\n [flexGrow]=\"2\"\n [isTreeColumn]=\"true\"\n [treeLevelIndent]=\"20\"\n [name]=\"'Site::DisplayName:Page.DisplayName' | abpLocalization\"\n >\n <ng-template\n let-row=\"row\"\n let-treeStatus=\"treeStatus\"\n let-onTreeAction=\"onTreeAction\"\n ngx-datatable-cell-template\n >\n @if (hasChildren(row)) {\n <button type=\"button\" class=\"page-tree-toggle\" (click)=\"onTreeAction()\">\n <i\n class=\"fa\"\n [ngClass]=\"treeStatus === 'collapsed' ? 'fa-caret-right' : 'fa-caret-down'\"\n ></i>\n </button>\n }\n {{ row.displayName }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n prop=\"name\"\n [flexGrow]=\"2\"\n [name]=\"'Site::DisplayName:Page.Name' | abpLocalization\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n prop=\"route\"\n [flexGrow]=\"2\"\n [name]=\"'Site::DisplayName:Page.Route' | abpLocalization\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n [flexGrow]=\"1\"\n [name]=\"'Site::DisplayName:Page.IsActive' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <i class=\"fa\" [ngClass]=\"row.isActive ? 'fa-check text-success' : 'fa-times text-muted'\"></i>\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column [flexGrow]=\"2\" [sortable]=\"false\" [name]=\"'AbpUi::Actions' | abpLocalization\">\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <a\n *abpPermission=\"policies.ContentTypes\"\n class=\"btn btn-sm btn-light me-1\"\n [routerLink]=\"['/site/pages', row.id, 'content-types']\"\n [title]=\"'Site::ContentTypes' | abpLocalization\"\n >\n <i class=\"fa fa-sitemap\"></i>\n </a>\n <button\n *abpPermission=\"policies.PagesUpdate\"\n type=\"button\"\n class=\"btn btn-sm btn-light me-1\"\n (click)=\"openEdit(row)\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button\n *abpPermission=\"policies.PagesDelete\"\n type=\"button\"\n class=\"btn btn-sm btn-light\"\n (click)=\"delete(row)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </ng-template>\n </ngx-datatable-column>\n </ngx-datatable>\n </div>\n</div>\n\n<abp-modal [(visible)]=\"isModalOpen\" [busy]=\"isModalBusy()\" (disappear)=\"closeModal()\">\n <ng-template #abpHeader>\n <h3>{{ (editingPage ? 'Site::EditPage' : 'Site::NewPage') | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n @if (form) {\n <form [formGroup]=\"form\" (submit)=\"save()\">\n <button type=\"submit\" #submitButton style=\"display: none\"></button>\n\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.DisplayName' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"displayName\" />\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Name' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"name\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Name' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Route' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"route\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Route' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Template' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"template\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Template' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.ParentId' | abpLocalization }}</label>\n <nz-tree-select\n class=\"form-select parent-picker-select\"\n formControlName=\"parentId\"\n [nzNodes]=\"parentTreeNodes\"\n nzAllowClear\n nzShowSearch\n nzDefaultExpandAll\n nzDropdownClassName=\"parent-picker-dropdown\"\n [nzPlaceHolder]=\"'Site::DisplayName:Page.ParentId' | abpLocalization\"\n ></nz-tree-select>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.ParentId' | abpLocalization }}\n </small>\n </div>\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"site-page-is-active\"\n formControlName=\"isActive\"\n />\n <label class=\"form-check-label\" for=\"site-page-is-active\">\n {{ 'Site::DisplayName:Page.IsActive' | abpLocalization }}\n </label>\n </div>\n </form>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>\n {{ 'AbpUi::Cancel' | abpLocalization }}\n </button>\n <abp-button\n iconClass=\"fa fa-check\"\n [disabled]=\"!form?.valid\"\n [loading]=\"isModalBusy()\"\n (click)=\"submitButton?.nativeElement?.click()\"\n >\n {{ 'AbpUi::Save' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n", styles: [":host ::ng-deep .datatable-tree-button{display:none}.page-tree-toggle{border:none;background:transparent;padding:0;width:16px;cursor:pointer;color:inherit}::ng-deep .parent-picker-select{width:100%}::ng-deep .parent-picker-select.ant-select{color:inherit!important;height:unset!important;font-size:unset!important;--bs-form-select-bg-img: unset !important}::ng-deep .parent-picker-select .ant-select-selector{background:transparent!important;border:none!important;padding:.475rem 1.25rem!important;box-shadow:none!important;height:auto!important}::ng-deep .parent-picker-select .ant-select-selection-placeholder{color:inherit!important}::ng-deep .parent-picker-select.form-select{padding:0!important}::ng-deep .parent-picker-dropdown.ant-select-dropdown{background:var(--lpx-content-bg, var(--bs-secondary-bg, #fff))!important}::ng-deep .parent-picker-dropdown .ant-select-tree-node-content-wrapper:hover{background-color:var(--bs-primary)!important;color:var(--bs-white)!important}::ng-deep .parent-picker-dropdown .ant-select-tree-node-content-wrapper.ant-select-tree-node-selected{background-color:var(--lpx-brand)!important;color:var(--bs-white)!important}::ng-deep .parent-picker-dropdown .ant-select-tree{color:var(--bs-body-color)!important;background-color:transparent!important}\n"] }]
|
|
251
|
+
], template: "<div class=\"card mb-3\">\n <div class=\"card-body\">\n <div class=\"row align-items-end g-2\">\n <div class=\"col-md-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.IsActive' | abpLocalization }}</label>\n <select class=\"form-select\" [(ngModel)]=\"filters.isActive\" (change)=\"applyFilters()\">\n <option [ngValue]=\"undefined\">--</option>\n <option [ngValue]=\"true\">{{ 'AbpUi::Yes' | abpLocalization }}</option>\n <option [ngValue]=\"false\">{{ 'AbpUi::No' | abpLocalization }}</option>\n </select>\n </div>\n <div class=\"col-md-5\">\n <label class=\"form-label\">{{ 'AbpUi::Search' | abpLocalization }}</label>\n <input\n type=\"text\"\n class=\"form-control\"\n [(ngModel)]=\"filters.filter\"\n (keyup.enter)=\"applyFilters()\"\n [placeholder]=\"'AbpUi::Search' | abpLocalization\"\n />\n </div>\n <div class=\"col-md-4\">\n <button type=\"button\" class=\"btn btn-primary me-2\" (click)=\"applyFilters()\">\n <i class=\"fa fa-search me-1\"></i>{{ 'AbpUi::Search' | abpLocalization }}\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"clearFilters()\">\n {{ 'AbpUi::Clear' | abpLocalization }}\n </button>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"card\">\n <div class=\"card-body\">\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <h5 class=\"mb-0\">{{ 'Site::Pages' | abpLocalization }}</h5>\n <button\n *abpPermission=\"policies.PagesCreate\"\n type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"openCreate()\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::NewPage' | abpLocalization }}\n </button>\n </div>\n\n <ngx-datatable\n class=\"material\"\n [rows]=\"data().items\"\n columnMode=\"flex\"\n [headerHeight]=\"42\"\n [footerHeight]=\"42\"\n rowHeight=\"auto\"\n treeFromRelation=\"parentId\"\n treeToRelation=\"id\"\n (treeAction)=\"onTreeAction($event)\"\n >\n <ngx-datatable-column\n prop=\"displayName\"\n [flexGrow]=\"2\"\n [isTreeColumn]=\"true\"\n [treeLevelIndent]=\"20\"\n [name]=\"'Site::DisplayName:Page.DisplayName' | abpLocalization\"\n >\n <ng-template\n let-row=\"row\"\n let-treeStatus=\"treeStatus\"\n let-onTreeAction=\"onTreeAction\"\n ngx-datatable-cell-template\n >\n @if (hasChildren(row)) {\n <button type=\"button\" class=\"page-tree-toggle\" (click)=\"onTreeAction()\">\n <i\n class=\"fa\"\n [ngClass]=\"treeStatus === 'collapsed' ? 'fa-caret-right' : 'fa-caret-down'\"\n ></i>\n </button>\n }\n {{ row.displayName }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n prop=\"name\"\n [flexGrow]=\"2\"\n [name]=\"'Site::DisplayName:Page.Name' | abpLocalization\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n prop=\"route\"\n [flexGrow]=\"2\"\n [name]=\"'Site::DisplayName:Page.Route' | abpLocalization\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n [flexGrow]=\"1\"\n [name]=\"'Site::DisplayName:Page.IsActive' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <i class=\"fa\" [ngClass]=\"row.isActive ? 'fa-check text-success' : 'fa-times text-muted'\"></i>\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column [flexGrow]=\"2\" [sortable]=\"false\" [name]=\"'AbpUi::Actions' | abpLocalization\">\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <a\n *abpPermission=\"policies.ContentTypes\"\n class=\"btn btn-sm btn-light me-1\"\n [routerLink]=\"['/site/pages', row.id, 'content-types']\"\n [title]=\"'Site::ContentTypes' | abpLocalization\"\n >\n <i class=\"fa fa-sitemap\"></i>\n </a>\n <button\n *abpPermission=\"policies.PagesUpdate\"\n type=\"button\"\n class=\"btn btn-sm btn-light me-1\"\n (click)=\"openEdit(row)\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button\n *abpPermission=\"policies.PagesDelete\"\n type=\"button\"\n class=\"btn btn-sm btn-light\"\n (click)=\"delete(row)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </ng-template>\n </ngx-datatable-column>\n </ngx-datatable>\n </div>\n</div>\n\n<abp-modal [(visible)]=\"isModalOpen\" [busy]=\"isModalBusy()\" (disappear)=\"closeModal()\">\n <ng-template #abpHeader>\n <h3>{{ (editingPage ? 'Site::EditPage' : 'Site::NewPage') | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n @if (form) {\n <form [formGroup]=\"form\" (submit)=\"save()\">\n <button type=\"submit\" #submitButton style=\"display: none\"></button>\n\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.DisplayName' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"displayName\" />\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Name' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"name\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Name' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Route' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"route\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Route' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Template' | abpLocalization }}</label>\n <input\n type=\"text\"\n class=\"form-control\"\n formControlName=\"template\"\n list=\"site-page-template-options\"\n autocomplete=\"off\"\n />\n <datalist id=\"site-page-template-options\">\n @for (path of templateOptions(); track path) {\n <option [value]=\"path\"></option>\n }\n </datalist>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Template' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.ParentId' | abpLocalization }}</label>\n <nz-tree-select\n class=\"form-select parent-picker-select\"\n formControlName=\"parentId\"\n [nzNodes]=\"parentTreeNodes\"\n nzAllowClear\n nzShowSearch\n nzDefaultExpandAll\n nzDropdownClassName=\"parent-picker-dropdown\"\n [nzPlaceHolder]=\"'Site::DisplayName:Page.ParentId' | abpLocalization\"\n ></nz-tree-select>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.ParentId' | abpLocalization }}\n </small>\n </div>\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"site-page-is-active\"\n formControlName=\"isActive\"\n />\n <label class=\"form-check-label\" for=\"site-page-is-active\">\n {{ 'Site::DisplayName:Page.IsActive' | abpLocalization }}\n </label>\n </div>\n </form>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>\n {{ 'AbpUi::Cancel' | abpLocalization }}\n </button>\n <abp-button\n iconClass=\"fa fa-check\"\n [disabled]=\"!form?.valid\"\n [loading]=\"isModalBusy()\"\n (click)=\"submitButton?.nativeElement?.click()\"\n >\n {{ 'AbpUi::Save' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n", styles: [":host ::ng-deep .datatable-tree-button{display:none}.page-tree-toggle{border:none;background:transparent;padding:0;width:16px;cursor:pointer;color:inherit}::ng-deep .parent-picker-select{width:100%}::ng-deep .parent-picker-select.ant-select{color:inherit!important;height:unset!important;font-size:unset!important;--bs-form-select-bg-img: unset !important}::ng-deep .parent-picker-select .ant-select-selector{background:transparent!important;border:none!important;padding:.475rem 1.25rem!important;box-shadow:none!important;height:auto!important}::ng-deep .parent-picker-select .ant-select-selection-placeholder{color:inherit!important}::ng-deep .parent-picker-select.form-select{padding:0!important}::ng-deep .parent-picker-dropdown.ant-select-dropdown{background:var(--lpx-content-bg, var(--bs-secondary-bg, #fff))!important}::ng-deep .parent-picker-dropdown .ant-select-tree-node-content-wrapper:hover{background-color:var(--bs-primary)!important;color:var(--bs-white)!important}::ng-deep .parent-picker-dropdown .ant-select-tree-node-content-wrapper.ant-select-tree-node-selected{background-color:var(--lpx-brand)!important;color:var(--bs-white)!important}::ng-deep .parent-picker-dropdown .ant-select-tree{color:var(--bs-body-color)!important;background-color:transparent!important}\n"] }]
|
|
229
252
|
}], ctorParameters: () => [], propDecorators: { submitButton: [{
|
|
230
253
|
type: ViewChild,
|
|
231
254
|
args: ['submitButton']
|
|
232
255
|
}] } });
|
|
233
256
|
|
|
234
257
|
export { PagesComponent };
|
|
235
|
-
//# sourceMappingURL=dignite-ng.site-pages.component-
|
|
258
|
+
//# sourceMappingURL=dignite-ng.site-pages.component-BwGyK7jw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dignite-ng.site-pages.component-BwGyK7jw.mjs","sources":["../../../projects/site/src/lib/components/pages/pages.component.ts","../../../projects/site/src/lib/components/pages/pages.component.html"],"sourcesContent":["import { CoreModule, ListResultDto, PermissionDirective, PermissionService } from '@abp/ng.core';\nimport {\n Confirmation,\n ConfirmationService,\n ThemeSharedModule,\n ToasterService,\n} from '@abp/ng.theme.shared';\nimport { NgxDatatableModule } from '@swimlane/ngx-datatable';\nimport type { TreeStatus } from '@swimlane/ngx-datatable';\nimport {\n Component,\n ElementRef,\n ViewChild,\n inject,\n signal,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { Router, RouterLink } from '@angular/router';\nimport { NzTreeSelectModule } from 'ng-zorro-antd/tree-select';\nimport type { NzTreeNodeOptions } from 'ng-zorro-antd/tree';\nimport { PageAdminService } from '../../proxy/dignite/site/admin/pages/page-admin.service';\nimport type { GetPageListInput } from '../../proxy/dignite/site/admin/pages/models';\nimport type { PageDto } from '../../proxy/dignite/site/pages/models';\nimport { SiteThemeAdminService } from '../../proxy/dignite/site/admin/themes/site-theme-admin.service';\nimport { SiteThemeFileStatus } from '../../proxy/dignite/site/themes/site-theme-file-status.enum';\nimport { eSitePolicyNames } from '../../enums/policy-names';\n\n/** Max lengths mirror `PageConsts` (`src/Dignite.Site.Domain.Shared/Pages/PageConsts.cs`). */\nconst PAGE_CONSTS = {\n maxNameLength: 64,\n maxDisplayNameLength: 128,\n maxRouteLength: 512,\n maxTemplateLength: 256,\n} as const;\n\n/** Mirrors `IdentifierName.Pattern` (`src/Dignite.Site.Domain.Shared/IdentifierName.cs`). */\nconst NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;\n\n/** Mirrors `PageConsts.RoutePattern`. */\nconst ROUTE_PATTERN = /^\\S+$/;\n\n/** Mirrors `PageConsts.TemplatePattern`. Required - at least one character - since `template` is required. */\nconst TEMPLATE_PATTERN = /^\\/?[A-Za-z0-9_][A-Za-z0-9_/-]*$/;\n\n/** A page, plus the expand/collapse state `ngx-datatable`'s tree mode keeps on each row. */\ntype PageRow = PageDto & { treeStatus?: TreeStatus };\n\n@Component({\n selector: 'site-pages',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './pages.component.html',\n imports: [\n CoreModule,\n ThemeSharedModule,\n ReactiveFormsModule,\n NgxDatatableModule,\n NzTreeSelectModule,\n PermissionDirective,\n RouterLink,\n ],\n styles: `\n /* ngx-datatable always renders its own .datatable-tree-button for every row in the tree column,\n with no chrome reset (bare native <button>) and no way to suppress it for a childless row -\n [treeToggleTemplate] is documented to override it but does not take effect in this library\n version (tried both content-projection via ngx-datatable-tree-toggle and a direct\n [treeToggleTemplate] binding; neither replaced the default). Hidden here instead, with our own\n toggle built into the column's ngx-datatable-cell-template - see pages.component.html - which\n only renders one when hasChildren() says there is something to expand. */\n :host ::ng-deep .datatable-tree-button {\n display: none;\n }\n\n .page-tree-toggle {\n border: none;\n background: transparent;\n padding: 0;\n width: 16px;\n cursor: pointer;\n color: inherit;\n }\n\n /* Dresses nz-tree-select up as a Bootstrap .form-select, matching field-arrangement.component.ts's\n .field-picker-select for the same reason: ng-zorro's own look does not match the plain\n .form-control/.form-select styling of every other field in this form.\n\n Plain ::ng-deep, not :host ::ng-deep - this form lives inside abp-modal, which ng-bootstrap\n renders as an NgbModalWindow appended straight to <body>, outside <site-pages>'s own DOM\n subtree. A :host-scoped rule compiles to an attribute-selector prefix scoped to this\n component's own host element, which can only ever match a descendant of that element - never\n true here, so the rule silently never applied and the select fell back to ng-zorro's raw\n styling (a barely 8px-tall selector box, nothing like the surrounding .form-control fields).\n The .parent-picker-dropdown rules below already got this right; these four did not. */\n ::ng-deep .parent-picker-select {\n width: 100%;\n }\n ::ng-deep .parent-picker-select.ant-select {\n color: inherit !important;\n height:unset !important;\n font-size: unset !important;\n --bs-form-select-bg-img: unset !important;\n }\n ::ng-deep .parent-picker-select .ant-select-selector {\n background: transparent !important;\n border: none !important;\n padding: 0.475rem 1.25rem !important;\n box-shadow: none !important;\n height: auto !important;\n }\n ::ng-deep .parent-picker-select .ant-select-selection-placeholder {\n color: inherit !important;\n }\n ::ng-deep .parent-picker-select.form-select {\n padding: 0 !important;\n }\n /* Compound, not descendant - nz-tree-select builds one class STRING (\"ant-select-dropdown\n ant-select-tree-dropdown parent-picker-dropdown\") and binds it with [class] on a single <div>\n (see NzTreeSelectComponent's dropdownClassName/ngOnChanges in ng-zorro-antd-tree-select.mjs),\n unlike nz-select, which puts nzDropdownClassName on the ancestor .cdk-overlay-pane via\n [cdkConnectedOverlayPanelClass] (see field-arrangement.component.ts's identically-shaped rule,\n which is a real ancestor-descendant match). \".parent-picker-dropdown .ant-select-dropdown\"\n (with a space) asks for .ant-select-dropdown *inside* .parent-picker-dropdown, but they're the\n same element here, so that never matched anything and this panel stayed on ant-design's own\n white default no matter what the nested rules below did. */\n /* --lpx-content-bg is a FULL LeptonX token (@volosoft/ngx-lepton-x: #f0f4f7 light, #121212 dark).\n LeptonX *Lite* - @volo/ngx-lepton-x.lite, what @abp/ng.theme.lepton-x wraps, and what this app\n actually runs - never defines it: it ships 11 --lpx-* tokens and this is not one of them. The\n chain therefore fell straight through to the literal #fff and this panel stayed white in every\n theme, while .ant-select-item/-tree below kept following --bs-body-color into light-grey-on-\n white. --bs-secondary-bg is the Bootstrap 5.3 \"one step off the body surface\" token, defined at\n :root by every Bootstrap-based theme and redefined under [data-bs-theme=dark] (#e9ecef ->\n #343a40 in Lite), so it flips with the host. Light mode moves from pure white to #e9ecef. */\n ::ng-deep .parent-picker-dropdown.ant-select-dropdown {\n background: var(--lpx-content-bg, var(--bs-secondary-bg, #fff)) !important;\n }\n /* nz-tree's per-node classes drop the \"select-\" infix outside of a select's dropdown\n (NzTreeNodeComponent's host bindings key every tree class off selectMode - see\n ng-zorro-antd-tree.mjs) - nz-tree-select's own embedded tree always runs in select mode, so\n its nodes carry ant-select-tree-node-content-wrapper/-selected, never the plain\n ant-tree-node-* classes a standalone <nz-tree> would use. The un-prefixed selectors here\n matched nothing, silently leaving every node on ant-design's own default colors. */\n ::ng-deep .parent-picker-dropdown .ant-select-tree-node-content-wrapper:hover {\n background-color: var(--bs-primary) !important;\n color: var(--bs-white) !important;\n }\n ::ng-deep .parent-picker-dropdown .ant-select-tree-node-content-wrapper.ant-select-tree-node-selected {\n background-color: var(--lpx-brand) !important;\n color: var(--bs-white) !important;\n }\n /* !important, matching every other rule in this block - ant-design's own .ant-select-tree rule\n (background: #fff, color: rgba(0,0,0,.85)) carries the same one-class specificity as this\n override, and its stylesheet is injected lazily when nz-tree-select first opens, i.e. after\n this component's styles - a same-specificity tie that source order was resolving in its\n favor, keeping idle (non-hover, non-selected) nodes on ant-design's white/dark-gray default. */\n ::ng-deep .parent-picker-dropdown .ant-select-tree {\n color: var(--bs-body-color) !important;\n background-color: transparent !important;\n }\n `,\n})\nexport class PagesComponent {\n private readonly pageService = inject(PageAdminService);\n private readonly fb = inject(FormBuilder);\n private readonly confirmation = inject(ConfirmationService);\n private readonly toaster = inject(ToasterService);\n private readonly router = inject(Router);\n private readonly permission = inject(PermissionService);\n private readonly themeService = inject(SiteThemeAdminService);\n\n readonly policies = eSitePolicyNames;\n\n /**\n * The whole (filtered) result set, unpaged - the datatable paginates it client-side.\n *\n * State that changes in an HTTP callback (this, and the modal flags below) is a signal, not a plain\n * field: the host layout's ancestors (`abp-router-outlet`, the LeptonX layouts) are OnPush, and a\n * plain-field write in a response callback never marks them for check, so the list would stay empty\n * until some unrelated event happened to.\n */\n readonly data = signal<ListResultDto<PageRow>>({ items: [] });\n filters = {} as GetPageListInput;\n\n readonly isModalOpen = signal(false);\n readonly isModalBusy = signal(false);\n /** The theme's template paths, suggested under the Template input. */\n readonly templateOptions = signal<string[]>([]);\n editingPage?: PageDto;\n form?: FormGroup;\n\n @ViewChild('submitButton') submitButton?: ElementRef<HTMLButtonElement>;\n\n constructor() {\n this.applyFilters();\n }\n\n /** Whether the tree-toggle template should render a toggle for this row at all. */\n hasChildren(row: PageRow): boolean {\n return this.data().items.some(page => page.parentId === row.id);\n }\n\n applyFilters(): void {\n this.pageService.getList(this.filters).subscribe(result => {\n // A page's parentId can point at a page the current filter excludes (isActive/filter are\n // backend params, so a match can survive while its parent does not). Rather than let such a\n // row vanish from the tree, it renders at the root - normalized here once so every reader of\n // `data().items` (the datatable's tree grouping, the tree-select's candidate list) sees a\n // consistent, dangling-free parentId.\n const ids = new Set(result.items.map(page => page.id));\n\n this.data.set({\n items: result.items.map(page => ({\n ...page,\n parentId: page.parentId && ids.has(page.parentId) ? page.parentId : null,\n treeStatus: 'expanded' as TreeStatus,\n })),\n });\n });\n }\n\n clearFilters(): void {\n this.filters = {} as GetPageListInput;\n this.applyFilters();\n }\n\n /** Toggles one row's branch. `ngx-datatable` reads `treeStatus` off the row it is given back. */\n onTreeAction(event: { row: PageRow }): void {\n event.row.treeStatus = event.row.treeStatus === 'collapsed' ? 'expanded' : 'collapsed';\n this.data.set({ items: [...this.data().items] });\n }\n\n openCreate(): void {\n this.editingPage = undefined;\n this.form = this.buildForm();\n this.loadTemplateOptions();\n this.isModalOpen.set(true);\n }\n\n openEdit(page: PageDto): void {\n this.editingPage = page;\n this.form = this.buildForm(page);\n this.loadTemplateOptions();\n this.isModalOpen.set(true);\n }\n\n /**\n * The theme's templates, offered under the Template input. A suggestion list, not a choice: a page can name a\n * Razor view instead. Skipped without the Themes permission, and quietly empty when the theme cannot be read.\n */\n private loadTemplateOptions(): void {\n if (!this.permission.getGrantedPolicy(eSitePolicyNames.Themes)) {\n return;\n }\n\n this.themeService.getFiles({ skipHandleError: true }).subscribe({\n next: files =>\n this.templateOptions.set(\n (files.items ?? [])\n .filter(file => !file.isAsset && file.status !== SiteThemeFileStatus.Deleted)\n .map(file => file.path ?? ''),\n ),\n error: () => this.templateOptions.set([]),\n });\n }\n\n closeModal(): void {\n this.isModalOpen.set(false);\n this.form = undefined;\n this.editingPage = undefined;\n }\n\n save(): void {\n if (!this.form || this.form.invalid || this.isModalBusy()) {\n return;\n }\n\n this.isModalBusy.set(true);\n const value = this.form.getRawValue();\n const isCreating = !this.editingPage;\n\n const request$ = this.editingPage\n ? this.pageService.update(this.editingPage.id!, value)\n : this.pageService.create(value);\n\n request$.subscribe({\n next: page => {\n this.isModalBusy.set(false);\n this.closeModal();\n this.toaster.success('AbpUi::SavedSuccessfully');\n\n // A fresh page always has exactly one auto-created content type\n // (PageAdminAppService.CreateDefaultContentTypeAsync) still waiting for its fields - go straight\n // there instead of leaving the user to find the sitemap icon themselves.\n if (isCreating && this.permission.getGrantedPolicy(this.policies.ContentTypes)) {\n this.router.navigate(['/site/pages', page.id, 'content-types']);\n return;\n }\n\n this.applyFilters();\n },\n error: () => this.isModalBusy.set(false),\n });\n }\n\n delete(page: PageDto): void {\n // Not the generic AbpUi::ItemWillBeDeletedMessage: deleting a page also deletes its content types and\n // every content of those types, and this confirmation is the only place a person is told.\n this.confirmation\n .warn('Site::DeletePageConfirmMessage', 'AbpUi::AreYouSure', {\n messageLocalizationParams: [page.displayName ?? ''],\n })\n .subscribe((status: Confirmation.Status) => {\n if (status === Confirmation.Status.confirm) {\n this.pageService.delete(page.id!).subscribe(() => {\n this.applyFilters();\n this.toaster.success('AbpUi::SuccessfullyDeleted');\n });\n }\n });\n }\n\n private parentTreeNodesCache?: {\n items: PageRow[];\n editingId: string | undefined;\n nodes: NzTreeNodeOptions[];\n };\n\n /**\n * The \"Parent page\" picker's candidates: every page except the one being edited and its own\n * subtree - offering either as a choice would only trade a clean rejection in the picker for a\n * `PageParentCycleException` from the server.\n *\n * Cached against a cheap key, not recomputed every read, for the same reason\n * `field-arrangement.component.ts`'s `addableFieldOptions` is: `nz-tree-select` expects a stable\n * array reference, and a plain rebuild here would hand it a fresh one on every change-detection\n * cycle, including the ones firing while its dropdown is open.\n */\n get parentTreeNodes(): NzTreeNodeOptions[] {\n const editingId = this.editingPage?.id;\n const items = this.data().items;\n\n if (\n this.parentTreeNodesCache?.items !== items ||\n this.parentTreeNodesCache?.editingId !== editingId\n ) {\n const excluded = editingId ? this.subtreeIds(editingId) : new Set<string>();\n this.parentTreeNodesCache = {\n items,\n editingId,\n nodes: this.buildTreeNodes(null, excluded),\n };\n }\n\n return this.parentTreeNodesCache.nodes;\n }\n\n /** `rootId` and everything beneath it, found by repeatedly sweeping for newly-matched children. */\n private subtreeIds(rootId: string): Set<string> {\n const ids = new Set<string>([rootId]);\n\n for (let grew = true; grew; ) {\n grew = false;\n for (const page of this.data().items) {\n if (page.parentId && ids.has(page.parentId) && !ids.has(page.id!)) {\n ids.add(page.id!);\n grew = true;\n }\n }\n }\n\n return ids;\n }\n\n private buildTreeNodes(parentId: string | null, excluded: Set<string>): NzTreeNodeOptions[] {\n const items = this.data().items;\n\n return items\n .filter(page => (page.parentId ?? null) === parentId && !excluded.has(page.id!))\n .map(page => ({\n key: page.id!,\n title: page.displayName || page.name || '',\n children: this.buildTreeNodes(page.id!, excluded),\n isLeaf: !items.some(child => child.parentId === page.id),\n }));\n }\n\n private buildForm(page?: PageDto): FormGroup {\n return this.fb.group({\n name: [\n page?.name ?? '',\n [Validators.required, Validators.maxLength(PAGE_CONSTS.maxNameLength), Validators.pattern(NAME_PATTERN)],\n ],\n displayName: [\n page?.displayName ?? '',\n [Validators.required, Validators.maxLength(PAGE_CONSTS.maxDisplayNameLength)],\n ],\n route: [\n page?.route ?? '',\n [Validators.required, Validators.maxLength(PAGE_CONSTS.maxRouteLength), Validators.pattern(ROUTE_PATTERN)],\n ],\n template: [\n page?.template ?? '',\n [Validators.required, Validators.maxLength(PAGE_CONSTS.maxTemplateLength), Validators.pattern(TEMPLATE_PATTERN)],\n ],\n parentId: [page?.parentId ?? null],\n isActive: [page?.isActive ?? true],\n });\n }\n}\n","<div class=\"card mb-3\">\n <div class=\"card-body\">\n <div class=\"row align-items-end g-2\">\n <div class=\"col-md-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.IsActive' | abpLocalization }}</label>\n <select class=\"form-select\" [(ngModel)]=\"filters.isActive\" (change)=\"applyFilters()\">\n <option [ngValue]=\"undefined\">--</option>\n <option [ngValue]=\"true\">{{ 'AbpUi::Yes' | abpLocalization }}</option>\n <option [ngValue]=\"false\">{{ 'AbpUi::No' | abpLocalization }}</option>\n </select>\n </div>\n <div class=\"col-md-5\">\n <label class=\"form-label\">{{ 'AbpUi::Search' | abpLocalization }}</label>\n <input\n type=\"text\"\n class=\"form-control\"\n [(ngModel)]=\"filters.filter\"\n (keyup.enter)=\"applyFilters()\"\n [placeholder]=\"'AbpUi::Search' | abpLocalization\"\n />\n </div>\n <div class=\"col-md-4\">\n <button type=\"button\" class=\"btn btn-primary me-2\" (click)=\"applyFilters()\">\n <i class=\"fa fa-search me-1\"></i>{{ 'AbpUi::Search' | abpLocalization }}\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"clearFilters()\">\n {{ 'AbpUi::Clear' | abpLocalization }}\n </button>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"card\">\n <div class=\"card-body\">\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <h5 class=\"mb-0\">{{ 'Site::Pages' | abpLocalization }}</h5>\n <button\n *abpPermission=\"policies.PagesCreate\"\n type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"openCreate()\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::NewPage' | abpLocalization }}\n </button>\n </div>\n\n <ngx-datatable\n class=\"material\"\n [rows]=\"data().items\"\n columnMode=\"flex\"\n [headerHeight]=\"42\"\n [footerHeight]=\"42\"\n rowHeight=\"auto\"\n treeFromRelation=\"parentId\"\n treeToRelation=\"id\"\n (treeAction)=\"onTreeAction($event)\"\n >\n <ngx-datatable-column\n prop=\"displayName\"\n [flexGrow]=\"2\"\n [isTreeColumn]=\"true\"\n [treeLevelIndent]=\"20\"\n [name]=\"'Site::DisplayName:Page.DisplayName' | abpLocalization\"\n >\n <ng-template\n let-row=\"row\"\n let-treeStatus=\"treeStatus\"\n let-onTreeAction=\"onTreeAction\"\n ngx-datatable-cell-template\n >\n @if (hasChildren(row)) {\n <button type=\"button\" class=\"page-tree-toggle\" (click)=\"onTreeAction()\">\n <i\n class=\"fa\"\n [ngClass]=\"treeStatus === 'collapsed' ? 'fa-caret-right' : 'fa-caret-down'\"\n ></i>\n </button>\n }\n {{ row.displayName }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n prop=\"name\"\n [flexGrow]=\"2\"\n [name]=\"'Site::DisplayName:Page.Name' | abpLocalization\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n prop=\"route\"\n [flexGrow]=\"2\"\n [name]=\"'Site::DisplayName:Page.Route' | abpLocalization\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n [flexGrow]=\"1\"\n [name]=\"'Site::DisplayName:Page.IsActive' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <i class=\"fa\" [ngClass]=\"row.isActive ? 'fa-check text-success' : 'fa-times text-muted'\"></i>\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column [flexGrow]=\"2\" [sortable]=\"false\" [name]=\"'AbpUi::Actions' | abpLocalization\">\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <a\n *abpPermission=\"policies.ContentTypes\"\n class=\"btn btn-sm btn-light me-1\"\n [routerLink]=\"['/site/pages', row.id, 'content-types']\"\n [title]=\"'Site::ContentTypes' | abpLocalization\"\n >\n <i class=\"fa fa-sitemap\"></i>\n </a>\n <button\n *abpPermission=\"policies.PagesUpdate\"\n type=\"button\"\n class=\"btn btn-sm btn-light me-1\"\n (click)=\"openEdit(row)\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button\n *abpPermission=\"policies.PagesDelete\"\n type=\"button\"\n class=\"btn btn-sm btn-light\"\n (click)=\"delete(row)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </ng-template>\n </ngx-datatable-column>\n </ngx-datatable>\n </div>\n</div>\n\n<abp-modal [(visible)]=\"isModalOpen\" [busy]=\"isModalBusy()\" (disappear)=\"closeModal()\">\n <ng-template #abpHeader>\n <h3>{{ (editingPage ? 'Site::EditPage' : 'Site::NewPage') | abpLocalization }}</h3>\n </ng-template>\n <ng-template #abpBody>\n @if (form) {\n <form [formGroup]=\"form\" (submit)=\"save()\">\n <button type=\"submit\" #submitButton style=\"display: none\"></button>\n\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.DisplayName' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"displayName\" />\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Name' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"name\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Name' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Route' | abpLocalization }}</label>\n <input type=\"text\" class=\"form-control\" formControlName=\"route\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Route' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.Template' | abpLocalization }}</label>\n <input\n type=\"text\"\n class=\"form-control\"\n formControlName=\"template\"\n list=\"site-page-template-options\"\n autocomplete=\"off\"\n />\n <datalist id=\"site-page-template-options\">\n @for (path of templateOptions(); track path) {\n <option [value]=\"path\"></option>\n }\n </datalist>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.Template' | abpLocalization }}\n </small>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Page.ParentId' | abpLocalization }}</label>\n <nz-tree-select\n class=\"form-select parent-picker-select\"\n formControlName=\"parentId\"\n [nzNodes]=\"parentTreeNodes\"\n nzAllowClear\n nzShowSearch\n nzDefaultExpandAll\n nzDropdownClassName=\"parent-picker-dropdown\"\n [nzPlaceHolder]=\"'Site::DisplayName:Page.ParentId' | abpLocalization\"\n ></nz-tree-select>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:Page.ParentId' | abpLocalization }}\n </small>\n </div>\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"site-page-is-active\"\n formControlName=\"isActive\"\n />\n <label class=\"form-check-label\" for=\"site-page-is-active\">\n {{ 'Site::DisplayName:Page.IsActive' | abpLocalization }}\n </label>\n </div>\n </form>\n }\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" abpClose>\n {{ 'AbpUi::Cancel' | abpLocalization }}\n </button>\n <abp-button\n iconClass=\"fa fa-check\"\n [disabled]=\"!form?.valid\"\n [loading]=\"isModalBusy()\"\n (click)=\"submitButton?.nativeElement?.click()\"\n >\n {{ 'AbpUi::Save' | abpLocalization }}\n </abp-button>\n </ng-template>\n</abp-modal>\n"],"names":["i2","i3","i4","i5","i6","i7"],"mappings":"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"}
|