From a76e1e06f83c334d49b6ceb0c69d7badb5682547 Mon Sep 17 00:00:00 2001 From: ranadheer-bolli Date: Wed, 1 Mar 2023 16:43:20 +0530 Subject: [PATCH] feat:added autofix screen --- .../modules/admin/admin.module.ts | 2 + .../create-edit-policy.component.css | 57 ++- .../create-edit-policy.component.html | 178 +++----- .../create-edit-policy.component.ts | 430 ++++++++---------- .../invoke-rule/invoke-rule.component.ts | 4 +- .../admin/policies/policies.component.html | 4 +- .../admin/policies/policies.component.ts | 128 +++--- .../policy-knowledgebase-details.component.ts | 4 +- .../app/shared/dropdown/dropdown.component.ts | 12 +- .../input-field/input-field.component.css | 12 + .../input-field/input-field.component.html | 9 + .../input-field/input-field.component.spec.ts | 25 + .../input-field/input-field.component.ts | 23 + webapp/src/app/shared/shared.module.ts | 7 +- .../app/shared/stepper/stepper.component.css | 4 +- .../app/shared/stepper/stepper.component.html | 9 - .../app/shared/stepper/stepper.component.ts | 12 +- .../src/app/shared/table/table.component.css | 4 + .../src/app/shared/table/table.component.html | 65 ++- .../src/app/shared/table/table.component.ts | 30 +- webapp/src/assets/icons/autofix.svg | 3 + webapp/src/assets/icons/no-autofix.svg | 3 + webapp/src/environments/environment.prod.ts | 14 +- webapp/src/environments/environment.stg.ts | 14 +- webapp/src/environments/environment.ts | 10 +- webapp/src/styles.css | 6 +- 26 files changed, 525 insertions(+), 544 deletions(-) create mode 100644 webapp/src/app/shared/input-field/input-field.component.css create mode 100644 webapp/src/app/shared/input-field/input-field.component.html create mode 100644 webapp/src/app/shared/input-field/input-field.component.spec.ts create mode 100644 webapp/src/app/shared/input-field/input-field.component.ts create mode 100644 webapp/src/assets/icons/autofix.svg create mode 100644 webapp/src/assets/icons/no-autofix.svg diff --git a/webapp/src/app/pacman-features/modules/admin/admin.module.ts b/webapp/src/app/pacman-features/modules/admin/admin.module.ts index aea4e04c44..227fdb7951 100644 --- a/webapp/src/app/pacman-features/modules/admin/admin.module.ts +++ b/webapp/src/app/pacman-features/modules/admin/admin.module.ts @@ -50,11 +50,13 @@ import { MatNativeDateModule } from '@angular/material/core'; import { MatInputModule } from "@angular/material/input"; import { UserManagementComponent } from './user-management/user-management.component'; import { AdminService } from "../../services/all-admin.service"; +import {MatSlideToggleModule} from '@angular/material/slide-toggle'; @NgModule({ imports: [ CommonModule, SharedModule, + MatSlideToggleModule, AdminRoutingModule, MatInputModule, MatDatepickerModule, diff --git a/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.css b/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.css index 0f782c8cd3..edbadd3bcf 100644 --- a/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.css +++ b/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.css @@ -37,10 +37,9 @@ .right-wrapper{ display: flex; flex-direction: column; -width: 80%; +width: calc(100% - 200px); padding-left:24px; overflow: scroll; -border-left: 2px solid var(--border-200); } .type-wrapper{ @@ -51,15 +50,6 @@ border-left: 2px solid var(--border-200); align-items: center; } -.input-wrapper{ - display: flex; - align-items: center; - gap: 12px; -} -.input-wrapper ::ng-deep .mat-form-field-label{ - padding: 5px 5px !important; -} - .right-wrapper ::ng-deep .mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label{ width: auto !important; padding: 3px 8px !important; @@ -140,9 +130,8 @@ flex-direction: column; gap: 16px; } -.form-wrapper-header{ - font: var(--text-subtitle-1); - color: var(--text-medium-emphasis); +.gap-20{ + gap: 20px; } .remove-icon{ @@ -161,7 +150,38 @@ gap: 16px; .isDisabled{ pointer-events: none; - opacity: 40%; + opacity: 60%; +} + +::ng-deep .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb-container{ + transform: translate3d(20px, 0, 0) !important; +} + +::ng-deep .mat-slide-toggle-thumb-container{ + top: 1px !important; + left: 3px !important; +} + +::ng-deep .mat-slide-toggle-thumb{ + height: 10px !important; + width: 10px !important; + background-color: white !important; +} + +::ng-deep .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb{ + background-color: white !important; +} + +::ng-deep .mat-slide-toggle-bar{ + background-color: var(--border-200) !important; +} + +::ng-deep .mat-slide-toggle.mat-checked .mat-slide-toggle-bar{ + background-color: var(--primary-400) !important; +} + +::ng-deep .mat-ripple{ + display: none !important; } .isEnabled{ @@ -256,12 +276,17 @@ input{ .right-wrapper ::ng-deep .mat-select-trigger{ height: 30px !important; + z-index: 100; } -.details-wrapper ::ng-deep .mat-form-field{ +.details-wrapper, .autofix-wrapper ::ng-deep .mat-form-field{ width: 100% !important; } +.notification-wrapper{ + padding-top: 24px; +} + .hide{ display: none; } diff --git a/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.html b/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.html index a4f3403a61..7e344bbf84 100644 --- a/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.html +++ b/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.html @@ -5,169 +5,97 @@
-
{{pageTitle}} - Follow the steps below to create a policy for an asset type + Follow the steps below to Edit a policy for an asset type
- {{FormHeader}} +
+ {{FormHeader}} + +
-
-
+
+ +
+ + + -
- - No File - Choosen -
-
- {{policyJarFileName}} -
- -
-
-
-
- - Policy Url - - -
- -
-
-
-
-
-
- - Policy Name - - -
- -
-
- - - -
-
+
Select Key Enter Value
-
- - - - - - -
- - +
+
+ + + +
+
+
+ + + + +
+
+
+ Mute Notification + +
+
+ + + + +
+ + + +
+
- - - - +
diff --git a/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.ts b/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.ts index 78a87dc0ea..e50160a4b3 100644 --- a/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.ts +++ b/webapp/src/app/pacman-features/modules/admin/create-edit-policy/create-edit-policy.component.ts @@ -31,6 +31,7 @@ import { UploadFileService } from '../../../services/upload-file-service'; import { MatDialog } from '@angular/material/dialog'; import { DialogBoxComponent } from 'src/app/shared/components/molecules/dialog-box/dialog-box.component'; import { NotificationObservableService } from 'src/app/shared/services/notification-observable.service'; +import { DATA_MAPPING } from 'src/app/shared/constants/data-mapping'; @Component({ selector: 'app-admin-create-edit-policy', @@ -45,18 +46,16 @@ import { NotificationObservableService } from 'src/app/shared/services/notificat }) export class CreateEditPolicyComponent implements OnInit, OnDestroy { - policyTypeList = ["Federated", "Serverless"]; selectedAssetType = ""; resolutionUrl = ""; isDisabled = true; currentStepperIndex = 0; + currentStepperName = ""; description = ""; readonly = true; policyLoader = false; - pageTitle = 'Create Policy'; + pageTitle = 'Edit Policy'; FormHeader = "Policy Details"; - ispolicyIdValid = -1; - isCreate; allPolicies = []; breadcrumbArray = ['policys']; breadcrumbLinks = ['policys']; @@ -66,7 +65,7 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { errorMessage; showingArr = ['policyName', 'policyId', 'policyDesc']; allColumns = []; - submitBtn = "Create"; + submitBtn = "Update"; totalRows = 0; currentBucket = []; bucketNumber = 0; @@ -76,17 +75,11 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { seekdata = false; showLoader = true; allMonthDays = []; - policyIds = []; allEnvironments = []; allpolicyParamKeys = []; allEnvParamKeys = []; allPolicyParams = Object(); - paramsList = [{ - "key": "", - "value": "", - "isEdit": false, - "isMandatory": false - }]; + paramsList = []; hideContent = false; ispolicyCreationFailed = false; ispolicyCreationSuccess = false; @@ -122,9 +115,8 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { assetGroupNames = []; datasourceDetails = []; targetTypesNames = []; - policyCategories = []; + policyCategories = ["cost","security","operations","tagging"]; policySeverities = ["critical", "high", "medium", "low"]; - allPolicyIds = []; policyJarFile; currentFileUpload: File; selectedFiles: FileList; @@ -136,6 +128,7 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { selectedpolicyName = ''; selectedTargetType = ''; isAutofixEnabled = false; + emailId : string; isRequired = true; public labels; @@ -143,9 +136,7 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { private pageLevel = 0; public backButtonRequired; private routeSubscription: Subscription; - private getKeywords: Subscription; private previousUrlSubscription: Subscription; - private downloadSubscription: Subscription; selectedCategory: any; selectedSeverity: any; selectedMonthId: number; @@ -160,12 +151,42 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { selectedPolicyType: any; policyName = ""; policyId: any; - isPolicyIdValid: number; policyDetails: any; resolution = ""; - isFileChanged: boolean = false; policyUrl = ""; - isManagePolicy: boolean = false; + stepperData = [ + { + id: 0, + name: "Policy Details" + }, + { + id: 1, + name: "Policy Parameters" + }, + { + id: 2, + name: "Autofix" + } + ] + isSilentNotificationEnabled = false; + isAutofixAvailable = false; + updatedAccounts: string[]; + attributeList : string[] = ["A","V"]; + selectedAttributes: string[]; + updatedAttributes: string[]; + selectedAccounts: string[]; + accountList: string[] = []; + fixMailSubject: string; + postFixMessage: string; + violationMessage: string; + warningMessage: any; + warningMailSubject: any; + index: string; + waitingTime: any; + maxEmailNotification: any; + elapsedTime: any; + fixType: any; + showAutofix = false; constructor( @@ -213,11 +234,7 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { } else this.currentStepperIndex++; - if (this.currentStepperIndex == 0) { - this.FormHeader = "Policy Details"; - } else { - this.FormHeader = "Policy Parameters"; - } + this.selectedStepperIndex(this.currentStepperIndex); } getDatasourceDetails() { @@ -280,96 +297,54 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { onSubmit(form: NgForm) { this.hideContent = true; this.policyLoader = true; - console.log(form.value, "Form"); - this.buildCreatepolicyModel(form.value); - } - - ispolicyIdAvailable(policyIdKeyword) { - if (policyIdKeyword.trim().length === 0) { - this.ispolicyIdValid = -1; - } else { - const isKeywordExits = this.policyIds.findIndex(item => policyIdKeyword.trim().toLowerCase() === item.trim().toLowerCase()); - if (isKeywordExits === -1) { - this.ispolicyIdValid = 1; - } else { - this.ispolicyIdValid = 0; - } - } - } - - getAllpolicyIds() { - this.policyPolicyLoader = true; - this.contentHidden = true; - this.policyPolicyLoaderFailure = false; - const url = environment.allPolicyIds.url; - const method = environment.allPolicyIds.method; - this.adminService.executeHttpAction(url, method, {}, {}).subscribe(reponse => { - this.policyIds = reponse[0]; - }, - error => { - this.contentHidden = true; - this.policyPolicyLoader = false; - this.policyPolicyLoaderFailure = true; - this.policyIds = []; - this.errorMessage = 'apiResponseError'; - this.showLoader = false; - }); + this.buildCreatepolicyModel(); } - private buildCreatepolicyModel(policyForm: any) { + private buildCreatepolicyModel() { const PolicyModel = Object(); PolicyModel.policyType = this.selectedPolicyType; - if (this.isPolicyIdValid && policyForm.policyDisplayName == this.policyDisplayName) { - PolicyModel.policyDisplayName = this.policyDisplayName; - PolicyModel.policyId = this.policyId; - PolicyModel.policyName = this.policyName; - } - else { - PolicyModel.policyDisplayName = policyForm.policyDisplayName; - PolicyModel.policyName = policyForm.policyDisplayName + '_' + this.selectedAssetGroup + '_' + this.selectedAssetType; - PolicyModel.policyName = PolicyModel.policyName.replace(/\s/g, '-'); - PolicyModel.policyId = PolicyModel.policyName; - } + PolicyModel.policyDisplayName = this.policyDisplayName; + PolicyModel.policyId = this.policyId; + PolicyModel.policyName = this.policyName; PolicyModel.targetType = this.selectedAssetType; PolicyModel.severity = this.selectedSeverity; PolicyModel.category = this.selectedCategory; - PolicyModel.policyDesc = policyForm.description; - PolicyModel.resolution = policyForm.resolution; - PolicyModel.resolutionUrl = policyForm.resolutionUrl; + PolicyModel.policyDesc = this.description; + PolicyModel.resolution = this.resolution; + PolicyModel.resolutionUrl = this.resolutionUrl; PolicyModel.assetGroup = this.selectedAssetGroup; PolicyModel.policyExecutable = this.policyJarFileName; PolicyModel.policyRestUrl = this.policyUrl; PolicyModel.policyParams = this.buildpolicyParams(); - PolicyModel.isFileChanged = this.isFileChanged; PolicyModel.policyFrequency = "0 0 ? * MON *"; - PolicyModel.isAutofixEnabled = false; - - if (this.isFileChanged && this.selectedPolicyType === 'Federated') { - this.currentFileUpload = this.selectedFiles.item(0); - } else { - this.currentFileUpload = new File([''], ''); + PolicyModel.autoFixAvailable = this.isAutofixAvailable; + PolicyModel.autofixEnabled = this.isAutofixEnabled; + + if(PolicyModel.autoFixAvailable){ + PolicyModel.allowList = this.selectedAccounts; + PolicyModel.fixMailSubject = this.fixMailSubject; + PolicyModel.fixMessage = this.postFixMessage; + PolicyModel.violationMessage = this.violationMessage; + PolicyModel.waitingTime = this.waitingTime; + PolicyModel.maxEmailNotification = this.maxEmailNotification; + PolicyModel.warningMessage = this.warningMessage; + PolicyModel.warningMailSubject = this.warningMailSubject; + PolicyModel.elapsedTime = this.elapsedTime; + PolicyModel. fixType = this.isSilentNotificationEnabled?"silent":"non-silent"; } - console.log(PolicyModel, "PolicyModel"); - if (this.selectedPolicyType == "Federated") { - const isFormValid = this.isValid(PolicyModel); - this.openDialog(PolicyModel, isFormValid); - } - else { - this.createOrUpdatepolicy(PolicyModel); - } - } - isValid(PolicyModel: any) { - return true; + this.currentFileUpload = new File([''], ''); + console.log(PolicyModel," PolicyModel "); + this.updatePolicy(PolicyModel); } - createOrUpdatepolicy(PolicyModel: any) { - const url = this.isPolicyIdValid ? environment.updatePolicy.url : environment.createPolicy.url; - const method = environment.createPolicy.method; + updatePolicy(PolicyModel: any) { + const url = environment.updatePolicy.url; + const method = environment.updatePolicy.method; this.uploadService.pushFileToStorage(url, method, this.currentFileUpload, PolicyModel).subscribe(event => { this.policyLoader = false; this.ispolicyCreationSuccess = true; - this.notificationObservableService.postMessage("Policy " + this.policyDisplayName + (this.isCreate ? " created" : " updated") + " successfully!!", 500, "success", "green-info-circle"); + this.notificationObservableService.postMessage("Policy " + this.policyDisplayName + " updated successfully!!", 3000, "variant1", "green-info-circle"); }, error => { this.ispolicyCreationFailed = true; @@ -388,25 +363,19 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { private buildpolicyParams() { const policyParms = Object(); - for (let i = 0; i < this.paramsList.length; i++) { - if (!this.paramsList[i].key || !this.paramsList[i].value) { - this.paramsList.splice(i, 1); - } - } policyParms.params = this.paramsList; policyParms.environmentVariables = this.allEnvironments; return JSON.stringify(policyParms); } - private getpolicyRestUrl(policyForm) { - const policyType = policyForm.policyType; - if (policyType === 'Serverless') { - return policyForm.resolutionUrl; - } else { - return ''; - } + toggleAutofix(event:any){ + this.isAutofixEnabled = event.checked; } + toggleSilentNotification(event:any){ + this.isSilentNotificationEnabled = event.checked; + } + onSelectCategory(selectedCategory) { this.selectedCategory = selectedCategory; } @@ -415,120 +384,44 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { this.selectedSeverity = selectedSeverity; } - - onSelectAssetType(selectedAssetType) { - this.selectedAssetType = selectedAssetType; - } - closeErrorMessage() { this.ispolicyCreationFailed = false; this.hideContent = false; } - onJarFileChange(event) { - this.selectedFiles = event.target.files; - this.policyJarFileName = this.selectedFiles[0].name; - const extension = this.policyJarFileName.substring(this.policyJarFileName.lastIndexOf('.') + 1); - if (extension !== 'jar') { - this.removeJarFileName(); - } - this.isFileChanged = true; - } - - removePolicyParameters(index: number): void { - if (this.paramsList[index].key != "policyKey") - this.paramsList.splice(index, 1); - } - - addPolicyParameters() { - this.paramsList.push({ - "key": "", - "value": "", - "isEdit": true, - "isMandatory": false - }); - } - - removeJarFileName() { - this.policyJarFileName = ''; - this.policyJarFile = ''; - this.isFileChanged = true; - } - - openJarFileBrowser(event) { - const element: HTMLElement = document.getElementById('selectJarFile') as HTMLElement; - element.click(); - } - getTargetTypeNamesByDatasourceName(datasourceName) { const url = environment.targetTypesByDatasource.url; const method = environment.targetTypesByDatasource.method; this.adminService.executeHttpAction(url, method, {}, { dataSourceName: datasourceName }).subscribe(reponse => { this.showLoader = false; - this.targetTypesNames = reponse[0]; - }, - error => { - this.allPolicyIds = []; - this.errorMessage = 'apiResponseError'; - this.showLoader = false; - }); - } - - getAllPolicyIds() { - this.policyPolicyLoader = true; - this.contentHidden = true; - this.policyPolicyLoaderFailure = false; - const url = environment.allPolicyIds.url; - const method = environment.allPolicyIds.method; - this.adminService.executeHttpAction(url, method, {}, {}).subscribe(reponse => { - this.allPolicyIds = reponse[0]; + this.targetTypesNames = [...reponse[0]]; }, error => { - this.contentHidden = true; - this.policyPolicyLoader = false; - this.policyPolicyLoaderFailure = true; - this.allPolicyIds = []; this.errorMessage = 'apiResponseError'; this.showLoader = false; }); } - public onSelectAssetGroup(selectedAssetGroup: any): void { - this.selectedAssetGroup = selectedAssetGroup; - this.getTargetTypeNamesByDatasourceName(selectedAssetGroup); - } - - addpolicyParameters(parametersInput: any, isEncrypted: any) { - if (parametersInput.policyKey !== '' && parametersInput.policyValue !== '') { - this.allPolicyParams.push({ key: parametersInput.policyKey.trim(), value: parametersInput.policyValue.trim(), encrypt: isEncrypted.checked }); - this.allpolicyParamKeys.push(parametersInput.policyKey.trim()); - parametersInput.policyKey = ''; - parametersInput.policyValue = ''; - isEncrypted.checked = false; - } - } - selectedStepperIndex(event: any) { + const index = this.stepperData.findIndex(element => element.id == event); this.currentStepperIndex = event; + this.currentStepperName = this.stepperData[index].name; + this.FormHeader = this.currentStepperName ; } onSelectPolicyId(policyId: any) { this.selectedPolicyId = policyId; this.getPolicyDetails(policyId); - this.ispolicyIdAvailable(this.selectedPolicyId + '_' + this.selectedpolicyName + '_' + this.selectedAssetType); } onSelectTargetType(targetType: any) { this.selectedTargetType = targetType; - this.ispolicyIdAvailable(this.selectedPolicyId + '_' + this.selectedpolicyName + '_' + this.selectedAssetType); } onSelectFrequency(frequencyType: any) { this.selectedFrequency = frequencyType; } getData() { - this.getpolicyCategoryDetails(); this.getDatasourceDetails(); - this.getAllPolicyIds(); } /* @@ -541,29 +434,19 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { // this.filterText saves the queryparam const currentQueryParams = this.routerUtilityService.getQueryParametersFromSnapshot(this.router.routerState.snapshot.root); if (currentQueryParams) { - this.FullQueryParams = currentQueryParams; this.queryParamsWithoutFilter = JSON.parse(JSON.stringify(this.FullQueryParams)); this.policyId = this.queryParamsWithoutFilter.policyId; + this.showAutofix = this.queryParamsWithoutFilter.showAutofix == "true"; delete this.queryParamsWithoutFilter['filter']; this.dataSourceName = this.queryParamsWithoutFilter.ag; if (this.policyId) { - this.policyTypeList.push("ManagePolicy"); - this.submitBtn = "Update"; - this.pageTitle = 'Edit Policy'; this.breadcrumbPresent = 'Edit Policy'; this.isDisabled = false; this.readonly = false; - this.isCreate = false; this.hideContent = true; - this.getpolicyCategoryDetails(); - this.isPolicyIdValid = 1; + // this.getpolicyCategoryDetails(); this.getPolicyDetails(this.policyId); - } else { - this.pageTitle = 'Create Policy'; - this.breadcrumbPresent = 'Create Policy'; - this.isCreate = true; - this.getAllPolicyIds(); } this.FullQueryParams = currentQueryParams; @@ -597,8 +480,8 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { * the filter array ,so that filter keynames are changed */ getPolicyDetails(policyId: any) { - let url = environment.getPolicyById.url; - let method = environment.getPolicyById.method; + let url = environment.getPolicyDetailsById.url; + let method = environment.getPolicyDetailsById.method; this.adminService.executeHttpAction(url, method, {}, { policyId: policyId }).subscribe(reponse => { this.policyDetails = reponse[0]; @@ -606,78 +489,133 @@ export class CreateEditPolicyComponent implements OnInit, OnDestroy { this.selectedSeverity = this.policyDetails.severity; this.selectedCategory = this.policyDetails.category; this.policyId = this.policyDetails.policyId; - if (!this.isCreate) { - this.policyDisplayName = this.policyDetails.policyDisplayName; - this.selectedPolicyType = this.policyDetails.policyType; - if (this.selectedPolicyType == "ManagePolicy") { - this.isManagePolicy = true; - } - } + this.policyDisplayName = this.policyDetails.policyDisplayName; + this.selectedPolicyType = this.policyDetails.policyType; this.policyName = this.policyDetails.policyName; this.selectedAssetGroup = this.policyDetails.assetGroup; - this.policyJarFileName = this.policyDetails.policyExecutable; this.policyUrl = this.policyDetails.policyRestUrl; this.selectedAssetType = this.policyDetails.targetType; this.description = this.policyDetails.policyDesc; this.resolution = this.policyDetails.resolution; this.resolutionUrl = this.policyDetails.resolutionUrl; + this.isAutofixAvailable = this.policyDetails.autoFixAvailable == "true"; + this.isAutofixEnabled =this.policyDetails.autoFixEnabled == "true"; + + + if(!this.isAutofixAvailable) + this.removeStepper("Autofix"); + else{ + this.getAccounts(); + this.selectedAccounts = this.policyDetails.allowList.split(",").slice(); + this.fixMailSubject = this.policyDetails.fixMailSubject; + this.postFixMessage = this.policyDetails.fixMessage; + this.violationMessage = this.policyDetails.violationMessage; + this.waitingTime = this.policyDetails.waitingTime; + this.maxEmailNotification = this.policyDetails.maxEmailNotification; + this.warningMessage = this.policyDetails.warningMessage; + this.warningMailSubject = this.policyDetails.warningMailSubject; + this.elapsedTime = this.policyDetails.elapsedTime; + this.fixType = this.policyDetails.fixType; + this.isSilentNotificationEnabled = this.fixType == "silent"; + } this.allPolicyParams = JSON.parse(this.policyDetails.policyParams)["params"]; this.paramsList = []; + let hasEditableParameters = false; for (let i = this.allPolicyParams.length - 1; i >= 0; i -= 1) { - if (this.allPolicyParams[i]["key"] == 'severity') { - this.selectedSeverity = this.allPolicyParams[i]["value"]; - this.allPolicyParams.splice(i, 1); - } else if (this.allPolicyParams[i]["key"] == 'policyCategory') { - if (this.allPolicyParams[i]["value"].toLowerCase() == "costoptimization") { - this.allPolicyParams[i]["value"] = "cost"; - } - else if (this.allPolicyParams[i]["value"].toLowerCase() == "governance") { - this.allPolicyParams[i]["value"] = "operations"; - } - this.selectedCategory = this.allPolicyParams[i]["value"]; - this.allPolicyParams.splice(i, 1); - } else { - this.paramsList.push( - { + if(this.allPolicyParams[i]["isEdit"]){ + hasEditableParameters = true; + } + this.paramsList.push( + { "key": this.allPolicyParams[i]["key"], "value": this.allPolicyParams[i]["value"], "isEdit": this.allPolicyParams[i]["isEdit"] ? this.allPolicyParams[i]["isEdit"] : false, - "isMandatory": this.allPolicyParams[i]["isMandatory"] ? this.allPolicyParams[i]["isMandatory"] : false - } - ) - } + "isMandatory": this.allPolicyParams[i]["isMandatory"] ? this.allPolicyParams[i]["isMandatory"] : false, + "description": this.allPolicyParams[i]["description"], + "displayName": this.allPolicyParams[i]["displayName"] + } + ) + } + + if (!hasEditableParameters) { + this.removeStepper("Policy Parameters"); } - if (this.paramsList.length == 0) { - this.paramsList.push({ - "key": "", - "value": "", - "isEdit": false, - "isMandatory": false - }); - } - // if (this.selectedPolicyType == "ManagePolicy") { - // this.isDisabled = true; - // } + this.stepperData.forEach((data,index)=>{ + data.id = index; + }) + if(this.showAutofix){ + const currentStepperIndex = this.stepperData.findIndex(data=> data.name == "Autofix"); + this.selectedStepperIndex(currentStepperIndex); + }else{ + this.currentStepperIndex = 0; + this.selectedStepperIndex(0); + } this.getTargetTypeNamesByDatasourceName(this.selectedAssetGroup); this.hideContent = false; }, error => { + this.logger.log("Error",error); }); } - openDialog(PolicyModel: any, valid: boolean): void { - const title = valid ? "Policy Validated Successfully!" : "Policy Validation Failed!" - const message = valid ? "Policy " + this.policyDisplayName + " has been validated. Confirm to create policy or discard run" : "Please fill the missing policy details"; - const yesButtonLabel = this.isCreate ? "Create" : "Update"; - const noButtonLabel = valid ? "Discard" : "Close"; + getAccounts(){ + + try{ + const url = environment.listTargetTypeAttributeValues.url; + const method = environment.listTargetTypeAttributeValues.method; + + let index = "",field="",accounts=[]; + if(this.selectedAssetGroup == "aws"){ + index = "/aws_account"; + field = "accountid.keyword"; + } else if(this.selectedAssetGroup == "azure"){ + index = "/azure_subscription"; + field = "subscription.keyword"; + } else{ + index = "/gcp_vminstance" + field = "projectId.keyword"; + + } + const payload = { + index: index +"/_search?filter_path=aggregations.alldata.buckets.key", + payload : '{"size":0,"aggs":{"alldata":{"terms":{"field":"'+field+'","size":10000}}}}' + } + this.adminService.executeHttpAction(url,method,payload,{}).subscribe(response=>{ + const aggregations = response[0]?.data?.aggregations; + const alldata = aggregations.alldata; + const buckets = alldata.buckets; + buckets.forEach(element => { + accounts.push(element.key); + }); + this.accountList = accounts; + }) + } catch (error) { + this.errorMessage = this.errorHandling.handleJavascriptError(error); + this.logger.log('error', error); + } + } + + onAccountsChange(updatedAccounts:any){ + this.updatedAccounts = updatedAccounts; + } + + removeStepper(stepperName: string){ + this.stepperData= this.stepperData.filter(element=> element.name != stepperName); + } + + openDialog(PolicyModel: any): void { + const title = "Update Policy!" + const yesButtonLabel = "Update"; const dialogRef = this.dialog.open(DialogBoxComponent, { width: '500px', - data: valid ? { title: title, message: message, yesButtonLabel: yesButtonLabel, noButtonLabel: noButtonLabel } : { title: title, message: message, noButtonLabel: noButtonLabel }, + data: { title: title, + yesButtonLabel: yesButtonLabel, + } }); dialogRef.afterClosed().subscribe(result => { if (result == "yes") { - this.createOrUpdatepolicy(PolicyModel); + this.updatePolicy(PolicyModel); } }); } diff --git a/webapp/src/app/pacman-features/modules/admin/invoke-rule/invoke-rule.component.ts b/webapp/src/app/pacman-features/modules/admin/invoke-rule/invoke-rule.component.ts index 58b1a09204..c76e14f51f 100644 --- a/webapp/src/app/pacman-features/modules/admin/invoke-rule/invoke-rule.component.ts +++ b/webapp/src/app/pacman-features/modules/admin/invoke-rule/invoke-rule.component.ts @@ -129,8 +129,8 @@ export class InvokeRuleComponent implements OnInit, OnDestroy { invokeRule() { this.hideContent = true; this.ruleLoader = true; - var url = environment.invokeRule.url; - var method = environment.invokeRule.method; + var url = environment.invokePolicy.url; + var method = environment.invokePolicy.method; this.adminService.executeHttpAction(url, method, this.allOptionalRuleParams, {policyId:this.policyId}).subscribe(reponse => { this.ruleLoader = false; this.isRuleInvokeSuccess = true; diff --git a/webapp/src/app/pacman-features/modules/admin/policies/policies.component.html b/webapp/src/app/pacman-features/modules/admin/policies/policies.component.html index 7e432d582e..2fa5cbf25d 100644 --- a/webapp/src/app/pacman-features/modules/admin/policies/policies.component.html +++ b/webapp/src/app/pacman-features/modules/admin/policies/policies.component.html @@ -24,7 +24,7 @@

{{pageTitle}}

  • - {{pageTitle}}
    - {{action}} Policy + {{action}} Are you really sure you want to {{action.toLowerCase()}} "{{selectedRowTitle}}"?
    \ No newline at end of file diff --git a/webapp/src/app/pacman-features/modules/admin/policies/policies.component.ts b/webapp/src/app/pacman-features/modules/admin/policies/policies.component.ts index cfaf6dc7fa..6fcf3d97bb 100644 --- a/webapp/src/app/pacman-features/modules/admin/policies/policies.component.ts +++ b/webapp/src/app/pacman-features/modules/admin/policies/policies.component.ts @@ -365,6 +365,8 @@ export class PoliciesComponent implements OnInit, OnDestroy { let cellData; for (var row = 0; row < getData.length; row++) { + const autoFixAvailable = getData[row].autoFixAvailable; + const autoFixEnabled = getData[row].autoFixEnabled; innerArr = {}; keynames.forEach(col => { cellData = getData[row][col]; @@ -383,19 +385,28 @@ export class PoliciesComponent implements OnInit, OnDestroy { // menuItems: [], // add this if isMenuBtn } if(col.toLowerCase()=="title"){ - cellObj = { + cellObj = { ...cellObj, + imgSrc: autoFixAvailable == "true" ?autoFixEnabled == "true" ?"autofix":"no-autofix":"noImg", isLink: true }; } else if (col.toLowerCase() == "actions") { - let dropDownItems: Array = ["Edit"]; + let dropDownItems: Array = ["Edit Policy"]; + if (autoFixAvailable === "true"){ + dropDownItems.push("Edit Autofix"); + if(autoFixEnabled == "true") { + dropDownItems.push("Disable Autofix"); + } else { + dropDownItems.push("Enable Autofix"); + } + } if (getData[row].Status.toLowerCase() === "enabled") { - dropDownItems.push("Disable"); - // dropDownItems.push("Invoke"); + dropDownItems.push("Disable Policy"); } else { - dropDownItems.push("Enable"); + dropDownItems.push("Enable Policy"); } + dropDownItems.push("Run Policy"); cellObj = { ...cellObj, isMenuBtn: true, @@ -435,57 +446,28 @@ export class PoliciesComponent implements OnInit, OnDestroy { } } - enableDisableRuleOrJob(event) { - try { + enableDisableRuleOrJob(policyId,action) { const url = environment.enableDisableRuleOrJob.url; const method = environment.enableDisableRuleOrJob.method; const params = {}; - params['policyId'] = event.rowSelected["Policy ID"].text; - - params['action'] = event.action; + params['policyId'] = policyId; + params['action'] = action; this.adminService.executeHttpAction(url, method, {}, params).subscribe(response => { - // event.rowSelected["Status"].text = event.action+"d"; - event.rowSelected["Status"] = { - ...event.rowSelected["Status"], - text: event.action+"d", - titleText: event.action+"d", - chipVariant: event.action.toLowerCase()=="enable"?"variant1":"variant2", - } - - let dropDownItems = ["Edit"]; - if (event.rowSelected["Status"].text.toLowerCase() === "enabled") { - dropDownItems.push("Disable"); - // dropDownItems.push("Invoke"); - } else { - dropDownItems.push("Enable"); - } - event.rowSelected["Actions"] = { - ...event.rowSelected["Actions"], - menuItems: dropDownItems, - } - const snackbarText = 'Policy "' + event.rowSelected["Title"].text + '" ' + event.action + 'd successfully'; + const snackbarText = 'Policy "' + policyId + '" ' + action + 'd successfully'; this.openSnackBar(snackbarText, "check-circle"); this.getPolicyDetails(); - - // this.isEnableDisableInvokeSuccess = true; - // this.invocationId = reponse[0].data; }, error => { - // this.isEnableDisableInvokeFailed = true; - // this.ruleLoader = false; + this.logger.log("error", error); }); - } catch (error) { - // this.errorMessage = this.errorHandling.handleJavascriptError(error); - this.logger.log("error", error); - } - - } openDialog(event): void { const action = event.action; const element = event.rowSelected; + const policyId = event.rowSelected["Policy ID"].text; + const autofix = element.autoFixEnabled.text == "true"? "disable" : "enable"; this.selectedRowTitle = element["Title"].text ; this.action = action; @@ -501,7 +483,12 @@ export class PoliciesComponent implements OnInit, OnDestroy { dialogRef.afterClosed().subscribe(result => { if(result=="yes"){ - this.enableDisableRuleOrJob(event); + if(action == "Enable Policy" || action == "Disable Policy") + { + this.enableDisableRuleOrJob(policyId,action.split(" ")[0].toLowerCase()); + } + else + this.enabelOrDisableAutofix(policyId,autofix); } }); } @@ -528,7 +515,11 @@ export class PoliciesComponent implements OnInit, OnDestroy { goToDetails(event) { const action = event?.action?.toLowerCase(); - if(action =="enable" || action =="disable"){ + if(action == "enable policy" + || action == "disable policy" + || action == "enable autofix" + || action == "disable autofix" + ){ this.openDialog(event); return; } @@ -536,6 +527,7 @@ export class PoliciesComponent implements OnInit, OnDestroy { // store in this function const row = event.rowSelected; const data = event.data; + const policyId = event.rowSelected["Policy ID"].text; const state = { totalRows: this.totalRows, data: data, @@ -552,22 +544,17 @@ export class PoliciesComponent implements OnInit, OnDestroy { this.workflowService.addRouterSnapshotToLevel( this.router.routerState.snapshot.root, 0, this.pageTitle ); - if (action && action === "edit") { + if (action && (action === "edit policy" || action === "edit autofix")) { this.router.navigate(["create-edit-policy"], { relativeTo: this.activatedRoute, queryParamsHandling: "merge", queryParams: { - policyId: event.rowSelected["Policy ID"].text, + policyId: policyId, + showAutofix: action == "edit autofix" }, }); - - }else{ - const policyParams = event?.rowSelected["policyParams"]; - const autoFixEnabled = JSON.parse(policyParams.text)["autofix"]??false; - this.router.navigate(["/pl/compliance/policy-knowledgebase-details", event?.rowSelected["Policy ID"]?.text, autoFixEnabled], { - relativeTo: this.activatedRoute, - queryParamsHandling: "merge", - }); + } else if (action && (action === "Run Policy")){ + this.invokePolicy(policyId); } } catch (error) { this.errorMessage = this.errorHandling.handleJavascriptError(error); @@ -575,9 +562,38 @@ export class PoliciesComponent implements OnInit, OnDestroy { } } - // searchCalled(search) { - // this.searchTxt = search; - // } + enabelOrDisableAutofix(policyId:string,autoFix:string){ + try{ + const url = environment.enableDisableAutofix.url; + const method = environment.enableDisableAutofix.method; + const queryParams = { + policyId: policyId, + autofixStatus: autoFix == "enable" + } + this.adminService.executeHttpAction(url,method,{},queryParams).subscribe(response=>{ + if(response && response[0].message=="success"){ + const snackbarText = 'Autofix for policy "' + policyId + '" ' + autoFix + 'd successfully'; + this.openSnackBar(snackbarText,"green-info-circle"); + this.getPolicyDetails(); + } + }) + }catch(error){ + this.errorHandling.handleJavascriptError(error); + } + } + + invokePolicy(policyId:string){ + var url = environment.invokePolicy.url; + var method = environment.invokePolicy.method; + this.adminService.executeHttpAction(url, method, [{}], {policyId:policyId}).subscribe(response => { + const invocationId = response[0].data; + if(invocationId) + this.openSnackBar("Invocation Id " + invocationId + " invoked successfully!!","green-info-circle"); + }, + error => { + this.errorHandling.handleJavascriptError(error); + }) + } callNewSearch(search) { this.searchTxt = search; diff --git a/webapp/src/app/pacman-features/modules/compliance/policy-knowledgebase-details/policy-knowledgebase-details.component.ts b/webapp/src/app/pacman-features/modules/compliance/policy-knowledgebase-details/policy-knowledgebase-details.component.ts index d9258c4406..00898406e4 100644 --- a/webapp/src/app/pacman-features/modules/compliance/policy-knowledgebase-details/policy-knowledgebase-details.component.ts +++ b/webapp/src/app/pacman-features/modules/compliance/policy-knowledgebase-details/policy-knowledgebase-details.component.ts @@ -460,12 +460,12 @@ export class PolicyKnowledgebaseDetailsComponent implements OnInit, OnDestroy { this.workflowService.addRouterSnapshotToLevel( this.router.routerState.snapshot.root, 0, this.pageTitle ); - if (action && action === "edit") { + if (action && action === "Edit") { this.router.navigate(["/pl/admin/policies/create-edit-policy"], { relativeTo: this.activatedRoute, queryParamsHandling: "merge", queryParams: { - policyId: this.policyID, + policyId: this.policyID }, }); diff --git a/webapp/src/app/shared/dropdown/dropdown.component.ts b/webapp/src/app/shared/dropdown/dropdown.component.ts index 2e7e046b12..6569e43595 100644 --- a/webapp/src/app/shared/dropdown/dropdown.component.ts +++ b/webapp/src/app/shared/dropdown/dropdown.component.ts @@ -6,7 +6,7 @@ import { FormControl } from '@angular/forms'; templateUrl: './dropdown.component.html', styleUrls: ['./dropdown.component.css'] }) -export class DropdownComponent implements OnChanges,AfterViewInit { +export class DropdownComponent implements OnChanges { @Input() items = []; @Input() required = false; @@ -16,7 +16,7 @@ export class DropdownComponent implements OnChanges,AfterViewInit { @Input() placeholder: string; @Input() selectedItem: string; @Input() isChipListEnabled: boolean = false; - @Input() selectedList; + @Input() selectedList = []; @Output() selected = new EventEmitter(); @Output() closeEventEmitter = new EventEmitter(); listControl = new FormControl([]); @@ -27,11 +27,6 @@ export class DropdownComponent implements OnChanges,AfterViewInit { selectedOptionImage: string; constructor() { } - ngAfterViewInit(): void { - if(this.selectedList) - this.listControl.setValue(this.selectedList); - } - onClose() { this.closeEventEmitter.emit(); } @@ -82,6 +77,9 @@ export class DropdownComponent implements OnChanges,AfterViewInit { } ngOnChanges(changes: SimpleChanges): void { + if(this.selectedList){ + this.listControl.setValue(this.selectedList); + } this.massageData(this.items, this.selectedItem); } diff --git a/webapp/src/app/shared/input-field/input-field.component.css b/webapp/src/app/shared/input-field/input-field.component.css new file mode 100644 index 0000000000..c981fdaeaa --- /dev/null +++ b/webapp/src/app/shared/input-field/input-field.component.css @@ -0,0 +1,12 @@ +.input-wrapper{ + display: flex; + align-items: center; + gap: 12px; + } + .input-wrapper ::ng-deep .mat-form-field-label{ + padding: 5px 5px !important; + } + + .input-wrapper ::ng-deep .mat-form-field{ + width: 100% !important; + } diff --git a/webapp/src/app/shared/input-field/input-field.component.html b/webapp/src/app/shared/input-field/input-field.component.html new file mode 100644 index 0000000000..21397b49c2 --- /dev/null +++ b/webapp/src/app/shared/input-field/input-field.component.html @@ -0,0 +1,9 @@ +
    + + {{placeholder}} + + +
    + +
    +
    \ No newline at end of file diff --git a/webapp/src/app/shared/input-field/input-field.component.spec.ts b/webapp/src/app/shared/input-field/input-field.component.spec.ts new file mode 100644 index 0000000000..83501a8c44 --- /dev/null +++ b/webapp/src/app/shared/input-field/input-field.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { InputFieldComponent } from './input-field.component'; + +describe('InputFieldComponent', () => { + let component: InputFieldComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ InputFieldComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(InputFieldComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/shared/input-field/input-field.component.ts b/webapp/src/app/shared/input-field/input-field.component.ts new file mode 100644 index 0000000000..da1d99bf35 --- /dev/null +++ b/webapp/src/app/shared/input-field/input-field.component.ts @@ -0,0 +1,23 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; + +@Component({ + selector: 'app-input-field', + templateUrl: './input-field.component.html', + styleUrls: ['./input-field.component.css'] +}) +export class InputFieldComponent implements OnInit { + + @Input() placeholder: string; + @Input() description: string; + @Input() value: string; + @Output() valueChange = new EventEmitter(); + + onInputChange(){ + this.valueChange.emit(this.value); + } + + ngOnInit(): void { + + } + +} diff --git a/webapp/src/app/shared/shared.module.ts b/webapp/src/app/shared/shared.module.ts index c32ac88241..7ed997e852 100644 --- a/webapp/src/app/shared/shared.module.ts +++ b/webapp/src/app/shared/shared.module.ts @@ -117,6 +117,8 @@ import { CustomCardComponent } from './components/molecules/custom-card/custom-c import { OverviewTileComponent } from './components/molecules/overview-tile/overview-tile.component'; import { TextWithIconComponent } from "./components/molecules/text-with-icon/text-with-icon.component"; import { MatChipsModule } from "@angular/material/chips"; +import { MatTooltipModule } from "@angular/material/tooltip"; +import { InputFieldComponent } from './input-field/input-field.component'; @NgModule({ imports: [ @@ -126,6 +128,7 @@ import { MatChipsModule } from "@angular/material/chips"; MatChipsModule, MatSnackBarModule, MatGridListModule, + MatTooltipModule, MatCardModule, MatSelectModule, MatIconModule, @@ -209,7 +212,8 @@ import { MatChipsModule } from "@angular/material/chips"; StepperComponent, CustomCardComponent, OverviewTileComponent, - TextWithIconComponent + TextWithIconComponent, + InputFieldComponent ], exports: [ TextWithIconComponent, @@ -240,6 +244,7 @@ import { MatChipsModule } from "@angular/material/chips"; TitleBurgerHeadComponent, MatSelectModule, OverlayComponent, + InputFieldComponent, SearchableDropdownComponent, FilteredSelectorComponent, OrderByPipe, diff --git a/webapp/src/app/shared/stepper/stepper.component.css b/webapp/src/app/shared/stepper/stepper.component.css index a4169286d8..1394cb589b 100644 --- a/webapp/src/app/shared/stepper/stepper.component.css +++ b/webapp/src/app/shared/stepper/stepper.component.css @@ -3,7 +3,9 @@ } .stepper-header-wrapper{ - width: 20%; + width: 200px; + padding-right: 20px; + border-right: 1px solid var(--border-200); } .stepper-wrapper{ diff --git a/webapp/src/app/shared/stepper/stepper.component.html b/webapp/src/app/shared/stepper/stepper.component.html index 3c15cef54e..f923d639fb 100644 --- a/webapp/src/app/shared/stepper/stepper.component.html +++ b/webapp/src/app/shared/stepper/stepper.component.html @@ -3,15 +3,6 @@ - - edit - - - format_align_center - - - done_all - {{data.name}} diff --git a/webapp/src/app/shared/stepper/stepper.component.ts b/webapp/src/app/shared/stepper/stepper.component.ts index 666af5f008..85f82906da 100644 --- a/webapp/src/app/shared/stepper/stepper.component.ts +++ b/webapp/src/app/shared/stepper/stepper.component.ts @@ -11,17 +11,7 @@ export class StepperComponent implements OnInit { @Output() selectedStepperIndex = new EventEmitter(); @ContentChild('stepsHeader', { read: TemplateRef }) stepsHeader: TemplateRef; @ContentChild('stepsContent', { read: TemplateRef }) stepsContent: TemplateRef; - - stepperData = [ - { - name: "Policy Details", - icon: "form" - }, - { - name: "Policy Parameters", - icon: "last" - } - ] + @Input() stepperData = []; constructor() { } ngOnInit(): void { } diff --git a/webapp/src/app/shared/table/table.component.css b/webapp/src/app/shared/table/table.component.css index 24c11505f0..4d6174da79 100644 --- a/webapp/src/app/shared/table/table.component.css +++ b/webapp/src/app/shared/table/table.component.css @@ -12,6 +12,10 @@ overflow-y: scroll; } +.noImg{ + opacity: 0; +} + .table-wrapper{ height: 100%; width: 100%; diff --git a/webapp/src/app/shared/table/table.component.html b/webapp/src/app/shared/table/table.component.html index bd10ad2d96..1eb1aa0e12 100644 --- a/webapp/src/app/shared/table/table.component.html +++ b/webapp/src/app/shared/table/table.component.html @@ -131,48 +131,43 @@ - -
    - - + +
    + + + +
    - -
    - - - - -
    -
    - -
    - - {{ element[column].text }} - -
    -
    - -
    - No Data + +
    +
    + + +
    + +
    + + {{ element[column].text }} +
    +
    +
    + +
    + No Data +
    +
    - +
    diff --git a/webapp/src/app/shared/table/table.component.ts b/webapp/src/app/shared/table/table.component.ts index 937bde4e47..565086c03b 100644 --- a/webapp/src/app/shared/table/table.component.ts +++ b/webapp/src/app/shared/table/table.component.ts @@ -38,7 +38,6 @@ export class TableComponent implements OnInit, AfterViewInit, OnChanges { @Input() doLocalSort = true; @Input() tableDataLoaded; @Output() rowSelectEventEmitter = new EventEmitter(); - @Output() cellSelectEventEmitter = new EventEmitter(); @Output() selectedAction = new EventEmitter(); @Output() headerColNameSelected = new EventEmitter(); @Output() searchCalledEventEmitter = new EventEmitter(); @@ -216,17 +215,15 @@ export class TableComponent implements OnInit, AfterViewInit, OnChanges { this.getWidthFactor(); } - handleClick(row, cell?) { + handleClick(row, col){ + if(row[col].isMenuBtn){ + return; + } let event = { tableScrollTop: this.customTable.first.nativeElement.scrollTop, rowSelected: row, data: this.data, - cell: cell - } - if (this.rowClickable) { - this.rowSelectEventEmitter.emit(event); - } else { - if (cell) this.cellSelectEventEmitter.emit(event); + col: col } this.rowSelectEventEmitter.emit(event); } @@ -237,7 +234,6 @@ export class TableComponent implements OnInit, AfterViewInit, OnChanges { rowSelected: element, } this.selectedAction.emit(event); - this.cellSelectEventEmitter.emit(event); } optionClick() { @@ -363,14 +359,16 @@ export class TableComponent implements OnInit, AfterViewInit, OnChanges { this.dataSource.data = this.mainDataSource.data.filter((item) => { for (const i in columnsToSearchIN) { const col = columnsToSearchIN[i]; - if (String(item[col].text).toLowerCase().match(searchTxt)) { + if(String(item[col].valueText).toLowerCase().match(searchTxt)){ return true; } } return false; }) - if (this.dataSource.data.length == 0) { + this.totalRows = this.dataSource.data.length; + + if(this.dataSource.data.length==0){ this.tableErrorMessage = 'noSearchFound'; } } @@ -412,19 +410,13 @@ export class TableComponent implements OnInit, AfterViewInit, OnChanges { // this.dataSource.data = this.mainDataSource.data.slice(); return; } - - const isAsc = this.direction=='asc'; + const isAsc = this.direction == 'asc'; this.dataSource.data = this.dataSource.data.sort((a, b) => { if (this.columnsSortFunctionMap && this.columnsSortFunctionMap[this.headerColName]) { return this.columnsSortFunctionMap[this.headerColName](a, b, isAsc); } - - // Till we add server side sorting - let elementA =a[this.headerColName]&&a[this.headerColName].valueText?a[this.headerColName].valueText.toLowerCase():isAsc?'zzzzzz':'000000'; - let elementB =b[this.headerColName]&&b[this.headerColName].valueText?b[this.headerColName].valueText.toLowerCase():isAsc?'zzzzzz':'000000'; - - return (elementA + + diff --git a/webapp/src/assets/icons/no-autofix.svg b/webapp/src/assets/icons/no-autofix.svg new file mode 100644 index 0000000000..b7f1b03662 --- /dev/null +++ b/webapp/src/assets/icons/no-autofix.svg @@ -0,0 +1,3 @@ + + + diff --git a/webapp/src/environments/environment.prod.ts b/webapp/src/environments/environment.prod.ts index cd26295ddd..0df7448673 100644 --- a/webapp/src/environments/environment.prod.ts +++ b/webapp/src/environments/environment.prod.ts @@ -598,11 +598,7 @@ export const environment = { url: '{{baseUrl}}/admin/job-execution-manager/create', method: 'POST' }, - updateRule: { - url: '{{baseUrl}}/admin/policy/update', - method: 'POST' - }, - invokeRule: { + invokePolicy: { url: '{{baseUrl}}/admin/policy/invoke', method: 'POST' }, @@ -618,6 +614,14 @@ export const environment = { url: '{{baseUrl}}/compliance/v1/policy-details-by-id', method: 'GET' }, + getPolicyDetailsById: { + url: "{{baseUrl}}/admin/policy/details-by-id", + method: 'GET' + }, + enableDisableAutofix:{ + url: "{{baseUrl}}/admin/policy/enable-disable-autofix", + method: 'POST' + }, enableDisableRule: { url: '{{baseUrl}}/admin/policy/enable-disable', method: 'POST' diff --git a/webapp/src/environments/environment.stg.ts b/webapp/src/environments/environment.stg.ts index 694d3654ee..624fd5b3e9 100644 --- a/webapp/src/environments/environment.stg.ts +++ b/webapp/src/environments/environment.stg.ts @@ -598,11 +598,7 @@ export const environment = { url: '{{baseUrl}}/admin/job-execution-manager/create', method: 'POST' }, - updateRule: { - url: '{{baseUrl}}/admin/policy/update', - method: 'POST' - }, - invokeRule: { + invokePolicy: { url: '{{baseUrl}}/admin/policy/invoke', method: 'POST' }, @@ -618,6 +614,14 @@ export const environment = { url: '{{baseUrl}}/compliance/v1/policy-details-by-id', method: 'GET' }, + getPolicyDetailsById: { + url: "{{baseUrl}}/admin/policy/details-by-id", + method: 'GET' + }, + enableDisableAutofix:{ + url: "{{baseUrl}}/admin/policy/enable-disable-autofix", + method: 'POST' + }, enableDisableRule: { url: '{{baseUrl}}/admin/policy/enable-disable', method: 'POST' diff --git a/webapp/src/environments/environment.ts b/webapp/src/environments/environment.ts index 9850b300f0..52ddce2d30 100644 --- a/webapp/src/environments/environment.ts +++ b/webapp/src/environments/environment.ts @@ -562,6 +562,14 @@ export const environment = { url: '{{baseUrl}}/compliance/v1/policy-details-by-id', method: 'GET' }, + getPolicyDetailsById: { + url: "{{baseUrl}}/admin/policy/details-by-id", + method: 'GET' + }, + enableDisableAutofix:{ + url: "{{baseUrl}}/admin/policy/enable-disable-autofix", + method: 'POST' + }, policyDetails: { url: '{{baseUrl}}/admin/policy/list', method: 'GET' @@ -598,7 +606,7 @@ export const environment = { url: '{{baseUrl}}/admin/job-execution-manager/create', method: 'POST' }, - invokeRule: { + invokePolicy: { url: '{{baseUrl}}/admin/policy/invoke', method: 'POST' }, diff --git a/webapp/src/styles.css b/webapp/src/styles.css index 4d5f060bf9..a3339d49fd 100644 --- a/webapp/src/styles.css +++ b/webapp/src/styles.css @@ -483,7 +483,6 @@ text.axis-title { } .flex { - display: table-cell; display: flex; } @@ -959,6 +958,11 @@ html body .offline-ui.offline-ui-down.offline-ui-waiting .offline-ui-retry { height: 100%; } +.subtitle-1{ + font: var(--text-subtitle-1); + color: var(--text-medium-emphasis); +} + .sub-header, .sub-head { padding-left: 34px;