@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
@@ -1,5 +1,5 @@
1
1
  import * as i4 from '@abp/ng.core';
2
- import { RestService, CoreModule, EnvironmentService, ListService, LIST_QUERY_DEBOUNCE_TIME, mapEnumToOptions, authGuard, permissionGuard, RouterOutletComponent } from '@abp/ng.core';
2
+ import { RestService, CoreModule, EnvironmentService, SessionStateService, ListService, LIST_QUERY_DEBOUNCE_TIME, mapEnumToOptions, authGuard, permissionGuard, RouterOutletComponent } from '@abp/ng.core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i0 from '@angular/core';
@@ -50,6 +50,14 @@ var eSitePolicyNames;
50
50
  eSitePolicyNames["ContentsCreate"] = "SiteAdmin.Contents.Create";
51
51
  eSitePolicyNames["ContentsUpdate"] = "SiteAdmin.Contents.Update";
52
52
  eSitePolicyNames["ContentsDelete"] = "SiteAdmin.Contents.Delete";
53
+ eSitePolicyNames["Themes"] = "SiteAdmin.Themes";
54
+ /** Changing the working copy: files, the default layout, restoring a release into it. */
55
+ eSitePolicyNames["ThemesEdit"] = "SiteAdmin.Themes.Edit";
56
+ /** Changing what the site renders: publishing, and making an older release live. */
57
+ eSitePolicyNames["ThemesPublish"] = "SiteAdmin.Themes.Publish";
58
+ eSitePolicyNames["Languages"] = "SiteAdmin.Languages";
59
+ /** Setting them: the default language is the one without a URL prefix, so this moves the address of pages. */
60
+ eSitePolicyNames["LanguagesUpdate"] = "SiteAdmin.Languages.Update";
53
61
  })(eSitePolicyNames || (eSitePolicyNames = {}));
54
62
 
55
63
  class ContentTypeAdminService {
@@ -503,7 +511,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImpor
503
511
  }]
504
512
  }] });
505
513
 
