@c8y/ngx-components 1017.0.338 → 1017.0.343

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/core/common/date.pipe.d.ts +2 -2
  2. package/core/common/stringify-object.pipe.d.ts +2 -1
  3. package/ecosystem/packages/deploy-application/deploy-application.component.d.ts +6 -5
  4. package/ecosystem/shared/ecosystem.constants.d.ts +2 -0
  5. package/ecosystem/shared/ecosystem.model.d.ts +3 -1
  6. package/ecosystem/shared/ecosystem.service.d.ts +11 -5
  7. package/esm2020/core/common/date.pipe.mjs +12 -7
  8. package/esm2020/core/common/stringify-object.pipe.mjs +11 -8
  9. package/esm2020/ecosystem/application-properties/application-properties.component.mjs +3 -3
  10. package/esm2020/ecosystem/applications/install-from-package/install-from-package.component.mjs +2 -2
  11. package/esm2020/ecosystem/packages/deploy-application/deploy-application.component.mjs +26 -81
  12. package/esm2020/ecosystem/shared/ecosystem.constants.mjs +5 -3
  13. package/esm2020/ecosystem/shared/ecosystem.model.mjs +3 -1
  14. package/esm2020/ecosystem/shared/ecosystem.service.mjs +121 -24
  15. package/fesm2015/c8y-ngx-components-ecosystem-shared.mjs +139 -27
  16. package/fesm2015/c8y-ngx-components-ecosystem-shared.mjs.map +1 -1
  17. package/fesm2015/c8y-ngx-components-ecosystem.mjs +23 -77
  18. package/fesm2015/c8y-ngx-components-ecosystem.mjs.map +1 -1
  19. package/fesm2015/c8y-ngx-components.mjs +20 -13
  20. package/fesm2015/c8y-ngx-components.mjs.map +1 -1
  21. package/fesm2020/c8y-ngx-components-ecosystem-shared.mjs +126 -25
  22. package/fesm2020/c8y-ngx-components-ecosystem-shared.mjs.map +1 -1
  23. package/fesm2020/c8y-ngx-components-ecosystem.mjs +23 -78
  24. package/fesm2020/c8y-ngx-components-ecosystem.mjs.map +1 -1
  25. package/fesm2020/c8y-ngx-components.mjs +20 -13
  26. package/fesm2020/c8y-ngx-components.mjs.map +1 -1
  27. package/locales/locales.pot +15 -3
  28. package/package.json +2 -2
@@ -10,7 +10,7 @@ import { __awaiter } from 'tslib';
10
10
  import * as i3 from '@c8y/client';
11
11
  import { ApplicationAvailability, ApplicationType } from '@c8y/client';
12
12
  import { saveAs } from 'file-saver';
13
- import { groupBy, uniqBy, get, pick, kebabCase, cloneDeep } from 'lodash-es';
13
+ import { groupBy, uniqBy, get, pick, omit, isUndefined, kebabCase, cloneDeep } from 'lodash-es';
14
14
  import { BehaviorSubject, defer, merge, combineLatest } from 'rxjs';
15
15
  import { map, shareReplay, debounceTime, take, distinctUntilKeyChanged, tap, filter, switchMap } from 'rxjs/operators';
16
16
  import { gt, coerce } from 'semver';
@@ -33,6 +33,7 @@ var ERROR_TYPE;
33
33
  (function (ERROR_TYPE) {
34
34
  ERROR_TYPE["TYPE_VALIDATION"] = "TYPE_VALIDATION";
35
35
  ERROR_TYPE["ALREADY_SUBSCRIBED"] = "ALREADY_SUBSCRIBED";
36
+ ERROR_TYPE["ALREADY_EXIST"] = "ALREADY_EXIST";
36
37
  ERROR_TYPE["INTERNAL_ERROR"] = "INTERNAL_ERROR";
37
38
  ERROR_TYPE["NO_MANIFEST_FILE"] = "NO_MANIFEST_FILE";
38
39
  ERROR_TYPE["INVALID_PACKAGE"] = "INVALID_PACKAGE";
@@ -40,6 +41,7 @@ var ERROR_TYPE;
40
41
  ERROR_TYPE["MICROSERVICE_NAME_TOO_LONG"] = "MICROSERVICE_NAME_TOO_LONG";
41
42
  ERROR_TYPE["APPLICATION_CREATION_FAILED"] = "APPLICATION_CREATION_FAILED";
42
43
  ERROR_TYPE["KEY_OR_CONTEXT_PATH_MISMATCH"] = "KEY_OR_CONTEXT_PATH_MISMATCH";
44
+ ERROR_TYPE["VERSION_NOT_FOUND"] = "VERSION_NOT_FOUND";
43
45
  })(ERROR_TYPE || (ERROR_TYPE = {}));
