@c8y/ngx-components 1017.0.75 → 1017.0.77

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.
@@ -6177,12 +6177,17 @@ class TenantUiService {
6177
6177
  * @returns True, if current tenant is an enterprise tenant.
6178
6178
  */
6179
6179
  async isEnterpriseTenant() {
6180
- const hasBranding = (await this.hasApp({ name: 'branding' })) ||
6181
- (await this.hasApp({ name: 'feature-branding' }));
6182
- const hasSslManagement = await this.hasApp({ name: 'sslmanagement' });
6183
- const hasUserHierarchy = await this.hasApp({ name: 'feature-user-hierarchy' });
6184
- const hasDataBroker = await this.hasApp({ name: 'feature-broker' });
6185
- return hasBranding && hasSslManagement && hasUserHierarchy && hasDataBroker;
6180
+ const { data: availableAppsOfUser } = await this.applicationService.listByUser(this.appStateService.currentUser.value, {
6181
+ dropOverwrittenApps: true,
6182
+ noPaging: true
6183
+ });
6184
+ const brandingAvailable = this.hasApp(availableAppsOfUser, 'branding') ||
6185
+ this.hasApp(availableAppsOfUser, 'feature-branding');
6186
+ const requiredAppsAndFeaturesAvailable = brandingAvailable &&
6187
+ this.hasApp(availableAppsOfUser, 'sslmanagement') &&
6188
+ this.hasApp(availableAppsOfUser, 'feature-user-hierarchy') &&
6189
+ this.hasApp(availableAppsOfUser, 'feature-broker');
6190
+ return requiredAppsAndFeaturesAvailable;
6186
6191
  }
6187
6192
  /**
6188
6193
  * Checks whether the current user has read access to tenants, i.e.:
@@ -6353,8 +6358,11 @@ class TenantUiService {
6353
6358
  .map(appRef => appRef.application)
6354
6359
  .filter(app => app.type === ApplicationType.MICROSERVICE);
6355
6360
  }
6356
- async hasApp(app) {
6357
- return (await this.applicationService.isAvailable(app)).data;
6361
+ hasApp(apps, requiredAppName) {
6362
+ if (!apps?.length) {
6363
+ return false;
6364
+ }
6365
+ return apps.some(app => app.name === requiredAppName);
6358
6366
  }
6359
6367
  isManagement(currentTenant) {
6360
6368
  return currentTenant.name === this.MANAGEMENT;
@@ -9058,12 +9066,28 @@ class DocsService {
9058
9066
  /**
9059
9067
  * Default documentation URL.
9060
9068
  */
9061
- this.DEFAULT_DOCS_BASE_URL = 'https://www.cumulocity.com/guides';
9069
+ this.DEFAULT_DOCS_BASE_URL = 'https://www.cumulocity.com/guides/{{ version }}';
9062
9070
  const supportUrlRefreshTrigger = this.app.map(({ supportUrl }) => supportUrl);
9063
9071
  this.items$ = fromTriggerOnce(router, [supportUrlRefreshTrigger, this.refreshTrigger], [getInjectedHooks(HOOK_DOCS, this.injectors), () => this.factories, this]).pipe(shareReplay(1), distinctUntilChanged());
9064
9072
  }