506
- var index$h = /*#__PURE__*/Object.freeze({
514
+ var index$k = /*#__PURE__*/Object.freeze({
507
515
  __proto__: null,
508
516
  DirectoryAdminService: DirectoryAdminService,
509
517
  FileAdminService: FileAdminService
@@ -775,7 +783,7 @@ const IMAGE_TYPE_OPTIONS = [
775
783
 
776
784
  /**
777
785
  * The path every Site file is served under - the server's `SiteFileUrl.RoutePrefix`. The admin API hands
778
- * out addresses relative to it (`FileDescriptorDto.url`, `/api/site-public/files/...?__tenant=`), and that
786
+ * out addresses relative to it (`FileDescriptorDto.url`, `/api/site-public/files/...`), and that
779
787
  * relative address is what a field stores: no host is written into content. The public site resolves it
780
788
  * against its own origin; this admin UI, served from another origin, shows it from its `SiteAdmin` API
781
789
  * host (`SiteFileUrlService`).
@@ -787,7 +795,7 @@ function isSiteFileUrl(url) {
787
795
  }
788
796
  /**
789
797
  * `url` asked for at `width` x `height` (`?Width=&Height=`, the server crops to fill when both are given),
790
- * keeping every other query parameter - `__tenant` in particular. Anything that is not a Site file address
798
+ * keeping every other query parameter (`__tenant`, on an address an earlier version issued). Anything that is not a Site file address
791
799
  * (a local `blob:` URL, an external image) comes back unchanged, as does a call without a size. Mirrors the
792
800
  * server's `SiteFileUrl.Sized`.
793
801
  */
@@ -811,14 +819,51 @@ function sizedFileUrl(url, width, height) {
811
819
  return `${base}?${[...kept, ...size].join('&')}`;
812
820
  }
813
821
  /**
814
- * `url` on `apiBase` when it is a relative Site file address; anything else - an absolute address, a local
815
- * `blob:`/`data:` URL, an external image - comes back unchanged, as does every address when `apiBase` is
816
- * empty (an admin UI served from its API's own origin). Mirrors the server's `SiteFileUrl.Absolutize`.
822
+ * `url` as this admin UI loads it: a relative Site file address, on `apiBase` and naming the tenant
823
+ * (`?__tenant=`) when `tenantId` is given. A stored address names no tenant, and an `<img>` request carries
824
+ * none of the headers the UI's API calls do, so the host could not tell which tenant's file is meant. An
825
+ * address that already has a `__tenant` (one an earlier version issued) keeps it. Anything else - an absolute
826
+ * address, a local `blob:`/`data:` URL, an external image - comes back unchanged, as does every relative
827
+ * address when `apiBase` and `tenantId` are both empty. Mirrors the server's `SiteFileUrl.Absolutize`.
828
+ */
829
+ function absoluteFileUrl(url, apiBase, tenantId) {
830
+ const value = url ?? '';
831
+ if (!value.toLowerCase().startsWith(SITE_FILE_PATH)) {
832
+ return value;
833
+ }
834
+ return trimBase(apiBase) + withTenant(value, tenantId);
835
+ }
836
+ /**
837
+ * The inverse of `absoluteFileUrl`: an address on `apiBase`, or a relative one, as it is stored - relative,
838
+ * without the `__tenant` that `absoluteFileUrl` added for `tenantId`. Another tenant's `__tenant`, an empty
839
+ * one and every address that is not a Site file come back unchanged.
817
840
  */
818
- function absoluteFileUrl(url, apiBase) {
841
+ function relativeFileUrl(url, apiBase, tenantId) {
819
842
  const value = url ?? '';
820
843
  const base = trimBase(apiBase);
821
- return base && value.toLowerCase().startsWith(SITE_FILE_PATH) ? base + value : value;
844
+ if (base && value.toLowerCase().startsWith(base.toLowerCase() + SITE_FILE_PATH)) {
845
+ return withoutTenant(value.substring(base.length), tenantId);
846
+ }
847
+ return value.toLowerCase().startsWith(SITE_FILE_PATH) ? withoutTenant(value, tenantId) : value;
848
+ }
849
+ function withTenant(url, tenantId) {
850
+ if (!tenantId || /[?&]__tenant=/i.test(url)) {
851
+ return url;
852
+ }
853
+ return `${url}${url.includes('?') ? '&' : '?'}__tenant=${encodeURIComponent(tenantId)}`;
854
+ }
855
+ function withoutTenant(url, tenantId) {
856
+ const queryStart = url.indexOf('?');
857
+ if (!tenantId || queryStart < 0) {
858
+ return url;
859
+ }
860
+ const added = `__tenant=${encodeURIComponent(tenantId)}`.toLowerCase();
861
+ const kept = url
862
+ .substring(queryStart + 1)
863
+ .split('&')
864
+ .filter(parameter => parameter.toLowerCase() !== added);
865
+ const base = url.substring(0, queryStart);
866
+ return kept.length ? `${base}?${kept.join('&')}` : base;
822
867
  }
823
868
  function trimBase(apiBase) {
824
869
  return (apiBase ?? '').trim().replace(/\/+$/, '');
@@ -829,12 +874,14 @@ function trimBase(apiBase) {
829
874
  * see `SITE_FILE_PATH`), and this UI is served from an origin of its own, so the previews
830
875
  * (`site-file-preview`: the file picker and modal, a file field, the SEO share image) put the `SiteAdmin`
831
876
  * API's host - `environment.apis.SiteAdmin.url`, where the file library's admin API lives - in front of it.
832
- * The CKEditor field does the same inside the editor (`siteCKEditorConfigContributor`). Nothing that is
833
- * saved carries that host.
877
+ * The CKEditor field does the same inside the editor (`siteCKEditorConfigContributor`). The previews also name
878
+ * the signed-in tenant (`?__tenant=`): a stored address names none, and an `<img>` request cannot carry the
879
+ * header the UI's API calls use. Nothing that is saved carries that host or tenant.
834
880
  */
835
881
  class SiteFileUrlService {
836
882
  constructor() {
837
883
  this.environment = inject(EnvironmentService);
884
+ this.session = inject(SessionStateService);
838
885
  }
839
886
  /** The `SiteAdmin` API's base URL, with no trailing slash; empty when the UI shares its API's origin. */
840
887
  get apiBase() {
@@ -843,9 +890,17 @@ class SiteFileUrlService {
843
890
  const apis = this.environment.getEnvironment()?.apis;
844
891
  return apis ? (this.environment.getApiUrl('SiteAdmin') ?? '').replace(/\/+$/, '') : '';
845
892
  }
893
+ /** The signed-in tenant's id; `null` on the host. */
894
+ get tenantId() {
895
+ return this.session.getTenant()?.id ?? null;
896
+ }
846
897
  /** A stored file address as this UI loads it - see `absoluteFileUrl`. */
847
898
  toDisplay(url) {
848
- return absoluteFileUrl(url, this.apiBase);
899
+ return absoluteFileUrl(url, this.apiBase, this.tenantId);
900
+ }
901
+ /** The inverse of `toDisplay`: an address as it is stored - see `relativeFileUrl`. */
902
+ toStored(url) {
903
+ return relativeFileUrl(url, this.apiBase, this.tenantId);
849
904
  }
850
905
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: SiteFileUrlService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
851
906
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: SiteFileUrlService, providedIn: 'root' }); }
@@ -1859,7 +1914,7 @@ const IMAGE_TYPES = ['imageBlock', 'imageInline'];
1859
1914
  * A stored address is relative (`<img src="/api/site-public/files/...">`, see `SITE_FILE_PATH`), and this
1860
1915
  * admin UI is served from another origin, where it does not resolve.
1861
1916
  *
1862
- * So the editor's **model** holds the absolute address, and only the data the editor hands out is
1917
+ * So the editor's **model** holds the absolute address (naming the signed-in tenant, as the previews do), and only the data the editor hands out is
1863
1918
  * relative: a plugin converts an image's `src` (`imageBlock`/`imageInline`) on the way in (upcast:
1864
1919
  * `setData()`, the initial value, a paste) from relative to absolute, and on the way out (data downcast:
1865
1920
  * `getData()` - the form value that is saved, the Source view, a copy) from absolute back to relative.
@@ -1875,14 +1930,12 @@ const IMAGE_TYPES = ['imageBlock', 'imageInline'];
1875
1930
  function siteCKEditorConfigContributor() {
1876
1931
  const fileUrls = inject(SiteFileUrlService);
1877
1932
  return config => {
1878
- const apiBase = fileUrls.apiBase;
1879
- if (!apiBase) {
1880
- // The UI shares its API's origin: a relative address already loads.
1933
+ if (!fileUrls.apiBase && !fileUrls.tenantId) {
1934
+ // The UI shares its API's origin and the host's: a relative address already loads.
1881
1935
  return;
1882
1936
  }
1883
- const absolutePrefix = apiBase + SITE_FILE_PATH;
1884
- const toModel = (src) => (src.startsWith(SITE_FILE_PATH) ? apiBase + src : src);
1885
- const toData = (src) => (src.startsWith(absolutePrefix) ? src.substring(apiBase.length) : src);
1937
+ const toModel = (src) => fileUrls.toDisplay(src);
1938
+ const toData = (src) => fileUrls.toStored(src);
1886
1939
  // A CKEditor 5 plugin can be a plain function of the editor.
1887
1940
  function SiteFileAddresses(editor) {
1888
1941
  // In: the image plugin creates the model image, src included, in its own `element:img` converter
@@ -1939,17 +1992,20 @@ function siteCKEditorConfigContributor() {
1939
1992
  *
1940
1993
  * Only `src` is rewritten, in the double- and single-quoted spellings; links (`<a href>`) are left alone, as
1941
1994
  * in the editor. The result is for display only: the view never hands HTML back, so nothing saved carries the
1942
- * host. When the UI shares its API's origin (`apiBase` empty) the HTML comes back untouched.
1995
+ * host. When the UI shares its API's origin (`apiBase` empty) and the host's, the HTML comes back untouched;
1996
+ * otherwise the address also names the signed-in tenant.
1943
1997
  *
1944
1998
  * Registered by `provideSite()` under `CKEDITOR_DISPLAY_CONTRIBUTORS` (with `useFactory`, so it can inject);
1945
1999
  * the pattern is the one in `@dignite/ng.flex-fields-ckeditor`'s README, "Customizing the read-only view".
1946
2000
  */
1947
2001
  function siteCKEditorDisplayContributor() {
1948
2002
  const fileUrls = inject(SiteFileUrlService);
1949
- const relativeSrc = new RegExp(String.raw `(\ssrc\s*=\s*["'])(${escapeRegExp(SITE_FILE_PATH)})`, 'gi');
2003
+ const relativeSrc = new RegExp(String.raw `(\ssrc\s*=\s*)(["'])(${escapeRegExp(SITE_FILE_PATH)}[^"']*)\2`, 'gi');
1950
2004
  return html => {
1951
- const apiBase = fileUrls.apiBase;
1952
- return apiBase ? html.replace(relativeSrc, (_match, prefix, path) => prefix + apiBase + path) : html;
2005
+ if (!fileUrls.apiBase && !fileUrls.tenantId) {
2006
+ return html;
2007
+ }
2008
+ return html.replace(relativeSrc, (_match, prefix, quote, address) => prefix + quote + fileUrls.toDisplay(address) + quote);
1953
2009
  };
1954
2010
  }
1955
2011
  function escapeRegExp(value) {
@@ -2024,7 +2080,7 @@ var FlexFieldValueType;
2024
2080
  })(FlexFieldValueType || (FlexFieldValueType = {}));
2025
2081
  const flexFieldValueTypeOptions = mapEnumToOptions(FlexFieldValueType);
2026
2082
 
2027
- var index$g = /*#__PURE__*/Object.freeze({
2083
+ var index$j = /*#__PURE__*/Object.freeze({
2028
2084
  __proto__: null,
2029
2085
  get FlexFieldQueryOperator () { return FlexFieldQueryOperator; },
2030
2086
  get FlexFieldValueType () { return FlexFieldValueType; },
@@ -2032,17 +2088,17 @@ var index$g = /*#__PURE__*/Object.freeze({
2032
2088
  flexFieldValueTypeOptions: flexFieldValueTypeOptions
2033
2089
  });
2034
2090
 
2035
- var index$f = /*#__PURE__*/Object.freeze({
2091
+ var index$i = /*#__PURE__*/Object.freeze({
2036
2092
  __proto__: null,
2037
- FlexFields: index$g
2093
+ FlexFields: index$j
2038
2094
  });
2039
2095
 
2040
- var index$e = /*#__PURE__*/Object.freeze({
2096
+ var index$h = /*#__PURE__*/Object.freeze({
2041
2097
  __proto__: null,
2042
2098
  ContentTypeAdminService: ContentTypeAdminService
2043
2099
  });
2044
2100
 
2045
- var index$d = /*#__PURE__*/Object.freeze({
2101
+ var index$g = /*#__PURE__*/Object.freeze({
2046
2102
  __proto__: null,
2047
2103
  ContentAdminService: ContentAdminService
2048
2104
  });
@@ -2099,11 +2155,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImpor
2099
2155
  }]
2100
2156
  }] });
2101
2157
 
2102
- var index$c = /*#__PURE__*/Object.freeze({
2158
+ var index$f = /*#__PURE__*/Object.freeze({
2103
2159
  __proto__: null,
2104
2160
  FieldAdminService: FieldAdminService
2105
2161
  });
2106
2162
 
2163
+ class SiteLanguageAdminService {
2164
+ constructor() {
2165
+ this.restService = inject(RestService);
2166
+ this.apiName = 'SiteAdmin';
2167
+ this.get = (config) => this.restService.request({
2168
+ method: 'GET',
2169
+ url: '/api/site-admin/languages',
2170
+ }, { apiName: this.apiName, ...config });
2171
+ this.update = (input, config) => this.restService.request({
2172
+ method: 'PUT',
2173
+ url: '/api/site-admin/languages',
2174
+ body: input,
2175
+ }, { apiName: this.apiName, ...config });
2176
+ }
2177
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: SiteLanguageAdminService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2178
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: SiteLanguageAdminService, providedIn: 'root' }); }
2179
+ }
2180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: SiteLanguageAdminService, decorators: [{
2181
+ type: Injectable,
2182
+ args: [{
2183
+ providedIn: 'root',
2184
+ }]
2185
+ }] });
2186
+
2187
+ var index$e = /*#__PURE__*/Object.freeze({
2188
+ __proto__: null,
2189
+ SiteLanguageAdminService: SiteLanguageAdminService
2190
+ });
2191
+
2107
2192
  class PageAdminService {
2108
2193
  constructor() {
2109
2194
  this.restService = inject(RestService);
@@ -2147,7 +2232,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImpor
2147
2232
  }]
2148
2233
  }] });
2149
2234
 
2150
- var index$b = /*#__PURE__*/Object.freeze({
2235
+ var index$d = /*#__PURE__*/Object.freeze({
2151
2236
  __proto__: null,
2152
2237
  PageAdminService: PageAdminService
2153
2238
  });
@@ -2171,22 +2256,134 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImpor
2171
2256
  }]
2172
2257
  }] });
2173
2258
 
2174
- var index$a = /*#__PURE__*/Object.freeze({
2259
+ var index$c = /*#__PURE__*/Object.freeze({
2175
2260
  __proto__: null,
2176
2261
  SiteSchemaAdminService: SiteSchemaAdminService
2177
2262
  });
2178
2263
 
2179
- var index$9 = /*#__PURE__*/Object.freeze({
2264
+ class SiteThemeAdminService {
2265
+ constructor() {
2266
+ this.restService = inject(RestService);
2267
+ this.apiName = 'SiteAdmin';
2268
+ this.check = (config) => this.restService.request({
2269
+ method: 'GET',
2270
+ url: '/api/site-admin/theme/check',
2271
+ }, { apiName: this.apiName, ...config });
2272
+ this.deleteFile = (path, config) => this.restService.request({
2273
+ method: 'DELETE',
2274
+ url: '/api/site-admin/theme/files/by-path',
2275
+ params: { path },
2276
+ }, { apiName: this.apiName, ...config });
2277
+ this.get = (config) => this.restService.request({
2278
+ method: 'GET',
2279
+ url: '/api/site-admin/theme',
2280
+ }, { apiName: this.apiName, ...config });
2281
+ this.getFile = (path, config) => this.restService.request({
2282
+ method: 'GET',
2283
+ url: '/api/site-admin/theme/files/by-path',
2284
+ params: { path },
2285
+ }, { apiName: this.apiName, ...config });
2286
+ this.getFileUsages = (path, config) => this.restService.request({
2287
+ method: 'GET',
2288
+ url: '/api/site-admin/theme/files/usages',
2289
+ params: { path },
2290
+ }, { apiName: this.apiName, ...config });
2291
+ this.getFiles = (config) => this.restService.request({
2292
+ method: 'GET',
2293
+ url: '/api/site-admin/theme/files',
2294
+ }, { apiName: this.apiName, ...config });
2295
+ this.getPreviewLink = (path, releaseId, config) => this.restService.request({
2296
+ method: 'GET',
2297
+ url: '/api/site-admin/theme/preview-link',
2298
+ params: { path, releaseId },
2299
+ }, { apiName: this.apiName, ...config });
2300
+ this.getRelease = (id, config) => this.restService.request({
2301
+ method: 'GET',
2302
+ url: `/api/site-admin/theme/releases/${id}`,
2303
+ }, { apiName: this.apiName, ...config });
2304
+ this.getReleaseFile = (id, path, config) => this.restService.request({
2305
+ method: 'GET',
2306
+ url: `/api/site-admin/theme/releases/${id}/files/by-path`,
2307
+ params: { path },
2308
+ }, { apiName: this.apiName, ...config });
2309
+ this.getReleases = (config) => this.restService.request({
2310
+ method: 'GET',
2311
+ url: '/api/site-admin/theme/releases',
2312
+ }, { apiName: this.apiName, ...config });
2313
+ this.preview = (path, releaseId, config) => this.restService.request({
2314
+ method: 'GET',
2315
+ url: '/api/site-admin/theme/preview',
2316
+ params: { path, releaseId },
2317
+ }, { apiName: this.apiName, ...config });
2318
+ this.publish = (input, config) => this.restService.request({
2319
+ method: 'POST',
2320
+ url: '/api/site-admin/theme/publish',
2321
+ body: input,
2322
+ }, { apiName: this.apiName, ...config });
2323
+ this.renameFile = (input, config) => this.restService.request({
2324
+ method: 'POST',
2325
+ url: '/api/site-admin/theme/files/rename',
2326
+ body: input,
2327
+ }, { apiName: this.apiName, ...config });
2328
+ this.restoreRelease = (id, config) => this.restService.request({
2329
+ method: 'POST',
2330
+ url: `/api/site-admin/theme/releases/${id}/restore`,
2331
+ }, { apiName: this.apiName, ...config });
2332
+ this.saveFile = (input, config) => this.restService.request({
2333
+ method: 'PUT',
2334
+ url: '/api/site-admin/theme/files',
2335
+ body: input,
2336
+ }, { apiName: this.apiName, ...config });
2337
+ this.setLiveRelease = (id, config) => this.restService.request({
2338
+ method: 'POST',
2339
+ url: `/api/site-admin/theme/releases/${id}/set-live`,
2340
+ }, { apiName: this.apiName, ...config });
2341
+ this.update = (input, config) => this.restService.request({
2342
+ method: 'PUT',
2343
+ url: '/api/site-admin/theme',
2344
+ body: input,
2345
+ }, { apiName: this.apiName, ...config });
2346
+ }
2347
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: SiteThemeAdminService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2348
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: SiteThemeAdminService, providedIn: 'root' }); }
2349
+ }
2350
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.2", ngImport: i0, type: SiteThemeAdminService, decorators: [{
2351
+ type: Injectable,
2352
+ args: [{
2353
+ providedIn: 'root',
2354
+ }]
2355
+ }] });
2356
+
2357
+ var SiteThemeUsageKindDto;
2358
+ (function (SiteThemeUsageKindDto) {
2359
+ SiteThemeUsageKindDto[SiteThemeUsageKindDto["Page"] = 0] = "Page";
2360
+ SiteThemeUsageKindDto[SiteThemeUsageKindDto["Include"] = 1] = "Include";
2361
+ SiteThemeUsageKindDto[SiteThemeUsageKindDto["AssetUrl"] = 2] = "AssetUrl";
2362
+ SiteThemeUsageKindDto[SiteThemeUsageKindDto["Layout"] = 3] = "Layout";
2363
+ SiteThemeUsageKindDto[SiteThemeUsageKindDto["DefaultLayout"] = 4] = "DefaultLayout";
2364
+ })(SiteThemeUsageKindDto || (SiteThemeUsageKindDto = {}));
2365
+ const siteThemeUsageKindDtoOptions = mapEnumToOptions(SiteThemeUsageKindDto);
2366
+
2367
+ var index$b = /*#__PURE__*/Object.freeze({
2180
2368
  __proto__: null,
2181
- ContentTypes: index$e,
2182
- Contents: index$d,
2183
- Fields: index$c,
2184
- Files: index$h,
2185
- Pages: index$b,
2186
- Schema: index$a
2369
+ SiteThemeAdminService: SiteThemeAdminService,
2370
+ get SiteThemeUsageKindDto () { return SiteThemeUsageKindDto; },
2371
+ siteThemeUsageKindDtoOptions: siteThemeUsageKindDtoOptions
2187
2372
  });
