Skip to content

Commit

Permalink
Merge pull request #548 from openziti/545-delete-orphaned-configs
Browse files Browse the repository at this point in the history
Optionally delete unused/orphaned entities when deleting a Service
  • Loading branch information
rgallettonf authored Nov 25, 2024
2 parents 8084616 + d050ade commit e7788e3
Show file tree
Hide file tree
Showing 26 changed files with 1,084 additions and 58 deletions.
1 change: 1 addition & 0 deletions projects/app-ziti-console/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
--greenShadow: rgba(82, 255, 13, 0.3);
--redShadow: rgba(255, 13, 73, 0.3);
--boxShadow: rgba(0, 0, 0, 0.08);
--redText: #9c0027;
overflow: hidden;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,20 @@
</div>
</div>
</div>
<div class="secondary-confirm-container" *ngIf="dataObj.showSecondaryConfirm">
<div class="cSelect" [ngClass]="{'selected': dataObj.secondaryConfirmed}" (click)="toggleSecondary($event)"></div>
<div class="secondary-confirm-label">{{dataObj.secondaryConfirmLabel}}</div>
<div
*ngIf="dataObj.secondaryInfoLabel"
class="form-field-info infoicon"
matTooltip="{{dataObj.secondaryInfoLabel}}"
matTooltipPosition="above"
></div>
</div>
<div class="confirm-buttons-container">
<div class="linkButton cancel" (click)="cancel()" *ngIf="dataObj.showCancelLink">{{dataObj.cancelLabel}}</div>
<button class="button save secondary-button" (click)="secondaryAction()" *ngIf="dataObj.secondaryActionLabel && dataObj.secondaryConfirmed">{{dataObj.secondaryActionLabel}}</button>
<button class="button save cancel" (click)="cancel()" *ngIf="dataObj.showCancelButton">{{dataObj.cancelLabel}}</button>
<button class="button save confirm" (click)="confirm()">{{dataObj.confirmLabel}}</button>
<button class="button save confirm" (click)="confirm()">{{dataObj.confirmLabelAlt && dataObj.secondaryConfirmed ? dataObj.confirmLabelAlt : dataObj.confirmLabel}}</button>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
flex-direction: column;
background-color: var(--background);
border-radius: 25px;
width: 600px;

.confirm-model-body {
display: flex;
Expand Down Expand Up @@ -80,6 +81,56 @@
margin: 0;
}
}

.secondary-confirm-container {
height: 35px;
width: 100%;
position: relative;
display: flex;
flex-direction: row;
align-items: center;
padding-left: 35px;
padding-top: 35px;
padding-bottom: 25px;

&.disabled {
opacity: 0.5;
filter: grayscale(1);
cursor: not-allowed;

.cSelect {
cursor: not-allowed;
&:hover {
transform: none;
border: 2px var(--inputBorder) solid;
}
&:active {
transform: none;
border: 2px var(--inputBorder) solid;
}
}
}

.cSelect {
position: relative;
top: initial;
left: initial;
height: 25px;
width: 25px;
}

.secondary-confirm-label {
font-size: 14px;
font-weight: 600;
color: var(--tableText);
margin-left: 7px;
}

.infoicon {
filter: brightness(0.8);
}
}

.confirm-buttons-container {
display: flex;
justify-content: flex-end;
Expand All @@ -94,6 +145,10 @@
color: var(--subText);
font-weight: 600;
}
.secondary-button {
margin-right: 10px;
background-color: var(--primary);
}
}

