@dignite/ng.site 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/{dignite-ng.site-content-editor.component-DA6FaJSU.mjs → dignite-ng.site-content-editor.component-DJEBh1ok.mjs} +2 -2
- package/fesm2022/{dignite-ng.site-content-editor.component-DA6FaJSU.mjs.map → dignite-ng.site-content-editor.component-DJEBh1ok.mjs.map} +1 -1
- package/fesm2022/{dignite-ng.site-content-types.component-Dnqe8A4t.mjs → dignite-ng.site-content-types.component-B3GpUeEa.mjs} +3 -3
- package/fesm2022/{dignite-ng.site-content-types.component-Dnqe8A4t.mjs.map → dignite-ng.site-content-types.component-B3GpUeEa.mjs.map} +1 -1
- package/fesm2022/{dignite-ng.site-contents.component-Ch5GYIHE.mjs → dignite-ng.site-contents.component-ht0WYCSN.mjs} +3 -3
- package/fesm2022/{dignite-ng.site-contents.component-Ch5GYIHE.mjs.map → dignite-ng.site-contents.component-ht0WYCSN.mjs.map} +1 -1
- package/fesm2022/{dignite-ng.site-dignite-ng.site-BMcNABSG.mjs → dignite-ng.site-dignite-ng.site-CJVw2UzZ.mjs} +145 -29
- package/fesm2022/dignite-ng.site-dignite-ng.site-CJVw2UzZ.mjs.map +1 -0
- package/fesm2022/{dignite-ng.site-fields.component-BaK27N9k.mjs → dignite-ng.site-fields.component-DpKMPRz3.mjs} +4 -4
- package/fesm2022/{dignite-ng.site-fields.component-BaK27N9k.mjs.map → dignite-ng.site-fields.component-DpKMPRz3.mjs.map} +1 -1
- package/fesm2022/{dignite-ng.site-pages.component-BwGyK7jw.mjs → dignite-ng.site-pages.component-Dc3kz6EW.mjs} +3 -3
- package/fesm2022/{dignite-ng.site-pages.component-BwGyK7jw.mjs.map → dignite-ng.site-pages.component-Dc3kz6EW.mjs.map} +1 -1
- package/fesm2022/dignite-ng.site-setting-management.mjs +77 -4
- package/fesm2022/dignite-ng.site-setting-management.mjs.map +1 -1
- package/fesm2022/dignite-ng.site-theme-workbench.component-HoSTVRBM.mjs +1283 -0
- package/fesm2022/dignite-ng.site-theme-workbench.component-HoSTVRBM.mjs.map +1 -0
- package/fesm2022/dignite-ng.site.mjs +1 -1
- package/package.json +1 -1
- package/types/dignite-ng.site-setting-management.d.ts +34 -4
- package/types/dignite-ng.site.d.ts +173 -89
- package/fesm2022/dignite-ng.site-dignite-ng.site-BMcNABSG.mjs.map +0 -1
- package/fesm2022/dignite-ng.site-theme-workbench.component-CA47DnTj.mjs +0 -1206
- package/fesm2022/dignite-ng.site-theme-workbench.component-CA47DnTj.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dignite-ng.site-content-types.component-Dnqe8A4t.mjs","sources":["../../../projects/site/src/lib/components/content-types/field-arrangement.component.ts","../../../projects/site/src/lib/components/content-types/field-arrangement.component.html","../../../projects/site/src/lib/components/content-types/content-types.component.ts","../../../projects/site/src/lib/components/content-types/content-types.component.html"],"sourcesContent":["import { CoreModule, LocalizationService } from '@abp/ng.core';\nimport { CdkDragDrop, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';\nimport { Component, Input, OnInit, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FieldTypeResolver, FlexFieldsStyleLoader, NZ_SELECT_STYLE } from '@dignite/ng.flex-fields';\nimport type { FieldTypeDefinition } from '@dignite/ng.flex-fields';\nimport { NzSelectModule } from 'ng-zorro-antd/select';\nimport type { NzSelectOptionInterface } from 'ng-zorro-antd/select';\nimport type { ContentTypeFieldDto } from '../../proxy/dignite/site/content-types/models';\nimport type { FieldDto } from '../../proxy/dignite/site/fields/models';\n\n/**\n * Arranges a content type's fields: which ones it pulls in from the library, in what order, and how\n * each is used.\n *\n * **The arrangement is edited in place and saved whole.** `UpdateContentTypeDto.Fields` replaces the\n * entire list server-side - any usage flag left out of the payload resets to its default. So the\n * parent holds the complete `ContentTypeFieldDto[]`, this component mutates that same array, and the\n * parent sends all of it. Never send a delta.\n *\n * `ContentTypeFieldDto` carries only `fieldId`; names, types and descriptions come from\n * {@link fieldsById}, joined here. A usage with nothing to join to is a field that was deleted from the\n * library - the content type keeps the usage and it is skipped from then on - and is shown as that\n * ({@link isDeleted}) rather than as a blank row.\n */\n@Component({\n selector: 'site-field-arrangement',\n changeDetection: ChangeDetectionStrategy.Eager,\n templateUrl: './field-arrangement.component.html',\n imports: [CoreModule, FormsModule, DragDropModule, NzSelectModule],\n styles: `\n /* Dresses nz-select up as a Bootstrap .form-select, matching flex-fields' ff-select-control. */\n :host ::ng-deep .field-picker-select {\n width: 100%;\n }\n :host ::ng-deep .field-picker-select.ant-select {\n color: inherit !important;\n }\n :host ::ng-deep .field-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 :host ::ng-deep .field-picker-select .ant-select-arrow {\n display: none !important;\n }\n :host ::ng-deep .field-picker-select .ant-select-selection-placeholder {\n color: inherit !important;\n }\n :host ::ng-deep .field-picker-select.form-select {\n padding: 0 !important;\n }\n /* This picker runs nzMode=\"multiple\", so every chosen field renders as a tag - and ng-zorro\n hardcodes that tag's whole chrome: background #f5f5f5, border #f0f0f0, and rgba(0, 0, 0, 0.45)\n on the remove icon, none of it theme-aware. The tag's label, by contrast, does follow the\n host, since .field-picker-select.ant-select above sets color:inherit - so in a dark host\n the label went light while the chip stayed near-white and the x disappeared, leaving the\n selected fields barely legible. Mapped onto the same --bs-* tokens as the rest of this block. */\n :host ::ng-deep .field-picker-select .ant-select-selection-item {\n background: var(--bs-secondary-bg, #f5f5f5) !important;\n border-color: var(--bs-border-color, #f0f0f0) !important;\n }\n :host ::ng-deep .field-picker-select .ant-select-selection-item-remove {\n color: var(--bs-secondary-color, rgba(0, 0, 0, 0.45)) !important;\n }\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 .field-picker-dropdown .ant-select-dropdown {\n background: var(--lpx-content-bg, var(--bs-secondary-bg, #fff)) !important;\n }\n ::ng-deep .field-picker-dropdown .ant-select-item-option-active:not(.ant-select-item-option-disabled) {\n background-color: var(--bs-primary) !important;\n color: var(--bs-white) !important;\n }\n /* A selected option is deliberately given no colour of its own: it reads exactly like an\n unselected one, and ant-design own checkmark (.ant-select-item-option-state) is the indicator.\n This picker is nzMode=\"multiple\", so several options are selected at once and filling each of\n their rows competes with the hover state for attention rather than adding information.\n\n There used to be a rule here setting --lpx-brand with white text, and it was broken in a way\n worth recording. Only its colour half carried !important; the .ant-select-item rule below\n zeroes every option background with !important, and !important beats specificity, so the\n background never applied while the white text always did. A selected option rendered\n white-on-panel: invisible while the panel was still #fff, and merely illegible once it became\n --bs-secondary-bg. The hover rule above has !important on both halves, which is why hovering a\n selected option looked right and moving off it did not. Same fix in @dignite/ng.flex-fields\n Select control, which carried an identical copy. */\n /* !important, matching every other rule in this block - ant-design's own .ant-select-item rule\n (color: rgba(0,0,0,.85)) carries the same one-class specificity as this override, and its\n stylesheet is injected lazily when nz-select first opens, i.e. after this component's styles -\n a same-specificity tie that source order was resolving in its favor, keeping idle\n (non-hover, non-selected) options on ant-design's default dark-gray-on-transparent. */\n ::ng-deep .field-picker-dropdown .ant-select-item {\n color: var(--bs-body-color) !important;\n background-color: transparent !important;\n }\n `,\n})\nexport class FieldArrangementComponent implements OnInit {\n private readonly fieldTypeResolver = inject(FieldTypeResolver);\n private readonly localization = inject(LocalizationService);\n private readonly styleLoader = inject(FlexFieldsStyleLoader);\n\n readonly fieldTypes: readonly FieldTypeDefinition[] = this.fieldTypeResolver.getAll();\n\n /**\n * Fetches `ng-zorro-antd-select.css` by bundle name, the way flex-fields' own `Select` controls and\n * `abp-tree` load theirs: the host declares that bundle with `inject: false`, so nothing else puts it\n * on the page. Same loader as flex-fields, so it is requested once however many selects render.\n */\n ngOnInit(): void {\n this.styleLoader.load(NZ_SELECT_STYLE);\n }\n\n /** The live arrangement. Mutated in place - the parent reads it back at save time. */\n @Input() arrangement: ContentTypeFieldDto[] = [];\n\n /** The whole field library, keyed by id. */\n @Input() fieldsById = new Map<string, FieldDto>();\n\n /**\n * Whether {@link fieldsById} has finished loading. Until it has, an empty map says nothing about any\n * field, so no usage is called deleted yet.\n */\n @Input() fieldsLoaded = false;\n\n /** Whether a field type has a query index at all, keyed by field type name. */\n @Input() indexableByFieldType = new Map<string, boolean>();\n\n /** Field ids chosen in the \"add field\" picker, before they're committed via {@link addFields}. */\n fieldsToAdd: string[] = [];\n\n fieldOf(entry: ContentTypeFieldDto): FieldDto | undefined {\n return entry.fieldId ? this.fieldsById.get(entry.fieldId) : undefined;\n }\n\n labelOf(entry: ContentTypeFieldDto): string {\n return entry.displayName || this.fieldOf(entry)?.displayName || this.fieldOf(entry)?.name || '';\n }\n\n /**\n * A usage whose field is no longer in the library. Deleting a field does not touch the content types\n * that arrange it, so the usage stays behind with no definition to join to. Only once the library has\n * loaded: before that every usage would look deleted.\n */\n isDeleted(entry: ContentTypeFieldDto): boolean {\n return this.fieldsLoaded && !this.fieldOf(entry);\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 /** Library fields not already in the arrangement. */\n get addableFields(): FieldDto[] {\n const used = new Set(this.arrangement.map(entry => entry.fieldId));\n return [...this.fieldsById.values()].filter(field => !used.has(field.id));\n }\n\n private addableFieldOptionsCache?: { key: string; options: NzSelectOptionInterface[] };\n\n /**\n * {@link addableFields} as `nz-select` options. Labels are resolved here, not in the template -\n * `nzOptions` is consumed internally by ng-zorro rather than rendered through Angular's pipe on each\n * row, so the localized field type name has to already be a plain string by the time it's bound.\n *\n * **Cached against a cheap key, not recomputed every read.** `nzOptions` expects a stable array\n * reference; `arrangement` is mutated in place ({@link arrangement}'s own doc), so its identity never\n * changes when a field is added or removed, and a plain `.map()` here would hand `nz-select` a fresh\n * array and fresh option objects on every change-detection cycle - including the ones firing while the\n * dropdown is open (hover, search keystrokes). `ff-select-control` in flex-fields guards the same\n * getter the same way, for the same reason.\n */\n get addableFieldOptions(): NzSelectOptionInterface[] {\n const key = `${this.fieldsById.size}:${this.arrangement.length}`;\n if (this.addableFieldOptionsCache?.key !== key) {\n this.addableFieldOptionsCache = {\n key,\n options: this.addableFields.map(field => ({\n label: `${field.displayName} (${this.localization.instant(this.displayNameKeyOf(field.fieldTypeName))})`,\n value: field.id,\n })),\n };\n }\n return this.addableFieldOptionsCache.options;\n }\n\n /**\n * A field whose type has no query-index slot can never be searched, whatever this flag says -\n * `FlexFieldIndexManagerBase.GetIndexableFieldsAsync` skips it. Lock the checkbox off and say why,\n * rather than letting someone set something that silently does nothing.\n */\n isSearchableSupported(entry: ContentTypeFieldDto): boolean {\n const fieldTypeName = this.fieldOf(entry)?.fieldTypeName;\n return !fieldTypeName || this.indexableByFieldType.get(fieldTypeName) !== false;\n }\n\n addFields(): void {\n if (this.fieldsToAdd.length === 0) {\n return;\n }\n\n this.fieldsToAdd.forEach(fieldId => {\n this.arrangement.push({\n fieldId,\n required: false,\n searchable: false,\n showInList: false,\n displayName: null,\n order: this.arrangement.length,\n });\n });\n\n this.fieldsToAdd = [];\n this.reindex();\n }\n\n removeField(index: number): void {\n this.arrangement.splice(index, 1);\n this.reindex();\n }\n\n drop(event: CdkDragDrop<ContentTypeFieldDto[]>): void {\n moveItemInArray(this.arrangement, event.previousIndex, event.currentIndex);\n this.reindex();\n }\n\n onSearchableChange(entry: ContentTypeFieldDto): void {\n if (!this.isSearchableSupported(entry)) {\n entry.searchable = false;\n }\n }\n\n /** `order` is the server's sort key, so it has to follow the visual order after any change. */\n private reindex(): void {\n this.arrangement.forEach((entry, index) => (entry.order = index));\n }\n}\n","<div class=\"d-flex align-items-end gap-2 mb-3\">\n <div class=\"flex-grow-1\">\n <label class=\"form-label\">{{ 'Site::AddField' | abpLocalization }}</label>\n <!--\n nzDropdownMatchSelectWidth defaults to true, but inside this abp-modal ng-zorro measures the\n trigger's width before the modal's layout has settled and gets ~0 - the dropdown then renders\n with no real width and swallows clicks. Forcing it off falls back to content-based auto-width,\n which sidesteps the bad measurement entirely.\n -->\n <nz-select\n class=\"form-select field-picker-select\"\n nzMode=\"multiple\"\n nzShowSearch\n nzPlaceHolder=\"---\"\n [nzDropdownMatchSelectWidth]=\"false\"\n nzDropdownClassName=\"field-picker-dropdown\"\n [nzOptions]=\"addableFieldOptions\"\n [(ngModel)]=\"fieldsToAdd\"\n [ngModelOptions]=\"{ standalone: true }\"\n ></nz-select>\n </div>\n <button\n type=\"button\"\n class=\"btn btn-outline-primary\"\n [disabled]=\"fieldsToAdd.length === 0\"\n (click)=\"addFields()\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::AddField' | abpLocalization }}\n </button>\n</div>\n\n@if (arrangement.length === 0) {\n <p class=\"text-muted\">{{ 'Site::NoFieldsArranged' | abpLocalization }}</p>\n} @else {\n <div class=\"table-responsive\">\n <table class=\"table table-sm align-middle mb-0\">\n <thead>\n <tr>\n <th style=\"width: 2rem\"></th>\n <th>{{ 'Site::DisplayName:Field.DisplayName' | abpLocalization }}</th>\n <th>{{ 'Site::DisplayName:Field.FieldTypeName' | abpLocalization }}</th>\n <th class=\"text-center\">{{ 'Site::DisplayName:ContentTypeField.Required' | abpLocalization }}</th>\n <th class=\"text-center\">{{ 'Site::DisplayName:ContentTypeField.Searchable' | abpLocalization }}</th>\n <th class=\"text-center\">{{ 'Site::DisplayName:ContentTypeField.ShowInList' | abpLocalization }}</th>\n <th>{{ 'Site::DisplayName:ContentTypeField.DisplayNameOverride' | abpLocalization }}</th>\n <th style=\"width: 3rem\"></th>\n </tr>\n </thead>\n <tbody cdkDropList (cdkDropListDropped)=\"drop($event)\">\n @for (entry of arrangement; track entry.fieldId; let i = $index) {\n <tr cdkDrag>\n <td class=\"text-muted\" cdkDragHandle style=\"cursor: move\">\n <i class=\"fa fa-grip-vertical\"></i>\n </td>\n <td>\n <div>{{ labelOf(entry) }}</div>\n @if (isDeleted(entry)) {\n <small class=\"text-danger\">{{ 'Site::DeletedField' | abpLocalization }}</small>\n <small class=\"d-block text-muted\">{{ 'Site::DeletedFieldHint' | abpLocalization }}</small>\n } @else {\n <small class=\"text-muted\">{{ fieldOf(entry)?.name }}</small>\n }\n </td>\n <td>{{ displayNameKeyOf(fieldOf(entry)?.fieldTypeName) | abpLocalization }}</td>\n <td class=\"text-center\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n [(ngModel)]=\"entry.required\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"isDeleted(entry)\"\n />\n </td>\n <td class=\"text-center\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n [(ngModel)]=\"entry.searchable\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"isDeleted(entry) || !isSearchableSupported(entry)\"\n (ngModelChange)=\"onSearchableChange(entry)\"\n />\n @if (!isSearchableSupported(entry)) {\n <div class=\"form-text small\">\n {{ 'Site::FieldTypeNotSearchable' | abpLocalization }}\n </div>\n }\n </td>\n <td class=\"text-center\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n [(ngModel)]=\"entry.showInList\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"isDeleted(entry)\"\n />\n </td>\n <td>\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n [(ngModel)]=\"entry.displayName\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"fieldOf(entry)?.displayName ?? ''\"\n [disabled]=\"isDeleted(entry)\"\n />\n </td>\n <td>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-link\"\n (click)=\"removeField(i)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n}\n","import { CoreModule, PermissionDirective, PermissionService } 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 inject,\n signal,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { ActivatedRoute } from '@angular/router';\nimport { forkJoin } from 'rxjs';\nimport { ContentTypeAdminService } from '../../proxy/dignite/site/admin/content-types/content-type-admin.service';\nimport { PageAdminService } from '../../proxy/dignite/site/admin/pages/page-admin.service';\nimport type {\n ContentTypeDto,\n ContentTypeFieldDto,\n} from '../../proxy/dignite/site/content-types/models';\nimport type { FieldDto } from '../../proxy/dignite/site/fields/models';\nimport type { PageDto } from '../../proxy/dignite/site/pages/models';\nimport { eSitePolicyNames } from '../../enums/policy-names';\nimport { SiteReferenceDataService } from '../../services/site-reference-data.service';\nimport { FieldArrangementComponent } from './field-arrangement.component';\n\nconst MAX_NAME_LENGTH = 64;\nconst MAX_DISPLAY_NAME_LENGTH = 128;\nconst MAX_DESCRIPTION_LENGTH = 512;\n\n/** Mirrors `IdentifierName.Pattern` (`src/Dignite.Site.Domain.Shared/IdentifierName.cs`). */\nconst NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;\n\n/** The content types of one page. Reached from the Pages list; there is no menu entry. */\n@Component({\n selector: 'site-content-types',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './content-types.component.html',\n imports: [\n CoreModule,\n ThemeSharedModule,\n ReactiveFormsModule,\n PermissionDirective,\n FieldArrangementComponent,\n ],\n})\nexport class ContentTypesComponent {\n private readonly contentTypeService = inject(ContentTypeAdminService);\n private readonly pageService = inject(PageAdminService);\n private readonly referenceData = inject(SiteReferenceDataService);\n private readonly route = inject(ActivatedRoute);\n private readonly fb = inject(FormBuilder);\n private readonly confirmation = inject(ConfirmationService);\n private readonly toaster = inject(ToasterService);\n private readonly permission = inject(PermissionService);\n\n readonly policies = eSitePolicyNames;\n\n readonly pageId: string = this.route.snapshot.paramMap.get('pageId') ?? '';\n\n // State that changes in an HTTP callback is a signal, not a plain field: the host layout's ancestors\n // (`abp-router-outlet`, the LeptonX layouts) are OnPush, and a plain-field write in a response\n // callback never marks them for check, so the page would stay empty until some unrelated event did.\n readonly page = signal<PageDto | undefined>(undefined);\n readonly contentTypes = signal<ContentTypeDto[]>([]);\n readonly fieldsById = signal(new Map<string, FieldDto>());\n readonly fieldsLoaded = signal(false);\n readonly indexableByFieldType = signal(new Map<string, boolean>());\n\n readonly isModalOpen = signal(false);\n readonly isModalBusy = signal(false);\n editingContentType?: ContentTypeDto;\n form?: FormGroup;\n\n /**\n * The complete arrangement being edited. Held here, not inside the form, because it is saved whole:\n * `UpdateContentTypeDto.Fields` replaces the server's list outright, so anything missing from this\n * array comes back reset to its default.\n */\n arrangement: ContentTypeFieldDto[] = [];\n\n @ViewChild('submitButton') submitButton?: ElementRef<HTMLButtonElement>;\n\n constructor() {\n this.pageService.get(this.pageId).subscribe(page => this.page.set(page));\n\n forkJoin({\n fields: this.referenceData.getFieldsById(),\n indexable: this.referenceData.getIndexableByFieldType(),\n }).subscribe(({ fields, indexable }) => {\n this.fieldsById.set(fields);\n this.fieldsLoaded.set(true);\n this.indexableByFieldType.set(indexable);\n });\n\n this.load(true);\n }\n\n /**\n * `autoOpenIfSingle` only applies to this initial load: a page with exactly one content type has\n * nothing to disambiguate, so arriving here always means \"go edit it\". Reloads after a save or delete\n * must not repeat this - otherwise closing the edit modal after a successful save would immediately\n * reopen it.\n */\n load(autoOpenIfSingle = false): void {\n this.contentTypeService.getListByPage(this.pageId).subscribe(result => {\n const contentTypes = result.items ?? [];\n this.contentTypes.set(contentTypes);\n\n if (\n autoOpenIfSingle &&\n contentTypes.length === 1 &&\n this.permission.getGrantedPolicy(this.policies.ContentTypesUpdate)\n ) {\n this.openEdit(contentTypes[0]);\n }\n });\n }\n\n fieldCountOf(contentType: ContentTypeDto): number {\n return contentType.fields?.length ?? 0;\n }\n\n openCreate(): void {\n this.editingContentType = undefined;\n this.arrangement = [];\n this.form = this.buildForm();\n this.isModalOpen.set(true);\n }\n\n openEdit(contentType: ContentTypeDto): void {\n this.editingContentType = contentType;\n // A copy: abandoning the modal must not leave the list's row mutated by the arrangement editor.\n this.arrangement = (contentType.fields ?? [])\n .map(entry => ({ ...entry }))\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n this.form = this.buildForm(contentType);\n this.isModalOpen.set(true);\n }\n\n closeModal(): void {\n this.isModalOpen.set(false);\n this.form = undefined;\n this.editingContentType = undefined;\n this.arrangement = [];\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\n const request$ = this.editingContentType\n ? this.contentTypeService.update(this.editingContentType.id!, {\n name: value.name,\n displayName: value.displayName,\n description: value.description,\n fields: this.arrangement,\n })\n : this.contentTypeService.create({\n pageId: this.pageId,\n name: value.name,\n displayName: value.displayName,\n description: value.description,\n fields: this.arrangement,\n });\n\n request$.subscribe({\n next: () => {\n this.isModalBusy.set(false);\n this.closeModal();\n this.load();\n this.referenceData.invalidateContentTypes();\n this.toaster.success('AbpUi::SavedSuccessfully');\n },\n error: () => this.isModalBusy.set(false),\n });\n }\n\n delete(contentType: ContentTypeDto): void {\n this.confirmation\n .warn('AbpUi::ItemWillBeDeletedMessage', 'AbpUi::AreYouSure', {\n messageLocalizationParams: [contentType.displayName ?? ''],\n })\n .subscribe((status: Confirmation.Status) => {\n if (status === Confirmation.Status.confirm) {\n // Answers ContentTypeStillHasContents when contents remain; the server's message says so.\n this.contentTypeService.delete(contentType.id!).subscribe(() => {\n this.load();\n this.referenceData.invalidateContentTypes();\n this.toaster.success('AbpUi::SuccessfullyDeleted');\n });\n }\n });\n }\n\n private buildForm(contentType?: ContentTypeDto): FormGroup {\n return this.fb.group({\n displayName: [\n contentType?.displayName ?? '',\n [Validators.required, Validators.maxLength(MAX_DISPLAY_NAME_LENGTH)],\n ],\n name: [\n contentType?.name ?? '',\n [Validators.required, Validators.maxLength(MAX_NAME_LENGTH), Validators.pattern(NAME_PATTERN)],\n ],\n description: [\n contentType?.description ?? '',\n [Validators.maxLength(MAX_DESCRIPTION_LENGTH)],\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\">\n {{ 'Site::ContentTypesOfPage' | abpLocalization: (page()?.displayName ?? '') }}\n </h5>\n <button\n *abpPermission=\"policies.ContentTypesCreate\"\n type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"openCreate()\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::NewContentType' | abpLocalization }}\n </button>\n </div>\n\n <div class=\"table-responsive\">\n <table class=\"table align-middle mb-0\">\n <thead>\n <tr>\n <th>{{ 'Site::DisplayName:ContentType.DisplayName' | abpLocalization }}</th>\n <th>{{ 'Site::DisplayName:ContentType.Name' | abpLocalization }}</th>\n <th>{{ 'Site::FieldArrangement' | abpLocalization }}</th>\n <th>{{ 'AbpUi::Actions' | abpLocalization }}</th>\n </tr>\n </thead>\n <tbody>\n @for (contentType of contentTypes(); track contentType.id) {\n <tr>\n <td>\n <div>{{ contentType.displayName }}</div>\n @if (contentType.description) {\n <small class=\"text-muted\">{{ contentType.description }}</small>\n }\n </td>\n <td>{{ contentType.name }}</td>\n <td>{{ fieldCountOf(contentType) }}</td>\n <td>\n <button\n *abpPermission=\"policies.ContentTypesUpdate\"\n type=\"button\"\n class=\"btn btn-sm btn-light me-1\"\n (click)=\"openEdit(contentType)\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button\n *abpPermission=\"policies.ContentTypesDelete\"\n type=\"button\"\n class=\"btn btn-sm btn-light\"\n (click)=\"delete(contentType)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </td>\n </tr>\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>\n {{ (editingContentType ? 'Site::EditContentType' : 'Site::NewContentType') | abpLocalization }}\n </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=\"row\">\n <div class=\"col-md-6 mb-3\">\n <label class=\"form-label\">\n {{ 'Site::DisplayName:ContentType.DisplayName' | abpLocalization }}\n </label>\n <input type=\"text\" class=\"form-control\" formControlName=\"displayName\" />\n </div>\n <div class=\"col-md-6 mb-3\">\n <label class=\"form-label\">\n {{ 'Site::DisplayName:ContentType.Name' | abpLocalization }}\n </label>\n <input type=\"text\" class=\"form-control\" formControlName=\"name\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:ContentType.Name' | abpLocalization }}\n </small>\n </div>\n </div>\n\n <!-- Description sits above everything structural on purpose: it is product copy aimed at AI -\n an MCP client picks the right content type by reading it (总体设计 §6.2.6). -->\n <div class=\"mb-3\">\n <label class=\"form-label fw-semibold\">\n {{ 'Site::DisplayName:ContentType.Description' | abpLocalization }}\n </label>\n <textarea class=\"form-control\" formControlName=\"description\" rows=\"3\"></textarea>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:ContentType.Description' | abpLocalization }}\n </small>\n </div>\n\n <hr />\n <h6>{{ 'Site::FieldArrangement' | abpLocalization }}</h6>\n </form>\n\n <!-- Outside the form: the arrangement is plain state, saved whole alongside it. -->\n <site-field-arrangement\n [arrangement]=\"arrangement\"\n [fieldsById]=\"fieldsById()\"\n [fieldsLoaded]=\"fieldsLoaded()\"\n [indexableByFieldType]=\"indexableByFieldType()\"\n ></site-field-arrangement>\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":["i4","i3"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dignite-ng.site-content-types.component-B3GpUeEa.mjs","sources":["../../../projects/site/src/lib/components/content-types/field-arrangement.component.ts","../../../projects/site/src/lib/components/content-types/field-arrangement.component.html","../../../projects/site/src/lib/components/content-types/content-types.component.ts","../../../projects/site/src/lib/components/content-types/content-types.component.html"],"sourcesContent":["import { CoreModule, LocalizationService } from '@abp/ng.core';\nimport { CdkDragDrop, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';\nimport { Component, Input, OnInit, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FieldTypeResolver, FlexFieldsStyleLoader, NZ_SELECT_STYLE } from '@dignite/ng.flex-fields';\nimport type { FieldTypeDefinition } from '@dignite/ng.flex-fields';\nimport { NzSelectModule } from 'ng-zorro-antd/select';\nimport type { NzSelectOptionInterface } from 'ng-zorro-antd/select';\nimport type { ContentTypeFieldDto } from '../../proxy/dignite/site/content-types/models';\nimport type { FieldDto } from '../../proxy/dignite/site/fields/models';\n\n/**\n * Arranges a content type's fields: which ones it pulls in from the library, in what order, and how\n * each is used.\n *\n * **The arrangement is edited in place and saved whole.** `UpdateContentTypeDto.Fields` replaces the\n * entire list server-side - any usage flag left out of the payload resets to its default. So the\n * parent holds the complete `ContentTypeFieldDto[]`, this component mutates that same array, and the\n * parent sends all of it. Never send a delta.\n *\n * `ContentTypeFieldDto` carries only `fieldId`; names, types and descriptions come from\n * {@link fieldsById}, joined here. A usage with nothing to join to is a field that was deleted from the\n * library - the content type keeps the usage and it is skipped from then on - and is shown as that\n * ({@link isDeleted}) rather than as a blank row.\n */\n@Component({\n selector: 'site-field-arrangement',\n changeDetection: ChangeDetectionStrategy.Eager,\n templateUrl: './field-arrangement.component.html',\n imports: [CoreModule, FormsModule, DragDropModule, NzSelectModule],\n styles: `\n /* Dresses nz-select up as a Bootstrap .form-select, matching flex-fields' ff-select-control. */\n :host ::ng-deep .field-picker-select {\n width: 100%;\n }\n :host ::ng-deep .field-picker-select.ant-select {\n color: inherit !important;\n }\n :host ::ng-deep .field-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 :host ::ng-deep .field-picker-select .ant-select-arrow {\n display: none !important;\n }\n :host ::ng-deep .field-picker-select .ant-select-selection-placeholder {\n color: inherit !important;\n }\n :host ::ng-deep .field-picker-select.form-select {\n padding: 0 !important;\n }\n /* This picker runs nzMode=\"multiple\", so every chosen field renders as a tag - and ng-zorro\n hardcodes that tag's whole chrome: background #f5f5f5, border #f0f0f0, and rgba(0, 0, 0, 0.45)\n on the remove icon, none of it theme-aware. The tag's label, by contrast, does follow the\n host, since .field-picker-select.ant-select above sets color:inherit - so in a dark host\n the label went light while the chip stayed near-white and the x disappeared, leaving the\n selected fields barely legible. Mapped onto the same --bs-* tokens as the rest of this block. */\n :host ::ng-deep .field-picker-select .ant-select-selection-item {\n background: var(--bs-secondary-bg, #f5f5f5) !important;\n border-color: var(--bs-border-color, #f0f0f0) !important;\n }\n :host ::ng-deep .field-picker-select .ant-select-selection-item-remove {\n color: var(--bs-secondary-color, rgba(0, 0, 0, 0.45)) !important;\n }\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 .field-picker-dropdown .ant-select-dropdown {\n background: var(--lpx-content-bg, var(--bs-secondary-bg, #fff)) !important;\n }\n ::ng-deep .field-picker-dropdown .ant-select-item-option-active:not(.ant-select-item-option-disabled) {\n background-color: var(--bs-primary) !important;\n color: var(--bs-white) !important;\n }\n /* A selected option is deliberately given no colour of its own: it reads exactly like an\n unselected one, and ant-design own checkmark (.ant-select-item-option-state) is the indicator.\n This picker is nzMode=\"multiple\", so several options are selected at once and filling each of\n their rows competes with the hover state for attention rather than adding information.\n\n There used to be a rule here setting --lpx-brand with white text, and it was broken in a way\n worth recording. Only its colour half carried !important; the .ant-select-item rule below\n zeroes every option background with !important, and !important beats specificity, so the\n background never applied while the white text always did. A selected option rendered\n white-on-panel: invisible while the panel was still #fff, and merely illegible once it became\n --bs-secondary-bg. The hover rule above has !important on both halves, which is why hovering a\n selected option looked right and moving off it did not. Same fix in @dignite/ng.flex-fields\n Select control, which carried an identical copy. */\n /* !important, matching every other rule in this block - ant-design's own .ant-select-item rule\n (color: rgba(0,0,0,.85)) carries the same one-class specificity as this override, and its\n stylesheet is injected lazily when nz-select first opens, i.e. after this component's styles -\n a same-specificity tie that source order was resolving in its favor, keeping idle\n (non-hover, non-selected) options on ant-design's default dark-gray-on-transparent. */\n ::ng-deep .field-picker-dropdown .ant-select-item {\n color: var(--bs-body-color) !important;\n background-color: transparent !important;\n }\n `,\n})\nexport class FieldArrangementComponent implements OnInit {\n private readonly fieldTypeResolver = inject(FieldTypeResolver);\n private readonly localization = inject(LocalizationService);\n private readonly styleLoader = inject(FlexFieldsStyleLoader);\n\n readonly fieldTypes: readonly FieldTypeDefinition[] = this.fieldTypeResolver.getAll();\n\n /**\n * Fetches `ng-zorro-antd-select.css` by bundle name, the way flex-fields' own `Select` controls and\n * `abp-tree` load theirs: the host declares that bundle with `inject: false`, so nothing else puts it\n * on the page. Same loader as flex-fields, so it is requested once however many selects render.\n */\n ngOnInit(): void {\n this.styleLoader.load(NZ_SELECT_STYLE);\n }\n\n /** The live arrangement. Mutated in place - the parent reads it back at save time. */\n @Input() arrangement: ContentTypeFieldDto[] = [];\n\n /** The whole field library, keyed by id. */\n @Input() fieldsById = new Map<string, FieldDto>();\n\n /**\n * Whether {@link fieldsById} has finished loading. Until it has, an empty map says nothing about any\n * field, so no usage is called deleted yet.\n */\n @Input() fieldsLoaded = false;\n\n /** Whether a field type has a query index at all, keyed by field type name. */\n @Input() indexableByFieldType = new Map<string, boolean>();\n\n /** Field ids chosen in the \"add field\" picker, before they're committed via {@link addFields}. */\n fieldsToAdd: string[] = [];\n\n fieldOf(entry: ContentTypeFieldDto): FieldDto | undefined {\n return entry.fieldId ? this.fieldsById.get(entry.fieldId) : undefined;\n }\n\n labelOf(entry: ContentTypeFieldDto): string {\n return entry.displayName || this.fieldOf(entry)?.displayName || this.fieldOf(entry)?.name || '';\n }\n\n /**\n * A usage whose field is no longer in the library. Deleting a field does not touch the content types\n * that arrange it, so the usage stays behind with no definition to join to. Only once the library has\n * loaded: before that every usage would look deleted.\n */\n isDeleted(entry: ContentTypeFieldDto): boolean {\n return this.fieldsLoaded && !this.fieldOf(entry);\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 /** Library fields not already in the arrangement. */\n get addableFields(): FieldDto[] {\n const used = new Set(this.arrangement.map(entry => entry.fieldId));\n return [...this.fieldsById.values()].filter(field => !used.has(field.id));\n }\n\n private addableFieldOptionsCache?: { key: string; options: NzSelectOptionInterface[] };\n\n /**\n * {@link addableFields} as `nz-select` options. Labels are resolved here, not in the template -\n * `nzOptions` is consumed internally by ng-zorro rather than rendered through Angular's pipe on each\n * row, so the localized field type name has to already be a plain string by the time it's bound.\n *\n * **Cached against a cheap key, not recomputed every read.** `nzOptions` expects a stable array\n * reference; `arrangement` is mutated in place ({@link arrangement}'s own doc), so its identity never\n * changes when a field is added or removed, and a plain `.map()` here would hand `nz-select` a fresh\n * array and fresh option objects on every change-detection cycle - including the ones firing while the\n * dropdown is open (hover, search keystrokes). `ff-select-control` in flex-fields guards the same\n * getter the same way, for the same reason.\n */\n get addableFieldOptions(): NzSelectOptionInterface[] {\n const key = `${this.fieldsById.size}:${this.arrangement.length}`;\n if (this.addableFieldOptionsCache?.key !== key) {\n this.addableFieldOptionsCache = {\n key,\n options: this.addableFields.map(field => ({\n label: `${field.displayName} (${this.localization.instant(this.displayNameKeyOf(field.fieldTypeName))})`,\n value: field.id,\n })),\n };\n }\n return this.addableFieldOptionsCache.options;\n }\n\n /**\n * A field whose type has no query-index slot can never be searched, whatever this flag says -\n * `FlexFieldIndexManagerBase.GetIndexableFieldsAsync` skips it. Lock the checkbox off and say why,\n * rather than letting someone set something that silently does nothing.\n */\n isSearchableSupported(entry: ContentTypeFieldDto): boolean {\n const fieldTypeName = this.fieldOf(entry)?.fieldTypeName;\n return !fieldTypeName || this.indexableByFieldType.get(fieldTypeName) !== false;\n }\n\n addFields(): void {\n if (this.fieldsToAdd.length === 0) {\n return;\n }\n\n this.fieldsToAdd.forEach(fieldId => {\n this.arrangement.push({\n fieldId,\n required: false,\n searchable: false,\n showInList: false,\n displayName: null,\n order: this.arrangement.length,\n });\n });\n\n this.fieldsToAdd = [];\n this.reindex();\n }\n\n removeField(index: number): void {\n this.arrangement.splice(index, 1);\n this.reindex();\n }\n\n drop(event: CdkDragDrop<ContentTypeFieldDto[]>): void {\n moveItemInArray(this.arrangement, event.previousIndex, event.currentIndex);\n this.reindex();\n }\n\n onSearchableChange(entry: ContentTypeFieldDto): void {\n if (!this.isSearchableSupported(entry)) {\n entry.searchable = false;\n }\n }\n\n /** `order` is the server's sort key, so it has to follow the visual order after any change. */\n private reindex(): void {\n this.arrangement.forEach((entry, index) => (entry.order = index));\n }\n}\n","<div class=\"d-flex align-items-end gap-2 mb-3\">\n <div class=\"flex-grow-1\">\n <label class=\"form-label\">{{ 'Site::AddField' | abpLocalization }}</label>\n <!--\n nzDropdownMatchSelectWidth defaults to true, but inside this abp-modal ng-zorro measures the\n trigger's width before the modal's layout has settled and gets ~0 - the dropdown then renders\n with no real width and swallows clicks. Forcing it off falls back to content-based auto-width,\n which sidesteps the bad measurement entirely.\n -->\n <nz-select\n class=\"form-select field-picker-select\"\n nzMode=\"multiple\"\n nzShowSearch\n nzPlaceHolder=\"---\"\n [nzDropdownMatchSelectWidth]=\"false\"\n nzDropdownClassName=\"field-picker-dropdown\"\n [nzOptions]=\"addableFieldOptions\"\n [(ngModel)]=\"fieldsToAdd\"\n [ngModelOptions]=\"{ standalone: true }\"\n ></nz-select>\n </div>\n <button\n type=\"button\"\n class=\"btn btn-outline-primary\"\n [disabled]=\"fieldsToAdd.length === 0\"\n (click)=\"addFields()\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::AddField' | abpLocalization }}\n </button>\n</div>\n\n@if (arrangement.length === 0) {\n <p class=\"text-muted\">{{ 'Site::NoFieldsArranged' | abpLocalization }}</p>\n} @else {\n <div class=\"table-responsive\">\n <table class=\"table table-sm align-middle mb-0\">\n <thead>\n <tr>\n <th style=\"width: 2rem\"></th>\n <th>{{ 'Site::DisplayName:Field.DisplayName' | abpLocalization }}</th>\n <th>{{ 'Site::DisplayName:Field.FieldTypeName' | abpLocalization }}</th>\n <th class=\"text-center\">{{ 'Site::DisplayName:ContentTypeField.Required' | abpLocalization }}</th>\n <th class=\"text-center\">{{ 'Site::DisplayName:ContentTypeField.Searchable' | abpLocalization }}</th>\n <th class=\"text-center\">{{ 'Site::DisplayName:ContentTypeField.ShowInList' | abpLocalization }}</th>\n <th>{{ 'Site::DisplayName:ContentTypeField.DisplayNameOverride' | abpLocalization }}</th>\n <th style=\"width: 3rem\"></th>\n </tr>\n </thead>\n <tbody cdkDropList (cdkDropListDropped)=\"drop($event)\">\n @for (entry of arrangement; track entry.fieldId; let i = $index) {\n <tr cdkDrag>\n <td class=\"text-muted\" cdkDragHandle style=\"cursor: move\">\n <i class=\"fa fa-grip-vertical\"></i>\n </td>\n <td>\n <div>{{ labelOf(entry) }}</div>\n @if (isDeleted(entry)) {\n <small class=\"text-danger\">{{ 'Site::DeletedField' | abpLocalization }}</small>\n <small class=\"d-block text-muted\">{{ 'Site::DeletedFieldHint' | abpLocalization }}</small>\n } @else {\n <small class=\"text-muted\">{{ fieldOf(entry)?.name }}</small>\n }\n </td>\n <td>{{ displayNameKeyOf(fieldOf(entry)?.fieldTypeName) | abpLocalization }}</td>\n <td class=\"text-center\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n [(ngModel)]=\"entry.required\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"isDeleted(entry)\"\n />\n </td>\n <td class=\"text-center\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n [(ngModel)]=\"entry.searchable\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"isDeleted(entry) || !isSearchableSupported(entry)\"\n (ngModelChange)=\"onSearchableChange(entry)\"\n />\n @if (!isSearchableSupported(entry)) {\n <div class=\"form-text small\">\n {{ 'Site::FieldTypeNotSearchable' | abpLocalization }}\n </div>\n }\n </td>\n <td class=\"text-center\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n [(ngModel)]=\"entry.showInList\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"isDeleted(entry)\"\n />\n </td>\n <td>\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n [(ngModel)]=\"entry.displayName\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"fieldOf(entry)?.displayName ?? ''\"\n [disabled]=\"isDeleted(entry)\"\n />\n </td>\n <td>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-link\"\n (click)=\"removeField(i)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n}\n","import { CoreModule, PermissionDirective, PermissionService } 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 inject,\n signal,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { ActivatedRoute } from '@angular/router';\nimport { forkJoin } from 'rxjs';\nimport { ContentTypeAdminService } from '../../proxy/dignite/site/admin/content-types/content-type-admin.service';\nimport { PageAdminService } from '../../proxy/dignite/site/admin/pages/page-admin.service';\nimport type {\n ContentTypeDto,\n ContentTypeFieldDto,\n} from '../../proxy/dignite/site/content-types/models';\nimport type { FieldDto } from '../../proxy/dignite/site/fields/models';\nimport type { PageDto } from '../../proxy/dignite/site/pages/models';\nimport { eSitePolicyNames } from '../../enums/policy-names';\nimport { SiteReferenceDataService } from '../../services/site-reference-data.service';\nimport { FieldArrangementComponent } from './field-arrangement.component';\n\nconst MAX_NAME_LENGTH = 64;\nconst MAX_DISPLAY_NAME_LENGTH = 128;\nconst MAX_DESCRIPTION_LENGTH = 512;\n\n/** Mirrors `IdentifierName.Pattern` (`src/Dignite.Site.Domain.Shared/IdentifierName.cs`). */\nconst NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;\n\n/** The content types of one page. Reached from the Pages list; there is no menu entry. */\n@Component({\n selector: 'site-content-types',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './content-types.component.html',\n imports: [\n CoreModule,\n ThemeSharedModule,\n ReactiveFormsModule,\n PermissionDirective,\n FieldArrangementComponent,\n ],\n})\nexport class ContentTypesComponent {\n private readonly contentTypeService = inject(ContentTypeAdminService);\n private readonly pageService = inject(PageAdminService);\n private readonly referenceData = inject(SiteReferenceDataService);\n private readonly route = inject(ActivatedRoute);\n private readonly fb = inject(FormBuilder);\n private readonly confirmation = inject(ConfirmationService);\n private readonly toaster = inject(ToasterService);\n private readonly permission = inject(PermissionService);\n\n readonly policies = eSitePolicyNames;\n\n readonly pageId: string = this.route.snapshot.paramMap.get('pageId') ?? '';\n\n // State that changes in an HTTP callback is a signal, not a plain field: the host layout's ancestors\n // (`abp-router-outlet`, the LeptonX layouts) are OnPush, and a plain-field write in a response\n // callback never marks them for check, so the page would stay empty until some unrelated event did.\n readonly page = signal<PageDto | undefined>(undefined);\n readonly contentTypes = signal<ContentTypeDto[]>([]);\n readonly fieldsById = signal(new Map<string, FieldDto>());\n readonly fieldsLoaded = signal(false);\n readonly indexableByFieldType = signal(new Map<string, boolean>());\n\n readonly isModalOpen = signal(false);\n readonly isModalBusy = signal(false);\n editingContentType?: ContentTypeDto;\n form?: FormGroup;\n\n /**\n * The complete arrangement being edited. Held here, not inside the form, because it is saved whole:\n * `UpdateContentTypeDto.Fields` replaces the server's list outright, so anything missing from this\n * array comes back reset to its default.\n */\n arrangement: ContentTypeFieldDto[] = [];\n\n @ViewChild('submitButton') submitButton?: ElementRef<HTMLButtonElement>;\n\n constructor() {\n this.pageService.get(this.pageId).subscribe(page => this.page.set(page));\n\n forkJoin({\n fields: this.referenceData.getFieldsById(),\n indexable: this.referenceData.getIndexableByFieldType(),\n }).subscribe(({ fields, indexable }) => {\n this.fieldsById.set(fields);\n this.fieldsLoaded.set(true);\n this.indexableByFieldType.set(indexable);\n });\n\n this.load(true);\n }\n\n /**\n * `autoOpenIfSingle` only applies to this initial load: a page with exactly one content type has\n * nothing to disambiguate, so arriving here always means \"go edit it\". Reloads after a save or delete\n * must not repeat this - otherwise closing the edit modal after a successful save would immediately\n * reopen it.\n */\n load(autoOpenIfSingle = false): void {\n this.contentTypeService.getListByPage(this.pageId).subscribe(result => {\n const contentTypes = result.items ?? [];\n this.contentTypes.set(contentTypes);\n\n if (\n autoOpenIfSingle &&\n contentTypes.length === 1 &&\n this.permission.getGrantedPolicy(this.policies.ContentTypesUpdate)\n ) {\n this.openEdit(contentTypes[0]);\n }\n });\n }\n\n fieldCountOf(contentType: ContentTypeDto): number {\n return contentType.fields?.length ?? 0;\n }\n\n openCreate(): void {\n this.editingContentType = undefined;\n this.arrangement = [];\n this.form = this.buildForm();\n this.isModalOpen.set(true);\n }\n\n openEdit(contentType: ContentTypeDto): void {\n this.editingContentType = contentType;\n // A copy: abandoning the modal must not leave the list's row mutated by the arrangement editor.\n this.arrangement = (contentType.fields ?? [])\n .map(entry => ({ ...entry }))\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n this.form = this.buildForm(contentType);\n this.isModalOpen.set(true);\n }\n\n closeModal(): void {\n this.isModalOpen.set(false);\n this.form = undefined;\n this.editingContentType = undefined;\n this.arrangement = [];\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\n const request$ = this.editingContentType\n ? this.contentTypeService.update(this.editingContentType.id!, {\n name: value.name,\n displayName: value.displayName,\n description: value.description,\n fields: this.arrangement,\n })\n : this.contentTypeService.create({\n pageId: this.pageId,\n name: value.name,\n displayName: value.displayName,\n description: value.description,\n fields: this.arrangement,\n });\n\n request$.subscribe({\n next: () => {\n this.isModalBusy.set(false);\n this.closeModal();\n this.load();\n this.referenceData.invalidateContentTypes();\n this.toaster.success('AbpUi::SavedSuccessfully');\n },\n error: () => this.isModalBusy.set(false),\n });\n }\n\n delete(contentType: ContentTypeDto): void {\n this.confirmation\n .warn('AbpUi::ItemWillBeDeletedMessage', 'AbpUi::AreYouSure', {\n messageLocalizationParams: [contentType.displayName ?? ''],\n })\n .subscribe((status: Confirmation.Status) => {\n if (status === Confirmation.Status.confirm) {\n // Answers ContentTypeStillHasContents when contents remain; the server's message says so.\n this.contentTypeService.delete(contentType.id!).subscribe(() => {\n this.load();\n this.referenceData.invalidateContentTypes();\n this.toaster.success('AbpUi::DeletedSuccessfully');\n });\n }\n });\n }\n\n private buildForm(contentType?: ContentTypeDto): FormGroup {\n return this.fb.group({\n displayName: [\n contentType?.displayName ?? '',\n [Validators.required, Validators.maxLength(MAX_DISPLAY_NAME_LENGTH)],\n ],\n name: [\n contentType?.name ?? '',\n [Validators.required, Validators.maxLength(MAX_NAME_LENGTH), Validators.pattern(NAME_PATTERN)],\n ],\n description: [\n contentType?.description ?? '',\n [Validators.maxLength(MAX_DESCRIPTION_LENGTH)],\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\">\n {{ 'Site::ContentTypesOfPage' | abpLocalization: (page()?.displayName ?? '') }}\n </h5>\n <button\n *abpPermission=\"policies.ContentTypesCreate\"\n type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"openCreate()\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::NewContentType' | abpLocalization }}\n </button>\n </div>\n\n <div class=\"table-responsive\">\n <table class=\"table align-middle mb-0\">\n <thead>\n <tr>\n <th>{{ 'Site::DisplayName:ContentType.DisplayName' | abpLocalization }}</th>\n <th>{{ 'Site::DisplayName:ContentType.Name' | abpLocalization }}</th>\n <th>{{ 'Site::FieldArrangement' | abpLocalization }}</th>\n <th>{{ 'AbpUi::Actions' | abpLocalization }}</th>\n </tr>\n </thead>\n <tbody>\n @for (contentType of contentTypes(); track contentType.id) {\n <tr>\n <td>\n <div>{{ contentType.displayName }}</div>\n @if (contentType.description) {\n <small class=\"text-muted\">{{ contentType.description }}</small>\n }\n </td>\n <td>{{ contentType.name }}</td>\n <td>{{ fieldCountOf(contentType) }}</td>\n <td>\n <button\n *abpPermission=\"policies.ContentTypesUpdate\"\n type=\"button\"\n class=\"btn btn-sm btn-light me-1\"\n (click)=\"openEdit(contentType)\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button\n *abpPermission=\"policies.ContentTypesDelete\"\n type=\"button\"\n class=\"btn btn-sm btn-light\"\n (click)=\"delete(contentType)\"\n [title]=\"'AbpUi::Delete' | abpLocalization\"\n >\n <i class=\"fa fa-trash text-danger\"></i>\n </button>\n </td>\n </tr>\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>\n {{ (editingContentType ? 'Site::EditContentType' : 'Site::NewContentType') | abpLocalization }}\n </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=\"row\">\n <div class=\"col-md-6 mb-3\">\n <label class=\"form-label\">\n {{ 'Site::DisplayName:ContentType.DisplayName' | abpLocalization }}\n </label>\n <input type=\"text\" class=\"form-control\" formControlName=\"displayName\" />\n </div>\n <div class=\"col-md-6 mb-3\">\n <label class=\"form-label\">\n {{ 'Site::DisplayName:ContentType.Name' | abpLocalization }}\n </label>\n <input type=\"text\" class=\"form-control\" formControlName=\"name\" />\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:ContentType.Name' | abpLocalization }}\n </small>\n </div>\n </div>\n\n <!-- Description sits above everything structural on purpose: it is product copy aimed at AI -\n an MCP client picks the right content type by reading it (总体设计 §6.2.6). -->\n <div class=\"mb-3\">\n <label class=\"form-label fw-semibold\">\n {{ 'Site::DisplayName:ContentType.Description' | abpLocalization }}\n </label>\n <textarea class=\"form-control\" formControlName=\"description\" rows=\"3\"></textarea>\n <small class=\"form-text text-muted\">\n {{ 'Site::Description:ContentType.Description' | abpLocalization }}\n </small>\n </div>\n\n <hr />\n <h6>{{ 'Site::FieldArrangement' | abpLocalization }}</h6>\n </form>\n\n <!-- Outside the form: the arrangement is plain state, saved whole alongside it. -->\n <site-field-arrangement\n [arrangement]=\"arrangement\"\n [fieldsById]=\"fieldsById()\"\n [fieldsLoaded]=\"fieldsLoaded()\"\n [indexableByFieldType]=\"indexableByFieldType()\"\n ></site-field-arrangement>\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":["i4","i3"],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ import * as i2 from '@angular/router';
|
|
|
10
10
|
import { RouterLink } from '@angular/router';
|
|
11
11
|
import { FlexFieldSearchComponent, FlexFieldViewComponent } from '@dignite/ng.flex-fields';
|
|
12
12
|
import { forkJoin, switchMap, of, map } from 'rxjs';
|
|
13
|
-
import { C as ContentAdminService, a as ContentQueryService, b as ContentListStateService, c as ContentTypeAdminService, P as PageAdminService, S as SiteReferenceDataService, e as eSitePolicyNames, d as ContentStatus, F as FlexFieldQueryOperator, f as FlexFieldValueType } from './dignite-ng.site-dignite-ng.site-
|
|
13
|
+
import { C as ContentAdminService, a as ContentQueryService, b as ContentListStateService, c as ContentTypeAdminService, P as PageAdminService, S as SiteReferenceDataService, e as eSitePolicyNames, d as ContentStatus, F as FlexFieldQueryOperator, f as FlexFieldValueType } from './dignite-ng.site-dignite-ng.site-CJVw2UzZ.mjs';
|
|
14
14
|
import * as i7 from '@abp/ng.components/tree';
|
|
15
15
|
import { TreeAdapter, TreeModule } from '@abp/ng.components/tree';
|
|
16
16
|
import * as i3 from '@ngx-validate/core';
|
|
@@ -578,7 +578,7 @@ class ContentsComponent {
|
|
|
578
578
|
if (status === Confirmation.Status.confirm) {
|
|
579
579
|
this.contentService.delete(content.id).subscribe(() => {
|
|
580
580
|
this.list.get();
|
|
581
|
-
this.toaster.success('AbpUi::
|
|
581
|
+
this.toaster.success('AbpUi::DeletedSuccessfully');
|
|
582
582
|
});
|
|
583
583
|
}
|
|
584
584
|
});
|
|
@@ -601,4 +601,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImpor
|
|
|
601
601
|
}], ctorParameters: () => [] });
|
|
602
602
|
|
|
603
603
|
export { ContentsComponent };
|
|
604
|
-
//# sourceMappingURL=dignite-ng.site-contents.component-
|
|
604
|
+
//# sourceMappingURL=dignite-ng.site-contents.component-ht0WYCSN.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dignite-ng.site-contents.component-Ch5GYIHE.mjs","sources":["../../../projects/site/src/lib/components/contents/page-tree-select.component.ts","../../../projects/site/src/lib/components/contents/contents.component.ts","../../../projects/site/src/lib/components/contents/contents.component.html"],"sourcesContent":["import { TreeAdapter, TreeModule } from '@abp/ng.components/tree';\nimport type { BaseNode, TreeNode } from '@abp/ng.components/tree';\nimport { CoreModule } from '@abp/ng.core';\nimport {\n Component,\n ElementRef,\n EventEmitter,\n HostListener,\n Input,\n Output,\n inject,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport type { PageDto } from '../../proxy/dignite/site/pages/models';\n\n/** `TreeAdapter` wants a non-optional `id`/`parentId`, which the generated `PageDto` leaves optional. */\ntype PageNode = PageDto & BaseNode;\n\n/**\n * Picks one page, laid out as the page hierarchy rather than a flat list - a child page's name alone\n * rarely says which section it sits under.\n *\n * Built like flex-fields' `ff-tree-search` - a `.form-select`-styled toggle over an `abp-tree` panel -\n * because both render in the same content-list filter bar and should look and behave alike. That\n * component's node renderer (`ff-tree-picker-nodes`) is not exported, hence `abp-tree` directly.\n */\n@Component({\n selector: 'site-page-tree-select',\n changeDetection: ChangeDetectionStrategy.Eager,\n imports: [CoreModule, TreeModule],\n template: `\n <div class=\"page-tree-select\">\n <button\n type=\"button\"\n class=\"form-select text-start page-tree-select-toggle\"\n [class.text-muted]=\"!selectedNode\"\n aria-haspopup=\"tree\"\n [attr.aria-expanded]=\"isOpen\"\n (click)=\"toggle()\"\n >\n {{ selectedNode?.title ?? '--' }}\n </button>\n @if (selectedNode) {\n <button\n type=\"button\"\n class=\"btn btn-link page-tree-select-clear\"\n [title]=\"'AbpUi::Clear' | abpLocalization\"\n (click)=\"clear($event)\"\n >\n <i class=\"fa fa-times\" aria-hidden=\"true\"></i>\n </button>\n }\n\n @if (isOpen) {\n <div class=\"page-tree-select-menu\">\n <abp-tree\n [nodes]=\"nodes\"\n [(expandedKeys)]=\"expandedKeys\"\n [selectedNode]=\"selectedNode\"\n (selectedNodeChange)=\"select($event)\"\n >\n <ng-template abpTreeNodeTemplate let-node>\n <span class=\"page-tree-select-node\">{{ node.title }}</span>\n </ng-template>\n <ng-template abpTreeExpandedIconTemplate let-node>\n <i\n class=\"fa\"\n [class.fa-minus]=\"node.isExpanded\"\n [class.fa-plus]=\"!node.isExpanded\"\n aria-hidden=\"true\"\n ></i>\n </ng-template>\n </abp-tree>\n </div>\n }\n </div>\n `,\n // Mirrors ff-tree-search's and ff-tree-picker-nodes' styles, so this sits beside a Tree field's\n // filter without looking like a different control. The panel renders inside the host, not in an\n // overlay, so :host-scoped rules reach it.\n styles: `\n .page-tree-select {\n position: relative;\n }\n .page-tree-select-toggle {\n height: auto;\n min-height: calc(1.5em + 1.35rem + 2px);\n padding-right: 3.75rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .page-tree-select-clear {\n position: absolute;\n top: 50%;\n right: 2rem;\n display: inline-flex;\n align-items: center;\n height: 100%;\n padding: 0 0.375rem;\n line-height: 1;\n color: var(--bs-secondary-color, #6c757d);\n text-decoration: none;\n transform: translateY(-50%);\n z-index: 2;\n }\n .page-tree-select-menu {\n position: absolute;\n z-index: 1050;\n width: 100%;\n max-height: 18rem;\n margin-top: 0.25rem;\n padding: 0.375rem;\n overflow: auto;\n color: var(--bs-body-color);\n background-color: var(--lpx-content-bg, var(--bs-secondary-bg, #fff));\n border: 1px solid var(--bs-border-color, rgba(0, 0, 0, 0.12));\n border-radius: 0.375rem;\n box-shadow: 0 0.125rem 0.25rem #00000013;\n }\n .page-tree-select-node {\n display: inline-block;\n min-height: 1.75rem;\n padding: 0.125rem 0.375rem;\n border-radius: 0.25rem;\n }\n :host ::ng-deep .ant-tree {\n background: transparent !important;\n }\n :host ::ng-deep .ant-tree-node-content-wrapper,\n :host ::ng-deep .ant-tree-node-content-wrapper:hover {\n background-color: transparent !important;\n }\n :host ::ng-deep .ant-tree-node-content-wrapper > .selected .page-tree-select-node {\n background-color: var(--lpx-brand, var(--bs-primary));\n color: var(--bs-white, #fff);\n }\n :host ::ng-deep .ant-tree-node-content-wrapper:hover > div:not(.selected) .page-tree-select-node {\n background-color: var(--bs-secondary-bg, #f5f5f5);\n }\n `,\n})\nexport class PageTreeSelectComponent {\n private readonly elementRef = inject(ElementRef);\n\n /** Every page, flat - the hierarchy is rebuilt from `parentId`. */\n @Input() set pages(pages: PageDto[]) {\n const ids = new Set(pages.map(page => page.id));\n // `TreeAdapter` silently drops a node whose parent is not in the list, taking its whole subtree\n // with it; such a page shows at the root instead.\n const list = pages.map(\n page =>\n ({\n ...page,\n id: page.id!,\n parentId: page.parentId && ids.has(page.parentId) ? page.parentId : null,\n }) as PageNode,\n );\n\n this.nodes = new TreeAdapter(list).getTree();\n this.nodesByKey = new Map();\n this.index(this.nodes);\n // Opens fully expanded, the same as the page form's parent picker (`nzDefaultExpandAll`).\n this.expandedKeys = [...this.nodesByKey.values()].filter(node => !node.isLeaf).map(node => node.key);\n }\n\n /** The selected page's id, or `null` for \"any page\". */\n @Input() value?: string | null;\n\n /** Emits only on an actual change, like a native `<select>`'s `change`. */\n @Output() readonly valueChange = new EventEmitter<string | null>();\n\n nodes: TreeNode<PageNode>[] = [];\n expandedKeys: string[] = [];\n isOpen = false;\n\n private nodesByKey = new Map<string, TreeNode<PageNode>>();\n\n /**\n * Passed to `abp-tree` as `selectedNode`, whose default `isNodeSelected` matches on `id` - which a\n * `TreeNode` carries as well as its entity. A stable reference from {@link nodesByKey}, so the\n * OnPush tree only re-renders when the selection really changes.\n */\n get selectedNode(): TreeNode<PageNode> | undefined {\n return this.value ? this.nodesByKey.get(this.value) : undefined;\n }\n\n toggle(): void {\n this.isOpen = !this.isOpen;\n }\n\n /** `abp-tree` emits the clicked node's entity, i.e. the page. */\n select(page: PageNode): void {\n this.isOpen = false;\n this.emit(page.id);\n }\n\n clear(event: Event): void {\n // Keeps the click from reaching the toggle underneath it.\n event.stopPropagation();\n this.emit(null);\n }\n\n @HostListener('document:click', ['$event'])\n closeOnOutsideClick(event: Event): void {\n if (this.isOpen && !event.composedPath().includes(this.elementRef.nativeElement)) {\n this.isOpen = false;\n }\n }\n\n @HostListener('keydown.escape')\n close(): void {\n this.isOpen = false;\n }\n\n private emit(pageId: string | null): void {\n if (pageId !== (this.value ?? null)) {\n this.valueChange.emit(pageId);\n }\n }\n\n private index(nodes: TreeNode<PageNode>[]): void {\n for (const node of nodes) {\n this.nodesByKey.set(node.key, node);\n this.index(node.children);\n }\n }\n}\n","import {\n ABP,\n CoreModule,\n LIST_QUERY_DEBOUNCE_TIME,\n ListService,\n PagedResultDto,\n PermissionDirective,\n} from '@abp/ng.core';\nimport {\n Confirmation,\n ConfirmationService,\n ThemeSharedModule,\n ToasterService,\n} from '@abp/ng.theme.shared';\nimport { Component, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { RouterLink } from '@angular/router';\nimport { FlexFieldSearchComponent, FlexFieldViewComponent } from '@dignite/ng.flex-fields';\nimport type { FlexFieldData, FlexFieldValue } from '@dignite/ng.flex-fields';\nimport { Observable, forkJoin, map, of, switchMap } from 'rxjs';\nimport { ContentAdminService } from '../../proxy/dignite/site/admin/contents/content-admin.service';\nimport { ContentTypeAdminService } from '../../proxy/dignite/site/admin/content-types/content-type-admin.service';\nimport { PageAdminService } from '../../proxy/dignite/site/admin/pages/page-admin.service';\nimport type { GetContentListInput } from '../../proxy/dignite/site/admin/contents/models';\nimport type { ContentTypeDto } from '../../proxy/dignite/site/content-types/models';\nimport type { ContentDto } from '../../proxy/dignite/site/contents/models';\nimport { ContentStatus } from '../../proxy/dignite/site/contents/content-status.enum';\nimport { FlexFieldQueryOperator } from '../../proxy/dignite/abp/flex-fields/flex-field-query-operator.enum';\nimport { FlexFieldValueType } from '../../proxy/dignite/abp/flex-fields/flex-field-value-type.enum';\nimport type { FlexFieldQueryCondition } from '../../proxy/dignite/abp/flex-fields/models';\nimport type { FieldDto } from '../../proxy/dignite/site/fields/models';\nimport type { PageDto } from '../../proxy/dignite/site/pages/models';\nimport { eSitePolicyNames } from '../../enums/policy-names';\nimport { ContentListStateService } from '../../services/content-list-state.service';\nimport { ContentQueryService } from '../../services/content-query.service';\nimport { SiteReferenceDataService } from '../../services/site-reference-data.service';\nimport type { ArrangedField, FieldColumn, RowFieldValues } from './arranged-field';\nimport { PageTreeSelectComponent } from './page-tree-select.component';\n\n@Component({\n selector: 'site-contents',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './contents.component.html',\n imports: [\n CoreModule,\n ThemeSharedModule,\n ReactiveFormsModule,\n PermissionDirective,\n RouterLink,\n FlexFieldSearchComponent,\n FlexFieldViewComponent,\n PageTreeSelectComponent,\n ],\n providers: [ListService, { provide: LIST_QUERY_DEBOUNCE_TIME, useValue: 300 }],\n})\nexport class ContentsComponent {\n private readonly contentService = inject(ContentAdminService);\n private readonly contentQuery = inject(ContentQueryService);\n private readonly listState = inject(ContentListStateService);\n private readonly contentTypeService = inject(ContentTypeAdminService);\n private readonly pageService = inject(PageAdminService);\n private readonly referenceData = inject(SiteReferenceDataService);\n private readonly fb = inject(FormBuilder);\n private readonly confirmation = inject(ConfirmationService);\n private readonly toaster = inject(ToasterService);\n\n readonly list = inject(ListService);\n readonly policies = eSitePolicyNames;\n readonly ContentStatus = ContentStatus;\n readonly statuses = [ContentStatus.Draft, ContentStatus.Published, ContentStatus.Archived];\n\n // Everything the template reads that changes in an HTTP callback is a signal, not a plain field: the\n // host layout's ancestors (`abp-router-outlet`, the LeptonX layouts) are OnPush, and a plain-field\n // write in a response callback never marks them for check, so the list would stay empty until some\n // unrelated event happened to.\n readonly data = signal<PagedResultDto<ContentDto>>({ items: [], totalCount: 0 });\n filters = {} as GetContentListInput;\n\n readonly pages = signal<PageDto[]>([]);\n readonly languages = signal<string[]>([]);\n readonly contentTypes = signal<ContentTypeDto[]>([]);\n\n /**\n * Every content type across every page, for resolving a row's display name. Deliberately separate\n * from {@link contentTypes}, which is scoped to the selected page and drives the filter dropdown and\n * field arrangements - a row's own page is not necessarily the one currently filtered on.\n */\n private readonly contentTypesById = signal(new Map<string, ContentTypeDto>());\n\n private fieldsById = new Map<string, FieldDto>();\n\n /** Each content type's arrangement, joined with the field library. Keyed by content type id. */\n private arrangementByContentType = new Map<string, ArrangedField[]>();\n\n /** Union of `showInList` fields across the page's content types, deduped by field. */\n readonly columns = signal<FieldColumn[]>([]);\n\n /** Union of searchable fields, deduped by field. */\n readonly searchFields = signal<ArrangedField[]>([]);\n\n // --- stable-reference caches --------------------------------------------------------------------\n //\n // `ff-flex-field-*` decide whether to re-render by comparing their `fields` input's *object\n // reference*. Binding `[fields]=\"someMethodCall(row, column)\"` in a template calls that method - and\n // allocates a new object - on every change-detection pass. The child sees a changed input, tears\n // down and recreates its dynamic sub-component, which itself triggers change detection: Angular\n // reports `NG0103: Infinite change detection` and the page never finishes rendering. So both caches\n // hold stable references, rebuilt only when the underlying data actually changes.\n\n /** Per field definition, for the search bar. Keyed by field name. */\n private readonly definitionValues = signal(new Map<string, FlexFieldValue>());\n\n /** Per row then field name, for the list cells. */\n private readonly rowValues = signal(new Map<string, RowFieldValues>());\n\n readonly searchForm = this.fb.group({ flexFieldSearch: this.fb.group({}) });\n private appliedConditions: FlexFieldQueryCondition[] = [];\n\n /** Raw `flexFieldSearch` value restored from {@link ContentListStateService}, keyed by field name. */\n private searchValues: Record<string, unknown> = {};\n\n constructor() {\n const cached = this.listState.restore();\n if (cached) {\n this.filters = cached.filters;\n this.appliedConditions = cached.appliedConditions;\n this.searchValues = cached.searchValues;\n this.list.page = cached.page;\n this.list.sortKey = cached.sortKey;\n this.list.sortOrder = cached.sortOrder;\n this.list.maxResultCount = cached.maxResultCount;\n }\n\n this.pageService.getList({}).subscribe(result => {\n this.pages.set(result.items ?? []);\n });\n\n // Restores the content-type dropdown, columns and search fields for a restored `pageId` - a no-op\n // when there is none, same as a fresh visit.\n this.fetchContentTypes().subscribe();\n\n forkJoin({\n schema: this.referenceData.getSchema(),\n fields: this.referenceData.getFieldsById(),\n contentTypes: this.referenceData.getContentTypesById(),\n }).subscribe(({ schema, fields, contentTypes }) => {\n // The schema projection is name-keyed, so it is used only for the site-level settings; field\n // resolution goes through the Guid-keyed library below.\n this.languages.set(schema.enabledLanguages ?? []);\n this.fieldsById = fields;\n this.contentTypesById.set(contentTypes);\n this.rebuildArrangements();\n });\n\n // Waits for the schema before querying: on a first visit the reference data is uncached and\n // routinely outlasts `ListService`'s 300ms debounce, so the first query would otherwise go out\n // with no `cultureName` and list every language under a dropdown already showing one.\n const getData = (query: ABP.PageQueryParams) =>\n this.referenceData.getSchema().pipe(\n switchMap(schema => {\n this.filters.cultureName ??=\n schema.defaultLanguage ?? schema.enabledLanguages?.[0] ?? null;\n\n // Snapshot on every real query, not just on `applyFilters()` - this is the one point\n // every filter, search and paging change already funnels through.\n this.listState.save({\n filters: this.filters,\n appliedConditions: this.appliedConditions,\n searchValues: this.searchForm.get('flexFieldSearch')?.value ?? {},\n page: this.list.page,\n sortKey: this.list.sortKey,\n sortOrder: this.list.sortOrder,\n maxResultCount: this.list.maxResultCount,\n });\n\n return this.contentQuery.getList({\n ...query,\n ...this.filters,\n flexFieldConditions: this.appliedConditions,\n });\n }),\n );\n const setData = (result: PagedResultDto<ContentDto>) => {\n this.data.set(result);\n this.rebuildRowValues();\n };\n\n this.list.hookToQuery(getData).subscribe(setData);\n }\n\n // --- filters ------------------------------------------------------------------------------------\n\n onPageChange(pageId: string | null): void {\n this.filters.pageId = pageId;\n this.filters.contentTypeId = null;\n this.clearSearch();\n this.loadContentTypes();\n }\n\n applyFilters(): void {\n this.appliedConditions = this.buildConditions();\n this.list.page = 0;\n this.list.get();\n }\n\n /**\n * Resets each existing control rather than replacing the `flexFieldSearch` group.\n *\n * Every `ff-flex-field-search` keeps its own reference to the group it registered its control on\n * (`FieldTypeControlBase.valuesGroup`), captured when its inputs were first set. Swapping in a new\n * group would not change the identity of anything those children can see - `searchForm` itself is\n * unchanged - so none of them would re-register. They would keep writing into the old, detached\n * group while `buildConditions()` read the new, permanently empty one.\n */\n clearSearch(): void {\n const group = this.searchForm.get('flexFieldSearch') as FormGroup;\n Object.values(group.controls).forEach(control => control.reset(''));\n this.appliedConditions = [];\n this.searchValues = {};\n }\n\n clearFiltersAndSearch(): void {\n const cultureName = this.filters.cultureName;\n this.filters = { cultureName } as GetContentListInput;\n this.clearSearch();\n this.contentTypes.set([]);\n this.rebuildArrangements();\n this.applyFilters();\n }\n\n private loadContentTypes(): void {\n this.fetchContentTypes().subscribe(() => this.applyFilters());\n }\n\n /** Loads `contentTypes` for the current `filters.pageId` and rebuilds the derived arrangements. */\n private fetchContentTypes(): Observable<void> {\n if (!this.filters.pageId) {\n this.contentTypes.set([]);\n this.rebuildArrangements();\n return of<void>(undefined);\n }\n\n return this.contentTypeService.getListByPage(this.filters.pageId).pipe(\n map(result => {\n this.contentTypes.set(result.items ?? []);\n this.rebuildArrangements();\n }),\n );\n }\n\n // --- arrangement, columns, search fields ---------------------------------------------------------\n\n /**\n * Recomputes everything derived from \"which content types are in play\": the per-type arrangements,\n * the column union and the searchable union. Runs on page change and whenever the field library\n * arrives, never per change-detection pass.\n */\n private rebuildArrangements(): void {\n this.arrangementByContentType = new Map(\n this.contentTypes().map(contentType => [\n contentType.id!,\n (contentType.fields ?? [])\n .map(entry => this.toArrangedField(entry.fieldId, entry))\n .filter((field): field is ArrangedField => !!field)\n .sort((a, b) => a.order - b.order),\n ]),\n );\n\n this.rebuildColumns();\n this.rebuildSearchFields();\n this.rebuildRowValues();\n }\n\n private toArrangedField(\n fieldId: string | undefined,\n usage: { required?: boolean; searchable?: boolean; showInList?: boolean; displayName?: string | null; order?: number },\n ): ArrangedField | undefined {\n const definition = fieldId ? this.fieldsById.get(fieldId) : undefined;\n\n if (!definition) {\n return undefined;\n }\n\n const fieldData: FlexFieldData = {\n id: definition.id!,\n name: definition.name!,\n displayName: usage.displayName || definition.displayName!,\n description: definition.description ?? undefined,\n fieldTypeName: definition.fieldTypeName!,\n configuration: (definition.configuration ?? {}) as Record<string, unknown>,\n };\n\n return {\n fieldId: definition.id!,\n name: definition.name!,\n displayName: fieldData.displayName,\n fieldTypeName: definition.fieldTypeName!,\n required: !!usage.required,\n searchable: !!usage.searchable,\n showInList: !!usage.showInList,\n order: usage.order ?? 0,\n fieldData,\n };\n }\n\n /**\n * A field earns a column when a content type marks it `showInList` - that flag is the whole answer.\n *\n * No capability check on top of it: whether a field type ships a view component is not a reason to\n * drop a column the arrangement explicitly asked for. Silently omitting it would leave the editor\n * looking at a setting that appears to do nothing.\n */\n private rebuildColumns(): void {\n const columns = new Map<string, FieldColumn>();\n\n for (const [contentTypeId, fields] of this.arrangementByContentType) {\n for (const field of fields) {\n if (!field.showInList) {\n continue;\n }\n\n const existing = columns.get(field.fieldId);\n if (existing) {\n existing.contentTypeIds.add(contentTypeId);\n } else {\n columns.set(field.fieldId, {\n fieldId: field.fieldId,\n name: field.name,\n displayName: field.displayName,\n fieldTypeName: field.fieldTypeName,\n contentTypeIds: new Set([contentTypeId]),\n });\n }\n }\n }\n\n this.columns.set([...columns.values()]);\n }\n\n /**\n * A field is filterable when a content type marks it `searchable` - again, that flag is the whole\n * answer. The field arrangement editor already refuses to set it on a type the server reports as\n * non-indexable, so the check belongs there, where it can explain itself, rather than here where it\n * would quietly drop a filter someone had configured.\n *\n * `ff-flex-field-search` renders nothing for a type with no search component (`DateTime` today); that\n * is the library's documented behaviour, not something to pre-empt by hiding the field.\n */\n private rebuildSearchFields(): void {\n const fields = new Map<string, ArrangedField>();\n\n for (const arranged of this.arrangementByContentType.values()) {\n for (const field of arranged) {\n if (fields.has(field.fieldId) || !field.searchable) {\n continue;\n }\n fields.set(field.fieldId, field);\n }\n }\n\n const searchFields = [...fields.values()];\n this.searchFields.set(searchFields);\n this.definitionValues.set(\n new Map(\n searchFields.map(field => [\n field.name,\n { field: field.fieldData, required: field.required, searchable: true, value: undefined },\n ]),\n ),\n );\n }\n\n private rebuildRowValues(): void {\n this.rowValues.set(\n new Map(\n (this.data().items ?? []).map(content => [\n content.id!,\n new Map(\n (this.arrangementByContentType.get(content.contentTypeId ?? '') ?? []).map(field => [\n field.name,\n {\n field: field.fieldData,\n required: field.required,\n searchable: field.searchable,\n value: content.fieldValues?.[field.name],\n } as FlexFieldValue,\n ]),\n ),\n ]),\n ),\n );\n }\n\n /** The stable value for one cell, or `undefined` when this row's type does not use the field. */\n rowValueOf(content: ContentDto, column: FieldColumn): FlexFieldValue | undefined {\n return this.rowValues().get(content.id!)?.get(column.name);\n }\n\n /** The stable value for one search widget. See {@link definitionValues}. */\n definitionValueOf(field: ArrangedField): FlexFieldValue | undefined {\n return this.definitionValues().get(field.name);\n }\n\n /** What one search widget should redisplay on restore - see {@link ContentListStateService}. */\n selectedValueOf(field: ArrangedField): unknown {\n return this.searchValues[field.name] ?? '';\n }\n\n // --- search conditions ---------------------------------------------------------------------------\n\n /**\n * Turns what each `ff-flex-field-search` wrote into the conditions the server understands. The\n * mapping depends on each field type's storage shape, not on anything generic the search form knows.\n */\n private buildConditions(): FlexFieldQueryCondition[] {\n const raw = (this.searchForm.get('flexFieldSearch')?.value ?? {}) as Record<string, unknown>;\n return this.searchFields().flatMap(field => this.toConditions(field, raw[field.name]));\n }\n\n private toConditions(field: ArrangedField, value: unknown): FlexFieldQueryCondition[] {\n switch (field.fieldTypeName) {\n case 'Text':\n return this.isBlank(value)\n ? []\n : [\n this.condition(\n field,\n FlexFieldQueryOperator.Contains,\n String(value),\n FlexFieldValueType.String,\n ),\n ];\n\n case 'Number': {\n // `ff-number-search` writes one \"min-max\" string; the executor composes two conditions on the\n // same field as a range rather than a conflict.\n const range = typeof value === 'string' ? value.split('-') : [];\n if (range.length !== 2 || range.some(part => part === '')) {\n return [];\n }\n return [\n this.condition(\n field,\n FlexFieldQueryOperator.GreaterThanOrEqual,\n range[0],\n FlexFieldValueType.Number,\n ),\n this.condition(\n field,\n FlexFieldQueryOperator.LessThanOrEqual,\n range[1],\n FlexFieldValueType.Number,\n ),\n ];\n }\n\n case 'Boolean':\n // A plain `<option [value]>` binding always stringifies, so this arrives as \"true\"/\"false\".\n return value === 'true' || value === 'false'\n ? [this.condition(field, FlexFieldQueryOperator.Equals, value, FlexFieldValueType.Boolean)]\n : [];\n\n case 'Select':\n case 'Tree': {\n const values = Array.isArray(value) ? value : this.isBlank(value) ? [] : [value];\n return values.length === 0\n ? []\n : [\n this.condition(\n field,\n FlexFieldQueryOperator.In,\n values.join(','),\n FlexFieldValueType.String,\n ),\n ];\n }\n\n default:\n return [];\n }\n }\n\n /** Both `fieldId` and `fieldName` are required by the server - always send the pair. */\n private condition(\n field: ArrangedField,\n operator: FlexFieldQueryOperator,\n value: string,\n valueType: FlexFieldValueType,\n ): FlexFieldQueryCondition {\n return { fieldId: field.fieldId, fieldName: field.name, operator, value, valueType };\n }\n\n private isBlank(value: unknown): boolean {\n return value === null || value === undefined || value === '';\n }\n\n // --- display helpers -----------------------------------------------------------------------------\n\n statusKeyOf(status?: ContentStatus): string {\n return `Site::Enum:ContentStatus:${ContentStatus[status ?? ContentStatus.Draft]}`;\n }\n\n contentTypeNameOf(contentTypeId?: string): string {\n return (contentTypeId ? this.contentTypesById().get(contentTypeId)?.displayName : undefined) ?? '---';\n }\n\n pageNameOf(pageId?: string): string {\n return this.pages().find(page => page.id === pageId)?.displayName ?? '---';\n }\n\n // --- create / edit -------------------------------------------------------------------------------\n //\n // Editing happens on its own page (`/site/contents/create`, `/site/contents/:id/edit`), so this\n // component only links there. Deleting stays here because it needs no form.\n\n /** Creating needs a page picked, since a content type belongs to one. */\n get canCreate(): boolean {\n return !!this.filters.pageId && this.contentTypes().length > 0;\n }\n\n delete(content: ContentDto): void {\n this.confirmation\n .warn('AbpUi::ItemWillBeDeletedMessage', 'AbpUi::AreYouSure', {\n messageLocalizationParams: [content.slug || this.pageNameOf(content.pageId)],\n })\n .subscribe((status: Confirmation.Status) => {\n if (status === Confirmation.Status.confirm) {\n this.contentService.delete(content.id!).subscribe(() => {\n this.list.get();\n this.toaster.success('AbpUi::SuccessfullyDeleted');\n });\n }\n });\n }\n}\n","<div class=\"card mb-3\">\n <div class=\"card-body\">\n <div class=\"row align-items-end g-2 mb-3\">\n <div class=\"col-md-3\">\n <label class=\"form-label\">{{ 'Site::Menu:Pages' | abpLocalization }}</label>\n <site-page-tree-select\n [pages]=\"pages()\"\n [value]=\"filters.pageId\"\n (valueChange)=\"onPageChange($event)\"\n ></site-page-tree-select>\n </div>\n <div class=\"col-md-2\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Content.ContentType' | abpLocalization }}</label>\n <select\n class=\"form-select\"\n [(ngModel)]=\"filters.contentTypeId\"\n (change)=\"applyFilters()\"\n [disabled]=\"!filters.pageId\"\n >\n <option [ngValue]=\"null\">--</option>\n @for (contentType of contentTypes(); track contentType.id) {\n <option [ngValue]=\"contentType.id\">{{ contentType.displayName }}</option>\n }\n </select>\n </div>\n <div class=\"col-md-2\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Content.CultureName' | abpLocalization }}</label>\n <select class=\"form-select\" [(ngModel)]=\"filters.cultureName\" (change)=\"applyFilters()\">\n @for (language of languages(); track language) {\n <option [ngValue]=\"language\">{{ language }}</option>\n }\n </select>\n </div>\n <div class=\"col-md-2\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Content.Status' | abpLocalization }}</label>\n <select class=\"form-select\" [(ngModel)]=\"filters.status\" (change)=\"applyFilters()\">\n <option [ngValue]=\"null\">--</option>\n @for (status of statuses; track status) {\n <option [ngValue]=\"status\">{{ statusKeyOf(status) | abpLocalization }}</option>\n }\n </select>\n </div>\n <div class=\"col-md-3\">\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>\n\n @if (searchFields().length > 0) {\n <hr />\n <h6>{{ 'Site::FilterByFieldValue' | abpLocalization }}</h6>\n <form [formGroup]=\"searchForm\">\n <div class=\"row g-2\">\n @for (field of searchFields(); track field.fieldId) {\n <!-- No label here: each search widget renders the field's own label. -->\n <div class=\"col-md-3\">\n <ff-flex-field-search\n [fields]=\"definitionValueOf(field)\"\n [selected]=\"selectedValueOf(field)\"\n [entity]=\"searchForm\"\n parentFieldName=\"flexFieldSearch\"\n ></ff-flex-field-search>\n </div>\n }\n </div>\n </form>\n }\n\n <div class=\"mt-3\">\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)=\"clearFiltersAndSearch()\">\n {{ 'AbpUi::Clear' | abpLocalization }}\n </button>\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::Contents' | abpLocalization }}</h5>\n <a\n *abpPermission=\"policies.ContentsCreate\"\n class=\"btn btn-primary\"\n [class.disabled]=\"!canCreate\"\n [routerLink]=\"canCreate ? ['/site/contents/create'] : null\"\n [queryParams]=\"{ pageId: filters.pageId, cultureName: filters.cultureName }\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::NewContent' | abpLocalization }}\n </a>\n </div>\n\n @if (!filters.pageId) {\n <p class=\"text-muted\">{{ 'Site::PageFilterRequiredForFieldColumns' | abpLocalization }}</p>\n }\n\n <!-- `[list]` drives paging through `ListService` (server-side: `skipCount`/`maxResultCount`) and\n renders the localized total, loading spinner and empty message; `default` is ABP's stock\n table look, including the horizontal scrollbar a wide field-column union needs. Every column\n is unsortable, keeping the server's default `PublishTime desc, Id desc` - a deterministic\n order, so pages never overlap or skip rows. Field columns could not sort anyway: `sorting`\n is a dynamic-LINQ order over entity properties, and field values live in JSON. -->\n <ngx-datatable default [rows]=\"data().items\" [count]=\"data().totalCount\" [list]=\"list\">\n <ngx-datatable-column\n [name]=\"'Site::DisplayName:Content.Slug' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n {{ row.slug || ('Site::SlugIsPageOwnAddress' | abpLocalization) }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n [name]=\"'Site::DisplayName:Content.ContentType' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n {{ contentTypeNameOf(row.contentTypeId) }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n [name]=\"'Site::DisplayName:Content.Status' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n {{ statusKeyOf(row.status) | abpLocalization }}\n </ng-template>\n </ngx-datatable-column>\n @for (column of columns(); track column.fieldId) {\n <ngx-datatable-column [name]=\"column.displayName\" [sortable]=\"false\">\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <!-- Columns are the union across the page's content types, so a row whose type does not\n use this field has nothing to show here. -->\n @if (rowValueOf(row, column); as fieldValue) {\n <ff-flex-field-view\n [showInList]=\"true\"\n [type]=\"column.fieldTypeName\"\n [fields]=\"fieldValue\"\n [value]=\"fieldValue.value\"\n ></ff-flex-field-view>\n } @else {\n ---\n }\n </ng-template>\n </ngx-datatable-column>\n }\n <ngx-datatable-column\n [name]=\"'Site::DisplayName:Content.PublishTime' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n {{ row.publishTime | shortDateTime }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n [name]=\"'AbpUi::Actions' | abpLocalization\"\n [sortable]=\"false\"\n [width]=\"130\"\n [maxWidth]=\"130\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <a\n *abpPermission=\"policies.ContentsUpdate\"\n class=\"btn btn-sm btn-light me-1\"\n [routerLink]=\"['/site/contents', row.id, 'edit']\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </a>\n <button\n *abpPermission=\"policies.ContentsDelete\"\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"],"names":["i1","i2","i5","i6"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dignite-ng.site-contents.component-ht0WYCSN.mjs","sources":["../../../projects/site/src/lib/components/contents/page-tree-select.component.ts","../../../projects/site/src/lib/components/contents/contents.component.ts","../../../projects/site/src/lib/components/contents/contents.component.html"],"sourcesContent":["import { TreeAdapter, TreeModule } from '@abp/ng.components/tree';\nimport type { BaseNode, TreeNode } from '@abp/ng.components/tree';\nimport { CoreModule } from '@abp/ng.core';\nimport {\n Component,\n ElementRef,\n EventEmitter,\n HostListener,\n Input,\n Output,\n inject,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport type { PageDto } from '../../proxy/dignite/site/pages/models';\n\n/** `TreeAdapter` wants a non-optional `id`/`parentId`, which the generated `PageDto` leaves optional. */\ntype PageNode = PageDto & BaseNode;\n\n/**\n * Picks one page, laid out as the page hierarchy rather than a flat list - a child page's name alone\n * rarely says which section it sits under.\n *\n * Built like flex-fields' `ff-tree-search` - a `.form-select`-styled toggle over an `abp-tree` panel -\n * because both render in the same content-list filter bar and should look and behave alike. That\n * component's node renderer (`ff-tree-picker-nodes`) is not exported, hence `abp-tree` directly.\n */\n@Component({\n selector: 'site-page-tree-select',\n changeDetection: ChangeDetectionStrategy.Eager,\n imports: [CoreModule, TreeModule],\n template: `\n <div class=\"page-tree-select\">\n <button\n type=\"button\"\n class=\"form-select text-start page-tree-select-toggle\"\n [class.text-muted]=\"!selectedNode\"\n aria-haspopup=\"tree\"\n [attr.aria-expanded]=\"isOpen\"\n (click)=\"toggle()\"\n >\n {{ selectedNode?.title ?? '--' }}\n </button>\n @if (selectedNode) {\n <button\n type=\"button\"\n class=\"btn btn-link page-tree-select-clear\"\n [title]=\"'AbpUi::Clear' | abpLocalization\"\n (click)=\"clear($event)\"\n >\n <i class=\"fa fa-times\" aria-hidden=\"true\"></i>\n </button>\n }\n\n @if (isOpen) {\n <div class=\"page-tree-select-menu\">\n <abp-tree\n [nodes]=\"nodes\"\n [(expandedKeys)]=\"expandedKeys\"\n [selectedNode]=\"selectedNode\"\n (selectedNodeChange)=\"select($event)\"\n >\n <ng-template abpTreeNodeTemplate let-node>\n <span class=\"page-tree-select-node\">{{ node.title }}</span>\n </ng-template>\n <ng-template abpTreeExpandedIconTemplate let-node>\n <i\n class=\"fa\"\n [class.fa-minus]=\"node.isExpanded\"\n [class.fa-plus]=\"!node.isExpanded\"\n aria-hidden=\"true\"\n ></i>\n </ng-template>\n </abp-tree>\n </div>\n }\n </div>\n `,\n // Mirrors ff-tree-search's and ff-tree-picker-nodes' styles, so this sits beside a Tree field's\n // filter without looking like a different control. The panel renders inside the host, not in an\n // overlay, so :host-scoped rules reach it.\n styles: `\n .page-tree-select {\n position: relative;\n }\n .page-tree-select-toggle {\n height: auto;\n min-height: calc(1.5em + 1.35rem + 2px);\n padding-right: 3.75rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .page-tree-select-clear {\n position: absolute;\n top: 50%;\n right: 2rem;\n display: inline-flex;\n align-items: center;\n height: 100%;\n padding: 0 0.375rem;\n line-height: 1;\n color: var(--bs-secondary-color, #6c757d);\n text-decoration: none;\n transform: translateY(-50%);\n z-index: 2;\n }\n .page-tree-select-menu {\n position: absolute;\n z-index: 1050;\n width: 100%;\n max-height: 18rem;\n margin-top: 0.25rem;\n padding: 0.375rem;\n overflow: auto;\n color: var(--bs-body-color);\n background-color: var(--lpx-content-bg, var(--bs-secondary-bg, #fff));\n border: 1px solid var(--bs-border-color, rgba(0, 0, 0, 0.12));\n border-radius: 0.375rem;\n box-shadow: 0 0.125rem 0.25rem #00000013;\n }\n .page-tree-select-node {\n display: inline-block;\n min-height: 1.75rem;\n padding: 0.125rem 0.375rem;\n border-radius: 0.25rem;\n }\n :host ::ng-deep .ant-tree {\n background: transparent !important;\n }\n :host ::ng-deep .ant-tree-node-content-wrapper,\n :host ::ng-deep .ant-tree-node-content-wrapper:hover {\n background-color: transparent !important;\n }\n :host ::ng-deep .ant-tree-node-content-wrapper > .selected .page-tree-select-node {\n background-color: var(--lpx-brand, var(--bs-primary));\n color: var(--bs-white, #fff);\n }\n :host ::ng-deep .ant-tree-node-content-wrapper:hover > div:not(.selected) .page-tree-select-node {\n background-color: var(--bs-secondary-bg, #f5f5f5);\n }\n `,\n})\nexport class PageTreeSelectComponent {\n private readonly elementRef = inject(ElementRef);\n\n /** Every page, flat - the hierarchy is rebuilt from `parentId`. */\n @Input() set pages(pages: PageDto[]) {\n const ids = new Set(pages.map(page => page.id));\n // `TreeAdapter` silently drops a node whose parent is not in the list, taking its whole subtree\n // with it; such a page shows at the root instead.\n const list = pages.map(\n page =>\n ({\n ...page,\n id: page.id!,\n parentId: page.parentId && ids.has(page.parentId) ? page.parentId : null,\n }) as PageNode,\n );\n\n this.nodes = new TreeAdapter(list).getTree();\n this.nodesByKey = new Map();\n this.index(this.nodes);\n // Opens fully expanded, the same as the page form's parent picker (`nzDefaultExpandAll`).\n this.expandedKeys = [...this.nodesByKey.values()].filter(node => !node.isLeaf).map(node => node.key);\n }\n\n /** The selected page's id, or `null` for \"any page\". */\n @Input() value?: string | null;\n\n /** Emits only on an actual change, like a native `<select>`'s `change`. */\n @Output() readonly valueChange = new EventEmitter<string | null>();\n\n nodes: TreeNode<PageNode>[] = [];\n expandedKeys: string[] = [];\n isOpen = false;\n\n private nodesByKey = new Map<string, TreeNode<PageNode>>();\n\n /**\n * Passed to `abp-tree` as `selectedNode`, whose default `isNodeSelected` matches on `id` - which a\n * `TreeNode` carries as well as its entity. A stable reference from {@link nodesByKey}, so the\n * OnPush tree only re-renders when the selection really changes.\n */\n get selectedNode(): TreeNode<PageNode> | undefined {\n return this.value ? this.nodesByKey.get(this.value) : undefined;\n }\n\n toggle(): void {\n this.isOpen = !this.isOpen;\n }\n\n /** `abp-tree` emits the clicked node's entity, i.e. the page. */\n select(page: PageNode): void {\n this.isOpen = false;\n this.emit(page.id);\n }\n\n clear(event: Event): void {\n // Keeps the click from reaching the toggle underneath it.\n event.stopPropagation();\n this.emit(null);\n }\n\n @HostListener('document:click', ['$event'])\n closeOnOutsideClick(event: Event): void {\n if (this.isOpen && !event.composedPath().includes(this.elementRef.nativeElement)) {\n this.isOpen = false;\n }\n }\n\n @HostListener('keydown.escape')\n close(): void {\n this.isOpen = false;\n }\n\n private emit(pageId: string | null): void {\n if (pageId !== (this.value ?? null)) {\n this.valueChange.emit(pageId);\n }\n }\n\n private index(nodes: TreeNode<PageNode>[]): void {\n for (const node of nodes) {\n this.nodesByKey.set(node.key, node);\n this.index(node.children);\n }\n }\n}\n","import {\n ABP,\n CoreModule,\n LIST_QUERY_DEBOUNCE_TIME,\n ListService,\n PagedResultDto,\n PermissionDirective,\n} from '@abp/ng.core';\nimport {\n Confirmation,\n ConfirmationService,\n ThemeSharedModule,\n ToasterService,\n} from '@abp/ng.theme.shared';\nimport { Component, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { RouterLink } from '@angular/router';\nimport { FlexFieldSearchComponent, FlexFieldViewComponent } from '@dignite/ng.flex-fields';\nimport type { FlexFieldData, FlexFieldValue } from '@dignite/ng.flex-fields';\nimport { Observable, forkJoin, map, of, switchMap } from 'rxjs';\nimport { ContentAdminService } from '../../proxy/dignite/site/admin/contents/content-admin.service';\nimport { ContentTypeAdminService } from '../../proxy/dignite/site/admin/content-types/content-type-admin.service';\nimport { PageAdminService } from '../../proxy/dignite/site/admin/pages/page-admin.service';\nimport type { GetContentListInput } from '../../proxy/dignite/site/admin/contents/models';\nimport type { ContentTypeDto } from '../../proxy/dignite/site/content-types/models';\nimport type { ContentDto } from '../../proxy/dignite/site/contents/models';\nimport { ContentStatus } from '../../proxy/dignite/site/contents/content-status.enum';\nimport { FlexFieldQueryOperator } from '../../proxy/dignite/abp/flex-fields/flex-field-query-operator.enum';\nimport { FlexFieldValueType } from '../../proxy/dignite/abp/flex-fields/flex-field-value-type.enum';\nimport type { FlexFieldQueryCondition } from '../../proxy/dignite/abp/flex-fields/models';\nimport type { FieldDto } from '../../proxy/dignite/site/fields/models';\nimport type { PageDto } from '../../proxy/dignite/site/pages/models';\nimport { eSitePolicyNames } from '../../enums/policy-names';\nimport { ContentListStateService } from '../../services/content-list-state.service';\nimport { ContentQueryService } from '../../services/content-query.service';\nimport { SiteReferenceDataService } from '../../services/site-reference-data.service';\nimport type { ArrangedField, FieldColumn, RowFieldValues } from './arranged-field';\nimport { PageTreeSelectComponent } from './page-tree-select.component';\n\n@Component({\n selector: 'site-contents',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './contents.component.html',\n imports: [\n CoreModule,\n ThemeSharedModule,\n ReactiveFormsModule,\n PermissionDirective,\n RouterLink,\n FlexFieldSearchComponent,\n FlexFieldViewComponent,\n PageTreeSelectComponent,\n ],\n providers: [ListService, { provide: LIST_QUERY_DEBOUNCE_TIME, useValue: 300 }],\n})\nexport class ContentsComponent {\n private readonly contentService = inject(ContentAdminService);\n private readonly contentQuery = inject(ContentQueryService);\n private readonly listState = inject(ContentListStateService);\n private readonly contentTypeService = inject(ContentTypeAdminService);\n private readonly pageService = inject(PageAdminService);\n private readonly referenceData = inject(SiteReferenceDataService);\n private readonly fb = inject(FormBuilder);\n private readonly confirmation = inject(ConfirmationService);\n private readonly toaster = inject(ToasterService);\n\n readonly list = inject(ListService);\n readonly policies = eSitePolicyNames;\n readonly ContentStatus = ContentStatus;\n readonly statuses = [ContentStatus.Draft, ContentStatus.Published, ContentStatus.Archived];\n\n // Everything the template reads that changes in an HTTP callback is a signal, not a plain field: the\n // host layout's ancestors (`abp-router-outlet`, the LeptonX layouts) are OnPush, and a plain-field\n // write in a response callback never marks them for check, so the list would stay empty until some\n // unrelated event happened to.\n readonly data = signal<PagedResultDto<ContentDto>>({ items: [], totalCount: 0 });\n filters = {} as GetContentListInput;\n\n readonly pages = signal<PageDto[]>([]);\n readonly languages = signal<string[]>([]);\n readonly contentTypes = signal<ContentTypeDto[]>([]);\n\n /**\n * Every content type across every page, for resolving a row's display name. Deliberately separate\n * from {@link contentTypes}, which is scoped to the selected page and drives the filter dropdown and\n * field arrangements - a row's own page is not necessarily the one currently filtered on.\n */\n private readonly contentTypesById = signal(new Map<string, ContentTypeDto>());\n\n private fieldsById = new Map<string, FieldDto>();\n\n /** Each content type's arrangement, joined with the field library. Keyed by content type id. */\n private arrangementByContentType = new Map<string, ArrangedField[]>();\n\n /** Union of `showInList` fields across the page's content types, deduped by field. */\n readonly columns = signal<FieldColumn[]>([]);\n\n /** Union of searchable fields, deduped by field. */\n readonly searchFields = signal<ArrangedField[]>([]);\n\n // --- stable-reference caches --------------------------------------------------------------------\n //\n // `ff-flex-field-*` decide whether to re-render by comparing their `fields` input's *object\n // reference*. Binding `[fields]=\"someMethodCall(row, column)\"` in a template calls that method - and\n // allocates a new object - on every change-detection pass. The child sees a changed input, tears\n // down and recreates its dynamic sub-component, which itself triggers change detection: Angular\n // reports `NG0103: Infinite change detection` and the page never finishes rendering. So both caches\n // hold stable references, rebuilt only when the underlying data actually changes.\n\n /** Per field definition, for the search bar. Keyed by field name. */\n private readonly definitionValues = signal(new Map<string, FlexFieldValue>());\n\n /** Per row then field name, for the list cells. */\n private readonly rowValues = signal(new Map<string, RowFieldValues>());\n\n readonly searchForm = this.fb.group({ flexFieldSearch: this.fb.group({}) });\n private appliedConditions: FlexFieldQueryCondition[] = [];\n\n /** Raw `flexFieldSearch` value restored from {@link ContentListStateService}, keyed by field name. */\n private searchValues: Record<string, unknown> = {};\n\n constructor() {\n const cached = this.listState.restore();\n if (cached) {\n this.filters = cached.filters;\n this.appliedConditions = cached.appliedConditions;\n this.searchValues = cached.searchValues;\n this.list.page = cached.page;\n this.list.sortKey = cached.sortKey;\n this.list.sortOrder = cached.sortOrder;\n this.list.maxResultCount = cached.maxResultCount;\n }\n\n this.pageService.getList({}).subscribe(result => {\n this.pages.set(result.items ?? []);\n });\n\n // Restores the content-type dropdown, columns and search fields for a restored `pageId` - a no-op\n // when there is none, same as a fresh visit.\n this.fetchContentTypes().subscribe();\n\n forkJoin({\n schema: this.referenceData.getSchema(),\n fields: this.referenceData.getFieldsById(),\n contentTypes: this.referenceData.getContentTypesById(),\n }).subscribe(({ schema, fields, contentTypes }) => {\n // The schema projection is name-keyed, so it is used only for the site-level settings; field\n // resolution goes through the Guid-keyed library below.\n this.languages.set(schema.enabledLanguages ?? []);\n this.fieldsById = fields;\n this.contentTypesById.set(contentTypes);\n this.rebuildArrangements();\n });\n\n // Waits for the schema before querying: on a first visit the reference data is uncached and\n // routinely outlasts `ListService`'s 300ms debounce, so the first query would otherwise go out\n // with no `cultureName` and list every language under a dropdown already showing one.\n const getData = (query: ABP.PageQueryParams) =>\n this.referenceData.getSchema().pipe(\n switchMap(schema => {\n this.filters.cultureName ??=\n schema.defaultLanguage ?? schema.enabledLanguages?.[0] ?? null;\n\n // Snapshot on every real query, not just on `applyFilters()` - this is the one point\n // every filter, search and paging change already funnels through.\n this.listState.save({\n filters: this.filters,\n appliedConditions: this.appliedConditions,\n searchValues: this.searchForm.get('flexFieldSearch')?.value ?? {},\n page: this.list.page,\n sortKey: this.list.sortKey,\n sortOrder: this.list.sortOrder,\n maxResultCount: this.list.maxResultCount,\n });\n\n return this.contentQuery.getList({\n ...query,\n ...this.filters,\n flexFieldConditions: this.appliedConditions,\n });\n }),\n );\n const setData = (result: PagedResultDto<ContentDto>) => {\n this.data.set(result);\n this.rebuildRowValues();\n };\n\n this.list.hookToQuery(getData).subscribe(setData);\n }\n\n // --- filters ------------------------------------------------------------------------------------\n\n onPageChange(pageId: string | null): void {\n this.filters.pageId = pageId;\n this.filters.contentTypeId = null;\n this.clearSearch();\n this.loadContentTypes();\n }\n\n applyFilters(): void {\n this.appliedConditions = this.buildConditions();\n this.list.page = 0;\n this.list.get();\n }\n\n /**\n * Resets each existing control rather than replacing the `flexFieldSearch` group.\n *\n * Every `ff-flex-field-search` keeps its own reference to the group it registered its control on\n * (`FieldTypeControlBase.valuesGroup`), captured when its inputs were first set. Swapping in a new\n * group would not change the identity of anything those children can see - `searchForm` itself is\n * unchanged - so none of them would re-register. They would keep writing into the old, detached\n * group while `buildConditions()` read the new, permanently empty one.\n */\n clearSearch(): void {\n const group = this.searchForm.get('flexFieldSearch') as FormGroup;\n Object.values(group.controls).forEach(control => control.reset(''));\n this.appliedConditions = [];\n this.searchValues = {};\n }\n\n clearFiltersAndSearch(): void {\n const cultureName = this.filters.cultureName;\n this.filters = { cultureName } as GetContentListInput;\n this.clearSearch();\n this.contentTypes.set([]);\n this.rebuildArrangements();\n this.applyFilters();\n }\n\n private loadContentTypes(): void {\n this.fetchContentTypes().subscribe(() => this.applyFilters());\n }\n\n /** Loads `contentTypes` for the current `filters.pageId` and rebuilds the derived arrangements. */\n private fetchContentTypes(): Observable<void> {\n if (!this.filters.pageId) {\n this.contentTypes.set([]);\n this.rebuildArrangements();\n return of<void>(undefined);\n }\n\n return this.contentTypeService.getListByPage(this.filters.pageId).pipe(\n map(result => {\n this.contentTypes.set(result.items ?? []);\n this.rebuildArrangements();\n }),\n );\n }\n\n // --- arrangement, columns, search fields ---------------------------------------------------------\n\n /**\n * Recomputes everything derived from \"which content types are in play\": the per-type arrangements,\n * the column union and the searchable union. Runs on page change and whenever the field library\n * arrives, never per change-detection pass.\n */\n private rebuildArrangements(): void {\n this.arrangementByContentType = new Map(\n this.contentTypes().map(contentType => [\n contentType.id!,\n (contentType.fields ?? [])\n .map(entry => this.toArrangedField(entry.fieldId, entry))\n .filter((field): field is ArrangedField => !!field)\n .sort((a, b) => a.order - b.order),\n ]),\n );\n\n this.rebuildColumns();\n this.rebuildSearchFields();\n this.rebuildRowValues();\n }\n\n private toArrangedField(\n fieldId: string | undefined,\n usage: { required?: boolean; searchable?: boolean; showInList?: boolean; displayName?: string | null; order?: number },\n ): ArrangedField | undefined {\n const definition = fieldId ? this.fieldsById.get(fieldId) : undefined;\n\n if (!definition) {\n return undefined;\n }\n\n const fieldData: FlexFieldData = {\n id: definition.id!,\n name: definition.name!,\n displayName: usage.displayName || definition.displayName!,\n description: definition.description ?? undefined,\n fieldTypeName: definition.fieldTypeName!,\n configuration: (definition.configuration ?? {}) as Record<string, unknown>,\n };\n\n return {\n fieldId: definition.id!,\n name: definition.name!,\n displayName: fieldData.displayName,\n fieldTypeName: definition.fieldTypeName!,\n required: !!usage.required,\n searchable: !!usage.searchable,\n showInList: !!usage.showInList,\n order: usage.order ?? 0,\n fieldData,\n };\n }\n\n /**\n * A field earns a column when a content type marks it `showInList` - that flag is the whole answer.\n *\n * No capability check on top of it: whether a field type ships a view component is not a reason to\n * drop a column the arrangement explicitly asked for. Silently omitting it would leave the editor\n * looking at a setting that appears to do nothing.\n */\n private rebuildColumns(): void {\n const columns = new Map<string, FieldColumn>();\n\n for (const [contentTypeId, fields] of this.arrangementByContentType) {\n for (const field of fields) {\n if (!field.showInList) {\n continue;\n }\n\n const existing = columns.get(field.fieldId);\n if (existing) {\n existing.contentTypeIds.add(contentTypeId);\n } else {\n columns.set(field.fieldId, {\n fieldId: field.fieldId,\n name: field.name,\n displayName: field.displayName,\n fieldTypeName: field.fieldTypeName,\n contentTypeIds: new Set([contentTypeId]),\n });\n }\n }\n }\n\n this.columns.set([...columns.values()]);\n }\n\n /**\n * A field is filterable when a content type marks it `searchable` - again, that flag is the whole\n * answer. The field arrangement editor already refuses to set it on a type the server reports as\n * non-indexable, so the check belongs there, where it can explain itself, rather than here where it\n * would quietly drop a filter someone had configured.\n *\n * `ff-flex-field-search` renders nothing for a type with no search component (`DateTime` today); that\n * is the library's documented behaviour, not something to pre-empt by hiding the field.\n */\n private rebuildSearchFields(): void {\n const fields = new Map<string, ArrangedField>();\n\n for (const arranged of this.arrangementByContentType.values()) {\n for (const field of arranged) {\n if (fields.has(field.fieldId) || !field.searchable) {\n continue;\n }\n fields.set(field.fieldId, field);\n }\n }\n\n const searchFields = [...fields.values()];\n this.searchFields.set(searchFields);\n this.definitionValues.set(\n new Map(\n searchFields.map(field => [\n field.name,\n { field: field.fieldData, required: field.required, searchable: true, value: undefined },\n ]),\n ),\n );\n }\n\n private rebuildRowValues(): void {\n this.rowValues.set(\n new Map(\n (this.data().items ?? []).map(content => [\n content.id!,\n new Map(\n (this.arrangementByContentType.get(content.contentTypeId ?? '') ?? []).map(field => [\n field.name,\n {\n field: field.fieldData,\n required: field.required,\n searchable: field.searchable,\n value: content.fieldValues?.[field.name],\n } as FlexFieldValue,\n ]),\n ),\n ]),\n ),\n );\n }\n\n /** The stable value for one cell, or `undefined` when this row's type does not use the field. */\n rowValueOf(content: ContentDto, column: FieldColumn): FlexFieldValue | undefined {\n return this.rowValues().get(content.id!)?.get(column.name);\n }\n\n /** The stable value for one search widget. See {@link definitionValues}. */\n definitionValueOf(field: ArrangedField): FlexFieldValue | undefined {\n return this.definitionValues().get(field.name);\n }\n\n /** What one search widget should redisplay on restore - see {@link ContentListStateService}. */\n selectedValueOf(field: ArrangedField): unknown {\n return this.searchValues[field.name] ?? '';\n }\n\n // --- search conditions ---------------------------------------------------------------------------\n\n /**\n * Turns what each `ff-flex-field-search` wrote into the conditions the server understands. The\n * mapping depends on each field type's storage shape, not on anything generic the search form knows.\n */\n private buildConditions(): FlexFieldQueryCondition[] {\n const raw = (this.searchForm.get('flexFieldSearch')?.value ?? {}) as Record<string, unknown>;\n return this.searchFields().flatMap(field => this.toConditions(field, raw[field.name]));\n }\n\n private toConditions(field: ArrangedField, value: unknown): FlexFieldQueryCondition[] {\n switch (field.fieldTypeName) {\n case 'Text':\n return this.isBlank(value)\n ? []\n : [\n this.condition(\n field,\n FlexFieldQueryOperator.Contains,\n String(value),\n FlexFieldValueType.String,\n ),\n ];\n\n case 'Number': {\n // `ff-number-search` writes one \"min-max\" string; the executor composes two conditions on the\n // same field as a range rather than a conflict.\n const range = typeof value === 'string' ? value.split('-') : [];\n if (range.length !== 2 || range.some(part => part === '')) {\n return [];\n }\n return [\n this.condition(\n field,\n FlexFieldQueryOperator.GreaterThanOrEqual,\n range[0],\n FlexFieldValueType.Number,\n ),\n this.condition(\n field,\n FlexFieldQueryOperator.LessThanOrEqual,\n range[1],\n FlexFieldValueType.Number,\n ),\n ];\n }\n\n case 'Boolean':\n // A plain `<option [value]>` binding always stringifies, so this arrives as \"true\"/\"false\".\n return value === 'true' || value === 'false'\n ? [this.condition(field, FlexFieldQueryOperator.Equals, value, FlexFieldValueType.Boolean)]\n : [];\n\n case 'Select':\n case 'Tree': {\n const values = Array.isArray(value) ? value : this.isBlank(value) ? [] : [value];\n return values.length === 0\n ? []\n : [\n this.condition(\n field,\n FlexFieldQueryOperator.In,\n values.join(','),\n FlexFieldValueType.String,\n ),\n ];\n }\n\n default:\n return [];\n }\n }\n\n /** Both `fieldId` and `fieldName` are required by the server - always send the pair. */\n private condition(\n field: ArrangedField,\n operator: FlexFieldQueryOperator,\n value: string,\n valueType: FlexFieldValueType,\n ): FlexFieldQueryCondition {\n return { fieldId: field.fieldId, fieldName: field.name, operator, value, valueType };\n }\n\n private isBlank(value: unknown): boolean {\n return value === null || value === undefined || value === '';\n }\n\n // --- display helpers -----------------------------------------------------------------------------\n\n statusKeyOf(status?: ContentStatus): string {\n return `Site::Enum:ContentStatus:${ContentStatus[status ?? ContentStatus.Draft]}`;\n }\n\n contentTypeNameOf(contentTypeId?: string): string {\n return (contentTypeId ? this.contentTypesById().get(contentTypeId)?.displayName : undefined) ?? '---';\n }\n\n pageNameOf(pageId?: string): string {\n return this.pages().find(page => page.id === pageId)?.displayName ?? '---';\n }\n\n // --- create / edit -------------------------------------------------------------------------------\n //\n // Editing happens on its own page (`/site/contents/create`, `/site/contents/:id/edit`), so this\n // component only links there. Deleting stays here because it needs no form.\n\n /** Creating needs a page picked, since a content type belongs to one. */\n get canCreate(): boolean {\n return !!this.filters.pageId && this.contentTypes().length > 0;\n }\n\n delete(content: ContentDto): void {\n this.confirmation\n .warn('AbpUi::ItemWillBeDeletedMessage', 'AbpUi::AreYouSure', {\n messageLocalizationParams: [content.slug || this.pageNameOf(content.pageId)],\n })\n .subscribe((status: Confirmation.Status) => {\n if (status === Confirmation.Status.confirm) {\n this.contentService.delete(content.id!).subscribe(() => {\n this.list.get();\n this.toaster.success('AbpUi::DeletedSuccessfully');\n });\n }\n });\n }\n}\n","<div class=\"card mb-3\">\n <div class=\"card-body\">\n <div class=\"row align-items-end g-2 mb-3\">\n <div class=\"col-md-3\">\n <label class=\"form-label\">{{ 'Site::Menu:Pages' | abpLocalization }}</label>\n <site-page-tree-select\n [pages]=\"pages()\"\n [value]=\"filters.pageId\"\n (valueChange)=\"onPageChange($event)\"\n ></site-page-tree-select>\n </div>\n <div class=\"col-md-2\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Content.ContentType' | abpLocalization }}</label>\n <select\n class=\"form-select\"\n [(ngModel)]=\"filters.contentTypeId\"\n (change)=\"applyFilters()\"\n [disabled]=\"!filters.pageId\"\n >\n <option [ngValue]=\"null\">--</option>\n @for (contentType of contentTypes(); track contentType.id) {\n <option [ngValue]=\"contentType.id\">{{ contentType.displayName }}</option>\n }\n </select>\n </div>\n <div class=\"col-md-2\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Content.CultureName' | abpLocalization }}</label>\n <select class=\"form-select\" [(ngModel)]=\"filters.cultureName\" (change)=\"applyFilters()\">\n @for (language of languages(); track language) {\n <option [ngValue]=\"language\">{{ language }}</option>\n }\n </select>\n </div>\n <div class=\"col-md-2\">\n <label class=\"form-label\">{{ 'Site::DisplayName:Content.Status' | abpLocalization }}</label>\n <select class=\"form-select\" [(ngModel)]=\"filters.status\" (change)=\"applyFilters()\">\n <option [ngValue]=\"null\">--</option>\n @for (status of statuses; track status) {\n <option [ngValue]=\"status\">{{ statusKeyOf(status) | abpLocalization }}</option>\n }\n </select>\n </div>\n <div class=\"col-md-3\">\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>\n\n @if (searchFields().length > 0) {\n <hr />\n <h6>{{ 'Site::FilterByFieldValue' | abpLocalization }}</h6>\n <form [formGroup]=\"searchForm\">\n <div class=\"row g-2\">\n @for (field of searchFields(); track field.fieldId) {\n <!-- No label here: each search widget renders the field's own label. -->\n <div class=\"col-md-3\">\n <ff-flex-field-search\n [fields]=\"definitionValueOf(field)\"\n [selected]=\"selectedValueOf(field)\"\n [entity]=\"searchForm\"\n parentFieldName=\"flexFieldSearch\"\n ></ff-flex-field-search>\n </div>\n }\n </div>\n </form>\n }\n\n <div class=\"mt-3\">\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)=\"clearFiltersAndSearch()\">\n {{ 'AbpUi::Clear' | abpLocalization }}\n </button>\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::Contents' | abpLocalization }}</h5>\n <a\n *abpPermission=\"policies.ContentsCreate\"\n class=\"btn btn-primary\"\n [class.disabled]=\"!canCreate\"\n [routerLink]=\"canCreate ? ['/site/contents/create'] : null\"\n [queryParams]=\"{ pageId: filters.pageId, cultureName: filters.cultureName }\"\n >\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::NewContent' | abpLocalization }}\n </a>\n </div>\n\n @if (!filters.pageId) {\n <p class=\"text-muted\">{{ 'Site::PageFilterRequiredForFieldColumns' | abpLocalization }}</p>\n }\n\n <!-- `[list]` drives paging through `ListService` (server-side: `skipCount`/`maxResultCount`) and\n renders the localized total, loading spinner and empty message; `default` is ABP's stock\n table look, including the horizontal scrollbar a wide field-column union needs. Every column\n is unsortable, keeping the server's default `PublishTime desc, Id desc` - a deterministic\n order, so pages never overlap or skip rows. Field columns could not sort anyway: `sorting`\n is a dynamic-LINQ order over entity properties, and field values live in JSON. -->\n <ngx-datatable default [rows]=\"data().items\" [count]=\"data().totalCount\" [list]=\"list\">\n <ngx-datatable-column\n [name]=\"'Site::DisplayName:Content.Slug' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n {{ row.slug || ('Site::SlugIsPageOwnAddress' | abpLocalization) }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n [name]=\"'Site::DisplayName:Content.ContentType' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n {{ contentTypeNameOf(row.contentTypeId) }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n [name]=\"'Site::DisplayName:Content.Status' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n {{ statusKeyOf(row.status) | abpLocalization }}\n </ng-template>\n </ngx-datatable-column>\n @for (column of columns(); track column.fieldId) {\n <ngx-datatable-column [name]=\"column.displayName\" [sortable]=\"false\">\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <!-- Columns are the union across the page's content types, so a row whose type does not\n use this field has nothing to show here. -->\n @if (rowValueOf(row, column); as fieldValue) {\n <ff-flex-field-view\n [showInList]=\"true\"\n [type]=\"column.fieldTypeName\"\n [fields]=\"fieldValue\"\n [value]=\"fieldValue.value\"\n ></ff-flex-field-view>\n } @else {\n ---\n }\n </ng-template>\n </ngx-datatable-column>\n }\n <ngx-datatable-column\n [name]=\"'Site::DisplayName:Content.PublishTime' | abpLocalization\"\n [sortable]=\"false\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n {{ row.publishTime | shortDateTime }}\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n [name]=\"'AbpUi::Actions' | abpLocalization\"\n [sortable]=\"false\"\n [width]=\"130\"\n [maxWidth]=\"130\"\n >\n <ng-template let-row=\"row\" ngx-datatable-cell-template>\n <a\n *abpPermission=\"policies.ContentsUpdate\"\n class=\"btn btn-sm btn-light me-1\"\n [routerLink]=\"['/site/contents', row.id, 'edit']\"\n [title]=\"'AbpUi::Edit' | abpLocalization\"\n >\n <i class=\"fa fa-pencil\"></i>\n </a>\n <button\n *abpPermission=\"policies.ContentsDelete\"\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"],"names":["i1","i2","i5","i6"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA;;;;;;;AAOG;MAqHU,uBAAuB,CAAA;AApHpC,IAAA,WAAA,GAAA;AAqHmB,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;;AA2B7B,QAAA,IAAA,CAAA,WAAW,GAAG,IAAI,YAAY,EAAiB;QAElE,IAAA,CAAA,KAAK,GAAyB,EAAE;QAChC,IAAA,CAAA,YAAY,GAAa,EAAE;QAC3B,IAAA,CAAA,MAAM,GAAG,KAAK;AAEN,QAAA,IAAA,CAAA,UAAU,GAAG,IAAI,GAAG,EAA8B;AAmD3D,IAAA;;IAjFC,IAAa,KAAK,CAAC,KAAgB,EAAA;AACjC,QAAA,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;;;QAG/C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CACpB,IAAI,KACD;AACC,YAAA,GAAG,IAAI;YACP,EAAE,EAAE,IAAI,CAAC,EAAG;YACZ,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI;AACzE,SAAA,CAAa,CACjB;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE;AAC5C,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,EAAE;AAC3B,QAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;;AAEtB,QAAA,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC;IACtG;AAcA;;;;AAIG;AACH,IAAA,IAAI,YAAY,GAAA;QACd,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS;IACjE;IAEA,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM;IAC5B;;AAGA,IAAA,MAAM,CAAC,IAAc,EAAA;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACpB;AAEA,IAAA,KAAK,CAAC,KAAY,EAAA;;QAEhB,KAAK,CAAC,eAAe,EAAE;AACvB,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACjB;AAGA,IAAA,mBAAmB,CAAC,KAAY,EAAA;AAC9B,QAAA,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;AAChF,YAAA,IAAI,CAAC,MAAM,GAAG,KAAK;QACrB;IACF;IAGA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;IACrB;AAEQ,IAAA,IAAI,CAAC,MAAqB,EAAA;QAChC,IAAI,MAAM,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE;AACnC,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/B;IACF;AAEQ,IAAA,KAAK,CAAC,KAA2B,EAAA;AACvC,QAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC;AACnC,YAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC3B;IACF;8GApFW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAvB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,KAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,gBAAA,EAAA,6BAAA,EAAA,gBAAA,EAAA,SAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAhHxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CT,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,o3CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA/CS,UAAU,8BAAE,UAAU,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,WAAA,EAAA,WAAA,EAAA,eAAA,EAAA,aAAA,EAAA,OAAA,EAAA,cAAA,EAAA,cAAA,EAAA,wBAAA,EAAA,gBAAA,EAAA,YAAA,CAAA,EAAA,OAAA,EAAA,CAAA,mBAAA,EAAA,oBAAA,EAAA,oBAAA,EAAA,UAAA,EAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,yBAAA,EAAA,QAAA,EAAA,gDAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,6BAAA,EAAA,QAAA,EAAA,iEAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,gBAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,KAAA,EAAA,CAAA,CAAA;;2FAiHrB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBApHnC,SAAS;+BACE,uBAAuB,EAAA,eAAA,EAChB,uBAAuB,CAAC,KAAK,EAAA,OAAA,EACrC,CAAC,UAAU,EAAE,UAAU,CAAC,EAAA,QAAA,EACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,o3CAAA,CAAA,EAAA;;sBAsEA;;sBAqBA;;sBAGA;;sBAiCA,YAAY;uBAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC;;sBAOzC,YAAY;uBAAC,gBAAgB;;;MC3JnB,iBAAiB,CAAA;AAkE5B,IAAA,WAAA,GAAA;AAjEiB,QAAA,IAAA,CAAA,cAAc,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC5C,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC1C,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,uBAAuB,CAAC;AAC3C,QAAA,IAAA,CAAA,kBAAkB,GAAG,MAAM,CAAC,uBAAuB,CAAC;AACpD,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACtC,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,wBAAwB,CAAC;AAChD,QAAA,IAAA,CAAA,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;AACxB,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC1C,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC;AAExC,QAAA,IAAA,CAAA,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;QAC1B,IAAA,CAAA,QAAQ,GAAG,gBAAgB;QAC3B,IAAA,CAAA,aAAa,GAAG,aAAa;AAC7B,QAAA,IAAA,CAAA,QAAQ,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,QAAQ,CAAC;;;;;QAMjF,IAAA,CAAA,IAAI,GAAG,MAAM,CAA6B,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE;iFAAC;QAChF,IAAA,CAAA,OAAO,GAAG,EAAyB;QAE1B,IAAA,CAAA,KAAK,GAAG,MAAM,CAAY,EAAE;kFAAC;QAC7B,IAAA,CAAA,SAAS,GAAG,MAAM,CAAW,EAAE;sFAAC;QAChC,IAAA,CAAA,YAAY,GAAG,MAAM,CAAmB,EAAE;yFAAC;AAEpD;;;;AAIG;AACc,QAAA,IAAA,CAAA,gBAAgB,GAAG,MAAM,CAAC,IAAI,GAAG,EAA0B;6FAAC;AAErE,QAAA,IAAA,CAAA,UAAU,GAAG,IAAI,GAAG,EAAoB;;AAGxC,QAAA,IAAA,CAAA,wBAAwB,GAAG,IAAI,GAAG,EAA2B;;QAG5D,IAAA,CAAA,OAAO,GAAG,MAAM,CAAgB,EAAE;oFAAC;;QAGnC,IAAA,CAAA,YAAY,GAAG,MAAM,CAAkB,EAAE;yFAAC;;;;;;;;;;AAYlC,QAAA,IAAA,CAAA,gBAAgB,GAAG,MAAM,CAAC,IAAI,GAAG,EAA0B;6FAAC;;AAG5D,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,IAAI,GAAG,EAA0B;sFAAC;QAE7D,IAAA,CAAA,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QACnE,IAAA,CAAA,iBAAiB,GAA8B,EAAE;;QAGjD,IAAA,CAAA,YAAY,GAA4B,EAAE;QAGhD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;QACvC,IAAI,MAAM,EAAE;AACV,YAAA,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO;AAC7B,YAAA,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB;AACjD,YAAA,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY;YACvC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI;YAC5B,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO;YAClC,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS;YACtC,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc;QAClD;AAEA,QAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,IAAG;YAC9C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;AACpC,QAAA,CAAC,CAAC;;;AAIF,QAAA,IAAI,CAAC,iBAAiB,EAAE,CAAC,SAAS,EAAE;AAEpC,QAAA,QAAQ,CAAC;AACP,YAAA,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;AACtC,YAAA,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE;AAC1C,YAAA,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,mBAAmB,EAAE;AACvD,SAAA,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,KAAI;;;YAGhD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC;AACjD,YAAA,IAAI,CAAC,UAAU,GAAG,MAAM;AACxB,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC;YACvC,IAAI,CAAC,mBAAmB,EAAE;AAC5B,QAAA,CAAC,CAAC;;;;QAKF,MAAM,OAAO,GAAG,CAAC,KAA0B,KACzC,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,IAAI,CACjC,SAAS,CAAC,MAAM,IAAG;YACjB,IAAI,CAAC,OAAO,CAAC,WAAW;AACtB,gBAAA,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,gBAAgB,GAAG,CAAC,CAAC,IAAI,IAAI;;;AAIhE,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAClB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;AACzC,gBAAA,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,KAAK,IAAI,EAAE;AACjE,gBAAA,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;AACpB,gBAAA,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO;AAC1B,gBAAA,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS;AAC9B,gBAAA,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc;AACzC,aAAA,CAAC;AAEF,YAAA,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;AAC/B,gBAAA,GAAG,KAAK;gBACR,GAAG,IAAI,CAAC,OAAO;gBACf,mBAAmB,EAAE,IAAI,CAAC,iBAAiB;AAC5C,aAAA,CAAC;QACJ,CAAC,CAAC,CACH;AACH,QAAA,MAAM,OAAO,GAAG,CAAC,MAAkC,KAAI;AACrD,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YACrB,IAAI,CAAC,gBAAgB,EAAE;AACzB,QAAA,CAAC;AAED,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC;IACnD;;AAIA,IAAA,YAAY,CAAC,MAAqB,EAAA;AAChC,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM;AAC5B,QAAA,IAAI,CAAC,OAAO,CAAC,aAAa,GAAG,IAAI;QACjC,IAAI,CAAC,WAAW,EAAE;QAClB,IAAI,CAAC,gBAAgB,EAAE;IACzB;IAEA,YAAY,GAAA;AACV,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,eAAe,EAAE;AAC/C,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;AAClB,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;IACjB;AAEA;;;;;;;;AAQG;IACH,WAAW,GAAA;QACT,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,iBAAiB,CAAc;QACjE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACnE,QAAA,IAAI,CAAC,iBAAiB,GAAG,EAAE;AAC3B,QAAA,IAAI,CAAC,YAAY,GAAG,EAAE;IACxB;IAEA,qBAAqB,GAAA;AACnB,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW;AAC5C,QAAA,IAAI,CAAC,OAAO,GAAG,EAAE,WAAW,EAAyB;QACrD,IAAI,CAAC,WAAW,EAAE;AAClB,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC,mBAAmB,EAAE;QAC1B,IAAI,CAAC,YAAY,EAAE;IACrB;IAEQ,gBAAgB,GAAA;AACtB,QAAA,IAAI,CAAC,iBAAiB,EAAE,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAC/D;;IAGQ,iBAAiB,GAAA;AACvB,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;AACxB,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,mBAAmB,EAAE;AAC1B,YAAA,OAAO,EAAE,CAAO,SAAS,CAAC;QAC5B;AAEA,QAAA,OAAO,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CACpE,GAAG,CAAC,MAAM,IAAG;YACX,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;YACzC,IAAI,CAAC,mBAAmB,EAAE;QAC5B,CAAC,CAAC,CACH;IACH;;AAIA;;;;AAIG;IACK,mBAAmB,GAAA;AACzB,QAAA,IAAI,CAAC,wBAAwB,GAAG,IAAI,GAAG,CACrC,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,WAAW,IAAI;AACrC,YAAA,WAAW,CAAC,EAAG;AACf,YAAA,CAAC,WAAW,CAAC,MAAM,IAAI,EAAE;AACtB,iBAAA,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC;iBACvD,MAAM,CAAC,CAAC,KAAK,KAA6B,CAAC,CAAC,KAAK;AACjD,iBAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;AACrC,SAAA,CAAC,CACH;QAED,IAAI,CAAC,cAAc,EAAE;QACrB,IAAI,CAAC,mBAAmB,EAAE;QAC1B,IAAI,CAAC,gBAAgB,EAAE;IACzB;IAEQ,eAAe,CACrB,OAA2B,EAC3B,KAAsH,EAAA;AAEtH,QAAA,MAAM,UAAU,GAAG,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,SAAS;QAErE,IAAI,CAAC,UAAU,EAAE;AACf,YAAA,OAAO,SAAS;QAClB;AAEA,QAAA,MAAM,SAAS,GAAkB;YAC/B,EAAE,EAAE,UAAU,CAAC,EAAG;YAClB,IAAI,EAAE,UAAU,CAAC,IAAK;AACtB,YAAA,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,UAAU,CAAC,WAAY;AACzD,YAAA,WAAW,EAAE,UAAU,CAAC,WAAW,IAAI,SAAS;YAChD,aAAa,EAAE,UAAU,CAAC,aAAc;AACxC,YAAA,aAAa,GAAG,UAAU,CAAC,aAAa,IAAI,EAAE,CAA4B;SAC3E;QAED,OAAO;YACL,OAAO,EAAE,UAAU,CAAC,EAAG;YACvB,IAAI,EAAE,UAAU,CAAC,IAAK;YACtB,WAAW,EAAE,SAAS,CAAC,WAAW;YAClC,aAAa,EAAE,UAAU,CAAC,aAAc;AACxC,YAAA,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ;AAC1B,YAAA,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU;AAC9B,YAAA,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU;AAC9B,YAAA,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;YACvB,SAAS;SACV;IACH;AAEA;;;;;;AAMG;IACK,cAAc,GAAA;AACpB,QAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB;QAE9C,KAAK,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,wBAAwB,EAAE;AACnE,YAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;AAC1B,gBAAA,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE;oBACrB;gBACF;gBAEA,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;gBAC3C,IAAI,QAAQ,EAAE;AACZ,oBAAA,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC;gBAC5C;qBAAO;AACL,oBAAA,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE;wBACzB,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC9B,aAAa,EAAE,KAAK,CAAC,aAAa;AAClC,wBAAA,cAAc,EAAE,IAAI,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC;AACzC,qBAAA,CAAC;gBACJ;YACF;QACF;AAEA,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC;AAEA;;;;;;;;AAQG;IACK,mBAAmB,GAAA;AACzB,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB;QAE/C,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,EAAE;AAC7D,YAAA,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE;AAC5B,gBAAA,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE;oBAClD;gBACF;gBACA,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC;YAClC;QACF;QAEA,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;AACzC,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC;AACnC,QAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CACvB,IAAI,GAAG,CACL,YAAY,CAAC,GAAG,CAAC,KAAK,IAAI;AACxB,YAAA,KAAK,CAAC,IAAI;AACV,YAAA,EAAE,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;SACzF,CAAC,CACH,CACF;IACH;IAEQ,gBAAgB,GAAA;QACtB,IAAI,CAAC,SAAS,CAAC,GAAG,CAChB,IAAI,GAAG,CACL,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC,OAAO,IAAI;AACvC,YAAA,OAAO,CAAC,EAAG;YACX,IAAI,GAAG,CACL,CAAC,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,KAAK,IAAI;AAClF,gBAAA,KAAK,CAAC,IAAI;AACV,gBAAA;oBACE,KAAK,EAAE,KAAK,CAAC,SAAS;oBACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,KAAK,EAAE,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC;AACvB,iBAAA;AACpB,aAAA,CAAC,CACH;SACF,CAAC,CACH,CACF;IACH;;IAGA,UAAU,CAAC,OAAmB,EAAE,MAAmB,EAAA;AACjD,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAG,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC5D;;AAGA,IAAA,iBAAiB,CAAC,KAAoB,EAAA;QACpC,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;IAChD;;AAGA,IAAA,eAAe,CAAC,KAAoB,EAAA;QAClC,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;IAC5C;;AAIA;;;AAGG;IACK,eAAe,GAAA;AACrB,QAAA,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,KAAK,IAAI,EAAE,CAA4B;QAC5F,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACxF;IAEQ,YAAY,CAAC,KAAoB,EAAE,KAAc,EAAA;AACvD,QAAA,QAAQ,KAAK,CAAC,aAAa;AACzB,YAAA,KAAK,MAAM;AACT,gBAAA,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;AACvB,sBAAE;AACF,sBAAE;AACE,wBAAA,IAAI,CAAC,SAAS,CACZ,KAAK,EACL,sBAAsB,CAAC,QAAQ,EAC/B,MAAM,CAAC,KAAK,CAAC,EACb,kBAAkB,CAAC,MAAM,CAC1B;qBACF;YAEP,KAAK,QAAQ,EAAE;;;AAGb,gBAAA,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;AAC/D,gBAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC,EAAE;AACzD,oBAAA,OAAO,EAAE;gBACX;gBACA,OAAO;AACL,oBAAA,IAAI,CAAC,SAAS,CACZ,KAAK,EACL,sBAAsB,CAAC,kBAAkB,EACzC,KAAK,CAAC,CAAC,CAAC,EACR,kBAAkB,CAAC,MAAM,CAC1B;AACD,oBAAA,IAAI,CAAC,SAAS,CACZ,KAAK,EACL,sBAAsB,CAAC,eAAe,EACtC,KAAK,CAAC,CAAC,CAAC,EACR,kBAAkB,CAAC,MAAM,CAC1B;iBACF;YACH;AAEA,YAAA,KAAK,SAAS;;AAEZ,gBAAA,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK;AACnC,sBAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,sBAAsB,CAAC,MAAM,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC;sBACxF,EAAE;AAER,YAAA,KAAK,QAAQ;YACb,KAAK,MAAM,EAAE;AACX,gBAAA,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC;AAChF,gBAAA,OAAO,MAAM,CAAC,MAAM,KAAK;AACvB,sBAAE;AACF,sBAAE;AACE,wBAAA,IAAI,CAAC,SAAS,CACZ,KAAK,EACL,sBAAsB,CAAC,EAAE,EACzB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAChB,kBAAkB,CAAC,MAAM,CAC1B;qBACF;YACP;AAEA,YAAA;AACE,gBAAA,OAAO,EAAE;;IAEf;;AAGQ,IAAA,SAAS,CACf,KAAoB,EACpB,QAAgC,EAChC,KAAa,EACb,SAA6B,EAAA;AAE7B,QAAA,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE;IACtF;AAEQ,IAAA,OAAO,CAAC,KAAc,EAAA;QAC5B,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;IAC9D;;AAIA,IAAA,WAAW,CAAC,MAAsB,EAAA;QAChC,OAAO,CAAA,yBAAA,EAA4B,aAAa,CAAC,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,CAAA,CAAE;IACnF;AAEA,IAAA,iBAAiB,CAAC,aAAsB,EAAA;QACtC,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,WAAW,GAAG,SAAS,KAAK,KAAK;IACvG;AAEA,IAAA,UAAU,CAAC,MAAe,EAAA;QACxB,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,WAAW,IAAI,KAAK;IAC5E;;;;;;AAQA,IAAA,IAAI,SAAS,GAAA;AACX,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,GAAG,CAAC;IAChE;AAEA,IAAA,MAAM,CAAC,OAAmB,EAAA;AACxB,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,iCAAiC,EAAE,mBAAmB,EAAE;AAC5D,YAAA,yBAAyB,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAC7E;AACA,aAAA,SAAS,CAAC,CAAC,MAA2B,KAAI;YACzC,IAAI,MAAM,KAAK,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE;AAC1C,gBAAA,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,EAAG,CAAC,CAAC,SAAS,CAAC,MAAK;AACrD,oBAAA,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;AACf,oBAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC;AACpD,gBAAA,CAAC,CAAC;YACJ;AACF,QAAA,CAAC,CAAC;IACN;8GA9dW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,SAAA,EAFjB,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECrDhF,8zPA8LA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDlJI,UAAU,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,wSAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,0BAAA,EAAA,QAAA,EAAA,0JAAA,EAAA,MAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,sGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,wBAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,QAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,iCAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACV,iBAAiB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,sBAAA,EAAA,MAAA,EAAA,aAAA,EAAA,aAAA,EAAA,SAAA,EAAA,UAAA,EAAA,YAAA,EAAA,mBAAA,EAAA,YAAA,EAAA,WAAA,EAAA,YAAA,EAAA,cAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,OAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,uBAAA,EAAA,eAAA,EAAA,aAAA,EAAA,aAAA,EAAA,UAAA,EAAA,OAAA,EAAA,YAAA,EAAA,UAAA,EAAA,UAAA,EAAA,aAAA,EAAA,cAAA,EAAA,uBAAA,EAAA,aAAA,EAAA,qBAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,gBAAA,EAAA,YAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,yBAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,MAAA,EAAA,MAAA,EAAA,SAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,YAAA,EAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,wBAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,kBAAA,EAAA,YAAA,EAAA,aAAA,EAAA,UAAA,EAAA,YAAA,EAAA,YAAA,EAAA,MAAA,EAAA,UAAA,EAAA,WAAA,EAAA,eAAA,EAAA,UAAA,EAAA,OAAA,EAAA,UAAA,EAAA,cAAA,EAAA,oBAAA,EAAA,aAAA,EAAA,WAAA,EAAA,cAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,oBAAA,EAAA,mBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,+BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,yBAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,QAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,QAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACjB,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAGnB,wBAAwB,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACxB,sBAAsB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,QAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACtB,uBAAuB,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,IAAA,EAAA,eAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAId,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAhB7B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,EAAA,eAAA,EACR,uBAAuB,CAAC,MAAM,EAAA,OAAA,EAEtC;wBACP,UAAU;wBACV,iBAAiB;wBACjB,mBAAmB;wBACnB,mBAAmB;wBACnB,UAAU;wBACV,wBAAwB;wBACxB,sBAAsB;wBACtB,uBAAuB;AACxB,qBAAA,EAAA,SAAA,EACU,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAA,QAAA,EAAA,8zPAAA,EAAA;;;;;"}
|