2188
2373
 
2189
- var index$8 = /*#__PURE__*/Object.freeze({
2374
+ var index$a = /*#__PURE__*/Object.freeze({
2375
+ __proto__: null,
2376
+ ContentTypes: index$h,
2377
+ Contents: index$g,
2378
+ Fields: index$f,
2379
+ Files: index$k,
2380
+ Languages: index$e,
2381
+ Pages: index$d,
2382
+ Schema: index$c,
2383
+ Themes: index$b
2384
+ });
2385
+
2386
+ var index$9 = /*#__PURE__*/Object.freeze({
2190
2387
  __proto__: null
2191
2388
  });
2192
2389
 
@@ -2198,32 +2395,57 @@ var ContentStatus;
2198
2395
  })(ContentStatus || (ContentStatus = {}));
2199
2396
  const contentStatusOptions = mapEnumToOptions(ContentStatus);
2200
2397
 
2201
- var index$7 = /*#__PURE__*/Object.freeze({
2398
+ var index$8 = /*#__PURE__*/Object.freeze({
2202
2399
  __proto__: null,
2203
2400
  get ContentStatus () { return ContentStatus; },
2204
2401
  contentStatusOptions: contentStatusOptions
2205
2402
  });
2206
2403
 
2404
+ var index$7 = /*#__PURE__*/Object.freeze({
2405
+ __proto__: null
2406
+ });
2407
+
2207
2408
  var index$6 = /*#__PURE__*/Object.freeze({
2208
2409
  __proto__: null
2209
2410
  });
2210
2411
 
2412
+ var SiteThemeFileStatus;
2413
+ (function (SiteThemeFileStatus) {
2414
+ SiteThemeFileStatus[SiteThemeFileStatus["Unchanged"] = 0] = "Unchanged";
2415
+ SiteThemeFileStatus[SiteThemeFileStatus["Modified"] = 1] = "Modified";
2416
+ SiteThemeFileStatus[SiteThemeFileStatus["Added"] = 2] = "Added";
2417
+ SiteThemeFileStatus[SiteThemeFileStatus["Deleted"] = 3] = "Deleted";
2418
+ })(SiteThemeFileStatus || (SiteThemeFileStatus = {}));
2419
+ const siteThemeFileStatusOptions = mapEnumToOptions(SiteThemeFileStatus);
2420
+
2421
+ var SiteThemeIssueSeverity;
2422
+ (function (SiteThemeIssueSeverity) {
2423
+ SiteThemeIssueSeverity[SiteThemeIssueSeverity["Error"] = 0] = "Error";
2424
+ SiteThemeIssueSeverity[SiteThemeIssueSeverity["Warning"] = 1] = "Warning";
2425
+ })(SiteThemeIssueSeverity || (SiteThemeIssueSeverity = {}));
2426
+ const siteThemeIssueSeverityOptions = mapEnumToOptions(SiteThemeIssueSeverity);
2427
+
2211
2428
  var index$5 = /*#__PURE__*/Object.freeze({
2212
- __proto__: null
2429
+ __proto__: null,
2430
+ get SiteThemeFileStatus () { return SiteThemeFileStatus; },
2431
+ get SiteThemeIssueSeverity () { return SiteThemeIssueSeverity; },
2432
+ siteThemeFileStatusOptions: siteThemeFileStatusOptions,
2433
+ siteThemeIssueSeverityOptions: siteThemeIssueSeverityOptions
2213
2434
  });
2214
2435
 
2215
2436
  var index$4 = /*#__PURE__*/Object.freeze({
2216
2437
  __proto__: null,
2217
- Admin: index$9,
2218
- ContentTypes: index$8,
2219
- Contents: index$7,
2220
- Fields: index$6,
2221
- Pages: index$5
2438
+ Admin: index$a,
2439
+ ContentTypes: index$9,
2440
+ Contents: index$8,
2441
+ Fields: index$7,
2442
+ Pages: index$6,
2443
+ Themes: index$5
2222
2444
  });
2223
2445
 
2224
2446
  var index$3 = /*#__PURE__*/Object.freeze({
2225
2447
  __proto__: null,
2226
- Abp: index$f,
2448
+ Abp: index$i,
2227
2449
  Site: index$4
2228
2450
  });
2229
2451
 
@@ -2414,36 +2636,42 @@ const SITE_ROUTES = [
2414
2636
  },
2415
2637
  {
2416
2638
  path: 'contents',
2417
- loadComponent: () => import('./dignite-ng.site-contents.component-DKuel8w-.mjs').then(c => c.ContentsComponent),
2639
+ loadComponent: () => import('./dignite-ng.site-contents.component-Ch5GYIHE.mjs').then(c => c.ContentsComponent),
2418
2640
  data: { requiredPolicy: eSitePolicyNames.Contents },
2419
2641
  },
2420
2642
  {
2421
2643
  // Editing a content is a page, not a dialog: the left half is a form as long as the content
2422
2644
  // type defines, which a dialog could only scroll.
2423
2645
  path: 'contents/create',
2424
- loadComponent: () => import('./dignite-ng.site-content-editor.component-iFWDeYJ9.mjs').then(c => c.ContentEditorComponent),
2646
+ loadComponent: () => import('./dignite-ng.site-content-editor.component-DA6FaJSU.mjs').then(c => c.ContentEditorComponent),
2425
2647
  data: { requiredPolicy: eSitePolicyNames.ContentsCreate },
2426
2648
  },
2427
2649
  {
2428
2650
  path: 'contents/:id/edit',
2429
- loadComponent: () => import('./dignite-ng.site-content-editor.component-iFWDeYJ9.mjs').then(c => c.ContentEditorComponent),
2651
+ loadComponent: () => import('./dignite-ng.site-content-editor.component-DA6FaJSU.mjs').then(c => c.ContentEditorComponent),
2430
2652
  data: { requiredPolicy: eSitePolicyNames.ContentsUpdate },
2431
2653
  },
2432
2654
  {
2433
2655
  path: 'pages',
2434
- loadComponent: () => import('./dignite-ng.site-pages.component-S9BEgC4W.mjs').then(c => c.PagesComponent),
2656
+ loadComponent: () => import('./dignite-ng.site-pages.component-BwGyK7jw.mjs').then(c => c.PagesComponent),
2435
2657
  data: { requiredPolicy: eSitePolicyNames.Pages },
2436
2658
  },
2437
2659
  {
2438
2660
  path: 'pages/:pageId/content-types',
2439
- loadComponent: () => import('./dignite-ng.site-content-types.component-D2jMSSq6.mjs').then(c => c.ContentTypesComponent),
2661
+ loadComponent: () => import('./dignite-ng.site-content-types.component-Dnqe8A4t.mjs').then(c => c.ContentTypesComponent),
2440
2662
  data: { requiredPolicy: eSitePolicyNames.ContentTypes },
2441
2663
  },
2442
2664
  {
2443
2665
  path: 'fields',
2444
- loadComponent: () => import('./dignite-ng.site-fields.component-By_YyfIx.mjs').then(c => c.FieldsComponent),
2666
+ loadComponent: () => import('./dignite-ng.site-fields.component-BaK27N9k.mjs').then(c => c.FieldsComponent),
2445
2667
  data: { requiredPolicy: eSitePolicyNames.Fields },
2446
2668
  },
2669
+ {
2670
+ // The theme is edited on a page of its own: a file tree, a code editor and the check side by side.
2671
+ path: 'theme',
2672
+ loadComponent: () => import('./dignite-ng.site-theme-workbench.component-CA47DnTj.mjs').then(c => c.ThemeWorkbenchComponent),
2673
+ data: { requiredPolicy: eSitePolicyNames.Themes },
2674
+ },
2447
2675
  ],
2448
2676
  },
