@dignite/ng.site 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/fesm2022/{dignite-ng.site-content-editor.component-DA6FaJSU.mjs → dignite-ng.site-content-editor.component-DJEBh1ok.mjs} +2 -2
  2. package/fesm2022/{dignite-ng.site-content-editor.component-DA6FaJSU.mjs.map → dignite-ng.site-content-editor.component-DJEBh1ok.mjs.map} +1 -1
  3. package/fesm2022/{dignite-ng.site-content-types.component-Dnqe8A4t.mjs → dignite-ng.site-content-types.component-B3GpUeEa.mjs} +3 -3
  4. package/fesm2022/{dignite-ng.site-content-types.component-Dnqe8A4t.mjs.map → dignite-ng.site-content-types.component-B3GpUeEa.mjs.map} +1 -1
  5. package/fesm2022/{dignite-ng.site-contents.component-Ch5GYIHE.mjs → dignite-ng.site-contents.component-ht0WYCSN.mjs} +3 -3
  6. package/fesm2022/{dignite-ng.site-contents.component-Ch5GYIHE.mjs.map → dignite-ng.site-contents.component-ht0WYCSN.mjs.map} +1 -1
  7. package/fesm2022/{dignite-ng.site-dignite-ng.site-BMcNABSG.mjs → dignite-ng.site-dignite-ng.site-CJVw2UzZ.mjs} +145 -29
  8. package/fesm2022/dignite-ng.site-dignite-ng.site-CJVw2UzZ.mjs.map +1 -0
  9. package/fesm2022/{dignite-ng.site-fields.component-BaK27N9k.mjs → dignite-ng.site-fields.component-DpKMPRz3.mjs} +4 -4
  10. package/fesm2022/{dignite-ng.site-fields.component-BaK27N9k.mjs.map → dignite-ng.site-fields.component-DpKMPRz3.mjs.map} +1 -1
  11. package/fesm2022/{dignite-ng.site-pages.component-BwGyK7jw.mjs → dignite-ng.site-pages.component-Dc3kz6EW.mjs} +3 -3
  12. package/fesm2022/{dignite-ng.site-pages.component-BwGyK7jw.mjs.map → dignite-ng.site-pages.component-Dc3kz6EW.mjs.map} +1 -1
  13. package/fesm2022/dignite-ng.site-setting-management.mjs +77 -4
  14. package/fesm2022/dignite-ng.site-setting-management.mjs.map +1 -1
  15. package/fesm2022/dignite-ng.site-theme-workbench.component-HoSTVRBM.mjs +1283 -0
  16. package/fesm2022/dignite-ng.site-theme-workbench.component-HoSTVRBM.mjs.map +1 -0
  17. package/fesm2022/dignite-ng.site.mjs +1 -1
  18. package/package.json +1 -1
  19. package/types/dignite-ng.site-setting-management.d.ts +34 -4
  20. package/types/dignite-ng.site.d.ts +173 -89
  21. package/fesm2022/dignite-ng.site-dignite-ng.site-BMcNABSG.mjs.map +0 -1
  22. package/fesm2022/dignite-ng.site-theme-workbench.component-CA47DnTj.mjs +0 -1206
  23. package/fesm2022/dignite-ng.site-theme-workbench.component-CA47DnTj.mjs.map +0 -1