9065
- getBaseUrl() {
9066
- return this.options.get('docsBaseUrl', this.DEFAULT_DOCS_BASE_URL);
9073
+ getBaseUrl(uiVersion) {
9074
+ const docsBaseUrl = this.options.get('docsBaseUrl', this.DEFAULT_DOCS_BASE_URL);
9075
+ return this.getUrlWithDocsVersion(docsBaseUrl, uiVersion);
9076
+ }
9077
+ /**
9078
+ * Takes a URL and replaces all `{{ version }}` placeholders with the relevant docs version
9079
+ * (the version is derived from the app state or from the provided parameter).
9080
+ * @param url Any URL that contains `{{ version }}` placeholders.
9081
+ * @param uiVersion A version string or object, defaults to the app state version.
9082
+ * @returns The URL with replaced `{{ version }}` placeholders.
9083
+ */
9084
+ getUrlWithDocsVersion(url, uiVersion = this.app.uiVersion) {
9085
+ const version = typeof uiVersion === 'string' ? uiVersion : get(uiVersion, 'ngx');
9086
+ let docsVersion = '';
9087
+ if (!(isUndefined(version) || version === '')) {
9088
+ docsVersion = this.getDocsVersionForUiVersion(version);
9089
+ }
9090
+ return url.replace(/{{\s*version\s*}}/g, docsVersion).replace(/\/+$/g, '');
9067
9091
  }
9068
9092
  get templateStr() {
9069
9093
  return this.options.get('guideHrefTemplate', '${docsBaseUrl}${partialUrl}');
@@ -9127,6 +9151,22 @@ class DocsService {
9127
9151
  const prefix = shouldPrefix ? '/' : '';
9128
9152
  return `${prefix}${partialLink}`;
9129
9153
  }
9154
+ /**
9155
+ * Returns the most relevant version of documentation for the given version of UI.
9156
+ * For maintenance versions, it's the first version in the line, e.g. 1017.0.123 -> 10.17.0.
9157
+ * For develop versions, it's the next minor one, e.g. 1017.123.0-SNAPSHOT -> 10.18.0.
9158
+ *
9159
+ * @param uiVersion The version of UI.
9160
+ * @private
9161
+ */
9162
+ getDocsVersionForUiVersion(uiVersion) {
9163
+ const [majorMinorStr, patchStr] = uiVersion.split('.');
9164
+ const patchNumber = parseInt(patchStr, 10);
9165
+ const takeNextMinor = patchNumber > 0;
9166
+ const majorNumber = Math.floor(parseInt(majorMinorStr, 10) / 100);
9167
+ const minorNumber = parseInt(majorMinorStr, 10) - majorNumber * 100 + (takeNextMinor ? 1 : 0);
9168
+ return `${majorNumber}.${minorNumber}.0`;
9169
+ }
9130
9170
  }
9131
9171
  DocsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: DocsService, deps: [{ token: OptionsService }, { token: AppStateService }, { token: i0.Injector }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Injectable });
9132
9172
  DocsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: DocsService, providedIn: 'root' });