button {
Expand All @@ -103,6 +158,7 @@
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;

&.confirm {
background-color: var(--secondary);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,18 @@ export class ConfirmComponent {
subtitle: '',
message: '',
confirmLabel: '',
confirmLabelAlt: undefined,
cancelLabel: '',
bulletList: [],
submessage: '',
showCancelButton: false,
showCancelLink: false,
showSecondaryConfirm: false,
secondaryConfirmLabel: '',
secondaryConfirmed: false,
secondaryActionLabel: undefined,
secondaryInfoLabel: undefined,
secondaryAction: undefined,
imageUrl: '../../assets/svgs/Confirm_Trash.svg'
}

Expand All @@ -49,10 +56,21 @@ export class ConfirmComponent {
}

confirm() {
this.dialogRef.close(true);
this.dialogRef.close({confirmed: true, secondaryConfirmed: this.dataObj.secondaryConfirmed});
}

secondaryAction() {
if (!this.dataObj.secondaryAction) {
return;
}
this.dataObj.secondaryAction();
}

cancel() {
this.dialogRef.close(false);
this.dialogRef.close({confirmed: false, secondaryConfirmed: false});
}

toggleSecondary(event) {
this.dataObj.secondaryConfirmed = !this.dataObj.secondaryConfirmed;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class TableCellNameComponent implements ICellRendererAngularComp {
event.preventDefault();
if (isFunction(this.cellParams?.cellNamePreCheck)) {
this.cellParams?.cellNamePreCheck(this.item).then((result) => {
if (!result) {
if (!result?.confirmed) {
return;
}
this.router.navigateByUrl(`${this.cellParams.pathRoot}/${this.item.id}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
right: 20px;
bottom: -100px;
min-width: 300px;
z-index: 9999999;
z-index: 999999999;
max-width: 500px;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<div class="listBox row">
<input *ngIf="showfilter" (keyup)="onKeydownEvent()" [(ngModel)]="filterFor" placeholder="Type to Filter"/>
<div class="text row">
<div *ngIf="previewItems.length <= 0" class="listText">
<span class="preview-name preview-placeholder">no items to display...</span>
</div>
<div (click)="selected(item)" *ngFor="let item of previewItems" [ngClass]="{ clickable: clickable }" class="listText">
<div *ngIf="allowRemove" class="icon-clear" (click)="remove(item)"></div>
<span *ngIf="!item.href" class="preview-name" matTooltip="{{tooltip}}" matTooltipPosition="below" matTooltipShowDelay="1000">{{ item }}</span>
<span *ngIf="!item.href" class="preview-name" matTooltip="{{tooltip}}" matTooltipPosition="below" matTooltipShowDelay="1000">{{ item.name || item }}</span>
<a *ngIf="item.href" [href]="'./' + item.href" (click)="linkClicked($event, item)" class="{{item.linkClass ? item.linkClass : ''}}" matTooltip="{{tooltip}}" matTooltipShowDelay="1000" matTooltipPosition="below">
<span *ngIf="item.name" class="preview-name">{{ item.name }}<div *ngIf="item.iconClass" class="preview-item-icon {{item.iconClass}}" (click)="remove(item)"></div></span>
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@

.preview-name {
white-space: pre;

&.preview-placeholder {
font-style: italic;
}
}

.preview-item-icon {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ export class PreviewListComponent {
constructor(private router: Router) {}

ngOnInit() {
this.setPreviewItems();
}

ngOnChanges() {
this.setPreviewItems();
this.sort();
}

setPreviewItems() {
this.previewItems = [];
if (!isEmpty(this.allNames)) {
this.previewItems.push(...this.allNames);
Expand All @@ -52,13 +61,6 @@ export class PreviewListComponent {
this.sort();
}

ngOnChanges() {
this.previewItems = [];
this.previewItems.push(...this.allNames);
this.previewItems = this.previewItems.filter((item) => item !== this.hideOption);
this.sort();
}

onKeydownEvent() {
this.previewItems = [];
for (let i = 0; i < this.allNames.length; i++) {
Expand Down Expand Up @@ -90,14 +92,20 @@ export class PreviewListComponent {
}

selected(item: string) {
if (this.clickable) this.itemSelected.emit(item);
if (!this.clickable) {
return;
}
this.itemSelected.emit(item);
}

remove(item) {
this.itemRemoved.emit(item);
}

linkClicked(event, item) {
if (!this.clickable) {
return;
}
this.router.navigateByUrl(item.href);
event.preventDefault();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<div class="preview-selections-container confirm-modal-container" [ngClass]="{'error-state': state === 'ERROR', 'loading-state': isLoading}">
<div class="close icon-close" (click)="cancel()"></div>
<div class="preview-selections-body">
<div class="preview-selections-content">
<div class="preview-selections-title-container">
<div class="confirm-modal-icon" style="background-image: url(&quot;../../assets/svgs/Confirm_Trash.svg&quot;);"></div>
<span class="preview-selections-title">Orphaned Configs & Service Policies</span>
<span class="preview-selections-subtitle">Preview of all associated entities that will be orphaned and deleted once the selected services are deleted</span>
</div>
<div class="preview-selections-info-message" *ngIf="infoMessage" [ngClass]="{'error-message': state === 'ERROR'}">{{infoMessage}}</div>
<div class="preview-selections-main">
<div class="preview-selections-left-side">
<lib-form-field-container
[showHeader]="true"
[title]="'Services To Delete'"
[class]="'hide-overflow bold-header-title'"
[count]="selectedItems.length"
>
<div class="selected-items-container">
<div class="selected-items">
<div class="selected-items-category">
<ul>
<li class="selected-items-item header-item" (click)="previewItem(allItem)" [ngClass]="{'selected': selectedItem.id === 'all'}">
<span class="selected-item-name">{{allItem.name}}</span>
<div class="associated-count-container">
<div class="associated-count-header-group">
<div
class="associated-header-icon icon-configuration"
matTooltip="Configs"
matTooltipPosition="below"
matTooltipShowDelay="500"
></div>
<span class="associated-configs-count">{{allItem.associatedConfigs.length}}</span>
</div>
<div class="count-divider header-divider"></div>
<div class="associated-count-header-group">
<div
class="associated-header-icon icon-Policies"
matTooltip="Service Policies"
matTooltipPosition="below"
matTooltipShowDelay="500"
></div>
<span class="associated-policies-count">{{allItem.associatedServicePolicies.length}}</span>
</div>
</div>
</li>
<div class="selected-items-divider"></div>
<li *ngFor="let item of selectedItems" class="selected-items-item" (click)="previewItem(item)" [ngClass]="{'selected': item.selected}">
<span class="selected-item-name">{{item.name}}</span>
<div class="associated-count-container">
<div class="associated-count-list-group">
<span class="associated-configs-header-count">{{allItem.associatedConfigs.length}}</span>
<span class="associated-configs-count">{{item.associatedConfigs.length}}</span>
</div>
<div class="count-divider"></div>
<div class="associated-count-list-group">
<span class="associated-configs-header-count">{{allItem.associatedServicePolicies.length}}</span>
<span class="associated-policies-count">{{item.associatedServicePolicies.length}}</span>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</lib-form-field-container>
</div>
<div class="preview-selections-divider"></div>
<div class="preview-selections-right-side">
<div class="preview-selections-lists-title">
<div class="resource-type"> Selected Service </div>
<div class="icon-next preview-selections-breadcrumb"></div>
<div class="selected-attribute"> {{selectedItem.name}} </div>
</div>
<div class="preview-selections-lists">
<lib-form-field-container
[title]="'Orphaned Configs'"
[titleIcon]="'icon-configuration'"
[count]="selectedItem.associatedConfigs.length"
[class]="'hide-overflow'"
[helpText]="'List of orphaned Configs that will be deleted.'"
>
<lib-preview-list
[clickable]="false"
[items]="selectedItem.associatedConfigs"
[allowRemove]="false"
></lib-preview-list>
</lib-form-field-container>
<lib-form-field-container
[title]="'Orphaned Service Policies'"
[titleIcon]="'icon-Policies'"
[count]="selectedItem.associatedServicePolicies.length"
[class]="'hide-overflow'"
[helpText]="'List of all orphaned Service Policies that will be deleted.'"
>
<lib-preview-list
[clickable]="false"
[items]="selectedItem.associatedServicePolicies"
[allowRemove]="false"
></lib-preview-list>
</lib-form-field-container>
</div>
</div>
</div>
</div>
</div>
<div class="preview-selections-buttons-container">
<button class="button save secondary-button" (click)="return()">Return</button>
<button class="button save confirm" *ngIf="dataObj.deleteConfirmed && state !== 'ERROR'" (click)="confirm()" [disabled]="isLoading">Delete All</button>
</div>
</div>

<lib-loading-indicator *ngIf="isLoading" [isLoading]="isLoading"></lib-loading-indicator>
Loading

0 comments on commit e7788e3

Please sign in to comment.