@@ -5,7 +5,7 @@ import * as i0 from '@angular/core';
5
5
  import { inject, signal, computed, ChangeDetectionStrategy, Component, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';
6
6
  import * as i1 from '@angular/forms';
7
7
  import { FormsModule } from '@angular/forms';
8
- import { Dignite, eSitePolicyNames } from '@dignite/ng.site';
8
+ import { Dignite, eSitePolicyNames, OG_IMAGE_CONTAINER_NAME, OG_IMAGE_WIDTH, OG_IMAGE_HEIGHT, FileModalComponent, FilePreviewComponent } from '@dignite/ng.site';
9
9
  import { SettingTabsService } from '@abp/ng.setting-management/config';
10
10
 
11
11
  /**
@@ -95,8 +95,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImpor
95
95
  args: [{ selector: 'site-languages-setting', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CoreModule, ThemeSharedModule, FormsModule, PermissionDirective], template: "<h4 class=\"mb-1\">{{ 'Site::Languages' | abpLocalization }}</h4>\n<p class=\"text-muted\">{{ 'Site::Languages:Hint' | abpLocalization }}</p>\n\n<ul class=\"list-group mb-3\">\n @for (language of languages(); track language; let i = $index) {\n <li class=\"list-group-item d-flex align-items-center gap-2\">\n <span class=\"fw-semibold\">{{ language }}</span>\n @if (i === 0) {\n <span class=\"badge bg-primary\">{{ 'Site::Languages:Default' | abpLocalization }}</span>\n }\n <span class=\"ms-auto d-flex gap-1\" *abpPermission=\"policies.LanguagesUpdate\">\n @if (i > 0) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"makeDefault(i)\">\n {{ 'Site::Languages:MakeDefault' | abpLocalization }}\n </button>\n }\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" [disabled]=\"i === 0\" (click)=\"move(i, -1)\">\n <i class=\"fa fa-arrow-up\"></i>\n </button>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-outline-secondary\"\n [disabled]=\"i === languages().length - 1\"\n (click)=\"move(i, 1)\"\n >\n <i class=\"fa fa-arrow-down\"></i>\n </button>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-outline-danger\"\n [disabled]=\"languages().length <= 1\"\n (click)=\"remove(i)\"\n >\n <i class=\"fa fa-trash\"></i>\n </button>\n </span>\n </li>\n }\n</ul>\n\n<ng-container *abpPermission=\"policies.LanguagesUpdate\">\n <div class=\"input-group mb-3\">\n <input\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"newLanguage()\"\n (ngModelChange)=\"newLanguage.set($event)\"\n (keydown.enter)=\"$event.preventDefault(); add()\"\n [placeholder]=\"'Site::Languages:Placeholder' | abpLocalization\"\n />\n <button type=\"button\" class=\"btn btn-outline-primary\" (click)=\"add()\">\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::Languages:Add' | abpLocalization }}\n </button>\n </div>\n\n @if (isDirty()) {\n <div class=\"alert alert-warning\">{{ 'Site::Languages:ChangeWarning' | abpLocalization }}</div>\n }\n\n <button type=\"button\" class=\"btn btn-primary\" [disabled]=\"!isDirty() || saving()\" (click)=\"save()\">\n <i class=\"fa fa-check me-1\"></i>{{ 'AbpUi::Save' | abpLocalization }}\n </button>\n</ng-container>\n" }]
96
96
  }], ctorParameters: () => [] });
97
97
 
98
+ /**
99
+ * The site's SEO settings, as a tab of Setting Management's page. For now the default share image: the one a page
100
+ * without a share image of its own is shared with. It is picked from the file library the way a page's own share
101
+ * image is (the `images` container); an address someone stored by other means shows and can be replaced or removed the
102
+ * same way. The server stores what it is given, and empty clears it. Without the update permission the tab only shows.
103
+ */
104
+ class SeoSettingComponent {
105
+ constructor() {
106
+ this.service = inject(Dignite.Site.Admin.Seo.SiteSeoSettingsAdminService);
107
+ this.toaster = inject(ToasterService);
108
+ this.policies = eSitePolicyNames;
109
+ this.imageContainerName = OG_IMAGE_CONTAINER_NAME;
110
+ this.imageWidth = OG_IMAGE_WIDTH;
111
+ this.imageHeight = OG_IMAGE_HEIGHT;
112
+ // Signals, not fields: the layout shell is OnPush, and a value set in a subscribe callback would not repaint.
113
+ this.image = signal('', /* @ts-ignore */
114
+ ...(ngDevMode ? [{ debugName: "image" }] : /* istanbul ignore next */ []));
115
+ this.saved = signal('', /* @ts-ignore */
116
+ ...(ngDevMode ? [{ debugName: "saved" }] : /* istanbul ignore next */ []));
117
+ this.pickerOpen = signal(false, /* @ts-ignore */
118
+ ...(ngDevMode ? [{ debugName: "pickerOpen" }] : /* istanbul ignore next */ []));
119
+ this.saving = signal(false, /* @ts-ignore */
120
+ ...(ngDevMode ? [{ debugName: "saving" }] : /* istanbul ignore next */ []));
121
+ this.isDirty = computed(() => this.image() !== this.saved(), /* @ts-ignore */
122
+ ...(ngDevMode ? [{ debugName: "isDirty" }] : /* istanbul ignore next */ []));
123
+ this.load();
124
+ }
125
+ load() {
126
+ this.service.get().subscribe(result => this.show(result.defaultShareImage ?? ''));
127
+ }
128
+ onPicked(files) {
129
+ const url = files[0]?.url;
130
+ if (url) {
131
+ this.image.set(url);
132
+ }
133
+ }
134
+ removeImage() {
135
+ this.image.set('');
136
+ }
137
+ save() {
138
+ if (this.saving() || !this.isDirty()) {
139
+ return;
140
+ }
141
+ this.saving.set(true);
142
+ this.service.update({ defaultShareImage: this.image() }).subscribe({
143
+ next: result => {
144
+ this.show(result.defaultShareImage ?? '');
145
+ this.saving.set(false);
146
+ this.toaster.success('AbpUi::SavedSuccessfully');
147
+ },
148
+ error: () => this.saving.set(false),
149
+ });
150
+ }
151
+ show(image) {
152
+ this.image.set(image);
153
+ this.saved.set(image);
154
+ }
155
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: SeoSettingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
156
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.2", type: SeoSettingComponent, isStandalone: true, selector: "site-seo-setting", ngImport: i0, template: "<h4 class=\"mb-1\">{{ 'Site::Seo' | abpLocalization }}</h4>\n\n<div class=\"mb-3\">\n <label class=\"form-label d-block fw-semibold\">\n {{ 'Site::DisplayName:Site.Seo.DefaultShareImage' | abpLocalization }}\n </label>\n @if (image()) {\n <div class=\"mb-2\">\n <site-file-preview\n width=\"240px\"\n type=\"image/*\"\n [src]=\"image()\"\n [name]=\"'Site::DisplayName:Site.Seo.DefaultShareImage' | abpLocalization\"\n [resizeWidth]=\"imageWidth\"\n [resizeHeight]=\"imageHeight\"\n ></site-file-preview>\n </div>\n } @else {\n <p class=\"text-muted mb-2\">{{ 'Site::Seo:NoImage' | abpLocalization }}</p>\n }\n\n <ng-container *abpPermission=\"policies.SeoUpdate\">\n <div>\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"pickerOpen.set(true)\">\n <i class=\"fa fa-image me-1\" aria-hidden=\"true\"></i>{{ 'Site::Seo:SelectImage' | abpLocalization }}\n </button>\n @if (image()) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary ms-2\" (click)=\"removeImage()\">\n <i class=\"fa fa-trash me-1\" aria-hidden=\"true\"></i>{{ 'AbpUi::Delete' | abpLocalization }}\n </button>\n }\n </div>\n </ng-container>\n <small class=\"form-text text-muted d-block mt-2\">{{ 'Site::Seo:Hint' | abpLocalization }}</small>\n</div>\n\n<ng-container *abpPermission=\"policies.SeoUpdate\">\n <button type=\"button\" class=\"btn btn-primary\" [disabled]=\"!isDirty() || saving()\" (click)=\"save()\">\n <i class=\"fa fa-check me-1\"></i>{{ 'AbpUi::Save' | abpLocalization }}\n </button>\n\n <site-file-modal\n [visible]=\"pickerOpen()\"\n (visibleChange)=\"pickerOpen.set($event)\"\n [multiple]=\"false\"\n [fileContainerName]=\"imageContainerName\"\n (selectFilefn)=\"onPicked($event)\"\n ></site-file-modal>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i2.PermissionDirective, selector: "[abpPermission]", inputs: ["abpPermission", "abpPermissionRunChangeDetection"] }, { kind: "ngmodule", type: ThemeSharedModule }, { kind: "component", type: FileModalComponent, selector: "site-file-modal", inputs: ["fileContainerName", "multiple", "limit", "visible", "selectPickerFile"], outputs: ["visibleChange", "selectFilefn"] }, { kind: "component", type: FilePreviewComponent, selector: "site-file-preview", inputs: ["width", "src", "type", "name", "className", "resizeWidth", "resizeHeight"] }, { kind: "pipe", type: i2.LocalizationPipe, name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
157
+ }
158
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: SeoSettingComponent, decorators: [{
159
+ type: Component,
160
+ args: [{ selector: 'site-seo-setting', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CoreModule, ThemeSharedModule, PermissionDirective, FileModalComponent, FilePreviewComponent], template: "<h4 class=\"mb-1\">{{ 'Site::Seo' | abpLocalization }}</h4>\n\n<div class=\"mb-3\">\n <label class=\"form-label d-block fw-semibold\">\n {{ 'Site::DisplayName:Site.Seo.DefaultShareImage' | abpLocalization }}\n </label>\n @if (image()) {\n <div class=\"mb-2\">\n <site-file-preview\n width=\"240px\"\n type=\"image/*\"\n [src]=\"image()\"\n [name]=\"'Site::DisplayName:Site.Seo.DefaultShareImage' | abpLocalization\"\n [resizeWidth]=\"imageWidth\"\n [resizeHeight]=\"imageHeight\"\n ></site-file-preview>\n </div>\n } @else {\n <p class=\"text-muted mb-2\">{{ 'Site::Seo:NoImage' | abpLocalization }}</p>\n }\n\n <ng-container *abpPermission=\"policies.SeoUpdate\">\n <div>\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"pickerOpen.set(true)\">\n <i class=\"fa fa-image me-1\" aria-hidden=\"true\"></i>{{ 'Site::Seo:SelectImage' | abpLocalization }}\n </button>\n @if (image()) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary ms-2\" (click)=\"removeImage()\">\n <i class=\"fa fa-trash me-1\" aria-hidden=\"true\"></i>{{ 'AbpUi::Delete' | abpLocalization }}\n </button>\n }\n </div>\n </ng-container>\n <small class=\"form-text text-muted d-block mt-2\">{{ 'Site::Seo:Hint' | abpLocalization }}</small>\n</div>\n\n<ng-container *abpPermission=\"policies.SeoUpdate\">\n <button type=\"button\" class=\"btn btn-primary\" [disabled]=\"!isDirty() || saving()\" (click)=\"save()\">\n <i class=\"fa fa-check me-1\"></i>{{ 'AbpUi::Save' | abpLocalization }}\n </button>\n\n <site-file-modal\n [visible]=\"pickerOpen()\"\n (visibleChange)=\"pickerOpen.set($event)\"\n [multiple]=\"false\"\n [fileContainerName]=\"imageContainerName\"\n (selectFilefn)=\"onPicked($event)\"\n ></site-file-modal>\n</ng-container>\n" }]
161
+ }], ctorParameters: () => [] });
162
+
98
163
  /** The name of the tab: a localization key of the `Site` resource, which the tab strip localizes. */
