Skip to content

Commit

Permalink
Update the current Configurations list page and edit form with new An…
Browse files Browse the repository at this point in the history
…gular components
  • Loading branch information
rgallettonf committed Jun 12, 2024
1 parent 12f7303 commit 905c048
Show file tree
Hide file tree
Showing 33 changed files with 1,072 additions and 558 deletions.
2 changes: 1 addition & 1 deletion projects/app-ziti-console/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const routes: Routes = [
},
{
path: 'configs',
component: ZacWrapperComponent,
component: ConfigurationsPageComponent,
canActivate: mapToCanActivate([AuthenticationGuard]),
runGuardsAndResolvers: 'always',
},
Expand Down
1 change: 1 addition & 0 deletions projects/ziti-console-lib/src/lib/assets/styles/forms.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ label {
font-family: 'Open Sans';
overflow: hidden;
text-overflow: ellipsis;
line-height: var(--defaultLineHeight);
}

textarea::placeholder {
Expand Down
1 change: 1 addition & 0 deletions projects/ziti-console-lib/src/lib/assets/styles/ziti.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ body {
--gapLarge: 10px;
--gapXL: 15px;
--defaultInputHeight: 43px;
--defaultLineHeight: 15px;
}

::placeholder {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div class="form-field-extended-fields" [hidden]="showJsonView">
<ng-container #dynamicform></ng-container>
</div>
<lib-json-view *ngIf="showJsonView && !hideConfigJSON" [(data)]="configData"></lib-json-view>
<lib-json-view *ngIf="showJsonView && hideConfigJSON" [(data)]="configData"></lib-json-view>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ConfigEditorComponent } from './config-editor.component';

describe('ConfigEditorComponent', () => {
let component: ConfigEditorComponent;
let fixture: ComponentFixture<ConfigEditorComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ConfigEditorComponent]
});
fixture = TestBed.createComponent(ConfigEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
import {Component, ComponentRef, EventEmitter, Input, OnInit, Output, ViewChild, ViewContainerRef} from '@angular/core';
import {JsonEditorComponent, JsonEditorOptions} from "ang-jsoneditor";
import {defer, isBoolean, isEmpty, isNil, keys} from "lodash";
import {SchemaService} from "../../services/schema.service";

@Component({
selector: 'lib-config-editor',
templateUrl: './config-editor.component.html',
styleUrls: ['./config-editor.component.scss']
})
export class ConfigEditorComponent implements OnInit {

items: any[] = [];

lColorArray = [
'white',
'white',
'white',
]

bColorArray = [
'var(--formBase)',
'var(--formGroup)',
'var(--formSubGroup)'
]
hideConfigJSON = false;

@Input() configErrors: any = {};
@Output() configErrorsChange = new EventEmitter<any>();

_configData: any = {};
@Input() set configData(data) {
this._configData = data;
};
@Output() configDataChange = new EventEmitter<any>();
get configData() {
return this._configData;
}

_showJsonView = false;
@Input() set showJsonView(showJsonView: boolean) {
this._showJsonView = showJsonView;
this.updateConfigData();
}
get showJsonView() {
return this._showJsonView;
}

_schema = false;
@Input() set schema(schema: any) {
this._schema = schema;
this.createForm();
this.updateConfigData();
}

get schema() {
return this._schema;
}

@ViewChild("dynamicform", {read: ViewContainerRef}) dynamicForm!: ViewContainerRef;
@ViewChild(JsonEditorComponent, {static: false}) editor!: JsonEditorComponent;
constructor(private schemaSvc: SchemaService) {
}

ngOnInit() {
this.createForm();
}

createForm() {
this.clearForm();
if (this.dynamicForm && this.schema) {
this.renderSchema(this.schema);
}
}

clearForm() {
this.items.forEach((item: any) => {
if (item?.component) item.component.destroy();
});
this.configErrors = {};
this.items = [];
}

renderSchema(schema: any) {
if (schema.properties) {
this.items = this.schemaSvc.render(schema, this.dynamicForm, this.lColorArray, this.bColorArray);
for (let obj of this.items) {
const cRef = obj.component;
cRef.instance.errors = this.configErrors;
if (cRef?.instance.valueChange) {
const pName: string[] = cRef.instance.parentage;
let parentKey;
if(pName) parentKey = pName.join('.');
//if (parentKey && !this.formData[parentKey]) this.formData[parentKey] = {};
}
}
}
}

updateConfigData() {
if (!this.showJsonView) {
this.updateFormView(this.items, this.configData);
} else {
this.hideConfigJSON = true;
defer(() => {
this.getConfigDataFromForm();
});
}
}

updateFormView(items, data: any = {}) {
items.forEach((item) => {
if (item.items) {
if (item.type === 'array') {
if (item?.component?.instance?.addedItems) {
item.addedItems = data[item.key] || [];
item.component.instance.addedItems = data[item.key] || [];
}
this.updateFormView(item.items, {});
} else {
this.updateFormView(item.items, data[item.key]);
}
} else if (item?.component?.instance?.setProperties) {
let val;
switch (item.key) {
case 'forwardingconfig':
val = {
protocol: data.protocol,
address: data.address,
port: data.port,
forwardProtocol: data.forwardProtocol,
forwardAddress: data.forwardAddress,
forwardPort: data.forwardPort,
allowedProtocols: data.allowedProtocols,
allowedAddresses: data.allowedAddresses,
allowedPortRanges: data.allowedPortRanges
}
break;
case 'pap':
val = {
protocol: data.protocol,
address: data.address,
port: data.port,
hostname: data.hostname,
}
break;
default:
val = data[item.key];
break;
}
item?.component?.instance?.setProperties(val);
} else if (item?.component?.setInput) {
item.component.setInput('fieldValue', data[item.key]);
}
});
return data;
}

getConfigDataFromForm() {
const data = {};
this.addItemsToConfig(this.items, data);
this._configData = data;
this.hideConfigJSON = false;
this.configDataChange.emit(this.configData);
}

addItemsToConfig(items, data: any = {}, parentType = 'object') {
items.forEach((item) => {
if (item.type === 'array') {
if (item.addedItems) {
data[item.key] = item.addedItems;
} else {
data[item.key] = [];
}
} else if (item.type === 'object') {
const val = this.addItemsToConfig(item.items, {}, item.type);
let hasDefinition = false;
keys(val).forEach((key) => {
if (isBoolean(val[key]) || (!isEmpty(val[key]) && !isNil(val[key]))) {
hasDefinition = true;
}
});
data[item.key] = hasDefinition ? val : undefined;
} else {
let props = [];
if (item?.component?.instance?.getProperties) {
props = item?.component?.instance?.getProperties();
} else if (item?.component?.instance) {
props = [{key: item.key, value: item.component.instance.fieldValue}];
}
props.forEach((prop) => {
data[prop.key] = prop.value;
});
}
});
return data;
}

validateConfig() {
this.configErrors = {};
const configItemsValid = this.validateConfigItems(this.items);
if (!configItemsValid) {
this.configErrors['configData'] = true;
}
this.configErrorsChange.emit(this.configErrors);
return isEmpty(this.configErrors);
}

validateConfigItems(items, parentType = 'object') {
let isValid = true;
items.forEach((item) => {
if (item.type === 'object') {
if (!this.validateConfigItems(item.items, item.type)) {
isValid = false;
}
} else if (item?.component?.instance?.isValid) {
if (!item?.component?.instance?.isValid()) {
isValid = false;
}
}
});
return isValid;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,7 @@ export class TableColumnDefaultComponent implements IHeaderAngularComp, AfterVie
this.columnDef.colId === 'name' &&
(_.has(this.columnFilters, 'hasApiSession') || _.has(this.columnFilters, 'online'));
this._showColumnMenu = headerParams.showColumnMenu;
this.filterOptions = _.map(this.headerParams.filterOptions, (option) => {
option.columnId = this.columnDef.colId;
option.filterName = this.headerName;
return option;
});
this.updateFilterOptions();
headerParams.api.addEventListener('sortChanged', (event) => {
const colId = _.get(event, 'columnDef.colId', '');
if (colId !== this.columnDef.colId) {
Expand All @@ -152,11 +148,7 @@ export class TableColumnDefaultComponent implements IHeaderAngularComp, AfterVie
headerParams.api.addEventListener('columnEverythingChanged', (event) => {
_.forEach(event.columnApi.columnModel.columnDefs, colDef => {
if (this.columnDef.colId === colDef.colId && colDef.headerComponentParams?.filterOptions) {
this.filterOptions = _.map(colDef.headerComponentParams?.filterOptions, (option) => {
option.columnId = this.columnDef.colId;
option.filterName = this.headerName;
return option;
});
this.updateFilterOptions();
}
});
});
Expand Down Expand Up @@ -213,12 +205,14 @@ export class TableColumnDefaultComponent implements IHeaderAngularComp, AfterVie
this.showFilter = !this.showFilter;
if (this.filterType === 'SELECT' || this.filterType === 'COMBO' || this.filterType === 'DATETIME') {
if (this.showFilter) {
_.invoke(this.headerParams, 'api.openHeaderFilter', event, this.filterOptions, this.filterType, this.columnDef?.colId);
this.updateFilterOptions();
_.invoke(this.headerParams, 'api.openHeaderFilter', event, this.filterOptions, this.filterType, this.columnDef?.colId, this.headerName);
} else {
_.invoke(this.headerParams, 'api.closeHeaderFilter', event);
}
} else if (this.filterType === 'CUSTOM') {
if (this.showFilter) {
this.updateFilterOptions();
_.invoke(this.headerParams, 'column.colDef.headerComponentParams.openHeaderFilter', event, this.filterOptions);
} else {
_.invoke(this.headerParams, 'column.colDef.headerComponentParams.closeHeaderFilter', event);
Expand Down Expand Up @@ -287,4 +281,19 @@ export class TableColumnDefaultComponent implements IHeaderAngularComp, AfterVie
}
this._showColumnMenu(this.menuButton.nativeElement);
}

updateFilterOptions() {
let options = [];
if (this.headerParams.getFilterOptions) {
options = this.headerParams.getFilterOptions();
} else {
options = this.headerParams.filterOptions;
}
this.filterOptions = _.map(options, (option) => {
option.columnId = this.columnDef.colId;
option.filterName = this.headerName;
option.type = this.filterType;
return option;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export class TableColumnFilterComponent implements OnInit, AfterViewInit, OnDest
columnId: this.columnId,
value: this.filterString,
label: this.filterString,
type: this.type,
};
this.filterService.updateFilter(filterObj)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type FilterObj = {
columnId: string;
value: any;
label: string;
type?: string;
}

@Injectable({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
</div>
</div>

<div *ngIf="showDateTimePicker" class="date-time-container" [ngStyle]="{ left: menuLeft + 'px', top: menuTop + 'px' }" (clickOutside)="closeHeaderFilter($event)">
<div *ngIf="showDateTimePicker" class="date-time-container data-table-date-time" [ngStyle]="{ left: menuLeft + 'px', top: menuTop + 'px' }" (clickOutside)="closeHeaderFilter($event)">
<p-calendar
[(ngModel)]="dateValue"
(onSelect)="setDateRangeFilter('custom')"
Expand Down
Loading

0 comments on commit 905c048

Please sign in to comment.