@dignite/ng.site 1.0.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +14 -0
  2. package/fesm2022/dignite-ng.site-config.mjs +10 -1
  3. package/fesm2022/dignite-ng.site-config.mjs.map +1 -1
  4. package/fesm2022/{dignite-ng.site-content-editor.component-iFWDeYJ9.mjs → dignite-ng.site-content-editor.component-DA6FaJSU.mjs} +2 -2
  5. package/fesm2022/{dignite-ng.site-content-editor.component-iFWDeYJ9.mjs.map → dignite-ng.site-content-editor.component-DA6FaJSU.mjs.map} +1 -1
  6. package/fesm2022/{dignite-ng.site-content-types.component-D2jMSSq6.mjs → dignite-ng.site-content-types.component-Dnqe8A4t.mjs} +27 -7
  7. package/fesm2022/dignite-ng.site-content-types.component-Dnqe8A4t.mjs.map +1 -0
  8. package/fesm2022/{dignite-ng.site-contents.component-DKuel8w-.mjs → dignite-ng.site-contents.component-Ch5GYIHE.mjs} +2 -2
  9. package/fesm2022/{dignite-ng.site-contents.component-DKuel8w-.mjs.map → dignite-ng.site-contents.component-Ch5GYIHE.mjs.map} +1 -1
  10. package/fesm2022/{dignite-ng.site-dignite-ng.site-CsKxqjY9.mjs → dignite-ng.site-dignite-ng.site-BMcNABSG.mjs} +283 -55
  11. package/fesm2022/dignite-ng.site-dignite-ng.site-BMcNABSG.mjs.map +1 -0
  12. package/fesm2022/{dignite-ng.site-fields.component-By_YyfIx.mjs → dignite-ng.site-fields.component-BaK27N9k.mjs} +5 -3
  13. package/fesm2022/dignite-ng.site-fields.component-BaK27N9k.mjs.map +1 -0
  14. package/fesm2022/{dignite-ng.site-pages.component-S9BEgC4W.mjs → dignite-ng.site-pages.component-BwGyK7jw.mjs} +28 -5
  15. package/fesm2022/dignite-ng.site-pages.component-BwGyK7jw.mjs.map +1 -0
  16. package/fesm2022/dignite-ng.site-setting-management.mjs +123 -0
  17. package/fesm2022/dignite-ng.site-setting-management.mjs.map +1 -0
  18. package/fesm2022/dignite-ng.site-theme-workbench.component-CA47DnTj.mjs +1206 -0
  19. package/fesm2022/dignite-ng.site-theme-workbench.component-CA47DnTj.mjs.map +1 -0
  20. package/fesm2022/dignite-ng.site.mjs +1 -1
  21. package/package.json +17 -1
  22. package/types/dignite-ng.site-config.d.ts +2 -1
  23. package/types/dignite-ng.site-setting-management.d.ts +41 -0
  24. package/types/dignite-ng.site.d.ts +386 -111
  25. package/fesm2022/dignite-ng.site-content-types.component-D2jMSSq6.mjs.map +0 -1
  26. package/fesm2022/dignite-ng.site-dignite-ng.site-CsKxqjY9.mjs.map +0 -1
  27. package/fesm2022/dignite-ng.site-fields.component-By_YyfIx.mjs.map +0 -1
  28. package/fesm2022/dignite-ng.site-pages.component-S9BEgC4W.mjs.map +0 -1
