diff --git a/projects/app-ziti-console/src/app/app-routing.module.ts b/projects/app-ziti-console/src/app/app-routing.module.ts
index 70510e29..4f804413 100644
--- a/projects/app-ziti-console/src/app/app-routing.module.ts
+++ b/projects/app-ziti-console/src/app/app-routing.module.ts
@@ -96,7 +96,7 @@ const routes: Routes = [
},
{
path: 'configs',
- component: ZacWrapperComponent,
+ component: ConfigurationsPageComponent,
canActivate: mapToCanActivate([AuthenticationGuard]),
runGuardsAndResolvers: 'always',
},
diff --git a/projects/ziti-console-lib/src/lib/assets/styles/forms.css b/projects/ziti-console-lib/src/lib/assets/styles/forms.css
index ceef67c2..53341da5 100644
--- a/projects/ziti-console-lib/src/lib/assets/styles/forms.css
+++ b/projects/ziti-console-lib/src/lib/assets/styles/forms.css
@@ -12,6 +12,7 @@ label {
font-family: 'Open Sans';
overflow: hidden;
text-overflow: ellipsis;
+ line-height: var(--defaultLineHeight);
}
textarea::placeholder {
diff --git a/projects/ziti-console-lib/src/lib/assets/styles/ziti.css b/projects/ziti-console-lib/src/lib/assets/styles/ziti.css
index 2d9c47c4..80cfcaa6 100644
--- a/projects/ziti-console-lib/src/lib/assets/styles/ziti.css
+++ b/projects/ziti-console-lib/src/lib/assets/styles/ziti.css
@@ -39,6 +39,7 @@ body {
--gapLarge: 10px;
--gapXL: 15px;
--defaultInputHeight: 43px;
+ --defaultLineHeight: 15px;
}
::placeholder {
diff --git a/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.html b/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.html
new file mode 100644
index 00000000..93f77074
--- /dev/null
+++ b/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.html
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.scss b/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.spec.ts b/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.spec.ts
new file mode 100644
index 00000000..c707ed56
--- /dev/null
+++ b/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.spec.ts
@@ -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;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [ConfigEditorComponent]
+ });
+ fixture = TestBed.createComponent(ConfigEditorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.ts b/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.ts
new file mode 100644
index 00000000..5418a426
--- /dev/null
+++ b/projects/ziti-console-lib/src/lib/features/config-editor/config-editor.component.ts
@@ -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();
+
+ _configData: any = {};
+ @Input() set configData(data) {
+ this._configData = data;
+ };
+ @Output() configDataChange = new EventEmitter();
+ 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;
+ }
+}
diff --git a/projects/ziti-console-lib/src/lib/features/data-table/column-headers/table-column-default/table-column-default.component.ts b/projects/ziti-console-lib/src/lib/features/data-table/column-headers/table-column-default/table-column-default.component.ts
index 249e1cc3..38d1e571 100644
--- a/projects/ziti-console-lib/src/lib/features/data-table/column-headers/table-column-default/table-column-default.component.ts
+++ b/projects/ziti-console-lib/src/lib/features/data-table/column-headers/table-column-default/table-column-default.component.ts
@@ -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) {
@@ -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();
}
});
});
@@ -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);
@@ -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;
+ });
+ }
}
diff --git a/projects/ziti-console-lib/src/lib/features/data-table/column-headers/table-column-filter/table-column-filter.component.ts b/projects/ziti-console-lib/src/lib/features/data-table/column-headers/table-column-filter/table-column-filter.component.ts
index eff18191..afa5d4ea 100644
--- a/projects/ziti-console-lib/src/lib/features/data-table/column-headers/table-column-filter/table-column-filter.component.ts
+++ b/projects/ziti-console-lib/src/lib/features/data-table/column-headers/table-column-filter/table-column-filter.component.ts
@@ -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)
}
diff --git a/projects/ziti-console-lib/src/lib/features/data-table/data-table-filter.service.ts b/projects/ziti-console-lib/src/lib/features/data-table/data-table-filter.service.ts
index 1d56eb29..1fd0a9c3 100644
--- a/projects/ziti-console-lib/src/lib/features/data-table/data-table-filter.service.ts
+++ b/projects/ziti-console-lib/src/lib/features/data-table/data-table-filter.service.ts
@@ -7,6 +7,7 @@ export type FilterObj = {
columnId: string;
value: any;
label: string;
+ type?: string;
}
@Injectable({
diff --git a/projects/ziti-console-lib/src/lib/features/data-table/data-table.component.html b/projects/ziti-console-lib/src/lib/features/data-table/data-table.component.html
index 67e8f49e..28c3db46 100644
--- a/projects/ziti-console-lib/src/lib/features/data-table/data-table.component.html
+++ b/projects/ziti-console-lib/src/lib/features/data-table/data-table.component.html
@@ -88,7 +88,7 @@
-
+
{
this.calendar.toggle();
}, 100);
@@ -355,8 +357,8 @@ export class DataTableComponent implements OnChanges, OnInit {
label = 'Last Day';
break;
}
- const startDateRange = encodeURIComponent('>=' + startDate.toISOString());
- const endDateRange = encodeURIComponent('<=' + endDate.toISOString());
+ const startDateRange = encodeURIComponent(startDate.toISOString());
+ const endDateRange = encodeURIComponent(endDate.toISOString());
this.columnFilters[this.dateTimeColumn] = [startDateRange, endDateRange];
if (closeCalendar) {
@@ -369,7 +371,8 @@ export class DataTableComponent implements OnChanges, OnInit {
columnId: this.dateTimeColumn,
value: [startDateRange, endDateRange],
label: label,
- filterName: 'Last Seen'
+ filterName: this.dateTimeFilterLabel,
+ type: 'DATETIME'
};
this.tableFilterService.updateFilter(filterObj);
diff --git a/projects/ziti-console-lib/src/lib/features/projectable-forms/configuration/configuration-form.component.html b/projects/ziti-console-lib/src/lib/features/projectable-forms/configuration/configuration-form.component.html
index 5c99e1b9..2162a13b 100644
--- a/projects/ziti-console-lib/src/lib/features/projectable-forms/configuration/configuration-form.component.html
+++ b/projects/ziti-console-lib/src/lib/features/projectable-forms/configuration/configuration-form.component.html
@@ -1,22 +1,102 @@
-
-
-
-
-
-
-
-
+
@@ -207,7 +207,7 @@
[clickable]="true"
[tooltip]="'View Config Data'"
(itemRemoved)="svc.removeConfig($event)"
- (itemSelected)="svc.previewConfig($event, dynamicForm)"
+ (itemSelected)="svc.previewConfig($event)"
>
{
this.svc.updatedAddedConfigs();
@@ -150,19 +152,30 @@ export class ServiceFormComponent extends ProjectableForm implements OnInit, OnC
}
configChanged($event) {
- this.svc.configChanged(this.dynamicForm);
+ if (this.svc.selectedConfigId === 'add-new') {
+ this.svc.newConfigName = '';
+ }
+ this.svc.configChanged();
}
configTypeChanged($event) {
- this.svc.configTypeChanged(this.dynamicForm);
+ this.svc.selectedConfigId = '';
+ this.svc.newConfigName = '';
+ this.svc.configTypeChanged();
}
get showConfigData() {
return this.svc.selectedConfigId === 'add-new' || this.svc.selectedConfigId === 'preview';
}
+ attachConfig() {
+ this.configEditor.getConfigDataFromForm();
+ this.svc.attachConfig(this.svc.selectedConfigId);
+ }
+
captureConfigEnterEvent(event) {
event.stopPropagation();
+ this.configEditor.getConfigDataFromForm();
this.svc.attachConfig(this.svc.selectedConfigId);
}
@@ -172,6 +185,7 @@ export class ServiceFormComponent extends ProjectableForm implements OnInit, OnC
this.save();
break;
case 'close':
+ this.resetForm();
this.closeModal(true);
break;
case 'toggle-view':
@@ -229,6 +243,13 @@ export class ServiceFormComponent extends ProjectableForm implements OnInit, OnC
}
}
+ resetForm() {
+ this.svc.selectedConfigId = '';
+ this.svc.selectedConfigTypeId = '';
+ this.errors = {};
+ this.svc.configErrors = {};
+ }
+
clear(): void {
}
}
diff --git a/projects/ziti-console-lib/src/lib/features/projectable-forms/service/service-form.service.ts b/projects/ziti-console-lib/src/lib/features/projectable-forms/service/service-form.service.ts
index 4eb1fb75..b788a0b3 100644
--- a/projects/ziti-console-lib/src/lib/features/projectable-forms/service/service-form.service.ts
+++ b/projects/ziti-console-lib/src/lib/features/projectable-forms/service/service-form.service.ts
@@ -26,6 +26,7 @@ import moment from 'moment';
import dynamic from "ajv/dist/vocabularies/dynamic";
import {SchemaService} from "../../../services/schema.service";
import {Subscription} from "rxjs";
+import {ConfigEditorComponent} from "../../config-editor/config-editor.component";
export const SERVICE_EXTENSION_SERVICE = new InjectionToken('SERVICE_EXTENSION_SERVICE');
@@ -93,8 +94,9 @@ export class ServiceFormService {
'var(--formSubGroup)'
]
- subscription: Subscription = new Subscription();Z
+ subscription: Subscription = new Subscription();
+ configEditor: ConfigEditorComponent;
constructor(
@Inject(SETTINGS_SERVICE) public settingsService: SettingsService,
@Inject(ZITI_DATA_SERVICE) private zitiService: ZitiDataService,
@@ -174,14 +176,13 @@ export class ServiceFormService {
});
}
- previewConfig(configName, dynamicForm) {
+ previewConfig(configName) {
this.showCfgPreviewOption = true;
this.configData = this.associatedConfigsMap[configName].data;
this.selectedConfigName = this.associatedConfigsMap[configName].name;
this.selectedConfigId = 'preview';
this.selectedConfigTypeId = this.associatedConfigsMap[configName].configTypeId;
- this.configTypeChanged(dynamicForm, false);
- this.updateConfigData();
+ this.configTypeChanged(false);
this.selectedConfigId = 'preview';
this.newConfigName = this.selectedConfigName;
defer(() => {
@@ -268,7 +269,7 @@ export class ServiceFormService {
});
}
- configTypeChanged(dynamicForm?, resetData?) {
+ configTypeChanged(resetData?) {
this.filteredConfigs = this.configs.filter((config) => {
return config.configTypeId === this.selectedConfigTypeId;
});
@@ -277,18 +278,10 @@ export class ServiceFormService {
this.selectedConfigType = configType;
}
});
- this.selectedConfigId = !isEmpty(this.selectedConfigTypeId) ? 'add-new' : '';
- this.configChanged(dynamicForm, resetData);
- }
-
- routerChanged(event?: any) {
- let selectedRouter;
- this.routers.forEach((router) => {
- if (this.selectedRouterId === router.id) {
- selectedRouter = router;
- }
- });
- this.selectedRouter = selectedRouter;
+ if (this.selectedConfigId !== 'preview') {
+ this.selectedConfigId = !isEmpty(this.selectedConfigTypeId) ? 'add-new' : '';
+ }
+ this.configChanged(resetData);
}
updatedAddedConfigs() {
@@ -310,48 +303,11 @@ export class ServiceFormService {
if (this.configJsonView) {
//this.configSubscriptions.unsubscribe();
}
- this.updateConfigData();
- }
-
- async createForm(dynamicForm) {
- this.clearForm();
- if (this.selectedConfigType && dynamicForm) {
- if (this.selectedSchema) {
- this.renderSchmea(this.selectedSchema, dynamicForm);
- }
- }
- }
-
- clearForm() {
- this.items.forEach((item: any) => {
- if (item?.component) item.component.destroy();
- });
- this.items = [];
- if (this.subscription) this.subscription.unsubscribe();
- }
-
- renderSchmea(schema: any, dynamicForm: any) {
- if (schema.properties) {
- this.items = this.schemaSvc.render(schema, dynamicForm, this.lColorArray, this.bColorArray);
- for (let obj of this.items) {
- const cRef = obj.component;
- cRef.instance.errors = this.errors;
- 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] = {};
- }
- }
- }
}
async attachConfig(addedConfigId) {
let configId;
if (this.selectedConfigId === 'add-new') {
- if (!this.configJsonView) {
- this.getConfigDataFromForm();
- }
if (!this.validateConfig()) {
const growlerData = new GrowlerModel(
'error',
@@ -405,6 +361,8 @@ export class ServiceFormService {
this.newConfigName = '';
this.selectedConfigTypeId = '';
this.selectedConfigId = '';
+ this.configData = {};
+ this.configEditor?.getConfigDataFromForm();
return;
}
} else {
@@ -460,76 +418,22 @@ export class ServiceFormService {
if (this.selectedConfigId === 'preview' && nameToRemove === this.selectedConfigName) {
this.selectedConfigId = '';
this.selectedConfigTypeId = '';
- this.updateConfigData();
}
}
}
- getConfigDataFromForm() {
- const data = {};
- this.addItemsToConfig(this.items, data);
- this.configData = data;
- this.hideConfigJSON = false;
- }
-
- 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;
- }
-
- 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;
- }
-
- async configChanged(dynamicForm, resetData = true) {
+ async configChanged(resetData = true) {
let selectedConfig: any = {};
this.configData = resetData ? undefined : this.configData;
let data;
let attachLabel = 'Attach to Service';
- if (this.selectedConfigId === 'add-new') {
+ if (this.selectedConfigId === 'preview') {
+ this.selectedSchema = await this.zitiService.schema(this.selectedConfigType.schema);
+ } else if (this.selectedConfigId === 'add-new') {
data = {};
this.selectedSchema = await this.zitiService.schema(this.selectedConfigType.schema);
attachLabel = 'Create and Attach';
- this.createForm(dynamicForm);
+ //this.createForm(dynamicForm);
this.saveDisabled = true;
} else if (this.selectedConfigId) {
this.filteredConfigs.forEach((config) => {
@@ -542,98 +446,17 @@ export class ServiceFormService {
} else {
this.saveDisabled = false;
}
- if (!this.configData) {
- this.configData = data;
- } else {
- defer(() => {
- this.configData = cloneDeep(data);
- });
- }
- this.updateConfigData();
- this.attachLabel = attachLabel;
- }
-
- updateConfigData() {
- if (!this.configJsonView) {
- 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;
- }
-
- addTerminator() {
- let termAdded = false;
- this.addedTerminators.forEach((termName) => {
- if (this.selectedRouter.name === termName) {
- termAdded = true;
- }
- });
- if (!termAdded) {
- const terminatorModel = {
- address: this.terminatorProtocol + ':' + this.terminatorHost + ":" + this.terminatorPort,
- binding: this.selectedBindingId,
- router: this.selectedRouter.id,
- service: undefined
+ if (this.selectedConfigId !== 'preview') {
+ if (!this.configData) {
+ this.configData = data;
+ } else {
+ defer(() => {
+ this.configData = cloneDeep(data);
+ });
}
- this.addedTerminatorNames = [...this.addedTerminatorNames, this.selectedRouter.name];
- this.addedTerminators.push(terminatorModel);
- this.selectedRouterId = '';
- this.selectedBindingId = '';
- this.terminatorPort = '';
- this.terminatorHost = '';
- this.terminatorProtocol = '';
}
+ //this.updateConfigData();
+ this.attachLabel = attachLabel;
}
validate() {
@@ -646,13 +469,10 @@ export class ServiceFormService {
validateConfig() {
this.configErrors = {};
+ this.configEditor?.validateConfig();
if (isEmpty(this.newConfigName)) {
this.configErrors['name'] = true;
}
- const configItemsValid = this.validateConfigItems(this.items);
- if (!configItemsValid) {
- this.configErrors['configData'] = true;
- }
return isEmpty(this.configErrors);
}
diff --git a/projects/ziti-console-lib/src/lib/models/config.ts b/projects/ziti-console-lib/src/lib/models/config.ts
new file mode 100644
index 00000000..afcc64e3
--- /dev/null
+++ b/projects/ziti-console-lib/src/lib/models/config.ts
@@ -0,0 +1,5 @@
+export class Config {
+ name = '';
+ data = {};
+ configTypeId = '';
+};
\ No newline at end of file
diff --git a/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.html b/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.html
index 860f4216..9bfb94f7 100644
--- a/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.html
+++ b/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.html
@@ -1,6 +1,7 @@
-
-
-
+
+
+
+
diff --git a/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.scss b/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.scss
index 7c5b8d6d..db459e7c 100644
--- a/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.scss
+++ b/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.scss
@@ -1,11 +1,3 @@
-:host {
- display: flex;
- flex: 1 1 auto;
- width: 100%;
- height: 100%;
- position: relative;
-}
-
.configurations {
width: 100%;
height: 100%;
diff --git a/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.ts b/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.ts
index 9ce29985..f3ebbeb4 100644
--- a/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.ts
+++ b/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.component.ts
@@ -19,11 +19,10 @@ import {DataTableFilterService} from "../../features/data-table/data-table-filte
import {ConfigurationsPageService} from "./configurations-page.service";
import {TabNameService} from "../../services/tab-name.service";
import {ListPageComponent} from "../../shared/list-page-component.class";
-import {CallbackResults} from "../../features/list-page-features/list-page-form/list-page-form.component";
-import {SettingsService} from "../../services/settings.service";
import {ConsoleEventsService} from "../../services/console-events.service";
import {MatDialog} from "@angular/material/dialog";
+
@Component({
selector: 'lib-configurations',
templateUrl: './configurations-page.component.html',
@@ -32,15 +31,11 @@ import {MatDialog} from "@angular/material/dialog";
export class ConfigurationsPageComponent extends ListPageComponent implements OnInit {
title = 'Configuration Management'
tabs: { url: string, label: string }[] ;
- formTitle = '';
- formSubtitle = '';
isLoading: boolean;
- showEditForm = false;
- showButtons = false;
- private schema: any;
+ formDataChanged = false;
constructor(
- svc: ConfigurationsPageService,
+ override svc: ConfigurationsPageService,
filterService: DataTableFilterService,
private tabNames: TabNameService,
consoleEvents: ConsoleEventsService,
@@ -52,13 +47,19 @@ export class ConfigurationsPageComponent extends ListPageComponent implements On
override ngOnInit() {
this.tabs = this.tabNames.getTabs('services');
this.svc.refreshData = this.refreshData;
+ this.svc.getConfigTypes().then((result) => {
+ console.log(result);
+ });
super.ngOnInit();
}
headerActionClicked(action: string) {
switch (action) {
case 'add':
- this.openUpdate();
+ this.svc.openUpdate();
+ break;
+ case 'edit':
+ this.svc.openUpdate(action);
break;
case 'delete':
const selectedItems = this.rowData.filter((row) => {
@@ -71,37 +72,38 @@ export class ConfigurationsPageComponent extends ListPageComponent implements On
}
}
- itemUpdate() {
-
- }
-
- tableAction($event: { action: string; item?: any }) {
-
- }
-
- private openUpdate(model?: any) {
- if (!model) {
- this.formTitle = 'Create Configuration'
- this.formSubtitle = 'Add a New Configuration by completing this form';
- } else {
- this.formTitle = 'Edit Configuration'
- this.formSubtitle = 'Change Configuration details';
+ tableAction(event: any) {
+ switch(event?.action) {
+ case 'toggleAll':
+ case 'toggleItem':
+ this.itemToggled(event.item)
+ break;
+ case 'update':
+ this.svc.openUpdate(event.item);
+ break;
+ case 'create':
+ this.svc.openUpdate();
+ break;
+ case 'delete':
+ this.deleteItem(event.item)
+ break;
+ default:
+ break;
}
- this.showEditForm = true;
}
- viewButtons(state: boolean) {
- this.showButtons = state;
+ deleteItem(item: any) {
+ this.openBulkDelete([item], 'config');
}
- validate = (formData: any): Promise => {
- return this.svc.validate(formData, this.schema);
- }
-
- onSchemaChange(schema: any) {
- this.schema = schema;
+ closeModal(event: any) {
+ this.svc.sideModalOpen = false;
+ if(event?.refresh) {
+ this.refreshData();
+ }
}
- closeModal(event: any) {
+ dataChanged(event) {
+ this.formDataChanged = event;
}
}
diff --git a/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.service.ts b/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.service.ts
index ed10ec69..206fbc35 100644
--- a/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.service.ts
+++ b/projects/ziti-console-lib/src/lib/pages/configurations/configurations-page.service.ts
@@ -16,7 +16,7 @@
import {Inject, Injectable} from '@angular/core';
import {DataTableFilterService, FilterObj} from "../../features/data-table/data-table-filter.service";
-import _, {isEmpty} from "lodash";
+import _, {isEmpty, unset} from "lodash";
import moment from "moment";
import {ListPageServiceClass} from "../../shared/list-page-service.class";
import {
@@ -27,6 +27,7 @@ import {SchemaService} from "../../services/schema.service";
import {SETTINGS_SERVICE, SettingsService} from "../../services/settings.service";
import {CsvDownloadService} from "../../services/csv-download.service";
import {ExtensionService, SHAREDZ_EXTENSION} from "../../features/extendable/extensions-noop.service";
+import {Service} from "../../models/service";
@Injectable({
providedIn: 'root'
@@ -35,7 +36,14 @@ export class ConfigurationsPageService extends ListPageServiceClass {
private paging = this.DEFAULT_PAGING;
- resourceType = 'configurations';
+ resourceType = 'configs';
+ selectedConfig: any = {};
+ modalType = '';
+
+ override menuItems = [
+ {name: 'Edit', action: 'update'},
+ {name: 'Delete', action: 'delete'},
+ ]
constructor(
private schemaSvc: SchemaService,
@@ -52,6 +60,13 @@ export class ConfigurationsPageService extends ListPageServiceClass {
return moment(row?.data?.createdAt).local().format('M/D/YYYY H:MM A');
}
+ const typeRenderer = (row) => {
+ return row?.data?.configType?.name;
+ };
+
+ const createdAtHeaderComponentParams = {
+ filterType: 'DATETIME',
+ };
return [
{
colId: 'name',
@@ -59,6 +74,13 @@ export class ConfigurationsPageService extends ListPageServiceClass {
headerName: 'Name',
headerComponent: TableColumnDefaultComponent,
headerComponentParams: this.headerComponentParams,
+ cellRenderer: this.nameColumnRenderer,
+ onCellClicked: (data) => {
+ if (this.hasSelectedText()) {
+ return;
+ }
+ this.openUpdate(data.data);
+ },
resizable: true,
cellClass: 'nf-cell-vert-align tCol',
sortable: true,
@@ -67,22 +89,23 @@ export class ConfigurationsPageService extends ListPageServiceClass {
},
{
colId: 'type',
- field: 'configType.name',
+ field: 'type',
headerName: 'Type',
headerComponent: TableColumnDefaultComponent,
- headerComponentParams: this.headerComponentParams,
+ headerComponentParams: this.typeHeaderComponentParams,
+ cellRenderer: typeRenderer,
resizable: true,
cellClass: 'nf-cell-vert-align tCol',
sortable: true,
filter: true,
- sortColumn: this.sort.bind(this)
+ sortColumn: this.sort.bind(this),
},
{
colId: 'createdAt',
field: 'createdAt',
headerName: 'Created At',
headerComponent: TableColumnDefaultComponent,
- headerComponentParams: this.headerComponentParams,
+ headerComponentParams: createdAtHeaderComponentParams,
valueFormatter: createdAtFormatter,
resizable: true,
cellClass: 'nf-cell-vert-align tCol',
@@ -90,6 +113,43 @@ export class ConfigurationsPageService extends ListPageServiceClass {
];
}
+ _typeHeaderComponentParams = {
+ filterType: 'SELECT',
+ enableSorting: true,
+ filterOptions: [
+ { label: 'ALL', value: '' },
+ ],
+ getFilterOptions: () => {
+ return this.typeHeaderComponentParams.filterOptions;
+ }
+ };
+
+ get typeHeaderComponentParams() {
+ return this._typeHeaderComponentParams;
+ }
+
+ set typeHeaderComponentParams(params) {
+ this._typeHeaderComponentParams = params;
+ }
+
+ getConfigTypes() {
+ const sort = {
+ ordering: 'asc',
+ sortBy: 'name'
+ };
+ return super.getTableData('config-types', this.DEFAULT_PAGING, [], sort)
+ .then((results: any) => {
+ this.typeHeaderComponentParams.filterOptions = [{ label: 'ALL', value: '' }];
+ results.data.forEach((configType: any) => {
+ this.typeHeaderComponentParams.filterOptions.push({
+ label: configType.name,
+ value: configType.id
+ });
+ });
+ return this.typeHeaderComponentParams;
+ });
+ }
+
getData(filters?: FilterObj[], sort?: any) {
// we can customize filters or sorting here before moving on...
return super.getTableData('configs', this.paging, filters, sort)
@@ -174,33 +234,22 @@ export class ConfigurationsPageService extends ListPageServiceClass {
return results;
}
- private addActionsPerRow(results: any) {
+ private addActionsPerRow(results: any): any[] {
return results.data.map((row) => {
- row.actionList = ['update', 'override', 'delete'];
- if (row?.enrollment?.ott) {
- if (row?.enrollment?.ott?.expiresAt) {
- const difference = moment(row?.enrollment?.ott?.expiresAt).diff(moment(new Date()));
- if (difference > 0) {
- row.actionList.push('download-enrollment');
- row.actionList.push('qr-code');
- }
- } else {
- row.actionList.push('download-enrollment');
- row.actionList.push('qr-code');
- }
- } else if (row?.enrollment?.updb) {
- if (row?.enrollment?.updb?.expiresAt != null) {
- const difference = moment(row?.enrollment?.updb?.expiresAt).diff(moment(new Date()));
- if (difference > 0) {
- row.actionList.push('download-enrollment');
- row.actionList.push('qr-code');
- }
- } else {
- row.actionList.push('download-enrollment');
- row.actionList.push('qr-code');
- }
- }
+ row.actionList = ['update', 'delete'];
return row;
});
}
+
+ public openUpdate(item?: any) {
+ this.modalType = 'config';
+ if (item) {
+ this.selectedConfig = item;
+ this.selectedConfig.badges = [];
+ unset(this.selectedConfig, '_links');
+ } else {
+ this.selectedConfig = new Service();
+ }
+ this.sideModalOpen = true;
+ }
}
diff --git a/projects/ziti-console-lib/src/lib/pages/services/services-page.component.ts b/projects/ziti-console-lib/src/lib/pages/services/services-page.component.ts
index 0e913bc5..ccf47e09 100644
--- a/projects/ziti-console-lib/src/lib/pages/services/services-page.component.ts
+++ b/projects/ziti-console-lib/src/lib/pages/services/services-page.component.ts
@@ -107,11 +107,8 @@ export class ServicesPageComponent extends ListPageComponent implements OnInit,
deleteItem(item: any) {
this.openBulkDelete([item], 'service');
- console.log('test');
}
-
-
getServiceRoleAttributes() {
this.svc.getServiceRoleAttributes().then((result: any) => {
this.serviceRoleAttributes = result.data;
diff --git a/projects/ziti-console-lib/src/lib/pages/services/services-page.service.ts b/projects/ziti-console-lib/src/lib/pages/services/services-page.service.ts
index 17aebd2c..a2355682 100644
--- a/projects/ziti-console-lib/src/lib/pages/services/services-page.service.ts
+++ b/projects/ziti-console-lib/src/lib/pages/services/services-page.service.ts
@@ -83,12 +83,6 @@ export class ServicesPageService extends ListPageServiceClass {
}
initTableColumns(): any {
- const nameRenderer = (row) => {
- return `
- ${row?.data?.name}
-
`
- }
-
const rolesRenderer = (row) => {
let roles = '';
row?.data?.roleAttributes?.forEach((attr) => {
@@ -116,7 +110,7 @@ export class ServicesPageService extends ListPageServiceClass {
this.openUpdate(data.data);
},
resizable: true,
- cellRenderer: nameRenderer,
+ cellRenderer: this.nameColumnRenderer,
cellClass: 'nf-cell-vert-align tCol',
sortable: true,
filter: true,
@@ -233,12 +227,6 @@ export class ServicesPageService extends ListPageServiceClass {
if (item) {
this.selectedService = item;
this.selectedService.badges = [];
- // TODO: implement when metrics and dialog features are available
- /*this.selectedService.moreActions = [
- {name: 'open-metrics', label: 'Open Metrics'},
- {name: 'dial-logs', label: 'Dial Logs'},
- {name: 'dial-logs', label: 'View Events'},
- ];*/
unset(this.selectedService, '_links');
} else {
this.selectedService = new Service();
diff --git a/projects/ziti-console-lib/src/lib/services/schema.service.ts b/projects/ziti-console-lib/src/lib/services/schema.service.ts
index f9481dc1..9980d36c 100644
--- a/projects/ziti-console-lib/src/lib/services/schema.service.ts
+++ b/projects/ziti-console-lib/src/lib/services/schema.service.ts
@@ -642,6 +642,8 @@ export class SchemaService {
} else if (subItem?.component?.instance?.fieldValue) {
itemData[subItem.key] = subItem.component.instance.fieldValue;
subItem.component.instance.fieldValue = undefined;
+ } else if (subItem.items) {
+ itemData[subItem.key] = this.addItemData(subItem);
}
}
});
diff --git a/projects/ziti-console-lib/src/lib/services/ziti-controller-data.service.ts b/projects/ziti-console-lib/src/lib/services/ziti-controller-data.service.ts
index 047daad4..8f02935f 100644
--- a/projects/ziti-console-lib/src/lib/services/ziti-controller-data.service.ts
+++ b/projects/ziti-console-lib/src/lib/services/ziti-controller-data.service.ts
@@ -95,7 +95,7 @@ export class ZitiControllerDataService extends ZitiDataService {
const apiVersions = this.settingsService.apiVersions || {};
const prefix = apiVersions["edge-management"]?.v1?.path || '/edge/management/v1';
const url = this.settingsService.settings.selectedEdgeController;
- const urlFilter = this.getUrlFilter(paging);
+ const urlFilter = this.getUrlFilter(paging, filters);
const serviceUrl = url + prefix + "/" + type + urlFilter;
return firstValueFrom(this.httpClient.get(serviceUrl,{}).pipe(
@@ -105,18 +105,6 @@ export class ZitiControllerDataService extends ZitiDataService {
throw({error: error});
}),
map((results: any) => {
- if(filters.length > 0) {
- filters.forEach((filter:FilterObj) => {
- let newData: any[] = [];
- if(filter.columnId !== 'name' && !isEmpty(filter.value )) {
- results.data.forEach(row => {
- if(get(row, filter.columnId)?.indexOf(filter.value) >= 0)
- newData.push(row);
- })
- results.data = newData;
- }
- });
- }
return results;
})
)
@@ -238,25 +226,43 @@ export class ZitiControllerDataService extends ZitiDataService {
);
}
- private getUrlFilter(paging: any) {
+ private getUrlFilter(paging, filters: any[]) {
let urlFilter = '';
let toSearchOn = "name";
- let noSearch = false;
+ let noSearch = filters?.length <= 0;
if (paging && paging.sort != null) {
if (paging.searchOn) toSearchOn = paging.searchOn;
if (paging.noSearch) noSearch = true;
if (!paging.filter) paging.filter = "";
paging.filter = paging.filter.split('#').join('');
- if (noSearch) {
- if (paging.page !== -1) urlFilter = "?limit=" + paging.total + "&offset=" + ((paging.page - 1) * paging.total) + "&sort=" + paging.sort + " " + paging.order;
+ }
+ filters.forEach((filter, index) => {
+ let filterVal = '';
+ switch (filter.type) {
+ case 'TEXTINPUT':
+ filterVal = `${filter.columnId} contains "${filter.value}"`;
+ break;
+ case 'SELECT':
+ case 'COMBO':
+ filterVal = `${filter.columnId} = "${filter.value}"`;
+ break;
+ case 'DATETIME':
+ filterVal = `${filter.columnId} >= datetime(${filter.value[0]}) and ${filter.columnId} <= datetime(${filter.value[1]})`;
+ break;
+ default:
+ filterVal = `${filter.columnId} contains "${filter.value}"`;
+ break;
+ }
+ if (index <= 0) {
+ urlFilter = `?filter= ${filterVal}`;
} else {
- if (paging.page !== -1) urlFilter = "?filter=(" + toSearchOn + " contains \"" + paging.filter + "\")&limit=" + paging.total + "&offset=" + ((paging.page - 1) * paging.total) + "&sort=" + paging.sort + " " + paging.order;
- if (paging.params) {
- for (const key in paging.params) {
- urlFilter += ((urlFilter.length === 0) ? "?" : "&") + key + "=" + paging.params[key];
- }
- }
+ urlFilter += ` and ${filterVal}`
}
+ });
+ if (noSearch) {
+ if (paging.page !== -1) urlFilter = "?limit=" + paging.total + "&offset=" + ((paging.page - 1) * paging.total) + "&sort=" + paging.sort + " " + paging.order;
+ } else {
+ urlFilter += `&limit=${paging.total}&offset=${((paging.page - 1) * paging.total)}&sort=${paging.sort} ${paging.order}`
}
return urlFilter;
}
diff --git a/projects/ziti-console-lib/src/lib/shared-assets/styles/global.scss b/projects/ziti-console-lib/src/lib/shared-assets/styles/global.scss
index d8674677..9e175c60 100644
--- a/projects/ziti-console-lib/src/lib/shared-assets/styles/global.scss
+++ b/projects/ziti-console-lib/src/lib/shared-assets/styles/global.scss
@@ -3,6 +3,7 @@ body {
overflow: hidden;
}
+select,
input {
&.error {
border-color: var(--red);
@@ -199,7 +200,8 @@ input {
}
.form-field-extended-fields {
- padding: 15px;
+ padding: var(--paddingXL);
+ padding-top: var(--paddingSmall);
background-color: var(--formSubGroup);
border-radius: 7px;
&[hidden] {
@@ -751,4 +753,132 @@ lib-tag-selector {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
+}
+
+.form-header-toggle-container {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+
+ .form-header-toggle {
+ display: flex;
+ flex-direction: row;
+ width: 30px;
+ height: 18px;
+ border-radius: 10px;
+ border-color: var(--inputBorder);
+ border-style: solid;
+ border-width: 2px;
+ margin-left: 5px;
+ margin-right: 5px;
+ cursor: pointer;
+ position: relative;
+ margin-right: 5px;
+
+ &:hover {
+ filter: brightness(90%);
+ }
+
+ &:active {
+ transform: translateY(1px);
+ filter: brightness(80%);
+ }
+
+ .form-toggle-switch {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: center;
+ height: 100%;
+ margin-left: 3px;
+ position: absolute;
+ transition: 0.5s;
+ left: 0;
+
+ &.toggle-right {
+ left: 10px;
+
+ .form-toggle-indicator {
+ border-color: var(--red);
+ }
+ }
+
+ .form-toggle-indicator {
+ height: 10px;
+ border-color: var(--green);
+ border-style: solid;
+ border-left-width: 1px;
+ border-right-width: 1px;
+ position: relative;
+ margin-left: 2px;
+ }
+ }
+ }
+
+ .toggle-option-text {
+ font-size: 13px;
+ font-weight: 600;
+ color: var(--placeholder);
+ cursor: pointer;
+
+ &:hover {
+ filter: brightness(90%);
+ &.toggle-option-selected {
+ filter: unset;
+ }
+ }
+
+ &.toggle-option-selected {
+ color: var(--tableText);
+ cursor: default;
+ }
+ }
+}
+
+.config-title-row {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+
+ .jsonButton {
+ color: var(--offWhite);
+ font-weight: 600;
+ opacity: 1;
+ }
+}
+
+.form-field-input-group {
+ gap: 10px;
+ display: flex;
+ flex-direction: column;
+
+ .form-field-title {
+ color: var(--offWhite);
+ }
+}
+
+.form-field-extended-fields {
+ label {
+ color: var(--white) !important;
+ margin-bottom: 0;
+ }
+ .invalid {
+ input {
+ border-color: var(--red);
+ }
+ .p-component {
+ &.p-input-wrapper {
+ border-color: var(--red);
+ }
+ }
+ }
+}
+
+.projectable-form-main-column {
+ &.form-group-row {
+ &[hidden] {
+ display: none;
+ }
+ }
}
\ No newline at end of file
diff --git a/projects/ziti-console-lib/src/lib/shared/list-page-service.class.ts b/projects/ziti-console-lib/src/lib/shared/list-page-service.class.ts
index dd2d8836..295f19d2 100644
--- a/projects/ziti-console-lib/src/lib/shared/list-page-service.class.ts
+++ b/projects/ziti-console-lib/src/lib/shared/list-page-service.class.ts
@@ -39,7 +39,7 @@ export abstract class ListPageServiceClass {
filterType: 'TEXTINPUT',
enableSorting: true
};
-
+
DEFAULT_PAGING: any = {
filter: "",
noSearch: false,
@@ -63,6 +63,12 @@ export abstract class ListPageServiceClass {
ordering: 'asc'
};
+ nameColumnRenderer = (row) => {
+ return `
+ ${row?.data?.name}
+
`
+ }
+
constructor(
@Inject(SETTINGS_SERVICE) protected settings: SettingsServiceClass,
protected filterService: DataTableFilterService,
@@ -114,17 +120,7 @@ export abstract class ListPageServiceClass {
paging.sort = sort.sortBy;
paging.order = sort.ordering;
}
- let nonNameFilters: FilterObj[] = [];
- if(filters) {
- for (let idx = 0; idx < filters.length; idx++) {
- if (filters[idx].columnId === 'name' && filters[idx].value) {
- paging.noSearch = false;
- paging.searchOn = 'name'
- paging.filter = filters[idx].value;
- } else nonNameFilters.push(filters[idx]);
- }
- }
- return this.dataService.get(resourceType, paging, nonNameFilters);
+ return this.dataService.get(resourceType, paging, filters);
}
removeItems(ids: string[]) {
diff --git a/projects/ziti-console-lib/src/lib/ziti-console-lib.module.ts b/projects/ziti-console-lib/src/lib/ziti-console-lib.module.ts
index 7be30e48..a3939d71 100644
--- a/projects/ziti-console-lib/src/lib/ziti-console-lib.module.ts
+++ b/projects/ziti-console-lib/src/lib/ziti-console-lib.module.ts
@@ -96,6 +96,7 @@ import { SimpleServiceComponent } from './features/projectable-forms/service/sim
import { CardComponent } from './features/card/card.component';
import { CreationSummaryDialogComponent } from './features/creation-summary-dialog/creation-summary-dialog.component';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
+import { ConfigEditorComponent } from './features/config-editor/config-editor.component';
export function playerFactory() {
return import(/* webpackChunkName: 'lottie-web' */ 'lottie-web');
@@ -162,7 +163,8 @@ export function playerFactory() {
CardListComponent,
SimpleServiceComponent,
CardComponent,
- CreationSummaryDialogComponent
+ CreationSummaryDialogComponent,
+ ConfigEditorComponent
],
imports: [
CommonModule,