@vendure/admin-ui 2.0.0 → 2.0.1

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 (70) hide show
  1. package/catalog/components/product-options-editor/product-options-editor.component.d.ts +6 -0
  2. package/core/common/base-detail.component.d.ts +28 -0
  3. package/core/common/version.d.ts +1 -1
  4. package/core/data/providers/interceptor.d.ts +11 -1
  5. package/core/providers/page/page.service.d.ts +7 -0
  6. package/esm2022/catalog/catalog.module.mjs +2 -2
  7. package/esm2022/catalog/components/create-product-variant-dialog/create-product-variant-dialog.component.mjs +3 -3
  8. package/esm2022/catalog/components/product-options-editor/product-options-editor.component.mjs +13 -5
  9. package/esm2022/core/common/base-detail.component.mjs +29 -1
  10. package/esm2022/core/common/base-list.component.mjs +1 -1
  11. package/esm2022/core/common/component-registry-types.mjs +1 -1
  12. package/esm2022/core/common/title-setter.mjs +1 -1
  13. package/esm2022/core/common/version.mjs +2 -2
  14. package/esm2022/core/data/providers/interceptor.mjs +32 -11
  15. package/esm2022/core/providers/bulk-action-registry/bulk-action-types.mjs +1 -1
  16. package/esm2022/core/providers/custom-field-component/custom-field-component.service.mjs +1 -1
  17. package/esm2022/core/providers/local-storage/local-storage.service.mjs +1 -4
  18. package/esm2022/core/providers/page/page.service.mjs +5 -2
  19. package/esm2022/core/shared/components/action-bar-items/action-bar-items.component.mjs +1 -1
  20. package/esm2022/core/shared/components/asset-file-input/asset-file-input.component.mjs +1 -1
  21. package/esm2022/core/shared/components/assign-to-channel-dialog/assign-to-channel-dialog.component.mjs +1 -1
  22. package/esm2022/core/shared/components/currency-code-selector/currency-code-selector.component.mjs +1 -1
  23. package/esm2022/core/shared/components/data-table/data-table.component.mjs +1 -1
  24. package/esm2022/core/shared/components/language-code-selector/language-code-selector.component.mjs +1 -1
  25. package/esm2022/core/shared/components/select-toggle/select-toggle.component.mjs +3 -3
  26. package/esm2022/core/shared/dynamic-form-inputs/register-dynamic-input-components.mjs +1 -1
  27. package/esm2022/core/shared/pipes/state-i18n-token.pipe.mjs +1 -1
  28. package/esm2022/customer/components/address-card/address-card.component.mjs +3 -3
  29. package/esm2022/customer/components/customer-list/customer-list.component.mjs +14 -10
  30. package/esm2022/customer/customer.module.mjs +1 -1
  31. package/esm2022/customer/customer.routes.mjs +2 -2
  32. package/esm2022/dashboard/components/dashboard/dashboard.component.mjs +1 -1
  33. package/esm2022/marketing/marketing.module.mjs +1 -1
  34. package/esm2022/order/components/add-manual-payment-dialog/add-manual-payment-dialog.component.mjs +3 -3
  35. package/esm2022/order/components/draft-order-detail/draft-order-detail.component.mjs +3 -3
  36. package/esm2022/order/components/order-detail/order-detail.component.mjs +2 -4
  37. package/esm2022/order/components/select-customer-dialog/select-customer-dialog.component.mjs +3 -3
  38. package/esm2022/order/order.module.mjs +1 -1
  39. package/esm2022/order/order.routes.mjs +1 -1
  40. package/esm2022/settings/components/channel-detail/channel-detail.component.mjs +2 -3
  41. package/esm2022/settings/components/tax-rate-detail/tax-rate-detail.component.mjs +8 -8
  42. package/esm2022/settings/settings.module.mjs +1 -1
  43. package/fesm2022/vendure-admin-ui-catalog.mjs +15 -7
  44. package/fesm2022/vendure-admin-ui-catalog.mjs.map +1 -1
  45. package/fesm2022/vendure-admin-ui-core.mjs +65 -16
  46. package/fesm2022/vendure-admin-ui-core.mjs.map +1 -1
  47. package/fesm2022/vendure-admin-ui-customer.mjs +16 -12
  48. package/fesm2022/vendure-admin-ui-customer.mjs.map +1 -1
  49. package/fesm2022/vendure-admin-ui-dashboard.mjs.map +1 -1
  50. package/fesm2022/vendure-admin-ui-marketing.mjs.map +1 -1
  51. package/fesm2022/vendure-admin-ui-order.mjs +7 -9
  52. package/fesm2022/vendure-admin-ui-order.mjs.map +1 -1
  53. package/fesm2022/vendure-admin-ui-settings.mjs +8 -9
  54. package/fesm2022/vendure-admin-ui-settings.mjs.map +1 -1
  55. package/package.json +14 -14
  56. package/static/i18n-messages/cs.json +770 -768
  57. package/static/i18n-messages/de.json +771 -769
  58. package/static/i18n-messages/en.json +771 -769
  59. package/static/i18n-messages/es.json +770 -768
  60. package/static/i18n-messages/fr.json +770 -768
  61. package/static/i18n-messages/it.json +770 -768
  62. package/static/i18n-messages/pl.json +770 -768
  63. package/static/i18n-messages/pt_BR.json +770 -768
  64. package/static/i18n-messages/pt_PT.json +770 -768
  65. package/static/i18n-messages/ru.json +770 -768
  66. package/static/i18n-messages/uk.json +770 -768
  67. package/static/i18n-messages/zh_Hans.json +770 -768
  68. package/static/i18n-messages/zh_Hant.json +770 -768
  69. package/static/styles/global/_buttons.scss +24 -0
  70. package/static/theme.min.css +1 -1