@@ -25173,9 +25213,8 @@ class HelpComponent {
25173
25213
  /**
25174
25214
  * @ignore Only private DI
25175
25215
  */
25176
- constructor(docsService, appState, helpService) {
25216
+ constructor(docsService, helpService) {
25177
25217
  this.docsService = docsService;
25178
- this.appState = appState;
25179
25218
  this.helpService = helpService;
25180
25219
  /**
25181
25220
  * The source of the documentation. Used to link to the documentation as well as
@@ -25191,13 +25230,7 @@ class HelpComponent {
25191
25230
  */
25192
25231
  this.priority = Infinity;
25193
25232
  /**
25194
- * Currrent version of the UI which will be used to get the correct data from
25195
- * the docs. If the UI version is equal to the latest doc version, the value
25196
- * must be ''.
25197
- */
25198
- this.version = this.parseVersion(this.appState.uiVersion);
25199
- /**
25200
- * An title. Set in open by passing the source.
25233
+ * A title. Set in open by passing the source.
25201
25234
  */
25202
25235
  this.title = '';
25203
25236
  /**
@@ -25243,23 +25276,19 @@ class HelpComponent {
25243
25276
  try {
25244
25277
  docsUrl =
25245
25278
  typeof this.helpService.contextHelp.value === 'string'
25246
- ? new URL(this.helpService.contextHelp.value)
25279
+ ? new URL(this.docsService.getUrlWithDocsVersion(this.helpService.contextHelp.value))
25247
25280
  : new URL(this.docsService.getBaseUrl());
25248
25281
  }
25249
25282
  catch (error) {
25250
- docsUrl = new URL(this.docsService.DEFAULT_DOCS_BASE_URL);
25283
+ docsUrl = new URL(this.docsService.getBaseUrl());
25251
25284
  console.warn(error);
25252
25285
  }
25253
- const srcUrl = new URL(`${docsUrl}${src}`);
25254
25286
  const [url, hashFragment] = src.split('#');
25255
25287
  this.sectionHeading = hashFragment;
25256
25288
  if (index) {
25257
25289
  src = `${url}index.json`;
25258
25290
  }
25259
- if (this.version === '') {
25260
- return index ? `${docsUrl.href + src}` : srcUrl.href;
25261
- }
25262
- return `${docsUrl.href}/${this.version}${src}`;
25291
+ return `${docsUrl.href}${src}`;
25263
25292
  }
25264
25293
  /**
25265
25294
  * Toggles the visibility of the help dialog.
@@ -25303,19 +25332,6 @@ class HelpComponent {
25303
25332
  this.hasError = false;
25304
25333
  this.sectionContent = '';
25305
25334
  }
25306
- parseVersion(uiVersion) {
25307
- const version = typeof uiVersion === 'string' ? uiVersion : get(uiVersion, 'ngx');
25308
- if (isUndefined(version)) {
25309
- return undefined;
25310
- }
25311
- if (version === '') {
25312
- return '';
25313
- }
25314
- const versionToParse = version.split('.').shift();
25315
- const majorNumber = Math.floor(parseInt(versionToParse, 10) / 100);
25316
- const minorNumber = parseInt(versionToParse, 10) - majorNumber * 100;
25317
- return `${majorNumber}.${minorNumber}.0`;
25318
- }
25319
25335
  resolveIcon() {
25320
25336
  try {
25321
25337
  const icon = Array.from(document.querySelector('nav .active i').classList).find(classes => classes.startsWith('c8y-icon-') || classes.startsWith('dlt-c8y-icon-'));
@@ -25328,10 +25344,6 @@ class HelpComponent {
25328
25344
  render(req) {
25329
25345
  if (req.readyState === 4) {
25330
25346
  this.isLoading = false;
25331
- if (req.status === 404 && this.version !== '') {
25332
- this.version = '';
25333
- this.open();
25334
- }
25335
25347
  if (req.status === 200) {
25336
25348
  this.hasError = false;
25337
25349
  const sectionData = req.response[this.sectionHeading];
@@ -25346,12 +25358,12 @@ class HelpComponent {
25346
25358
  }
25347
25359
  }
25348
25360
  }
25349
- HelpComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: HelpComponent, deps: [{ token: DocsService }, { token: AppStateService }, { token: HelpService }], target: i0.ɵɵFactoryTarget.Component });
25361
+ HelpComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: HelpComponent, deps: [{ token: DocsService }, { token: HelpService }], target: i0.ɵɵFactoryTarget.Component });
25350
25362
  HelpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: HelpComponent, selector: "c8y-help", inputs: { src: "src", isCollapsed: "isCollapsed", priority: "priority", icon: "icon" }, ngImport: i0, template: "<c8y-action-bar-item\n [placement]=\"'right'\"\n itemClass=\"pull-right m-l-8\"\n [priority]=\"priority\"\n *ngIf=\"!!(helpService.contextHelp | async)\"\n>\n <button\n class=\"btn-help\"\n type=\"button\"\n [attr.aria-label]=\"'About this page' | translate\"\n [attr.aria-expanded]=\"!isCollapsed\"\n aria-controls=\"collapseHelp\"\n tooltip=\"{{ 'About this page' | translate }}\"\n [delay]=\"750\"\n placement=\"left\"\n container=\"body\"\n (click)=\"toggle()\"\n c8yProductExperience\n [actionName]=\"isCollapsed ? 'helpOpened' : 'helpClosed'\"\n [actionData]=\"{ src: src }\"\n >\n </button>\n</c8y-action-bar-item>\n\n<div\n id=\"collapseHelp\"\n class=\"c8y-help-drawer\"\n [collapse]=\"isCollapsed\"\n [isAnimated]=\"true\"\n (collapsed)=\"onCollapsed()\"\n>\n <div\n [ngClass]=\"{ 'c8y-help-drawer-block': isInit }\"\n #docOutlet\n >\n <div *ngIf=\"isLoading\">\n <c8y-loading></c8y-loading>\n </div>\n\n <div *ngIf=\"!isLoading\">\n <div class=\"d-flex\">\n <i\n [c8yIcon]=\"!hasError ? icon : 'unlink'\"\n [ngClass]=\"{ 'text-warning': hasError, 'text-muted': !hasError }\"\n class=\"c8y-icon-duocolor icon-48\"\n ></i>\n <div\n class=\"p-l-16 flex-grow\"\n *ngIf=\"!hasError\"\n >\n <div\n class=\"alert alert-info m-b-16\"\n *ngIf=\"\n !helpService.isSupportedLanguage() &&\n !showLangWarning &&\n !helpService.isWarningAlertViewed\n \"\n >\n <button\n class=\"close\"\n type=\"button\"\n (click)=\"\n showLangWarning = !showLangWarning;\n helpService.isWarningAlertViewed = !helpService.isWarningAlertViewed\n \"\n [attr.aria-label]=\"'Close' | translate\"\n >\n <span aria-hidden=\"true\">\u00D7</span>\n <span class=\"sr-only\">Close</span>\n </button>\n <p>\n {{ 'Help content is only available in English.' | translate }}\n </p>\n </div>\n <h4 class=\"text-bold text-primary p-t-16 m-b-16\">\n {{ title }}\n </h4>\n <div\n id=\"helpContent\"\n class=\"help-content\"\n [innerHTML]=\"sectionContent\"\n ></div>\n </div>\n\n <div\n class=\"p-l-16 p-t-16 flex-grow\"\n *ngIf=\"hasError\"\n >\n <h4\n class=\"text-bold m-b-16\"\n translate\n >Sorry, that didn't work</h4>\n <div class=\"help-content\">\n <p translate>The content couldn't be loaded.</p>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"c8y-help-drawer-footer animated fadeIn\"\n style=\"animation-delay: 0.35s\"\n *ngIf=\"!isLoading && !hasError\"\n >\n <button\n class=\"btn btn-default\"\n (click)=\"toggle()\"\n [title]=\"'Close help' | translate\"\n type=\"button\"\n [attr.aria-expanded]=\"!isCollapsed\"\n aria-controls=\"collapseHelp\"\n translate\n >\n Close\n </button>\n <a\n href=\"{{ hasError ? getUrl() : getUrl(src) }}\"\n class=\"btn btn-primary\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <span\n translate\n *ngIf=\"!hasError\"\n >\n Open the\n <span>User guide`KEEP_ORIGINAL`</span>\n </span>\n <span\n translate\n *ngIf=\"hasError\"\n >\n Check the\n <span>User guide`KEEP_ORIGINAL`</span>\n </span>\n </a>\n </div>\n</div>", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i1$5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading" }, { kind: "directive", type: i1$a.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "directive", type: i1$8.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i1$5.AsyncPipe, name: "async" }] });
25351
25363
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: HelpComponent, decorators: [{
25352
25364
  type: Component,
25353
25365
  args: [{ selector: 'c8y-help', template: "<c8y-action-bar-item\n [placement]=\"'right'\"\n itemClass=\"pull-right m-l-8\"\n [priority]=\"priority\"\n *ngIf=\"!!(helpService.contextHelp | async)\"\n>\n <button\n class=\"btn-help\"\n type=\"button\"\n [attr.aria-label]=\"'About this page' | translate\"\n [attr.aria-expanded]=\"!isCollapsed\"\n aria-controls=\"collapseHelp\"\n tooltip=\"{{ 'About this page' | translate }}\"\n [delay]=\"750\"\n placement=\"left\"\n container=\"body\"\n (click)=\"toggle()\"\n c8yProductExperience\n [actionName]=\"isCollapsed ? 'helpOpened' : 'helpClosed'\"\n [actionData]=\"{ src: src }\"\n >\n </button>\n</c8y-action-bar-item>\n\n<div\n id=\"collapseHelp\"\n class=\"c8y-help-drawer\"\n [collapse]=\"isCollapsed\"\n [isAnimated]=\"true\"\n (collapsed)=\"onCollapsed()\"\n>\n <div\n [ngClass]=\"{ 'c8y-help-drawer-block': isInit }\"\n #docOutlet\n >\n <div *ngIf=\"isLoading\">\n <c8y-loading></c8y-loading>\n </div>\n\n <div *ngIf=\"!isLoading\">\n <div class=\"d-flex\">\n <i\n [c8yIcon]=\"!hasError ? icon : 'unlink'\"\n [ngClass]=\"{ 'text-warning': hasError, 'text-muted': !hasError }\"\n class=\"c8y-icon-duocolor icon-48\"\n ></i>\n <div\n class=\"p-l-16 flex-grow\"\n *ngIf=\"!hasError\"\n >\n <div\n class=\"alert alert-info m-b-16\"\n *ngIf=\"\n !helpService.isSupportedLanguage() &&\n !showLangWarning &&\n !helpService.isWarningAlertViewed\n \"\n >\n <button\n class=\"close\"\n type=\"button\"\n (click)=\"\n showLangWarning = !showLangWarning;\n helpService.isWarningAlertViewed = !helpService.isWarningAlertViewed\n \"\n [attr.aria-label]=\"'Close' | translate\"\n >\n <span aria-hidden=\"true\">\u00D7</span>\n <span class=\"sr-only\">Close</span>\n </button>\n <p>\n {{ 'Help content is only available in English.' | translate }}\n </p>\n </div>\n <h4 class=\"text-bold text-primary p-t-16 m-b-16\">\n {{ title }}\n </h4>\n <div\n id=\"helpContent\"\n class=\"help-content\"\n [innerHTML]=\"sectionContent\"\n ></div>\n </div>\n\n <div\n class=\"p-l-16 p-t-16 flex-grow\"\n *ngIf=\"hasError\"\n >\n <h4\n class=\"text-bold m-b-16\"\n translate\n >Sorry, that didn't work</h4>\n <div class=\"help-content\">\n <p translate>The content couldn't be loaded.</p>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"c8y-help-drawer-footer animated fadeIn\"\n style=\"animation-delay: 0.35s\"\n *ngIf=\"!isLoading && !hasError\"\n >\n <button\n class=\"btn btn-default\"\n (click)=\"toggle()\"\n [title]=\"'Close help' | translate\"\n type=\"button\"\n [attr.aria-expanded]=\"!isCollapsed\"\n aria-controls=\"collapseHelp\"\n translate\n >\n Close\n </button>\n <a\n href=\"{{ hasError ? getUrl() : getUrl(src) }}\"\n class=\"btn btn-primary\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <span\n translate\n *ngIf=\"!hasError\"\n >\n Open the\n <span>User guide`KEEP_ORIGINAL`</span>\n </span>\n <span\n translate\n *ngIf=\"hasError\"\n >\n Check the\n <span>User guide`KEEP_ORIGINAL`</span>\n </span>\n </a>\n </div>\n</div>" }]
25354
- }], ctorParameters: function () { return [{ type: DocsService }, { type: AppStateService }, { type: HelpService }]; }, propDecorators: { src: [{
25366
+ }], ctorParameters: function () { return [{ type: DocsService }, { type: HelpService }]; }, propDecorators: { src: [{
25355
25367
  type: Input
25356
25368
  }], isCollapsed: [{
25357
25369
  type: Input