2449
2677
  ];
@@ -2460,5 +2688,5 @@ const SITE_ROUTES = [
2460
2688
  * Generated bundle index. Do not edit.
2461
2689
  */
2462
2690
 
2463
- export { sizedFileUrl as $, FormatFileSizePipe as A, SEO_FIELD_TYPE as B, ContentAdminService as C, SEO_FIELD_TYPE_NAME as D, SITE_FILE_CONTAINER_NAMES as E, FlexFieldQueryOperator as F, SITE_FILE_PATH as G, SITE_IMAGES_CONTAINER_NAME as H, IMAGE_TYPE_OPTIONS as I, SITE_ROUTES as J, SeoConfigComponent as K, SeoConfiguration as L, MY_FILES_NODE_KEY as M, SeoControlComponent as N, ObjectUrlService as O, PageAdminService as P, SeoViewComponent as Q, SiteCKEditorUploadProvider as R, SiteReferenceDataService as S, SiteFileUrlService as T, index as U, ValidatorsService as V, absoluteFileUrl as W, isMyFilesNode as X, isSiteFileUrl as Y, siteCKEditorConfigContributor as Z, siteCKEditorDisplayContributor as _, ContentQueryService as a, toContentListParams as a0, ContentListStateService as b, ContentTypeAdminService as c, ContentStatus as d, eSitePolicyNames as e, FlexFieldValueType as f, FieldAdminService as g, CONTENT_FIELD_TYPE as h, CONTENT_FIELD_TYPE_NAME as i, ContentConfigComponent as j, ContentConfiguration as k, ContentControlComponent as l, ContentViewComponent as m, index$3 as n, FILE_FIELD_CONFIGURATION_NAMES as o, FILE_FIELD_TYPE as p, FILE_FIELD_TYPE_NAME as q, FileConfigComponent as r, FileControlComponent as s, FileDirectoryTreeComponent as t, FileFieldConfiguration as u, FileModalComponent as v, FilePickerComponent as w, FilePreviewComponent as x, FileUploadComponent as y, FileViewComponent as z };
2464
- //# sourceMappingURL=dignite-ng.site-dignite-ng.site-CsKxqjY9.mjs.map
2691
+ export { isMyFilesNode as $, FilePickerComponent as A, FilePreviewComponent as B, ContentAdminService as C, FileUploadComponent as D, FileViewComponent as E, FlexFieldQueryOperator as F, FormatFileSizePipe as G, SEO_FIELD_TYPE as H, IMAGE_TYPE_OPTIONS as I, SEO_FIELD_TYPE_NAME as J, SITE_FILE_CONTAINER_NAMES as K, SITE_FILE_PATH as L, MY_FILES_NODE_KEY as M, SITE_IMAGES_CONTAINER_NAME as N, ObjectUrlService as O, PageAdminService as P, SITE_ROUTES as Q, SeoConfigComponent as R, SiteReferenceDataService as S, SeoConfiguration as T, SeoControlComponent as U, SeoViewComponent as V, SiteCKEditorUploadProvider as W, SiteFileUrlService as X, ValidatorsService as Y, index as Z, absoluteFileUrl as _, ContentQueryService as a, isSiteFileUrl as a0, relativeFileUrl as a1, siteCKEditorConfigContributor as a2, siteCKEditorDisplayContributor as a3, sizedFileUrl as a4, toContentListParams as a5, ContentListStateService as b, ContentTypeAdminService as c, ContentStatus as d, eSitePolicyNames as e, FlexFieldValueType as f, SiteThemeAdminService as g, SiteThemeFileStatus as h, FieldAdminService as i, SiteThemeIssueSeverity as j, SiteThemeUsageKindDto as k, CONTENT_FIELD_TYPE as l, CONTENT_FIELD_TYPE_NAME as m, ContentConfigComponent as n, ContentConfiguration as o, ContentControlComponent as p, ContentViewComponent as q, index$3 as r, FILE_FIELD_CONFIGURATION_NAMES as s, FILE_FIELD_TYPE as t, FILE_FIELD_TYPE_NAME as u, FileConfigComponent as v, FileControlComponent as w, FileDirectoryTreeComponent as x, FileFieldConfiguration as y, FileModalComponent as z };
2692
+ //# sourceMappingURL=dignite-ng.site-dignite-ng.site-BMcNABSG.mjs.map