@@ -6362,9 +6362,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImpor
6362
6362
  */
6363
6363
  const ADMIN_SPECIFIC_KEYS = [
6364
6364
  'activeTheme',
6365
- 'uiLanguageCode',
6366
- 'uiLocale',
6367
- 'contentLanguageCode',
6368
6365
  'dashboardWidgetLayout',
6369
6366
  'activeTheme',
6370
6367
  'livePreviewCollectionContents',
@@ -10213,21 +10210,25 @@ class DefaultInterceptor {
10213
10210
  else {
10214
10211
  // GraphQL errors still return 200 OK responses, but have the actual error message
10215
10212
  // inside the body of the response.
10216
- const graqhQLErrors = response.body.errors;
10217
- if (graqhQLErrors && Array.isArray(graqhQLErrors)) {
10218
- const firstCode = graqhQLErrors[0]?.extensions?.code;
10213
+ const graphQLErrors = response.body.errors;
10214
+ if (graphQLErrors && Array.isArray(graphQLErrors)) {
10215
+ const firstCode = graphQLErrors[0]?.extensions?.code;
10219
10216
  if (firstCode === 'FORBIDDEN') {
10220
10217
  this.authService.logOut().subscribe(() => {
10221
10218
  const { loginUrl } = getAppConfig();
10222
- if (loginUrl) {
10219
+ // If there is a `loginUrl` which is external to the AdminUI, redirect to it (with no query parameters)
10220
+ if (loginUrl && !this.areUrlsOnSameOrigin(loginUrl, window.location.origin)) {
10223
10221
  window.location.href = loginUrl;
10224
10222
  return;
10225
10223
  }
10226
- if (!window.location.pathname.includes('login')) {
10227
- const path = graqhQLErrors[0].path.join(' > ');
10224
+ // Else, we build the login path from the login url if one is provided or fallback to `/login`
10225
+ const loginPath = loginUrl ? this.getPathFromLoginUrl(loginUrl) : '/login';
10226
+ if (!window.location.pathname.includes(loginPath)) {
10227
+ const path = graphQLErrors[0].path.join(' > ');
10228
10228
  this.displayErrorNotification(marker(`error.403-forbidden`), { path });
10229
10229
  }
10230
- this.router.navigate(['/login'], {
10230
+ // Navigate to the `loginPath` route by ensuring the query param in charge of the redirection is provided
10231
+ this.router.navigate([loginPath], {
10231
10232
  queryParams: {
10232
10233
  [AUTH_REDIRECT_PARAM]: btoa(this.router.url),
10233
10234
  },
@@ -10235,12 +10236,12 @@ class DefaultInterceptor {
10235
10236
  });
10236
10237
  }
10237
10238
  else if (firstCode === 'CHANNEL_NOT_FOUND') {
10238
- const message = graqhQLErrors.map(err => err.message).join('\n');
10239
+ const message = graphQLErrors.map(err => err.message).join('\n');
10239
10240
  this.displayErrorNotification(message);
10240
10241
  this.localStorageService.remove('activeChannelToken');
10241
10242
  }
10242
10243
  else {
10243
- const message = graqhQLErrors.map(err => err.message).join('\n');
10244
+ const message = graphQLErrors.map(err => err.message).join('\n');
10244
10245
  this.displayErrorNotification(message);
10245
10246
  }
10246
10247
  }
@@ -10276,6 +10277,23 @@ class DefaultInterceptor {
10276
10277
  }
10277
10278
  }
10278
10279
  }
10280
+ /**
10281
+ * Determine if two urls are on the same origin.
10282
+ */
10283
+ areUrlsOnSameOrigin(urlA, urlB) {
10284
+ return new URL(urlA).origin === new URL(urlB).origin;
10285
+ }
10286
+ /**
10287
+ * If the provided `loginUrl` is on the same origin than the AdminUI, return the path
10288
+ * after the `/admin`.
10289
+ * Else, return the whole login url.
10290
+ */
10291
+ getPathFromLoginUrl(loginUrl) {
10292
+ if (!this.areUrlsOnSameOrigin(loginUrl, window.location.origin)) {
10293
+ return loginUrl;
10294
+ }
10295
+ return loginUrl.split('/admin')[1];
10296
+ }
10279
10297
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: DefaultInterceptor, deps: [{ token: DataService }, { token: i0.Injector }, { token: AuthService }, { token: i1$2.Router }, { token: LocalStorageService }], target: i0.ɵɵFactoryTarget.Injectable }); }
10280
10298
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: DefaultInterceptor }); }
10281
10299
  }
@@ -12441,11 +12459,11 @@ class SelectToggleComponent {
12441
12459
  this.selectedChange = new EventEmitter();
12442
12460
  }
12443
12461
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: SelectToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12444
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.3", type: SelectToggleComponent, selector: "vdr-select-toggle", inputs: { size: "size", selected: "selected", hiddenWhenOff: "hiddenWhenOff", disabled: "disabled", label: "label" }, outputs: { selectedChange: "selectedChange" }, ngImport: i0, template: "<div\r\n class=\"toggle\"\r\n [class.hide-when-off]=\"hiddenWhenOff\"\r\n [class.disabled]=\"disabled\"\r\n [class.small]=\"size === 'small'\"\r\n [attr.tabindex]=\"disabled ? null : 0\"\r\n [class.selected]=\"selected\"\r\n (keydown.enter)=\"selectedChange.emit(!selected)\"\r\n (keydown.space)=\"$event.preventDefault(); selectedChange.emit(!selected)\"\r\n (click)=\"selectedChange.emit(!selected)\"\r\n>\r\n <clr-icon shape=\"check-circle\" [attr.size]=\"size === 'small' ? 24 : 32\"></clr-icon>\r\n</div>\r\n<div class=\"toggle-label\" [class.disabled]=\"disabled\" *ngIf=\"label\" (click)=\"selectedChange.emit(!selected)\">\r\n {{ label }}\r\n</div>\r\n", styles: [":host{display:flex;align-items:center;justify-content:center}.toggle{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer;color:var(--color-grey-300);background-color:var(--color-component-bg-100);border-radius:50%;top:-12px;left:-12px;transition:opacity .2s,color .2s}.toggle.hide-when-off{opacity:0}.toggle.small{width:24px;height:24px}.toggle:not(.disabled):hover{color:var(--color-success-400);opacity:.9}.toggle.selected{opacity:1;color:var(--color-success-500)}.toggle.selected:not(.disabled):hover{color:var(--color-success-400);opacity:.9}.toggle:focus{outline:none;box-shadow:0 0 2px 2px var(--color-primary-500)}.toggle.disabled{cursor:default}.toggle-label{flex:1;margin-left:6px;text-align:left;font-size:12px}.toggle-label:not(.disabled){cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i1$4.ClrIconCustomTag, selector: "clr-icon" }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12462
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.3", type: SelectToggleComponent, selector: "vdr-select-toggle", inputs: { size: "size", selected: "selected", hiddenWhenOff: "hiddenWhenOff", disabled: "disabled", label: "label" }, outputs: { selectedChange: "selectedChange" }, ngImport: i0, template: "<div\r\n class=\"toggle\"\r\n [class.hide-when-off]=\"hiddenWhenOff\"\r\n [class.disabled]=\"disabled\"\r\n [class.small]=\"size === 'small'\"\r\n [attr.tabindex]=\"disabled ? null : 0\"\r\n [class.selected]=\"selected\"\r\n (keydown.enter)=\"selectedChange.emit(!selected)\"\r\n (keydown.space)=\"$event.preventDefault(); selectedChange.emit(!selected)\"\r\n (click)=\"selectedChange.emit(!selected)\"\r\n>\r\n <clr-icon\r\n shape=\"check-circle\"\r\n [class.is-solid]=\"selected\"\r\n [attr.size]=\"size === 'small' ? 24 : 32\"\r\n ></clr-icon>\r\n</div>\r\n<div\r\n class=\"toggle-label\"\r\n [class.selected]=\"selected\"\r\n [class.disabled]=\"disabled\"\r\n *ngIf=\"label\"\r\n (click)=\"selectedChange.emit(!selected)\"\r\n>\r\n {{ label }}\r\n</div>\r\n", styles: [":host{display:flex;align-items:center;justify-content:center}.toggle{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer;color:var(--color-grey-300);background-color:var(--color-component-bg-100);border-radius:50%;top:-12px;left:-12px;transition:opacity .1s,color .1s}.toggle.hide-when-off{opacity:0}.toggle.small{width:24px;height:24px}.toggle:not(.disabled):hover{color:var(--color-success-600);opacity:.9}.toggle.selected{opacity:1;color:var(--color-success-700)}.toggle.selected:not(.disabled):hover{color:var(--color-success-600);opacity:.9}.toggle:focus{outline:none;box-shadow:0 0 2px 2px var(--color-primary-700)}.toggle.disabled{cursor:default}.toggle-label{flex:1;margin-left:6px;text-align:left;font-size:12px}.toggle-label:not(.disabled){cursor:pointer}.toggle-label.selected{color:var(--color-success-800)}\n"], dependencies: [{ kind: "directive", type: i1$4.ClrIconCustomTag, selector: "clr-icon" }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12445
12463
  }
12446
12464
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: SelectToggleComponent, decorators: [{
12447
12465
  type: Component,
12448
- args: [{ selector: 'vdr-select-toggle', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"toggle\"\r\n [class.hide-when-off]=\"hiddenWhenOff\"\r\n [class.disabled]=\"disabled\"\r\n [class.small]=\"size === 'small'\"\r\n [attr.tabindex]=\"disabled ? null : 0\"\r\n [class.selected]=\"selected\"\r\n (keydown.enter)=\"selectedChange.emit(!selected)\"\r\n (keydown.space)=\"$event.preventDefault(); selectedChange.emit(!selected)\"\r\n (click)=\"selectedChange.emit(!selected)\"\r\n>\r\n <clr-icon shape=\"check-circle\" [attr.size]=\"size === 'small' ? 24 : 32\"></clr-icon>\r\n</div>\r\n<div class=\"toggle-label\" [class.disabled]=\"disabled\" *ngIf=\"label\" (click)=\"selectedChange.emit(!selected)\">\r\n {{ label }}\r\n</div>\r\n", styles: [":host{display:flex;align-items:center;justify-content:center}.toggle{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer;color:var(--color-grey-300);background-color:var(--color-component-bg-100);border-radius:50%;top:-12px;left:-12px;transition:opacity .2s,color .2s}.toggle.hide-when-off{opacity:0}.toggle.small{width:24px;height:24px}.toggle:not(.disabled):hover{color:var(--color-success-400);opacity:.9}.toggle.selected{opacity:1;color:var(--color-success-500)}.toggle.selected:not(.disabled):hover{color:var(--color-success-400);opacity:.9}.toggle:focus{outline:none;box-shadow:0 0 2px 2px var(--color-primary-500)}.toggle.disabled{cursor:default}.toggle-label{flex:1;margin-left:6px;text-align:left;font-size:12px}.toggle-label:not(.disabled){cursor:pointer}\n"] }]
12466
+ args: [{ selector: 'vdr-select-toggle', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"toggle\"\r\n [class.hide-when-off]=\"hiddenWhenOff\"\r\n [class.disabled]=\"disabled\"\r\n [class.small]=\"size === 'small'\"\r\n [attr.tabindex]=\"disabled ? null : 0\"\r\n [class.selected]=\"selected\"\r\n (keydown.enter)=\"selectedChange.emit(!selected)\"\r\n (keydown.space)=\"$event.preventDefault(); selectedChange.emit(!selected)\"\r\n (click)=\"selectedChange.emit(!selected)\"\r\n>\r\n <clr-icon\r\n shape=\"check-circle\"\r\n [class.is-solid]=\"selected\"\r\n [attr.size]=\"size === 'small' ? 24 : 32\"\r\n ></clr-icon>\r\n</div>\r\n<div\r\n class=\"toggle-label\"\r\n [class.selected]=\"selected\"\r\n [class.disabled]=\"disabled\"\r\n *ngIf=\"label\"\r\n (click)=\"selectedChange.emit(!selected)\"\r\n>\r\n {{ label }}\r\n</div>\r\n", styles: [":host{display:flex;align-items:center;justify-content:center}.toggle{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer;color:var(--color-grey-300);background-color:var(--color-component-bg-100);border-radius:50%;top:-12px;left:-12px;transition:opacity .1s,color .1s}.toggle.hide-when-off{opacity:0}.toggle.small{width:24px;height:24px}.toggle:not(.disabled):hover{color:var(--color-success-600);opacity:.9}.toggle.selected{opacity:1;color:var(--color-success-700)}.toggle.selected:not(.disabled):hover{color:var(--color-success-600);opacity:.9}.toggle:focus{outline:none;box-shadow:0 0 2px 2px var(--color-primary-700)}.toggle.disabled{cursor:default}.toggle-label{flex:1;margin-left:6px;text-align:left;font-size:12px}.toggle-label:not(.disabled){cursor:pointer}.toggle-label.selected{color:var(--color-success-800)}\n"] }]
12449
12467
  }], propDecorators: { size: [{
12450
12468
  type: Input
12451
12469
  }], selected: [{
@@ -18209,7 +18227,7 @@ class PageService {
18209
18227
  if (isComponentWithResolver(config.component)) {
18210
18228
  const { component: cmp, breadcrumbFn, resolveFn } = config.component;
18211
18229
  component = cmp;
18212
- route.resolve = { detail: config.component.resolveFn };
18230
+ route.resolve = { detail: resolveFn };
18213
18231
  route.data = {
18214
18232
  breadcrumb: data => data.detail.entity.pipe(map(entity => breadcrumbFn(entity))),
18215
18233
  };
@@ -18220,6 +18238,9 @@ class PageService {
18220
18238
  const guards = typeof component.prototype.canDeactivate === 'function' ? [CanDeactivateDetailGuard] : [];
18221
18239
  route.component = component;
18222
18240
  route.canDeactivate = guards;
18241
+ if (config.routeConfig) {
18242
+ Object.assign(route, config.routeConfig);
18243
+ }
18223
18244
  return route;
18224
18245
  });
18225
18246
  }
@@ -19884,6 +19905,34 @@ class TypedBaseDetailComponent extends BaseDetailComponent {
19884
19905
  this.setUpStreams();
19885
19906
  }
19886
19907
  }
19908
+ /**
19909
+ * @description
19910
+ * A helper function for creating tabs that point to a {@link TypedBaseDetailComponent}. This takes
19911
+ * care of the route resolver parts so that the detail component automatically has access to the
19912
+ * correct resolved detail data.
19913
+ *
19914
+ * @example
19915
+ * ```TypeScript
19916
+ * \@NgModule({
19917
+ * imports: [ReviewsSharedModule],
19918
+ * declarations: [/* ... *\/],
19919
+ * providers: [
19920
+ * registerPageTab({
19921
+ * location: 'product-detail',
19922
+ * tab: 'Specs',
19923
+ * route: 'specs',
19924
+ * component: detailComponentWithResolver({
19925
+ * component: ProductSpecDetailComponent,
19926
+ * query: GetProductSpecsDocument,
19927
+ * entityKey: 'spec',
19928
+ * }),
19929
+ * }),
19930
+ * ],
19931
+ * })
19932
+ * export class ProductSpecsUiExtensionModule {}
19933
+ * ```
19934
+ * @docsCategory list-detail-views
19935
+ */
19887
19936
  function detailComponentWithResolver(config) {
19888
19937
  const resolveFn = (route, state) => {
19889
19938
  const router = inject(Router);
@@ -20972,7 +21021,7 @@ function patchObject(obj, patch) {
20972
21021
  }
20973
21022
 
20974
21023
  // Auto-generated by the set-version.js script.
20975
- const ADMIN_UI_VERSION = '2.0.0';
21024
+ const ADMIN_UI_VERSION = '2.0.1';
20976
21025
 
20977
21026
  /**
20978
21027
  * @description