99
164
  const SITE_LANGUAGES_SETTING_TAB_NAME = 'Site::Languages';
165
+ const SITE_SEO_SETTING_TAB_NAME = 'Site::Seo';
100
166
  function configureSiteSettingTabs() {
101
167
  inject(SettingTabsService).add([
102
168
  {
@@ -105,11 +171,18 @@ function configureSiteSettingTabs() {
105
171
  requiredPolicy: eSitePolicyNames.Languages,
106
172
  component: LanguagesSettingComponent,
107
173
  },
174
+ {
175
+ name: SITE_SEO_SETTING_TAB_NAME,
176
+ order: 20,
177
+ requiredPolicy: eSitePolicyNames.Seo,
178
+ component: SeoSettingComponent,
179
+ },
108
180
  ]);
109
181
  }
110
182
  /**
111
- * Adds the site's languages to Setting Management's page as a tab. Next to `provideSettingManagementConfig()` in the
112
- * application's configuration: the page is that module's, and an application that does not use it does not use this.
183
+ * Adds the site's languages and SEO settings to Setting Management's page as tabs. Next to
184
+ * `provideSettingManagementConfig()` in the application's configuration: the page is that module's, and an
185
+ * application that does not use it does not use this.
113
186
  */
114
187
  function provideSiteSettingTabs() {
115
188
  return makeEnvironmentProviders([provideAppInitializer(configureSiteSettingTabs)]);
@@ -119,5 +192,5 @@ function provideSiteSettingTabs() {
119
192
  * Generated bundle index. Do not edit.
120
193
  */
121
194
 
122
- export { LanguagesSettingComponent, SITE_LANGUAGES_SETTING_TAB_NAME, configureSiteSettingTabs, provideSiteSettingTabs };
195
+ export { LanguagesSettingComponent, SITE_LANGUAGES_SETTING_TAB_NAME, SITE_SEO_SETTING_TAB_NAME, SeoSettingComponent, configureSiteSettingTabs, provideSiteSettingTabs };
123
196
  //# sourceMappingURL=dignite-ng.site-setting-management.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"dignite-ng.site-setting-management.mjs","sources":["../../../projects/site/setting-management/src/languages-setting.component.ts","../../../projects/site/setting-management/src/languages-setting.component.html","../../../projects/site/setting-management/src/providers/setting-tab.provider.ts","../../../projects/site/setting-management/src/dignite-ng.site-setting-management.ts"],"sourcesContent":["import { CoreModule, PermissionDirective } from '@abp/ng.core';\nimport { ThemeSharedModule, ToasterService } from '@abp/ng.theme.shared';\nimport { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { Dignite, eSitePolicyNames } from '@dignite/ng.site';\n\n/**\n * The languages the site serves, as a tab of Setting Management's page: the whole ordered list: the first is the default, whose pages have no language\n * prefix in their address. The server refuses a tag it does not recognize and canonicalizes the ones it keeps, so the\n * list shown after a save is what it stored.\n */\n@Component({\n selector: 'site-languages-setting',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './languages-setting.component.html',\n imports: [CoreModule, ThemeSharedModule, FormsModule, PermissionDirective],\n})\nexport class LanguagesSettingComponent {\n private readonly service = inject(Dignite.Site.Admin.Languages.SiteLanguageAdminService);\n private readonly toaster = inject(ToasterService);\n\n readonly policies = eSitePolicyNames;\n\n // Signals, not fields: the layout shell is OnPush, and a value set in a subscribe callback would not repaint.\n readonly languages = signal<string[]>([]);\n readonly saved = signal<string[]>([]);\n readonly newLanguage = signal('');\n readonly saving = signal(false);\n\n readonly isDirty = computed(() => this.languages().join(',') !== this.saved().join(','));\n\n constructor() {\n this.load();\n }\n\n load() {\n this.service.get().subscribe(result => this.show(result.enabledLanguages));\n }\n\n /** Adds the tag typed, once; the server decides whether it is a language. */\n add() {\n const tag = this.newLanguage().trim();\n if (!tag) {\n return;\n }\n\n if (!this.languages().some(language => language.toLowerCase() === tag.toLowerCase())) {\n this.languages.update(list => [...list, tag]);\n }\n this.newLanguage.set('');\n }\n\n /** The last language cannot go: a site serves at least one. */\n remove(index: number) {\n if (this.languages().length <= 1) {\n return;\n }\n this.languages.update(list => list.filter((_, i) => i !== index));\n }\n\n move(index: number, offset: -1 | 1) {\n const target = index + offset;\n if (target < 0 || target >= this.languages().length) {\n return;\n }\n this.languages.update(list => {\n const next = [...list];\n [next[index], next[target]] = [next[target], next[index]];\n return next;\n });\n }\n\n makeDefault(index: number) {\n if (index <= 0) {\n return;\n }\n this.languages.update(list => [list[index], ...list.filter((_, i) => i !== index)]);\n }\n\n save() {\n if (this.saving() || !this.isDirty()) {\n return;\n }\n\n this.saving.set(true);\n this.service.update({ enabledLanguages: this.languages() }).subscribe({\n next: result => {\n this.show(result.enabledLanguages);\n this.saving.set(false);\n this.toaster.success('AbpUi::SavedSuccessfully');\n },\n error: () => this.saving.set(false),\n });\n }\n\n private show(languages: string[]) {\n this.languages.set([...languages]);\n this.saved.set([...languages]);\n }\n}\n","<h4 class=\"mb-1\">{{ 'Site::Languages' | abpLocalization }}</h4>\n<p class=\"text-muted\">{{ 'Site::Languages:Hint' | abpLocalization }}</p>\n\n<ul class=\"list-group mb-3\">\n @for (language of languages(); track language; let i = $index) {\n <li class=\"list-group-item d-flex align-items-center gap-2\">\n <span class=\"fw-semibold\">{{ language }}</span>\n @if (i === 0) {\n <span class=\"badge bg-primary\">{{ 'Site::Languages:Default' | abpLocalization }}</span>\n }\n <span class=\"ms-auto d-flex gap-1\" *abpPermission=\"policies.LanguagesUpdate\">\n @if (i > 0) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"makeDefault(i)\">\n {{ 'Site::Languages:MakeDefault' | abpLocalization }}\n </button>\n }\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" [disabled]=\"i === 0\" (click)=\"move(i, -1)\">\n <i class=\"fa fa-arrow-up\"></i>\n </button>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-outline-secondary\"\n [disabled]=\"i === languages().length - 1\"\n (click)=\"move(i, 1)\"\n >\n <i class=\"fa fa-arrow-down\"></i>\n </button>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-outline-danger\"\n [disabled]=\"languages().length <= 1\"\n (click)=\"remove(i)\"\n >\n <i class=\"fa fa-trash\"></i>\n </button>\n </span>\n </li>\n }\n</ul>\n\n<ng-container *abpPermission=\"policies.LanguagesUpdate\">\n <div class=\"input-group mb-3\">\n <input\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"newLanguage()\"\n (ngModelChange)=\"newLanguage.set($event)\"\n (keydown.enter)=\"$event.preventDefault(); add()\"\n [placeholder]=\"'Site::Languages:Placeholder' | abpLocalization\"\n />\n <button type=\"button\" class=\"btn btn-outline-primary\" (click)=\"add()\">\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::Languages:Add' | abpLocalization }}\n </button>\n </div>\n\n @if (isDirty()) {\n <div class=\"alert alert-warning\">{{ 'Site::Languages:ChangeWarning' | abpLocalization }}</div>\n }\n\n <button type=\"button\" class=\"btn btn-primary\" [disabled]=\"!isDirty() || saving()\" (click)=\"save()\">\n <i class=\"fa fa-check me-1\"></i>{{ 'AbpUi::Save' | abpLocalization }}\n </button>\n</ng-container>\n","import { SettingTabsService } from '@abp/ng.setting-management/config';\nimport { eSitePolicyNames } from '@dignite/ng.site';\nimport { inject, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';\nimport { LanguagesSettingComponent } from '../languages-setting.component';\n\n/** The name of the tab: a localization key of the `Site` resource, which the tab strip localizes. */\nexport const SITE_LANGUAGES_SETTING_TAB_NAME = 'Site::Languages';\n\nexport function configureSiteSettingTabs() {\n inject(SettingTabsService).add([\n {\n name: SITE_LANGUAGES_SETTING_TAB_NAME,\n order: 10,\n requiredPolicy: eSitePolicyNames.Languages,\n component: LanguagesSettingComponent,\n },\n ]);\n}\n\n/**\n * Adds the site's languages to Setting Management's page as a tab. Next to `provideSettingManagementConfig()` in the\n * application's configuration: the page is that module's, and an application that does not use it does not use this.\n */\nexport function provideSiteSettingTabs() {\n return makeEnvironmentProviders([provideAppInitializer(configureSiteSettingTabs)]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dignite-ng.site-setting-management.mjs","sources":["../../../projects/site/setting-management/src/languages-setting.component.ts","../../../projects/site/setting-management/src/languages-setting.component.html","../../../projects/site/setting-management/src/seo-setting.component.ts","../../../projects/site/setting-management/src/seo-setting.component.html","../../../projects/site/setting-management/src/providers/setting-tab.provider.ts","../../../projects/site/setting-management/src/dignite-ng.site-setting-management.ts"],"sourcesContent":["import { CoreModule, PermissionDirective } from '@abp/ng.core';\nimport { ThemeSharedModule, ToasterService } from '@abp/ng.theme.shared';\nimport { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { Dignite, eSitePolicyNames } from '@dignite/ng.site';\n\n/**\n * The languages the site serves, as a tab of Setting Management's page: the whole ordered list: the first is the default, whose pages have no language\n * prefix in their address. The server refuses a tag it does not recognize and canonicalizes the ones it keeps, so the\n * list shown after a save is what it stored.\n */\n@Component({\n selector: 'site-languages-setting',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './languages-setting.component.html',\n imports: [CoreModule, ThemeSharedModule, FormsModule, PermissionDirective],\n})\nexport class LanguagesSettingComponent {\n private readonly service = inject(Dignite.Site.Admin.Languages.SiteLanguageAdminService);\n private readonly toaster = inject(ToasterService);\n\n readonly policies = eSitePolicyNames;\n\n // Signals, not fields: the layout shell is OnPush, and a value set in a subscribe callback would not repaint.\n readonly languages = signal<string[]>([]);\n readonly saved = signal<string[]>([]);\n readonly newLanguage = signal('');\n readonly saving = signal(false);\n\n readonly isDirty = computed(() => this.languages().join(',') !== this.saved().join(','));\n\n constructor() {\n this.load();\n }\n\n load() {\n this.service.get().subscribe(result => this.show(result.enabledLanguages));\n }\n\n /** Adds the tag typed, once; the server decides whether it is a language. */\n add() {\n const tag = this.newLanguage().trim();\n if (!tag) {\n return;\n }\n\n if (!this.languages().some(language => language.toLowerCase() === tag.toLowerCase())) {\n this.languages.update(list => [...list, tag]);\n }\n this.newLanguage.set('');\n }\n\n /** The last language cannot go: a site serves at least one. */\n remove(index: number) {\n if (this.languages().length <= 1) {\n return;\n }\n this.languages.update(list => list.filter((_, i) => i !== index));\n }\n\n move(index: number, offset: -1 | 1) {\n const target = index + offset;\n if (target < 0 || target >= this.languages().length) {\n return;\n }\n this.languages.update(list => {\n const next = [...list];\n [next[index], next[target]] = [next[target], next[index]];\n return next;\n });\n }\n\n makeDefault(index: number) {\n if (index <= 0) {\n return;\n }\n this.languages.update(list => [list[index], ...list.filter((_, i) => i !== index)]);\n }\n\n save() {\n if (this.saving() || !this.isDirty()) {\n return;\n }\n\n this.saving.set(true);\n this.service.update({ enabledLanguages: this.languages() }).subscribe({\n next: result => {\n this.show(result.enabledLanguages);\n this.saving.set(false);\n this.toaster.success('AbpUi::SavedSuccessfully');\n },\n error: () => this.saving.set(false),\n });\n }\n\n private show(languages: string[]) {\n this.languages.set([...languages]);\n this.saved.set([...languages]);\n }\n}\n","<h4 class=\"mb-1\">{{ 'Site::Languages' | abpLocalization }}</h4>\n<p class=\"text-muted\">{{ 'Site::Languages:Hint' | abpLocalization }}</p>\n\n<ul class=\"list-group mb-3\">\n @for (language of languages(); track language; let i = $index) {\n <li class=\"list-group-item d-flex align-items-center gap-2\">\n <span class=\"fw-semibold\">{{ language }}</span>\n @if (i === 0) {\n <span class=\"badge bg-primary\">{{ 'Site::Languages:Default' | abpLocalization }}</span>\n }\n <span class=\"ms-auto d-flex gap-1\" *abpPermission=\"policies.LanguagesUpdate\">\n @if (i > 0) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"makeDefault(i)\">\n {{ 'Site::Languages:MakeDefault' | abpLocalization }}\n </button>\n }\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" [disabled]=\"i === 0\" (click)=\"move(i, -1)\">\n <i class=\"fa fa-arrow-up\"></i>\n </button>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-outline-secondary\"\n [disabled]=\"i === languages().length - 1\"\n (click)=\"move(i, 1)\"\n >\n <i class=\"fa fa-arrow-down\"></i>\n </button>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-outline-danger\"\n [disabled]=\"languages().length <= 1\"\n (click)=\"remove(i)\"\n >\n <i class=\"fa fa-trash\"></i>\n </button>\n </span>\n </li>\n }\n</ul>\n\n<ng-container *abpPermission=\"policies.LanguagesUpdate\">\n <div class=\"input-group mb-3\">\n <input\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"newLanguage()\"\n (ngModelChange)=\"newLanguage.set($event)\"\n (keydown.enter)=\"$event.preventDefault(); add()\"\n [placeholder]=\"'Site::Languages:Placeholder' | abpLocalization\"\n />\n <button type=\"button\" class=\"btn btn-outline-primary\" (click)=\"add()\">\n <i class=\"fa fa-plus me-1\"></i>{{ 'Site::Languages:Add' | abpLocalization }}\n </button>\n </div>\n\n @if (isDirty()) {\n <div class=\"alert alert-warning\">{{ 'Site::Languages:ChangeWarning' | abpLocalization }}</div>\n }\n\n <button type=\"button\" class=\"btn btn-primary\" [disabled]=\"!isDirty() || saving()\" (click)=\"save()\">\n <i class=\"fa fa-check me-1\"></i>{{ 'AbpUi::Save' | abpLocalization }}\n </button>\n</ng-container>\n","import { CoreModule, PermissionDirective } from '@abp/ng.core';\nimport { ThemeSharedModule, ToasterService } from '@abp/ng.theme.shared';\nimport { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport {\n Dignite,\n FileModalComponent,\n FilePreviewComponent,\n OG_IMAGE_CONTAINER_NAME,\n OG_IMAGE_HEIGHT,\n OG_IMAGE_WIDTH,\n eSitePolicyNames,\n} from '@dignite/ng.site';\n\n/**\n * The site's SEO settings, as a tab of Setting Management's page. For now the default share image: the one a page\n * without a share image of its own is shared with. It is picked from the file library the way a page's own share\n * image is (the `images` container); an address someone stored by other means shows and can be replaced or removed the\n * same way. The server stores what it is given, and empty clears it. Without the update permission the tab only shows.\n */\n@Component({\n selector: 'site-seo-setting',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './seo-setting.component.html',\n imports: [CoreModule, ThemeSharedModule, PermissionDirective, FileModalComponent, FilePreviewComponent],\n})\nexport class SeoSettingComponent {\n private readonly service = inject(Dignite.Site.Admin.Seo.SiteSeoSettingsAdminService);\n private readonly toaster = inject(ToasterService);\n\n readonly policies = eSitePolicyNames;\n readonly imageContainerName = OG_IMAGE_CONTAINER_NAME;\n readonly imageWidth = OG_IMAGE_WIDTH;\n readonly imageHeight = OG_IMAGE_HEIGHT;\n\n // Signals, not fields: the layout shell is OnPush, and a value set in a subscribe callback would not repaint.\n readonly image = signal('');\n readonly saved = signal('');\n readonly pickerOpen = signal(false);\n readonly saving = signal(false);\n\n readonly isDirty = computed(() => this.image() !== this.saved());\n\n constructor() {\n this.load();\n }\n\n load() {\n this.service.get().subscribe(result => this.show(result.defaultShareImage ?? ''));\n }\n\n onPicked(files: Dignite.Site.Admin.Files.FileDescriptorDto[]) {\n const url = files[0]?.url;\n if (url) {\n this.image.set(url);\n }\n }\n\n removeImage() {\n this.image.set('');\n }\n\n save() {\n if (this.saving() || !this.isDirty()) {\n return;\n }\n\n this.saving.set(true);\n this.service.update({ defaultShareImage: this.image() }).subscribe({\n next: result => {\n this.show(result.defaultShareImage ?? '');\n this.saving.set(false);\n this.toaster.success('AbpUi::SavedSuccessfully');\n },\n error: () => this.saving.set(false),\n });\n }\n\n private show(image: string) {\n this.image.set(image);\n this.saved.set(image);\n }\n}\n","<h4 class=\"mb-1\">{{ 'Site::Seo' | abpLocalization }}</h4>\n\n<div class=\"mb-3\">\n <label class=\"form-label d-block fw-semibold\">\n {{ 'Site::DisplayName:Site.Seo.DefaultShareImage' | abpLocalization }}\n </label>\n @if (image()) {\n <div class=\"mb-2\">\n <site-file-preview\n width=\"240px\"\n type=\"image/*\"\n [src]=\"image()\"\n [name]=\"'Site::DisplayName:Site.Seo.DefaultShareImage' | abpLocalization\"\n [resizeWidth]=\"imageWidth\"\n [resizeHeight]=\"imageHeight\"\n ></site-file-preview>\n </div>\n } @else {\n <p class=\"text-muted mb-2\">{{ 'Site::Seo:NoImage' | abpLocalization }}</p>\n }\n\n <ng-container *abpPermission=\"policies.SeoUpdate\">\n <div>\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"pickerOpen.set(true)\">\n <i class=\"fa fa-image me-1\" aria-hidden=\"true\"></i>{{ 'Site::Seo:SelectImage' | abpLocalization }}\n </button>\n @if (image()) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary ms-2\" (click)=\"removeImage()\">\n <i class=\"fa fa-trash me-1\" aria-hidden=\"true\"></i>{{ 'AbpUi::Delete' | abpLocalization }}\n </button>\n }\n </div>\n </ng-container>\n <small class=\"form-text text-muted d-block mt-2\">{{ 'Site::Seo:Hint' | abpLocalization }}</small>\n</div>\n\n<ng-container *abpPermission=\"policies.SeoUpdate\">\n <button type=\"button\" class=\"btn btn-primary\" [disabled]=\"!isDirty() || saving()\" (click)=\"save()\">\n <i class=\"fa fa-check me-1\"></i>{{ 'AbpUi::Save' | abpLocalization }}\n </button>\n\n <site-file-modal\n [visible]=\"pickerOpen()\"\n (visibleChange)=\"pickerOpen.set($event)\"\n [multiple]=\"false\"\n [fileContainerName]=\"imageContainerName\"\n (selectFilefn)=\"onPicked($event)\"\n ></site-file-modal>\n</ng-container>\n","import { SettingTabsService } from '@abp/ng.setting-management/config';\nimport { eSitePolicyNames } from '@dignite/ng.site';\nimport { inject, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';\nimport { LanguagesSettingComponent } from '../languages-setting.component';\nimport { SeoSettingComponent } from '../seo-setting.component';\n\n/** The name of the tab: a localization key of the `Site` resource, which the tab strip localizes. */\nexport const SITE_LANGUAGES_SETTING_TAB_NAME = 'Site::Languages';\n\nexport const SITE_SEO_SETTING_TAB_NAME = 'Site::Seo';\n\nexport function configureSiteSettingTabs() {\n inject(SettingTabsService).add([\n {\n name: SITE_LANGUAGES_SETTING_TAB_NAME,\n order: 10,\n requiredPolicy: eSitePolicyNames.Languages,\n component: LanguagesSettingComponent,\n },\n {\n name: SITE_SEO_SETTING_TAB_NAME,\n order: 20,\n requiredPolicy: eSitePolicyNames.Seo,\n component: SeoSettingComponent,\n },\n ]);\n}\n\n/**\n * Adds the site's languages and SEO settings to Setting Management's page as tabs. Next to\n * `provideSettingManagementConfig()` in the application's configuration: the page is that module's, and an\n * application that does not use it does not use this.\n */\nexport function provideSiteSettingTabs() {\n return makeEnvironmentProviders([provideAppInitializer(configureSiteSettingTabs)]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1"],"mappings":"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"}