@@ -8,7 +8,7 @@ import * as i1 from '@angular/forms';
8
8
  import { FormsModule, FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
9
9
  import { ActivatedRoute } from '@angular/router';
10
10
  import { forkJoin } from 'rxjs';
11
- import { c as ContentTypeAdminService, P as PageAdminService, S as SiteReferenceDataService, e as eSitePolicyNames } from './dignite-ng.site-dignite-ng.site-CsKxqjY9.mjs';
11
+ import { c as ContentTypeAdminService, P as PageAdminService, S as SiteReferenceDataService, e as eSitePolicyNames } from './dignite-ng.site-dignite-ng.site-BMcNABSG.mjs';
12
12
  import * as i2 from '@angular/cdk/drag-drop';
13
13
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
14
14
  import { FieldTypeResolver, FlexFieldsStyleLoader, NZ_SELECT_STYLE } from '@dignite/ng.flex-fields';
@@ -26,7 +26,9 @@ import * as i3$1 from '@ngx-validate/core';
26
26
  * parent sends all of it. Never send a delta.
27
27
  *
28
28
  * `ContentTypeFieldDto` carries only `fieldId`; names, types and descriptions come from
29
- * {@link fieldsById}, joined here.
29
+ * {@link fieldsById}, joined here. A usage with nothing to join to is a field that was deleted from the
30
+ * library - the content type keeps the usage and it is skipped from then on - and is shown as that
31
+ * ({@link isDeleted}) rather than as a blank row.
30
32
  */
31
33
  class FieldArrangementComponent {
32
34
  constructor() {
@@ -38,6 +40,11 @@ class FieldArrangementComponent {
38
40
  this.arrangement = [];
39
41
  /** The whole field library, keyed by id. */
40
42
  this.fieldsById = new Map();
43
+ /**
44
+ * Whether {@link fieldsById} has finished loading. Until it has, an empty map says nothing about any
45
+ * field, so no usage is called deleted yet.
46
+ */
47
+ this.fieldsLoaded = false;
41
48
  /** Whether a field type has a query index at all, keyed by field type name. */
42
49
  this.indexableByFieldType = new Map();
43
50
  /** Field ids chosen in the "add field" picker, before they're committed via {@link addFields}. */
@@ -57,6 +64,14 @@ class FieldArrangementComponent {
57
64
  labelOf(entry) {
58
65
  return entry.displayName || this.fieldOf(entry)?.displayName || this.fieldOf(entry)?.name || '';
59
66
  }
67
+ /**
68
+ * A usage whose field is no longer in the library. Deleting a field does not touch the content types
69
+ * that arrange it, so the usage stays behind with no definition to join to. Only once the library has
70
+ * loaded: before that every usage would look deleted.
71
+ */
72
+ isDeleted(entry) {
73
+ return this.fieldsLoaded && !this.fieldOf(entry);
74
+ }
60
75
  /** Localization key for a field type's display name, for use with `| abpLocalization`. */
61
76
  displayNameKeyOf(fieldTypeName) {
62
77
  return (this.fieldTypes.find(type => type.name === fieldTypeName)?.displayNameKey ??
@@ -137,15 +152,17 @@ class FieldArrangementComponent {
137
152
  this.arrangement.forEach((entry, index) => (entry.order = index));
138
153
  }
139
154
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: FieldArrangementComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
140
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.2", type: FieldArrangementComponent, isStandalone: true, selector: "site-field-arrangement", inputs: { arrangement: "arrangement", fieldsById: "fieldsById", indexableByFieldType: "indexableByFieldType" }, ngImport: i0, template: "<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 <small class=\"text-muted\">{{ fieldOf(entry)?.name }}</small>\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 />\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]=\"!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 />\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 />\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", styles: [":host ::ng-deep .field-picker-select{width:100%}:host ::ng-deep .field-picker-select.ant-select{color:inherit!important}:host ::ng-deep .field-picker-select .ant-select-selector{background:transparent!important;border:none!important;padding:.475rem 1.25rem!important;box-shadow:none!important;height:auto!important}:host ::ng-deep .field-picker-select .ant-select-arrow{display:none!important}:host ::ng-deep .field-picker-select .ant-select-selection-placeholder{color:inherit!important}:host ::ng-deep .field-picker-select.form-select{padding:0!important}:host ::ng-deep .field-picker-select .ant-select-selection-item{background:var(--bs-secondary-bg, #f5f5f5)!important;border-color:var(--bs-border-color, #f0f0f0)!important}:host ::ng-deep .field-picker-select .ant-select-selection-item-remove{color:var(--bs-secondary-color, rgba(0, 0, 0, .45))!important}::ng-deep .field-picker-dropdown .ant-select-dropdown{background:var(--lpx-content-bg, var(--bs-secondary-bg, #fff))!important}::ng-deep .field-picker-dropdown .ant-select-item-option-active:not(.ant-select-item-option-disabled){background-color:var(--bs-primary)!important;color:var(--bs-white)!important}::ng-deep .field-picker-dropdown .ant-select-item{color:var(--bs-body-color)!important;background-color:transparent!important}\n"], dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: NzSelectModule }, { kind: "component", type: i3.NzSelectComponent, selector: "nz-select", inputs: ["nzId", "nzSize", "nzStatus", "nzVariant", "nzOptionHeightPx", "nzOptionOverflowSize", "nzDropdownClassName", "nzDropdownMatchSelectWidth", "nzDropdownStyle", "nzNotFoundContent", "nzPlaceHolder", "nzPlacement", "nzMaxTagCount", "nzDropdownRender", "nzCustomTemplate", "nzPrefix", "nzSuffixIcon", "nzClearIcon", "nzRemoveIcon", "nzMenuItemSelectedIcon", "nzTokenSeparators", "nzMaxTagPlaceholder", "nzMaxMultipleCount", "nzMode", "nzFilterOption", "compareWith", "nzAllowClear", "nzShowSearch", "nzLoading", "nzAutoFocus", "nzAutoClearSearchValue", "nzServerSearch", "nzDisabled", "nzOpen", "nzSelectOnTab", "nzBackdrop", "nzOptions", "nzShowArrow"], outputs: ["nzOnSearch", "nzScrollToBottom", "nzOpenChange", "nzBlur", "nzFocus", "nzOnClear"], exportAs: ["nzSelect"] }, { kind: "pipe", type: i4.LocalizationPipe, name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
155
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.2", type: FieldArrangementComponent, isStandalone: true, selector: "site-field-arrangement", inputs: { arrangement: "arrangement", fieldsById: "fieldsById", fieldsLoaded: "fieldsLoaded", indexableByFieldType: "indexableByFieldType" }, ngImport: i0, template: "<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", styles: [":host ::ng-deep .field-picker-select{width:100%}:host ::ng-deep .field-picker-select.ant-select{color:inherit!important}:host ::ng-deep .field-picker-select .ant-select-selector{background:transparent!important;border:none!important;padding:.475rem 1.25rem!important;box-shadow:none!important;height:auto!important}:host ::ng-deep .field-picker-select .ant-select-arrow{display:none!important}:host ::ng-deep .field-picker-select .ant-select-selection-placeholder{color:inherit!important}:host ::ng-deep .field-picker-select.form-select{padding:0!important}:host ::ng-deep .field-picker-select .ant-select-selection-item{background:var(--bs-secondary-bg, #f5f5f5)!important;border-color:var(--bs-border-color, #f0f0f0)!important}:host ::ng-deep .field-picker-select .ant-select-selection-item-remove{color:var(--bs-secondary-color, rgba(0, 0, 0, .45))!important}::ng-deep .field-picker-dropdown .ant-select-dropdown{background:var(--lpx-content-bg, var(--bs-secondary-bg, #fff))!important}::ng-deep .field-picker-dropdown .ant-select-item-option-active:not(.ant-select-item-option-disabled){background-color:var(--bs-primary)!important;color:var(--bs-white)!important}::ng-deep .field-picker-dropdown .ant-select-item{color:var(--bs-body-color)!important;background-color:transparent!important}\n"], dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: NzSelectModule }, { kind: "component", type: i3.NzSelectComponent, selector: "nz-select", inputs: ["nzId", "nzSize", "nzStatus", "nzVariant", "nzOptionHeightPx", "nzOptionOverflowSize", "nzDropdownClassName", "nzDropdownMatchSelectWidth", "nzDropdownStyle", "nzNotFoundContent", "nzPlaceHolder", "nzPlacement", "nzMaxTagCount", "nzDropdownRender", "nzCustomTemplate", "nzPrefix", "nzSuffixIcon", "nzClearIcon", "nzRemoveIcon", "nzMenuItemSelectedIcon", "nzTokenSeparators", "nzMaxTagPlaceholder", "nzMaxMultipleCount", "nzMode", "nzFilterOption", "compareWith", "nzAllowClear", "nzShowSearch", "nzLoading", "nzAutoFocus", "nzAutoClearSearchValue", "nzServerSearch", "nzDisabled", "nzOpen", "nzSelectOnTab", "nzBackdrop", "nzOptions", "nzShowArrow"], outputs: ["nzOnSearch", "nzScrollToBottom", "nzOpenChange", "nzBlur", "nzFocus", "nzOnClear"], exportAs: ["nzSelect"] }, { kind: "pipe", type: i4.LocalizationPipe, name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
141
156
  }
142
157
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: FieldArrangementComponent, decorators: [{
143
158
  type: Component,
144
- args: [{ selector: 'site-field-arrangement', changeDetection: ChangeDetectionStrategy.Eager, imports: [CoreModule, FormsModule, DragDropModule, NzSelectModule], template: "<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 <small class=\"text-muted\">{{ fieldOf(entry)?.name }}</small>\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 />\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]=\"!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 />\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 />\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", styles: [":host ::ng-deep .field-picker-select{width:100%}:host ::ng-deep .field-picker-select.ant-select{color:inherit!important}:host ::ng-deep .field-picker-select .ant-select-selector{background:transparent!important;border:none!important;padding:.475rem 1.25rem!important;box-shadow:none!important;height:auto!important}:host ::ng-deep .field-picker-select .ant-select-arrow{display:none!important}:host ::ng-deep .field-picker-select .ant-select-selection-placeholder{color:inherit!important}:host ::ng-deep .field-picker-select.form-select{padding:0!important}:host ::ng-deep .field-picker-select .ant-select-selection-item{background:var(--bs-secondary-bg, #f5f5f5)!important;border-color:var(--bs-border-color, #f0f0f0)!important}:host ::ng-deep .field-picker-select .ant-select-selection-item-remove{color:var(--bs-secondary-color, rgba(0, 0, 0, .45))!important}::ng-deep .field-picker-dropdown .ant-select-dropdown{background:var(--lpx-content-bg, var(--bs-secondary-bg, #fff))!important}::ng-deep .field-picker-dropdown .ant-select-item-option-active:not(.ant-select-item-option-disabled){background-color:var(--bs-primary)!important;color:var(--bs-white)!important}::ng-deep .field-picker-dropdown .ant-select-item{color:var(--bs-body-color)!important;background-color:transparent!important}\n"] }]
159
+ args: [{ selector: 'site-field-arrangement', changeDetection: ChangeDetectionStrategy.Eager, imports: [CoreModule, FormsModule, DragDropModule, NzSelectModule], template: "<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", styles: [":host ::ng-deep .field-picker-select{width:100%}:host ::ng-deep .field-picker-select.ant-select{color:inherit!important}:host ::ng-deep .field-picker-select .ant-select-selector{background:transparent!important;border:none!important;padding:.475rem 1.25rem!important;box-shadow:none!important;height:auto!important}:host ::ng-deep .field-picker-select .ant-select-arrow{display:none!important}:host ::ng-deep .field-picker-select .ant-select-selection-placeholder{color:inherit!important}:host ::ng-deep .field-picker-select.form-select{padding:0!important}:host ::ng-deep .field-picker-select .ant-select-selection-item{background:var(--bs-secondary-bg, #f5f5f5)!important;border-color:var(--bs-border-color, #f0f0f0)!important}:host ::ng-deep .field-picker-select .ant-select-selection-item-remove{color:var(--bs-secondary-color, rgba(0, 0, 0, .45))!important}::ng-deep .field-picker-dropdown .ant-select-dropdown{background:var(--lpx-content-bg, var(--bs-secondary-bg, #fff))!important}::ng-deep .field-picker-dropdown .ant-select-item-option-active:not(.ant-select-item-option-disabled){background-color:var(--bs-primary)!important;color:var(--bs-white)!important}::ng-deep .field-picker-dropdown .ant-select-item{color:var(--bs-body-color)!important;background-color:transparent!important}\n"] }]
145
160
  }], propDecorators: { arrangement: [{
146
161
  type: Input
147
162
  }], fieldsById: [{
148
163
  type: Input
164
+ }], fieldsLoaded: [{
165
+ type: Input
149
166
  }], indexableByFieldType: [{
150
167
  type: Input
151
168
  }] } });
@@ -177,6 +194,8 @@ class ContentTypesComponent {
177
194
  ...(ngDevMode ? [{ debugName: "contentTypes" }] : /* istanbul ignore next */ []));
178
195
  this.fieldsById = signal(new Map(), /* @ts-ignore */
179
196
  ...(ngDevMode ? [{ debugName: "fieldsById" }] : /* istanbul ignore next */ []));
197
+ this.fieldsLoaded = signal(false, /* @ts-ignore */
198
+ ...(ngDevMode ? [{ debugName: "fieldsLoaded" }] : /* istanbul ignore next */ []));
180
199
  this.indexableByFieldType = signal(new Map(), /* @ts-ignore */
181
200
  ...(ngDevMode ? [{ debugName: "indexableByFieldType" }] : /* istanbul ignore next */ []));
182
201
  this.isModalOpen = signal(false, /* @ts-ignore */
@@ -195,6 +214,7 @@ class ContentTypesComponent {
195
214
  indexable: this.referenceData.getIndexableByFieldType(),
196
215
  }).subscribe(({ fields, indexable }) => {
197
216
  this.fieldsById.set(fields);
217
+ this.fieldsLoaded.set(true);
198
218
  this.indexableByFieldType.set(indexable);
199
219
  });
200
220
  this.load(true);
@@ -304,7 +324,7 @@ class ContentTypesComponent {
304
324
  });
305
325
  }
306
326
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: ContentTypesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
307
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.2", type: ContentTypesComponent, isStandalone: true, selector: "site-content-types", viewQueries: [{ propertyName: "submitButton", first: true, predicate: ["submitButton"], descendants: true }], ngImport: i0, template: "<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 (\u603B\u4F53\u8BBE\u8BA1 \u00A76.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 [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", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3$1.ValidationGroupDirective, selector: "[formGroup],[formGroupName]", exportAs: ["validationGroup"] }, { kind: "directive", type: i3$1.ValidationDirective, selector: "[formControl],[formControlName]", exportAs: ["validationDirective"] }, { kind: "directive", type: i4.PermissionDirective, selector: "[abpPermission]", inputs: ["abpPermission", "abpPermissionRunChangeDetection"] }, { kind: "ngmodule", type: ThemeSharedModule }, { kind: "component", type: i2$1.ButtonComponent, selector: "abp-button", inputs: ["buttonId", "buttonClass", "buttonType", "formName", "iconClass", "loading", "disabled", "attributes"], outputs: ["click", "focus", "blur", "abpClick", "abpFocus", "abpBlur"] }, { kind: "component", type: i2$1.ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }, { kind: "directive", type: i2$1.ModalCloseDirective, selector: "[abpClose]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FieldArrangementComponent, selector: "site-field-arrangement", inputs: ["arrangement", "fieldsById", "indexableByFieldType"] }, { kind: "pipe", type: i4.LocalizationPipe, name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
327
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.2", type: ContentTypesComponent, isStandalone: true, selector: "site-content-types", viewQueries: [{ propertyName: "submitButton", first: true, predicate: ["submitButton"], descendants: true }], ngImport: i0, template: "<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 (\u603B\u4F53\u8BBE\u8BA1 \u00A76.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", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3$1.ValidationGroupDirective, selector: "[formGroup],[formGroupName]", exportAs: ["validationGroup"] }, { kind: "directive", type: i3$1.ValidationDirective, selector: "[formControl],[formControlName]", exportAs: ["validationDirective"] }, { kind: "directive", type: i4.PermissionDirective, selector: "[abpPermission]", inputs: ["abpPermission", "abpPermissionRunChangeDetection"] }, { kind: "ngmodule", type: ThemeSharedModule }, { kind: "component", type: i2$1.ButtonComponent, selector: "abp-button", inputs: ["buttonId", "buttonClass", "buttonType", "formName", "iconClass", "loading", "disabled", "attributes"], outputs: ["click", "focus", "blur", "abpClick", "abpFocus", "abpBlur"] }, { kind: "component", type: i2$1.ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }, { kind: "directive", type: i2$1.ModalCloseDirective, selector: "[abpClose]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FieldArrangementComponent, selector: "site-field-arrangement", inputs: ["arrangement", "fieldsById", "fieldsLoaded", "indexableByFieldType"] }, { kind: "pipe", type: i4.LocalizationPipe, name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
308
328
  }
309
329
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: ContentTypesComponent, decorators: [{
310
330
  type: Component,
@@ -314,11 +334,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImpor
314
334
  ReactiveFormsModule,
315
335
  PermissionDirective,
316
336
  FieldArrangementComponent,
317
- ], template: "<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 (\u603B\u4F53\u8BBE\u8BA1 \u00A76.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 [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" }]
337
+ ], template: "<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 (\u603B\u4F53\u8BBE\u8BA1 \u00A76.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" }]
318
338
  }], ctorParameters: () => [], propDecorators: { submitButton: [{
319
339
  type: ViewChild,
320
340
  args: ['submitButton']
321
341
  }] } });
322
342
 
323
343
  export { ContentTypesComponent };
324
- //# sourceMappingURL=dignite-ng.site-content-types.component-D2jMSSq6.mjs.map
344
+ //# sourceMappingURL=dignite-ng.site-content-types.component-Dnqe8A4t.mjs.map
@@ -0,0 +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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"}
@@ -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-CsKxqjY9.mjs';
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-BMcNABSG.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';
@@ -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-DKuel8w-.mjs.map
604
+ //# sourceMappingURL=dignite-ng.site-contents.component-Ch5GYIHE.mjs.map