44
46
  const PRODUCT_EXPERIENCE = {
45
47
  APPLICATIONS: {
@@ -92,6 +94,7 @@ const PRODUCT_EXPERIENCE = {
92
94
  };
93
95
 
94
96
  const ERROR_MESSAGES = {
97
+ [ERROR_TYPE.ALREADY_EXIST]: gettext('Could not deploy the application, as the application with the same name, context-path or key exist already.'),
95
98
  [ERROR_TYPE.TYPE_VALIDATION]: gettext('Wrong file format. Expected a *.zip file with a valid manifest.'),
96
99
  [ERROR_TYPE.ALREADY_SUBSCRIBED]: gettext('Could not subscribe to the microservice because another application with the same context path is already subscribed.'),
97
100
  [ERROR_TYPE.NO_MANIFEST_FILE]: gettext('Could not find a manifest.'),
@@ -100,7 +103,8 @@ const ERROR_MESSAGES = {
100
103
  [ERROR_TYPE.INTERNAL_ERROR]: gettext('An internal error occurred, try to upload again.'),
101
104
  [ERROR_TYPE.MICROSERVICE_NAME_TOO_LONG]: gettext('Microservice name "{{ name }}" must not be longer than {{ maxChars }} characters.'),
102
105
  [ERROR_TYPE.APPLICATION_CREATION_FAILED]: gettext('Application creation failed.'),
103
- [ERROR_TYPE.KEY_OR_CONTEXT_PATH_MISMATCH]: gettext('The contextPath or key of the uploaded archive do not match with the existing app.')
106
+ [ERROR_TYPE.KEY_OR_CONTEXT_PATH_MISMATCH]: gettext('The "contextPath`KEEP_ORIGINAL`" or "key`KEEP_ORIGINAL`" of the uploaded archive do not match with the existing application.'),
107
+ [ERROR_TYPE.VERSION_NOT_FOUND]: gettext('The selected version was not found on the server.')
104
108
  };
105
109
  const APP_STATE = {
106
110
  SUBSCRIBED: {
@@ -130,7 +134,7 @@ const APP_STATE = {
130
134
  };
131
135
  const packageProperties = [
132
136
  {
133
- label: gettext('Version'),
137
+ label: gettext('Latest version'),
134
138
  key: 'version'
135
139
  },
136
140
  {
@@ -273,6 +277,18 @@ class EcosystemService {
273
277
  });
274
278
  }
275
279
  getPackageApplications(customFilter = {}) {
280
+ return __awaiter(this, void 0, void 0, function* () {
281
+ const filterCallback = app => this.isPackage(app);
282
+ return this.getApplicationsFiltered(customFilter, filterCallback);
283
+ });
284
+ }
285
+ getHostedAndPackageApplications(customFilter = {}) {
286
+ return __awaiter(this, void 0, void 0, function* () {
287
+ const filterCallback = app => this.isPackage(app) || this.isApplication(app);
288
+ return this.getApplicationsFiltered(customFilter, filterCallback);
289
+ });
290
+ }
291
+ getApplicationsFiltered(customFilter = {}, filterCallback = (app) => !!app) {
276
292
  return __awaiter(this, void 0, void 0, function* () {
277
293
  const filter = Object.assign({}, customFilter);
278
294
  const sharedFilter = Object.assign({
@@ -284,7 +300,7 @@ class EcosystemService {
284
300
  this.getApplications(filter),
285
301
  this.applicationService.list(sharedFilter)
286
302
  ]);
287
- const webApps = [...apps, ...shared].filter(app => this.isPackage(app));
303
+ const webApps = [...apps, ...shared].filter(filterCallback);
288
304
  // an app could be subscribed to a tenant, but also have it's availability set to SHARED, in that case it would occur twice.
289
305
  const uniqWebApps = uniqBy(webApps, (app) => app.id);
290
306
  return uniqWebApps.sort((a, b) => a.name.localeCompare(b.name));
@@ -370,20 +386,6 @@ class EcosystemService {
370
386
  availability });
371
387
  return config;
372
388
  }
373
- updateAppManifest(application, sourcePackage) {
374
- return __awaiter(this, void 0, void 0, function* () {
375
- const { id } = application;
376
- const cleanedApp = this.removeAppProperties(application);
377
- if (!cleanedApp.manifest) {
378
- cleanedApp.manifest = {};
379
- }
380
- cleanedApp.manifest.isPackage = false;
381
- cleanedApp.manifest.source = sourcePackage.id;
382
- return yield this.applicationService
383
- .binary(id)
384
- .updateFiles([{ path: CUMULOCITY_JSON, contents: JSON.stringify(cleanedApp) }]);
385
- });
386
- }
387
389
  listArchives(appId) {
388
390
  return __awaiter(this, void 0, void 0, function* () {
389
391
  const filter = {
@@ -617,6 +619,85 @@ class EcosystemService {
617
619
  }
618
620
  });
619
621
  }
622
+ deployApp(selectedPackage, formGroupValue, model) {
623
+ var _a;
624
+ return __awaiter(this, void 0, void 0, function* () {
625
+ // Create new app config
626
+ const config = this.createConfig(selectedPackage, formGroupValue);
627
+ const requestedVersion = model.selected.version;
628
+ let cleanManifest;
629
+ try {
630
+ const manifest = yield this.applicationService.getAppManifest(selectedPackage, requestedVersion);
631
+ cleanManifest = omit(manifest, ['name', 'contextPath', 'key']);
632
+ }
633
+ catch (ex) {
634
+ throw new EcosystemError(ERROR_TYPE.VERSION_NOT_FOUND);
635
+ }
636
+ config.isSetup = true;
637
+ config.manifest = cleanManifest;
638
+ config.availability = ApplicationAvailability.PRIVATE;
639
+ config.manifest.isPackage = false;
640
+ config.manifest.source = selectedPackage.id;
641
+ config.manifest.package = 'blueprint';
642
+ // because of a issue with SHARED availability we always should check again
643
+ // if the app not exist already
644
+ const allExistingApps = yield this.getHostedAndPackageApplications();
645
+ const doesAppKeyOrContextPathExist = this.checkIfAppNameKeyPathExists(allExistingApps, config);
646
+ if (doesAppKeyOrContextPathExist) {
647
+ throw new EcosystemError(ERROR_TYPE.ALREADY_EXIST);
648
+ }
649
+ // Create new app
650
+ const newApp = (yield this.applicationService.create(config)).data;
651
+ try {
652
+ // Binary upload can fail if SHARED package
653
+ // in this case, catch error and fall back to
654
+ // clone API.
655
+ yield this.uploadBinaryFromOtherPackage(selectedPackage, newApp, model.selected.binaryId, requestedVersion);
656
+ }
657
+ catch (error) {
658
+ if (((_a = error === null || error === void 0 ? void 0 : error.res) === null || _a === void 0 ? void 0 : _a.status) === 404) {
659
+ yield this.fallbackToClone(newApp, selectedPackage, requestedVersion);
660
+ }
661
+ }
662
+ return newApp;
663
+ });
664
+ }
665
+ fallbackToClone(application, selectedPackage, requestedVersion) {
666
+ return __awaiter(this, void 0, void 0, function* () {
667
+ let wasSuccess = true;
668
+ let clonedPkg;
669
+ try {
670
+ clonedPkg = (yield this.applicationService.clone(selectedPackage, requestedVersion)).data;
671
+ yield this.uploadBinaryFromOtherPackage(selectedPackage, application, clonedPkg.activeVersionId, requestedVersion, clonedPkg);
672
+ }
673
+ catch (error) {
674
+ this.alertError(error);
675
+ wasSuccess = false;
676
+ }
677
+ finally {
678
+ yield this.deleteApp(clonedPkg, true);
679
+ }
680
+ return wasSuccess;
681
+ });
682
+ }
683
+ uploadBinaryFromOtherPackage(selectedPackage, applicationToUploadBinaryTo, binaryId, requestedVersion, useBinariesFrom) {
684
+ return __awaiter(this, void 0, void 0, function* () {
685
+ const { data: binaryDetails } = yield this.inventoryService.detail(binaryId);
686
+ // Get binary from specific package version
687
+ const binary = yield this.getBinary(useBinariesFrom || selectedPackage, {
688
+ id: binaryId
689
+ });
690
+ // Create zip
691
+ const fileBinary = new Blob([binary], { type: binaryDetails.contentType });
692
+ const file = new File([fileBinary], binaryDetails.name, {
693
+ type: binaryDetails.contentType
694
+ });
695
+ // Upload binary to new app
696
+ yield this.uploadArchiveToApp(file, applicationToUploadBinaryTo);
697
+ // update the app manifest
698
+ yield this.updateAppManifest(applicationToUploadBinaryTo, selectedPackage, requestedVersion);
699
+ });
700
+ }
620
701
  getAppState(app) {
621
702
  if (!this.isOwner(app)) {
622
703
  return APP_STATE.SUBSCRIBED;
@@ -709,6 +790,45 @@ class EcosystemService {
709
790
  }
710
791
  });
711
792
  }
793
+ filterContainString(name, filterTerm) {
794
+ const term = filterTerm.toLowerCase().trim();
795
+ return name && name.toLowerCase().indexOf(term) > -1;
796
+ }
797
+ updateAppManifest(application, selectedPackage, requestedVersion) {
798
+ return __awaiter(this, void 0, void 0, function* () {
799
+ const { id } = application;
800
+ const cleanedApp = this.removeAppProperties(application);
801
+ let manifest = selectedPackage.manifest || {};
802
+ if (requestedVersion) {
803
+ try {
804
+ const versionedAppManifest = yield this.applicationService.getAppManifest(selectedPackage, requestedVersion);
805
+ manifest = versionedAppManifest;
806
+ }
807
+ catch (ex) {
808
+ throw new EcosystemError(ERROR_TYPE.VERSION_NOT_FOUND);
809
+ }
810
+ }
811
+ cleanedApp.manifest = manifest;
812
+ cleanedApp.manifest.isPackage = false;
813
+ cleanedApp.manifest.source = selectedPackage.id;
814
+ return yield this.applicationService
815
+ .binary(id)
816
+ .updateFiles([{ path: CUMULOCITY_JSON, contents: JSON.stringify(cleanedApp) }]);
817
+ });
818
+ }
819
+ checkIfAppNameKeyPathExists(existingApps, app, retryNo) {
820
+ if (isUndefined(retryNo)) {
821
+ return existingApps.find(existingApp => existingApp.name === app.name ||
822
+ existingApp.key === app.key ||
823
+ existingApp.contextPath === app.contextPath);
824
+ }
825
+ return existingApps.find(existingApp => existingApp.name === app.name ||
826
+ existingApp.key === app.key ||
827
+ existingApp.contextPath === app.contextPath ||
828
+ existingApp.name === [app.name, retryNo].join('-') ||
829
+ existingApp.key === [app.key, retryNo].join('-') ||
830
+ existingApp.contextPath === [app.contextPath, retryNo].join('-'));
831
+ }
712
832
  getAppKey(appModel, name) {
713
833
  let key = appModel === null || appModel === void 0 ? void 0 : appModel.key;
714
834
  if (!key) {
@@ -745,17 +865,9 @@ class EcosystemService {
745
865
  }
746
866
  return baseName;
747
867
  }
748
- checkIfAppNameKeyPathExists(existingApps, app, retryNo) {
749
- return existingApps.find(existingApp => existingApp.name === app.name ||
750
- existingApp.key === app.key ||
751
- existingApp.contextPath === app.contextPath ||
752
- existingApp.name === [app.name, retryNo].join('-') ||
753
- existingApp.key === [app.key, retryNo].join('-') ||
754
- existingApp.contextPath === [app.contextPath, retryNo].join('-'));
755
- }
756
868
  removeAppProperties(app) {
757
869
  const tempApp = cloneDeep(app);
758
- const propertiesToRemove = ['id', 'owner', 'activeVersionId', 'self'];
870
+ const propertiesToRemove = ['id', 'owner', 'activeVersionId', 'self', 'type'];
759
871
  propertiesToRemove.forEach(prop => delete tempApp[prop]);
760
872
  return tempApp;
761
873
  }