@devtron-labs/devtron-fe-common-lib 0.0.34-beta-3 → 0.0.34-beta-5

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.
@@ -1,4 +1,4 @@
1
- import { TeamList, ResponseType, DeploymentNodeType } from './Types';
1
+ import { TeamList, ResponseType, DeploymentNodeType, CDMaterialServiceEnum, CDMaterialServiceQueryParams, CDMaterialResponseType } from './Types';
2
2
  export declare const getTeamListMin: () => Promise<TeamList>;
3
3
  interface UserRole extends ResponseType {
4
4
  result?: {
@@ -13,7 +13,7 @@ export declare const SourceTypeMap: {
13
13
  };
14
14
  export declare function getUserRole(appName?: string): Promise<UserRole>;
15
15
  export declare function setImageTags(request: any, pipelineId: number, artifactId: number): Promise<ResponseType>;
16
- export declare const getCDMaterials: (cdMaterialId: any, stageType: DeploymentNodeType, abortSignal: AbortSignal, isApprovalNode?: boolean, imageTag?: string) => Promise<any>;
16
+ export declare const genericCDMaterialsService: (serviceType: CDMaterialServiceEnum, cdMaterialID: number, stage: DeploymentNodeType, signal: AbortSignal, queryParams?: CDMaterialServiceQueryParams) => Promise<CDMaterialResponseType>;
17
17
  export declare function extractImage(image: string): string;
18
18
  export declare function createGitCommitUrl(url: string, revision: string): string;
19
19
  export {};
@@ -19,6 +19,7 @@ export declare const ROUTES: {
19
19
  PROJECT_LIST_MIN: string;
20
20
  USER_CHECK_ROLE: string;
21
21
  IMAGE_TAGGING: string;
22
+ CD_MATERIAL_GET: string;
22
23
  };
23
24
  export declare enum KEY_VALUE {
24
25
  KEY = "key",
@@ -24,7 +24,6 @@ export interface ImageTaggingContainerType {
24
24
  setTagsEditable?: (tagsEditable: boolean) => void;
25
25
  toggleCardMode?: (id: number) => void;
26
26
  hideHardDelete?: boolean;
27
- isSuperAdmin?: boolean;
28
27
  }
29
28
  export interface ImageButtonType {
30
29
  text: string;
@@ -1,4 +1,4 @@
1
1
  /// <reference types="react" />
2
2
  import { ImageButtonType, ImageTaggingContainerType } from './ImageTags.Types';
3
- export declare const ImageTagsContainer: ({ ciPipelineId, artifactId, imageComment, imageReleaseTags, updateCurrentAppMaterial, appReleaseTagNames, setAppReleaseTagNames, tagsEditable, setTagsEditable, toggleCardMode, hideHardDelete, forceReInit, isSuperAdmin }: ImageTaggingContainerType) => JSX.Element;
3
+ export declare const ImageTagsContainer: ({ ciPipelineId, artifactId, imageComment, imageReleaseTags, updateCurrentAppMaterial, appReleaseTagNames, setAppReleaseTagNames, tagsEditable, setTagsEditable, toggleCardMode, hideHardDelete, forceReInit, }: ImageTaggingContainerType) => JSX.Element;
4
4
  export declare const ImageTagButton: ({ text, isSoftDeleted, isEditing, onSoftDeleteClick, onHardDeleteClick, tagId, softDeleteTags, isSuperAdmin, duplicateTag, hideHardDelete, }: ImageButtonType) => JSX.Element;
@@ -197,6 +197,9 @@ export declare enum FilterStates {
197
197
  BLOCKED = 1,
198
198
  ERROR = 2
199
199
  }
200
+ export declare enum MaterialDataSource {
201
+ EXTERNAL = "ext"
202
+ }
200
203
  export interface CDMaterialType {
201
204
  index: number;
202
205
  id: string;
@@ -223,6 +226,31 @@ export interface CDMaterialType {
223
226
  imageReleaseTags?: ReleaseTag[];
224
227
  artifactStatus?: string;
225
228
  filterState: FilterStates;
229
+ scanToolId?: number;
230
+ appliedFiltersTimestamp?: string;
231
+ appliedFilters?: FilterConditionsListType[];
232
+ appliedFiltersState?: FilterStates;
233
+ createdTime?: string;
234
+ deployed?: boolean;
235
+ dataSource?: MaterialDataSource;
236
+ }
237
+ export declare enum CDMaterialServiceEnum {
238
+ ROLLBACK = "rollback",
239
+ CD_MATERIALS = "cd-materials"
240
+ }
241
+ export declare enum CDMaterialResourceQuery {
242
+ PENDING_APPROVAL = "PENDING_APPROVAL"
243
+ }
244
+ export declare enum CDMaterialFilterQuery {
245
+ RESOURCE = "ELIGIBLE_RESOURCES",
246
+ ALL = "ALL_RESOURCES"
247
+ }
248
+ export interface CDMaterialServiceQueryParams {
249
+ search?: string;
250
+ offset?: number;
251
+ size?: number;
252
+ resource?: CDMaterialResourceQuery;
253
+ filter?: CDMaterialFilterQuery;
226
254
  }
227
255
  export interface CommonNodeAttr {
228
256
  connectingCiPipelineId?: number;
@@ -329,15 +357,20 @@ export interface FilterConditionsListType {
329
357
  description: string;
330
358
  conditions: FilterConditionsInfo[];
331
359
  }
332
- export interface CDMaterialResponseType {
360
+ export interface CDMaterialsApprovalInfo {
333
361
  approvalUsers: string[];
334
- materials: any[];
335
362
  userApprovalConfig: UserApprovalConfigType;
336
363
  requestedUserId: number;
364
+ }
365
+ export interface CDMaterialsMetaInfo {
337
366
  tagsEditable: boolean;
338
367
  appReleaseTagNames: string[];
339
368
  hideImageTaggingHardDelete: boolean;
340
369
  resourceFilters?: FilterConditionsListType[];
370
+ totalCount: number;
371
+ }
372
+ export interface CDMaterialResponseType extends CDMaterialsMetaInfo, CDMaterialsApprovalInfo {
373
+ materials: CDMaterialType[];
341
374
  }
342
375
  export interface InputDetailType {
343
376
  label: string;
package/dist/index.js CHANGED
@@ -44,6 +44,7 @@ var ROUTES = {
44
44
  PROJECT_LIST_MIN: 'team/autocomplete',
45
45
  USER_CHECK_ROLE: 'user/check/roles',
46
46
  IMAGE_TAGGING: 'app/image-tagging',
47
+ CD_MATERIAL_GET: 'app/cd-pipeline'
47
48
  };
48
49
  exports.KEY_VALUE = void 0;
49
50
  (function (KEY_VALUE) {
@@ -430,6 +431,24 @@ exports.FilterStates = void 0;
430
431
  FilterStates[FilterStates["BLOCKED"] = 1] = "BLOCKED";
431
432
  FilterStates[FilterStates["ERROR"] = 2] = "ERROR";
432
433
  })(exports.FilterStates || (exports.FilterStates = {}));
434
+ exports.MaterialDataSource = void 0;
435
+ (function (MaterialDataSource) {
436
+ MaterialDataSource["EXTERNAL"] = "ext";
437
+ })(exports.MaterialDataSource || (exports.MaterialDataSource = {}));
438
+ exports.CDMaterialServiceEnum = void 0;
439
+ (function (CDMaterialServiceEnum) {
440
+ CDMaterialServiceEnum["ROLLBACK"] = "rollback";
441
+ CDMaterialServiceEnum["CD_MATERIALS"] = "cd-materials";
442
+ })(exports.CDMaterialServiceEnum || (exports.CDMaterialServiceEnum = {}));
443
+ exports.CDMaterialResourceQuery = void 0;
444
+ (function (CDMaterialResourceQuery) {
445
+ CDMaterialResourceQuery["PENDING_APPROVAL"] = "PENDING_APPROVAL";
446
+ })(exports.CDMaterialResourceQuery || (exports.CDMaterialResourceQuery = {}));
447
+ exports.CDMaterialFilterQuery = void 0;
448
+ (function (CDMaterialFilterQuery) {
449
+ CDMaterialFilterQuery["RESOURCE"] = "ELIGIBLE_RESOURCES";
450
+ CDMaterialFilterQuery["ALL"] = "ALL_RESOURCES";
451
+ })(exports.CDMaterialFilterQuery || (exports.CDMaterialFilterQuery = {}));
433
452
  exports.DeploymentAppTypes = void 0;
434
453
  (function (DeploymentAppTypes) {
435
454
  DeploymentAppTypes["HELM"] = "helm";
@@ -22688,77 +22707,168 @@ function getUserRole(appName) {
22688
22707
  function setImageTags(request, pipelineId, artifactId) {
22689
22708
  return post("".concat(ROUTES.IMAGE_TAGGING, "/").concat(pipelineId, "/").concat(artifactId), request);
22690
22709
  }
22691
- // FIXME: This is only returning materials to cater the case of search in approval but it should be a common function service coming from dashboard.
22692
- var getCDMaterials = function (cdMaterialId, stageType, abortSignal, isApprovalNode, imageTag) {
22693
- var URL = (!imageTag) ? "app/cd-pipeline/".concat(cdMaterialId, "/material?stage=").concat(stageMap[stageType]) : "app/cd-pipeline/".concat(cdMaterialId, "/material?stage=").concat(stageMap[stageType], "&search=").concat(imageTag);
22694
- return get(URL, {
22695
- signal: abortSignal,
22696
- }).then(function (response) {
22697
- var _a;
22698
- var artifacts = (_a = response.result.ci_artifacts) !== null && _a !== void 0 ? _a : [];
22699
- if (!response.result) {
22700
- return {
22701
- materials: [],
22702
- };
22710
+ var processURL = function (url, params) {
22711
+ var validParams = Object.keys(params).filter(function (key) {
22712
+ return params[key] != null;
22713
+ });
22714
+ if (!validParams.length) {
22715
+ return url;
22716
+ }
22717
+ var queryString = validParams
22718
+ .map(function (key) {
22719
+ if (Array.isArray(params[key])) {
22720
+ return "".concat(key, "=").concat(params[key].join(','));
22703
22721
  }
22704
- else {
22705
- var materials = artifacts.map(function (material, index) {
22706
- var _a;
22707
- var artifactStatusValue = '';
22708
- var filterState = (_a = material.filterState) !== null && _a !== void 0 ? _a : exports.FilterStates.ALLOWED;
22709
- return {
22710
- index: index,
22711
- id: material.id,
22712
- deployedTime: material.deployed_time
22713
- ? moment(material.deployed_time).format('ddd, DD MMM YYYY, hh:mm A')
22714
- : 'Not Deployed',
22715
- deployedBy: material.deployedBy,
22716
- wfrId: material.wfrId,
22717
- image: extractImage(material.image),
22718
- showChanges: false,
22719
- vulnerabilities: [],
22720
- buildTime: material.build_time || '',
22721
- tab: CDModalTab.Changes,
22722
- showSourceInfo: false,
22723
- deployed: material.deployed || false,
22724
- latest: material.latest || false,
22725
- vulnerabilitiesLoading: true,
22726
- scanned: material.scanned,
22727
- scanEnabled: material.scanEnabled,
22728
- isSelected: !material.vulnerable && filterState === exports.FilterStates.ALLOWED && index === 0,
22729
- vulnerable: material.vulnerable,
22730
- runningOnParentCd: material.runningOnParentCd,
22731
- artifactStatus: artifactStatusValue,
22732
- userApprovalMetadata: material.userApprovalMetadata,
22733
- triggeredBy: material.triggeredBy,
22734
- isVirtualEnvironment: material.isVirtualEnvironment,
22735
- imageComment: material.imageComment,
22736
- imageReleaseTags: material.imageReleaseTags,
22737
- materialInfo: material.material_info
22738
- ? material.material_info.map(function (mat) {
22739
- return {
22740
- modifiedTime: mat.modifiedTime ? moment(mat.modifiedTime).format("ddd, DD MMM YYYY, hh:mm A") : '',
22741
- commitLink: createGitCommitUrl(mat.url, mat.revision),
22742
- author: mat.author || '',
22743
- message: mat.message || '',
22744
- revision: mat.revision || '',
22745
- tag: mat.tag || '',
22746
- webhookData: mat.webhookData || '',
22747
- url: mat.url || '',
22748
- branch: (material.ciConfigureSourceType === SourceTypeMap.WEBHOOK
22749
- ? material.ciConfigureSourceValue
22750
- : mat.branch) || '',
22751
- type: material.ciConfigureSourceType || '',
22752
- };
22753
- })
22754
- : [],
22755
- filterState: filterState,
22756
- };
22757
- });
22758
- return {
22759
- materials: materials
22760
- };
22722
+ return "".concat(key, "=").concat(params[key]);
22723
+ })
22724
+ .join('&');
22725
+ return "".concat(url, "?").concat(queryString);
22726
+ };
22727
+ var cdMaterialListModal = function (artifacts, offset, artifactId, artifactStatus) {
22728
+ if (!artifacts || !artifacts.length)
22729
+ return [];
22730
+ var markFirstSelected = offset === 0;
22731
+ var startIndex = offset;
22732
+ var isImageMarked = false;
22733
+ var materials = artifacts.map(function (material, index) {
22734
+ var _a, _b, _c, _d, _e, _f;
22735
+ var artifactStatusValue = '';
22736
+ var filterState = (_a = material.filterState) !== null && _a !== void 0 ? _a : exports.FilterStates.ALLOWED;
22737
+ if (artifactId && artifactStatus && material.id === artifactId) {
22738
+ artifactStatusValue = artifactStatus;
22739
+ }
22740
+ var selectImage = !isImageMarked && markFirstSelected && filterState === exports.FilterStates.ALLOWED ? !material.vulnerable : false;
22741
+ if (selectImage) {
22742
+ isImageMarked = true;
22761
22743
  }
22744
+ return {
22745
+ index: startIndex + index,
22746
+ id: material.id,
22747
+ deployedTime: material.deployed_time
22748
+ ? moment(material.deployed_time).format('ddd, DD MMM YYYY, hh:mm A')
22749
+ : 'Not Deployed',
22750
+ deployedBy: material.deployedBy,
22751
+ wfrId: material.wfrId,
22752
+ tab: CDModalTab.Changes,
22753
+ image: extractImage(material.image),
22754
+ showChanges: false,
22755
+ vulnerabilities: [],
22756
+ buildTime: material.build_time || '',
22757
+ isSelected: selectImage,
22758
+ showSourceInfo: false,
22759
+ deployed: material.deployed || false,
22760
+ latest: material.latest || false,
22761
+ vulnerabilitiesLoading: true,
22762
+ scanned: material.scanned,
22763
+ scanEnabled: material.scanEnabled,
22764
+ vulnerable: material.vulnerable,
22765
+ runningOnParentCd: material.runningOnParentCd,
22766
+ artifactStatus: artifactStatusValue,
22767
+ userApprovalMetadata: material.userApprovalMetadata,
22768
+ triggeredBy: material.triggeredBy,
22769
+ isVirtualEnvironment: material.isVirtualEnvironment,
22770
+ imageComment: material.imageComment,
22771
+ imageReleaseTags: material.imageReleaseTags,
22772
+ // It is going to be null but required in type so can't remove
22773
+ lastExecution: material.lastExecution,
22774
+ materialInfo: material.material_info
22775
+ ? material.material_info.map(function (mat) {
22776
+ return {
22777
+ modifiedTime: mat.modifiedTime
22778
+ ? moment(mat.modifiedTime).format('ddd, DD MMM YYYY, hh:mm A')
22779
+ : '',
22780
+ commitLink: createGitCommitUrl(mat.url, mat.revision),
22781
+ author: mat.author || '',
22782
+ message: mat.message || '',
22783
+ revision: mat.revision || '',
22784
+ tag: mat.tag || '',
22785
+ webhookData: mat.webhookData || '',
22786
+ url: mat.url || '',
22787
+ branch: (material.ciConfigureSourceType === SourceTypeMap.WEBHOOK
22788
+ ? material.ciConfigureSourceValue
22789
+ : mat.branch) || '',
22790
+ type: material.ciConfigureSourceType || '',
22791
+ };
22792
+ })
22793
+ : [],
22794
+ filterState: filterState,
22795
+ appliedFiltersTimestamp: (_b = material.appliedFiltersTimestamp) !== null && _b !== void 0 ? _b : '',
22796
+ appliedFilters: (_c = material.appliedFilters) !== null && _c !== void 0 ? _c : [],
22797
+ appliedFiltersState: (_d = material.appliedFiltersState) !== null && _d !== void 0 ? _d : exports.FilterStates.ALLOWED,
22798
+ createdTime: (_e = material.createdTime) !== null && _e !== void 0 ? _e : '',
22799
+ dataSource: (_f = material.data_source) !== null && _f !== void 0 ? _f : '',
22800
+ };
22801
+ });
22802
+ return materials;
22803
+ };
22804
+ var processCDMaterialsApprovalInfo = function (enableApproval, cdMaterialsResult) {
22805
+ if (!enableApproval) {
22806
+ return {
22807
+ approvalUsers: [],
22808
+ userApprovalConfig: null,
22809
+ requestedUserId: 0,
22810
+ };
22811
+ }
22812
+ return {
22813
+ approvalUsers: cdMaterialsResult.approvalUsers,
22814
+ userApprovalConfig: cdMaterialsResult.userApprovalConfig,
22815
+ requestedUserId: cdMaterialsResult.requestedUserId,
22816
+ };
22817
+ };
22818
+ var processCDMaterialsMetaInfo = function (cdMaterialsResult) {
22819
+ var _a, _b;
22820
+ if (!cdMaterialsResult) {
22821
+ return {
22822
+ tagsEditable: false,
22823
+ appReleaseTagNames: [],
22824
+ hideImageTaggingHardDelete: false,
22825
+ resourceFilters: [],
22826
+ totalCount: 0,
22827
+ };
22828
+ }
22829
+ return {
22830
+ appReleaseTagNames: cdMaterialsResult.appReleaseTagNames,
22831
+ tagsEditable: cdMaterialsResult.tagsEditable,
22832
+ hideImageTaggingHardDelete: cdMaterialsResult.hideImageTaggingHardDelete,
22833
+ resourceFilters: (_a = cdMaterialsResult.resourceFilters) !== null && _a !== void 0 ? _a : [],
22834
+ totalCount: (_b = cdMaterialsResult.totalCount) !== null && _b !== void 0 ? _b : 0,
22835
+ };
22836
+ };
22837
+ var processCDMaterialServiceResponse = function (cdMaterialsResult, stage, offset, filter) {
22838
+ if (!cdMaterialsResult) {
22839
+ return __assign(__assign({ materials: [] }, processCDMaterialsMetaInfo(cdMaterialsResult)), processCDMaterialsApprovalInfo(false, cdMaterialsResult));
22840
+ }
22841
+ var materials = cdMaterialListModal(cdMaterialsResult.ci_artifacts, offset !== null && offset !== void 0 ? offset : 0, cdMaterialsResult.latest_wf_artifact_id, cdMaterialsResult.latest_wf_artifact_status);
22842
+ var approvalInfo = processCDMaterialsApprovalInfo(stage === exports.DeploymentNodeType.CD || stage === exports.DeploymentNodeType.APPROVAL, cdMaterialsResult);
22843
+ var metaInfo = processCDMaterialsMetaInfo(cdMaterialsResult);
22844
+ // TODO: On update of service would remove from here
22845
+ var filteredMaterials = filter && filter === exports.CDMaterialFilterQuery.RESOURCE
22846
+ ? materials.filter(function (material) {
22847
+ return material.filterState === exports.FilterStates.ALLOWED;
22848
+ })
22849
+ : materials;
22850
+ return __assign(__assign({ materials: filteredMaterials }, approvalInfo), metaInfo);
22851
+ };
22852
+ var getSanitizedQueryParams = function (queryParams) {
22853
+ queryParams.filter; var rest = __rest(queryParams, ["filter"]);
22854
+ return rest;
22855
+ };
22856
+ var genericCDMaterialsService = function (serviceType, cdMaterialID, stage, signal, queryParams) {
22857
+ if (queryParams === void 0) { queryParams = {}; }
22858
+ // TODO: On update of service would remove from here
22859
+ var manipulatedParams = getSanitizedQueryParams(queryParams);
22860
+ var URL;
22861
+ switch (serviceType) {
22862
+ case exports.CDMaterialServiceEnum.ROLLBACK:
22863
+ URL = processURL("".concat(ROUTES.CD_MATERIAL_GET, "/").concat(cdMaterialID, "/material/rollback"), manipulatedParams);
22864
+ break;
22865
+ // Meant for handling getCDMaterialList
22866
+ default:
22867
+ URL = processURL("".concat(ROUTES.CD_MATERIAL_GET, "/").concat(cdMaterialID, "/material"), __assign(__assign({}, manipulatedParams), { stage: stageMap[stage] }));
22868
+ break;
22869
+ }
22870
+ return get(URL, { signal: signal }).then(function (response) {
22871
+ return processCDMaterialServiceResponse(response.result, stage, queryParams.offset, queryParams.filter);
22762
22872
  });
22763
22873
  };
22764
22874
  function extractImage(image) {
@@ -23125,7 +23235,9 @@ var SvgIcEnter = function SvgIcEnter(props) {
23125
23235
  };
23126
23236
 
23127
23237
  var ImageTagsContainer = function (_a) {
23128
- var ciPipelineId = _a.ciPipelineId, artifactId = _a.artifactId, imageComment = _a.imageComment, imageReleaseTags = _a.imageReleaseTags, updateCurrentAppMaterial = _a.updateCurrentAppMaterial, appReleaseTagNames = _a.appReleaseTagNames, setAppReleaseTagNames = _a.setAppReleaseTagNames, tagsEditable = _a.tagsEditable, setTagsEditable = _a.setTagsEditable, toggleCardMode = _a.toggleCardMode, hideHardDelete = _a.hideHardDelete, forceReInit = _a.forceReInit, isSuperAdmin = _a.isSuperAdmin;
23238
+ var
23239
+ // Setting it to zero in case of external pipeline
23240
+ ciPipelineId = _a.ciPipelineId, artifactId = _a.artifactId, imageComment = _a.imageComment, imageReleaseTags = _a.imageReleaseTags, updateCurrentAppMaterial = _a.updateCurrentAppMaterial, appReleaseTagNames = _a.appReleaseTagNames, setAppReleaseTagNames = _a.setAppReleaseTagNames, tagsEditable = _a.tagsEditable, setTagsEditable = _a.setTagsEditable, toggleCardMode = _a.toggleCardMode, hideHardDelete = _a.hideHardDelete, forceReInit = _a.forceReInit;
23129
23241
  var _b = __read(React.useState(imageReleaseTags ? imageReleaseTags : []), 2), initialTags = _b[0], setInitialTags = _b[1];
23130
23242
  var _c = __read(React.useState(imageComment ? imageComment.comment : ''), 2), initialDescription = _c[0], setInitialDescription = _c[1];
23131
23243
  var _d = __read(React.useState(appReleaseTagNames ? appReleaseTagNames : []), 2), existingTags = _d[0], setExistingTags = _d[1];
@@ -23137,14 +23249,42 @@ var ImageTagsContainer = function (_a) {
23137
23249
  var _k = __read(React.useState([]), 2), createTags = _k[0], setCreateTags = _k[1];
23138
23250
  var _l = __read(React.useState([]), 2), softDeleteTags = _l[0], setSoftDeleteTags = _l[1];
23139
23251
  var _m = __read(React.useState([]), 2), hardDeleteTags = _m[0], setHardDeleteTags = _m[1];
23140
- var _o = __read(React.useState(''), 2), descriptionValidationMessage = _o[0], setDescriptionValidationMessage = _o[1];
23141
- var _p = __read(React.useState(''), 2), textInput = _p[0], setTextInput = _p[1];
23252
+ var _o = __read(React.useState(false), 2), isSuperAdmin = _o[0], setSuperAdmin = _o[1];
23253
+ var _p = __read(React.useState(''), 2), descriptionValidationMessage = _p[0], setDescriptionValidationMessage = _p[1];
23254
+ var _q = __read(React.useState(''), 2), textInput = _q[0], setTextInput = _q[1];
23255
+ var _r = __read(React.useState(false), 2), loading = _r[0], setLoading = _r[1];
23256
+ React.useEffect(function () {
23257
+ initialise();
23258
+ }, []);
23142
23259
  React.useEffect(function () {
23143
23260
  reInitState();
23144
23261
  }, [imageReleaseTags, imageComment, tagsEditable]);
23145
23262
  React.useEffect(function () {
23146
23263
  setExistingTags(appReleaseTagNames ? appReleaseTagNames : []);
23147
23264
  }, [appReleaseTagNames]);
23265
+ function initialise() {
23266
+ var _a, _b;
23267
+ return __awaiter(this, void 0, void 0, function () {
23268
+ var userRole, superAdmin, err_1;
23269
+ return __generator(this, function (_c) {
23270
+ switch (_c.label) {
23271
+ case 0:
23272
+ _c.trys.push([0, 2, , 3]);
23273
+ return [4 /*yield*/, getUserRole()];
23274
+ case 1:
23275
+ userRole = _c.sent();
23276
+ superAdmin = (_b = (_a = userRole === null || userRole === void 0 ? void 0 : userRole.result) === null || _a === void 0 ? void 0 : _a.roles) === null || _b === void 0 ? void 0 : _b.includes('role:super-admin___');
23277
+ setSuperAdmin(superAdmin);
23278
+ return [3 /*break*/, 3];
23279
+ case 2:
23280
+ err_1 = _c.sent();
23281
+ showError(err_1);
23282
+ return [3 /*break*/, 3];
23283
+ case 3: return [2 /*return*/];
23284
+ }
23285
+ });
23286
+ });
23287
+ }
23148
23288
  var reInitState = function () {
23149
23289
  if (forceReInit || !isEditing) {
23150
23290
  setInitialTags(imageReleaseTags ? imageReleaseTags : []);
@@ -23286,7 +23426,8 @@ var ImageTagsContainer = function (_a) {
23286
23426
  hardDeleteTags: hardDeleteTags,
23287
23427
  };
23288
23428
  // set loading state true
23289
- setImageTags(payload, ciPipelineId, artifactId)
23429
+ setLoading(true);
23430
+ setImageTags(payload, ciPipelineId !== null && ciPipelineId !== void 0 ? ciPipelineId : 0, artifactId)
23290
23431
  .then(function (res) {
23291
23432
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
23292
23433
  var tags = (_b = (_a = res.result) === null || _a === void 0 ? void 0 : _a.imageReleaseTags) === null || _b === void 0 ? void 0 : _b.map(function (tag) { return ({
@@ -23325,6 +23466,9 @@ var ImageTagsContainer = function (_a) {
23325
23466
  else {
23326
23467
  showError(err);
23327
23468
  }
23469
+ })
23470
+ .finally(function () {
23471
+ setLoading(false);
23328
23472
  });
23329
23473
  return [2 /*return*/];
23330
23474
  });
@@ -23375,10 +23519,10 @@ var ImageTagsContainer = function (_a) {
23375
23519
  }, tagId: tag.id, softDeleteTags: softDeleteTags, isSuperAdmin: isSuperAdmin, duplicateTag: tag === null || tag === void 0 ? void 0 : tag.duplicateTag, hideHardDelete: hideHardDelete }, tag.id)); }) })), showTagsWarning && (jsxRuntime.jsxs("div", __assign({ className: "cn-7 mb-8 flex left" }, { children: [jsxRuntime.jsx(SvgIcInfoFilled, { className: "form__icon--info icon-dim-16 mr-2" }), "Tags cannot be edited/removed later"] }))), jsxRuntime.jsx("div", __assign({ className: "cn-7 mt-12" }, { children: "Comment" })), jsxRuntime.jsx("div", __assign({ className: "flex left flex-wrap dc__gap-8 w-100 mt-6 mb-12", "data-testid": "add-image-comment-text-area" }, { children: jsxRuntime.jsx("textarea", { value: newDescription, onChange: handleDescriptionChange, className: "flex left flex-wrap dc__gap-8 dc__description-textarea fs-13", style: { height: '90px !important' } }) })), descriptionValidationMessage !== '' && (jsxRuntime.jsxs("div", __assign({ className: "flex left" }, { children: [jsxRuntime.jsx(SvgIcWarning, { className: "form__icon form__icon--error" }), jsxRuntime.jsx("div", __assign({ className: "form__error" }, { children: descriptionValidationMessage }))] }))), jsxRuntime.jsxs("div", __assign({ className: "w-100 flex right mt-12" }, { children: [jsxRuntime.jsx("button", __assign({ className: "cta flex cancel h-32 lh-32-imp", type: "button", onClick: function (e) {
23376
23520
  stopPropagation(e);
23377
23521
  handleCancel();
23378
- } }, { children: "Cancel" })), jsxRuntime.jsx("button", __assign({ className: "cta flex h-32 lh-32-imp ml-12", "data-testid": "save-tags-button", type: "button", onClick: function (e) {
23522
+ }, disabled: loading }, { children: "Cancel" })), jsxRuntime.jsx("button", __assign({ className: "cta flex h-32 lh-32-imp ml-12", "data-testid": "save-tags-button", type: "button", onClick: function (e) {
23379
23523
  stopPropagation(e);
23380
23524
  onClickSave();
23381
- } }, { children: "Save" }))] }))] }))) : (jsxRuntime.jsxs("div", __assign({ className: "top br-4 bcn-0 image-tags-container flexbox" }, { children: [jsxRuntime.jsx("div", __assign({ className: "flex left image-tag-left-border w-100 mt-8 mb-8 pr-10 pl-10", "data-testid": "image-tags-container-hover" }, { children: jsxRuntime.jsxs("div", __assign({ className: 'w-100' }, { children: [initialDescription && jsxRuntime.jsx("div", __assign({ className: "mb-6 fs-13 lh-20 dc__word-break-all" }, { children: initialDescription })), jsxRuntime.jsx("div", __assign({ className: "flex-wrap flex left" }, { children: initialTags === null || initialTags === void 0 ? void 0 : initialTags.map(function (tag, index) { return (jsxRuntime.jsx(ImageTagButton, { text: tag === null || tag === void 0 ? void 0 : tag.tagName, isSoftDeleted: tag === null || tag === void 0 ? void 0 : tag.deleted, isEditing: isEditing, onSoftDeleteClick: function (e) {
23525
+ }, disabled: loading }, { children: loading ? jsxRuntime.jsx(Progressing, {}) : 'Save' }))] }))] }))) : (jsxRuntime.jsxs("div", __assign({ className: "top br-4 bcn-0 image-tags-container flexbox" }, { children: [jsxRuntime.jsx("div", __assign({ className: "flex left image-tag-left-border w-100 mt-8 mb-8 pr-10 pl-10", "data-testid": "image-tags-container-hover" }, { children: jsxRuntime.jsxs("div", __assign({ className: 'w-100' }, { children: [initialDescription && jsxRuntime.jsx("div", __assign({ className: "mb-6 fs-13 lh-20 dc__word-break-all" }, { children: initialDescription })), jsxRuntime.jsx("div", __assign({ className: "flex-wrap flex left" }, { children: initialTags === null || initialTags === void 0 ? void 0 : initialTags.map(function (tag, index) { return (jsxRuntime.jsx(ImageTagButton, { text: tag === null || tag === void 0 ? void 0 : tag.tagName, isSoftDeleted: tag === null || tag === void 0 ? void 0 : tag.deleted, isEditing: isEditing, onSoftDeleteClick: function (e) {
23382
23526
  stopPropagation(e);
23383
23527
  handleTagSoftDelete(index);
23384
23528
  }, onHardDeleteClick: function (e) {
@@ -23663,9 +23807,9 @@ exports.closeOnEscKeyPressed = closeOnEscKeyPressed;
23663
23807
  exports.copyToClipboard = copyToClipboard;
23664
23808
  exports.createGitCommitUrl = createGitCommitUrl;
23665
23809
  exports.extractImage = extractImage;
23810
+ exports.genericCDMaterialsService = genericCDMaterialsService;
23666
23811
  exports.get = get;
23667
23812
  exports.getAlphabetIcon = getAlphabetIcon;
23668
- exports.getCDMaterials = getCDMaterials;
23669
23813
  exports.getCookie = getCookie;
23670
23814
  exports.getEmptyArrayOfLength = getEmptyArrayOfLength;
23671
23815
  exports.getLoginInfo = getLoginInfo;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devtron-labs/devtron-fe-common-lib",
3
- "version": "0.0.34-beta-3",
3
+ "version": "0.0.34-beta-5",
4
4
  "description": "Supporting common component library",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -2,7 +2,19 @@ import moment from 'moment';
2
2
  import {get, post} from './Api';
3
3
  import { ROUTES } from './Constants'
4
4
  import { sortCallback } from './Helper';
5
- import { TeamList ,ResponseType, DeploymentNodeType, CDModalTab, FilterStates } from './Types';
5
+ import {
6
+ TeamList,
7
+ ResponseType,
8
+ DeploymentNodeType,
9
+ CDModalTab,
10
+ FilterStates,
11
+ CDMaterialServiceEnum,
12
+ CDMaterialServiceQueryParams,
13
+ CDMaterialResponseType,
14
+ CDMaterialsMetaInfo,
15
+ CDMaterialsApprovalInfo,
16
+ CDMaterialFilterQuery,
17
+ } from './Types'
6
18
 
7
19
  export const getTeamListMin = (): Promise<TeamList> => {
8
20
  // ignore active field
@@ -30,7 +42,7 @@ interface UserRole extends ResponseType {
30
42
  }
31
43
  }
32
44
 
33
- let stageMap = {
45
+ const stageMap = {
34
46
  PRECD: 'PRE',
35
47
  CD: 'DEPLOY',
36
48
  POSTCD: 'POST',
@@ -51,83 +63,216 @@ export function setImageTags(request, pipelineId: number, artifactId: number){
51
63
  return post(`${ROUTES.IMAGE_TAGGING}/${pipelineId}/${artifactId}`,request )
52
64
  }
53
65
 
54
- // FIXME: This is only returning materials to cater the case of search in approval but it should be a common function service coming from dashboard.
55
- export const getCDMaterials = (
56
- cdMaterialId,
57
- stageType: DeploymentNodeType,
58
- abortSignal: AbortSignal,
59
- isApprovalNode?: boolean,
60
- imageTag?: string): Promise<any> => {
61
- const URL = (!imageTag) ? `app/cd-pipeline/${cdMaterialId}/material?stage=${stageMap[stageType]}` : `app/cd-pipeline/${cdMaterialId}/material?stage=${stageMap[stageType]}&search=${imageTag}`
62
-
63
- return get(URL, {
64
- signal: abortSignal,
65
- }).then((response) => {
66
- let artifacts = response.result.ci_artifacts ?? []
67
- if (!response.result) {
68
- return {
69
- materials: [],
66
+ const processURL = (url: string, params: object) => {
67
+ const validParams = Object.keys(params).filter((key) => {
68
+ return params[key] != null
69
+ })
70
+
71
+ if (!validParams.length) {
72
+ return url
73
+ }
74
+
75
+ const queryString = validParams
76
+ .map((key) => {
77
+ if (Array.isArray(params[key])) {
78
+ return `${key}=${params[key].join(',')}`
70
79
  }
80
+ return `${key}=${params[key]}`
81
+ })
82
+ .join('&')
83
+
84
+ return `${url}?${queryString}`
85
+ }
86
+
87
+ const cdMaterialListModal = (artifacts: any[], offset: number, artifactId?: number, artifactStatus?: string) => {
88
+ if (!artifacts || !artifacts.length) return []
89
+
90
+ const markFirstSelected = offset === 0
91
+ const startIndex = offset
92
+ let isImageMarked = false
93
+
94
+ const materials = artifacts.map((material, index) => {
95
+ let artifactStatusValue = ''
96
+ const filterState = material.filterState ?? FilterStates.ALLOWED
97
+
98
+ if (artifactId && artifactStatus && material.id === artifactId) {
99
+ artifactStatusValue = artifactStatus
71
100
  }
72
- else {
73
- const materials = artifacts.map((material, index) => {
74
- let artifactStatusValue = ''
75
- const filterState = material.filterState ?? FilterStates.ALLOWED
76
-
77
- return {
78
- index,
79
- id: material.id,
80
- deployedTime: material.deployed_time
81
- ? moment(material.deployed_time).format('ddd, DD MMM YYYY, hh:mm A')
82
- : 'Not Deployed',
83
- deployedBy: material.deployedBy,
84
- wfrId: material.wfrId,
85
- image: extractImage(material.image),
86
- showChanges: false,
87
- vulnerabilities: [],
88
- buildTime: material.build_time || '',
89
- tab: CDModalTab.Changes,
90
- showSourceInfo: false,
91
- deployed: material.deployed || false,
92
- latest: material.latest || false,
93
- vulnerabilitiesLoading: true,
94
- scanned: material.scanned,
95
- scanEnabled: material.scanEnabled,
96
- isSelected: !material.vulnerable && filterState === FilterStates.ALLOWED && index === 0,
97
- vulnerable: material.vulnerable,
98
- runningOnParentCd: material.runningOnParentCd,
99
- artifactStatus: artifactStatusValue,
100
- userApprovalMetadata: material.userApprovalMetadata,
101
- triggeredBy: material.triggeredBy,
102
- isVirtualEnvironment: material.isVirtualEnvironment,
103
- imageComment: material.imageComment,
104
- imageReleaseTags: material.imageReleaseTags,
105
- materialInfo: material.material_info
106
- ? material.material_info.map((mat) => {
107
- return {
108
- modifiedTime: mat.modifiedTime ? moment(mat.modifiedTime).format("ddd, DD MMM YYYY, hh:mm A") : '',
109
- commitLink: createGitCommitUrl(mat.url, mat.revision),
110
- author: mat.author || '',
111
- message: mat.message || '',
112
- revision: mat.revision || '',
113
- tag: mat.tag || '',
114
- webhookData: mat.webhookData || '',
115
- url: mat.url || '',
116
- branch:
117
- (material.ciConfigureSourceType === SourceTypeMap.WEBHOOK
118
- ? material.ciConfigureSourceValue
119
- : mat.branch) || '',
120
- type: material.ciConfigureSourceType || '',
121
- }
122
- })
123
- : [],
124
- filterState,
125
- }
126
- })
127
- return {
128
- materials: materials
129
- }
101
+
102
+ const selectImage =
103
+ !isImageMarked && markFirstSelected && filterState === FilterStates.ALLOWED ? !material.vulnerable : false
104
+ if (selectImage) {
105
+ isImageMarked = true
106
+ }
107
+
108
+ return {
109
+ index: startIndex + index,
110
+ id: material.id,
111
+ deployedTime: material.deployed_time
112
+ ? moment(material.deployed_time).format('ddd, DD MMM YYYY, hh:mm A')
113
+ : 'Not Deployed',
114
+ deployedBy: material.deployedBy,
115
+ wfrId: material.wfrId,
116
+ tab: CDModalTab.Changes,
117
+ image: extractImage(material.image),
118
+ showChanges: false,
119
+ vulnerabilities: [],
120
+ buildTime: material.build_time || '',
121
+ isSelected: selectImage,
122
+ showSourceInfo: false,
123
+ deployed: material.deployed || false,
124
+ latest: material.latest || false,
125
+ vulnerabilitiesLoading: true,
126
+ scanned: material.scanned,
127
+ scanEnabled: material.scanEnabled,
128
+ vulnerable: material.vulnerable,
129
+ runningOnParentCd: material.runningOnParentCd,
130
+ artifactStatus: artifactStatusValue,
131
+ userApprovalMetadata: material.userApprovalMetadata,
132
+ triggeredBy: material.triggeredBy,
133
+ isVirtualEnvironment: material.isVirtualEnvironment,
134
+ imageComment: material.imageComment,
135
+ imageReleaseTags: material.imageReleaseTags,
136
+ // It is going to be null but required in type so can't remove
137
+ lastExecution: material.lastExecution,
138
+ materialInfo: material.material_info
139
+ ? material.material_info.map((mat) => {
140
+ return {
141
+ modifiedTime: mat.modifiedTime
142
+ ? moment(mat.modifiedTime).format('ddd, DD MMM YYYY, hh:mm A')
143
+ : '',
144
+ commitLink: createGitCommitUrl(mat.url, mat.revision),
145
+ author: mat.author || '',
146
+ message: mat.message || '',
147
+ revision: mat.revision || '',
148
+ tag: mat.tag || '',
149
+ webhookData: mat.webhookData || '',
150
+ url: mat.url || '',
151
+ branch:
152
+ (material.ciConfigureSourceType === SourceTypeMap.WEBHOOK
153
+ ? material.ciConfigureSourceValue
154
+ : mat.branch) || '',
155
+ type: material.ciConfigureSourceType || '',
156
+ }
157
+ })
158
+ : [],
159
+ filterState,
160
+ appliedFiltersTimestamp: material.appliedFiltersTimestamp ?? '',
161
+ appliedFilters: material.appliedFilters ?? [],
162
+ appliedFiltersState: material.appliedFiltersState ?? FilterStates.ALLOWED,
163
+ createdTime: material.createdTime ?? '',
164
+ dataSource: material.data_source ?? '',
165
+ }
166
+ })
167
+ return materials
168
+ }
169
+
170
+ const processCDMaterialsApprovalInfo = (enableApproval: boolean, cdMaterialsResult): CDMaterialsApprovalInfo => {
171
+ if (!enableApproval) {
172
+ return {
173
+ approvalUsers: [],
174
+ userApprovalConfig: null,
175
+ requestedUserId: 0,
176
+ }
177
+ }
178
+
179
+ return {
180
+ approvalUsers: cdMaterialsResult.approvalUsers,
181
+ userApprovalConfig: cdMaterialsResult.userApprovalConfig,
182
+ requestedUserId: cdMaterialsResult.requestedUserId,
183
+ }
184
+ }
185
+
186
+ const processCDMaterialsMetaInfo = (cdMaterialsResult): CDMaterialsMetaInfo => {
187
+ if (!cdMaterialsResult) {
188
+ return {
189
+ tagsEditable: false,
190
+ appReleaseTagNames: [],
191
+ hideImageTaggingHardDelete: false,
192
+ resourceFilters: [],
193
+ totalCount: 0,
130
194
  }
195
+ }
196
+
197
+ return {
198
+ appReleaseTagNames: cdMaterialsResult.appReleaseTagNames,
199
+ tagsEditable: cdMaterialsResult.tagsEditable,
200
+ hideImageTaggingHardDelete: cdMaterialsResult.hideImageTaggingHardDelete,
201
+ resourceFilters: cdMaterialsResult.resourceFilters ?? [],
202
+ totalCount: cdMaterialsResult.totalCount ?? 0,
203
+ }
204
+ }
205
+
206
+ const processCDMaterialServiceResponse = (
207
+ cdMaterialsResult,
208
+ stage: DeploymentNodeType,
209
+ offset: number,
210
+ filter: CDMaterialFilterQuery,
211
+ ): CDMaterialResponseType => {
212
+ if (!cdMaterialsResult) {
213
+ return {
214
+ materials: [],
215
+ ...processCDMaterialsMetaInfo(cdMaterialsResult),
216
+ ...processCDMaterialsApprovalInfo(false, cdMaterialsResult),
217
+ }
218
+ }
219
+
220
+ const materials = cdMaterialListModal(
221
+ cdMaterialsResult.ci_artifacts,
222
+ offset ?? 0,
223
+ cdMaterialsResult.latest_wf_artifact_id,
224
+ cdMaterialsResult.latest_wf_artifact_status,
225
+ )
226
+ const approvalInfo = processCDMaterialsApprovalInfo(
227
+ stage === DeploymentNodeType.CD || stage === DeploymentNodeType.APPROVAL,
228
+ cdMaterialsResult,
229
+ )
230
+ const metaInfo = processCDMaterialsMetaInfo(cdMaterialsResult)
231
+
232
+ // TODO: On update of service would remove from here
233
+ const filteredMaterials =
234
+ filter && filter === CDMaterialFilterQuery.RESOURCE
235
+ ? materials.filter((material) => {
236
+ return material.filterState === FilterStates.ALLOWED
237
+ })
238
+ : materials
239
+
240
+ return {
241
+ materials: filteredMaterials,
242
+ ...approvalInfo,
243
+ ...metaInfo,
244
+ }
245
+ }
246
+
247
+ const getSanitizedQueryParams = (queryParams: CDMaterialServiceQueryParams): CDMaterialServiceQueryParams => {
248
+ const { filter, ...rest } = queryParams
249
+ return rest
250
+ }
251
+
252
+ export const genericCDMaterialsService = (
253
+ serviceType: CDMaterialServiceEnum,
254
+ cdMaterialID: number,
255
+ stage: DeploymentNodeType,
256
+ signal: AbortSignal,
257
+ queryParams: CDMaterialServiceQueryParams = {},
258
+ ): Promise<CDMaterialResponseType> => {
259
+ // TODO: On update of service would remove from here
260
+ const manipulatedParams = getSanitizedQueryParams(queryParams)
261
+
262
+ let URL
263
+ switch (serviceType) {
264
+ case CDMaterialServiceEnum.ROLLBACK:
265
+ URL = processURL(`${ROUTES.CD_MATERIAL_GET}/${cdMaterialID}/material/rollback`, manipulatedParams)
266
+ break
267
+
268
+ // Meant for handling getCDMaterialList
269
+ default:
270
+ URL = processURL(`${ROUTES.CD_MATERIAL_GET}/${cdMaterialID}/material`, { ...manipulatedParams, stage: stageMap[stage] })
271
+ break
272
+ }
273
+
274
+ return get(URL, { signal }).then((response) => {
275
+ return processCDMaterialServiceResponse(response.result, stage, queryParams.offset, queryParams.filter)
131
276
  })
132
277
  }
133
278
 
@@ -24,6 +24,7 @@ export const ROUTES = {
24
24
  PROJECT_LIST_MIN: 'team/autocomplete',
25
25
  USER_CHECK_ROLE: 'user/check/roles',
26
26
  IMAGE_TAGGING:'app/image-tagging',
27
+ CD_MATERIAL_GET: 'app/cd-pipeline'
27
28
  }
28
29
 
29
30
  export enum KEY_VALUE {
@@ -27,7 +27,6 @@ export interface ImageTaggingContainerType {
27
27
  setTagsEditable?: (tagsEditable: boolean) => void
28
28
  toggleCardMode?: (id: number) => void
29
29
  hideHardDelete?: boolean
30
- isSuperAdmin?: boolean
31
30
  }
32
31
 
33
32
  export interface ImageButtonType {
@@ -18,8 +18,10 @@ import { showError, stopPropagation } from './Helper'
18
18
  import { TippyCustomized } from './TippyCustomized'
19
19
  import { setImageTags, getUserRole } from './Common.service'
20
20
  import Tippy from '@tippyjs/react'
21
+ import { Progressing } from './Progressing'
21
22
 
22
23
  export const ImageTagsContainer = ({
24
+ // Setting it to zero in case of external pipeline
23
25
  ciPipelineId,
24
26
  artifactId,
25
27
  imageComment,
@@ -32,7 +34,6 @@ export const ImageTagsContainer = ({
32
34
  toggleCardMode,
33
35
  hideHardDelete,
34
36
  forceReInit,
35
- isSuperAdmin
36
37
  }: ImageTaggingContainerType) => {
37
38
  const [initialTags, setInitialTags] = useState<ReleaseTag[]>(imageReleaseTags ? imageReleaseTags : [])
38
39
  const [initialDescription, setInitialDescription] = useState(imageComment ? imageComment.comment : '')
@@ -45,9 +46,14 @@ export const ImageTagsContainer = ({
45
46
  const [createTags, setCreateTags] = useState<ReleaseTag[]>([])
46
47
  const [softDeleteTags, setSoftDeleteTags] = useState<ReleaseTag[]>([])
47
48
  const [hardDeleteTags, setHardDeleteTags] = useState<ReleaseTag[]>([])
49
+ const [isSuperAdmin, setSuperAdmin] = useState<boolean>(false)
48
50
  const [descriptionValidationMessage, setDescriptionValidationMessage] = useState<string>('')
49
51
  const [textInput, setTextInput] = useState<string>('')
52
+ const [loading, setLoading] = useState<boolean>(false)
50
53
 
54
+ useEffect(() => {
55
+ initialise()
56
+ }, [])
51
57
 
52
58
  useEffect(() => {
53
59
  reInitState()
@@ -57,6 +63,16 @@ export const ImageTagsContainer = ({
57
63
  setExistingTags(appReleaseTagNames ? appReleaseTagNames : [])
58
64
  }, [appReleaseTagNames])
59
65
 
66
+ async function initialise() {
67
+ try {
68
+ const userRole = await getUserRole()
69
+
70
+ const superAdmin = userRole?.result?.roles?.includes('role:super-admin___')
71
+ setSuperAdmin(superAdmin)
72
+ } catch (err) {
73
+ showError(err)
74
+ }
75
+ }
60
76
 
61
77
  const reInitState = () => {
62
78
  if (forceReInit || !isEditing) {
@@ -213,7 +229,8 @@ export const ImageTagsContainer = ({
213
229
  }
214
230
 
215
231
  // set loading state true
216
- setImageTags(payload, ciPipelineId, artifactId)
232
+ setLoading(true)
233
+ setImageTags(payload, ciPipelineId ?? 0, artifactId)
217
234
  .then((res) => {
218
235
  const tags = res.result?.imageReleaseTags?.map((tag) => ({
219
236
  id: tag.id,
@@ -249,6 +266,9 @@ export const ImageTagsContainer = ({
249
266
  showError(err)
250
267
  }
251
268
  })
269
+ .finally(()=>{
270
+ setLoading(false)
271
+ })
252
272
  }
253
273
 
254
274
  const renderInfoCard = (): JSX.Element => {
@@ -425,6 +445,7 @@ export const ImageTagsContainer = ({
425
445
  stopPropagation(e)
426
446
  handleCancel()
427
447
  }}
448
+ disabled={loading}
428
449
  >
429
450
  Cancel
430
451
  </button>
@@ -436,8 +457,9 @@ export const ImageTagsContainer = ({
436
457
  stopPropagation(e)
437
458
  onClickSave()
438
459
  }}
460
+ disabled={loading}
439
461
  >
440
- Save
462
+ {loading ? <Progressing /> : 'Save'}
441
463
  </button>
442
464
  </div>
443
465
  </div>
@@ -221,6 +221,10 @@ export enum FilterStates {
221
221
  ERROR = 2,
222
222
  }
223
223
 
224
+ export enum MaterialDataSource {
225
+ EXTERNAL = "ext"
226
+ }
227
+
224
228
  export interface CDMaterialType {
225
229
  index: number
226
230
  id: string
@@ -247,6 +251,36 @@ export interface CDMaterialType {
247
251
  imageReleaseTags?: ReleaseTag[]
248
252
  artifactStatus?: string
249
253
  filterState: FilterStates
254
+ // Not even coming from API but required in CDMaterials for Security which makes its own api call but stores data in CDMaterials
255
+ scanToolId?: number
256
+ appliedFiltersTimestamp?: string
257
+ appliedFilters?: FilterConditionsListType[]
258
+ appliedFiltersState?: FilterStates
259
+ createdTime?: string
260
+ deployed?: boolean
261
+ dataSource?: MaterialDataSource
262
+ }
263
+
264
+ export enum CDMaterialServiceEnum {
265
+ ROLLBACK = 'rollback',
266
+ CD_MATERIALS = 'cd-materials',
267
+ }
268
+
269
+ export enum CDMaterialResourceQuery {
270
+ PENDING_APPROVAL = 'PENDING_APPROVAL'
271
+ }
272
+
273
+ export enum CDMaterialFilterQuery {
274
+ RESOURCE = 'ELIGIBLE_RESOURCES',
275
+ ALL = 'ALL_RESOURCES'
276
+ }
277
+
278
+ export interface CDMaterialServiceQueryParams {
279
+ search?: string
280
+ offset?: number
281
+ size?: number
282
+ resource?: CDMaterialResourceQuery
283
+ filter?: CDMaterialFilterQuery
250
284
  }
251
285
 
252
286
  export interface CommonNodeAttr {
@@ -362,15 +396,22 @@ export interface FilterConditionsListType {
362
396
  conditions: FilterConditionsInfo[]
363
397
  }
364
398
 
365
- export interface CDMaterialResponseType {
399
+ export interface CDMaterialsApprovalInfo {
366
400
  approvalUsers: string[]
367
- materials: any[]
368
401
  userApprovalConfig: UserApprovalConfigType
369
402
  requestedUserId: number
403
+ }
404
+
405
+ export interface CDMaterialsMetaInfo {
370
406
  tagsEditable: boolean
371
407
  appReleaseTagNames: string[]
372
408
  hideImageTaggingHardDelete: boolean
373
409
  resourceFilters?: FilterConditionsListType[]
410
+ totalCount: number
411
+ }
412
+
413
+ export interface CDMaterialResponseType extends CDMaterialsMetaInfo, CDMaterialsApprovalInfo {
414
+ materials: CDMaterialType[]
374
415
  }
375
416
 
376
417
  export interface InputDetailType {