ng-kinintel 20.0.3 → 20.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1171,11 +1171,11 @@ class DatasetFilterInclusionComponent {
1171
1171
  ngOnInit() {
1172
1172
  }
1173
1173
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatasetFilterInclusionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1174
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DatasetFilterInclusionComponent, isStandalone: false, selector: "ki-dataset-filter-inclusion", inputs: { filter: "filter", parameterValues: "parameterValues", dependsString: "dependsString" }, ngImport: i0, template: "@if (parameterValues && parameterValues.length) {\n <div class=\"m-2\">\n <mat-checkbox #depends [checked]=\"filter.inclusionCriteria && filter.inclusionCriteria !== 'Always'\"\n (change)=\"filter.inclusionCriteria = depends.checked ? 'ParameterPresent' : 'Always'\">\n <span class=\"font-normal\">{{ dependsString }}</span>\n </mat-checkbox>\n </div>\n @if (filter.inclusionCriteria && filter.inclusionCriteria !== 'Always') {\n <select\n class=\"mr-1 py-2\" [(ngModel)]=\"filter.inclusionCriteria\">\n <option value=\"ParameterPresent\">Parameter Is Set</option>\n <option value=\"ParameterNotPresent\">Parameter Is Not Set</option>\n <option value=\"ParameterValue\">Parameter Has Value</option>\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterPresent' || filter.inclusionCriteria == 'ParameterNotPresent') {\n <select class=\"mr-1 py-2\"\n [(ngModel)]=\"filter._inclusionParam\" (change)=\"filter.inclusionData = filter._inclusionParam\">\n @for (param of parameterValues; track param) {\n <option [ngValue]=\"param.name\">\n {{ param.title }}\n </option>\n }\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterValue') {\n <select class=\"mr-1 py-2\"\n [(ngModel)]=\"filter._inclusionParam\">\n @for (param of parameterValues; track param) {\n <option [ngValue]=\"param.name\">\n {{ param.title }}\n </option>\n }\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterValue') {\n <input\n placeholder=\"Enter value\"\n class=\"py-2\" [(ngModel)]=\"filter._inclusionParamValue\"\n (change)=\"filter.inclusionData = filter._inclusionParam + '=' + filter._inclusionParamValue\"/>\n}\n\n}\n", styles: [":host{display:flex;align-items:flex-start}\n"], dependencies: [{ kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }] }); }
1174
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DatasetFilterInclusionComponent, isStandalone: false, selector: "ki-dataset-filter-inclusion", inputs: { filter: "filter", parameterValues: "parameterValues", dependsString: "dependsString" }, ngImport: i0, template: "@if (parameterValues && parameterValues.length) {\n <div class=\"m-2\">\n <mat-checkbox #depends [checked]=\"filter.inclusionCriteria && filter.inclusionCriteria !== 'Always'\"\n (change)=\"filter.inclusionCriteria = depends.checked ? 'ParameterPresent' : 'Always'\">\n <span class=\"font-normal\">{{ dependsString }}</span>\n </mat-checkbox>\n </div>\n @if (filter.inclusionCriteria && filter.inclusionCriteria !== 'Always') {\n <select\n class=\"mr-1 py-2\" [(ngModel)]=\"filter.inclusionCriteria\">\n <option value=\"ParameterPresent\">Parameter Is Set</option>\n <option value=\"ParameterNotPresent\">Parameter Is Not Set</option>\n <option value=\"ParameterValue\">Parameter Has Value</option>\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterPresent' || filter.inclusionCriteria == 'ParameterNotPresent') {\n <select class=\"mr-1 py-2\"\n [(ngModel)]=\"filter._inclusionParam\" (change)=\"filter.inclusionData = filter._inclusionParam\">\n @for (param of parameterValues; track param) {\n <option [ngValue]=\"param.name\">\n {{ param.title }}\n </option>\n }\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterValue') {\n <select class=\"mr-1 py-2\"\n [(ngModel)]=\"filter._inclusionParam\">\n @for (param of parameterValues; track param) {\n <option [ngValue]=\"param.name\">\n {{ param.title }}\n </option>\n }\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterValue') {\n <input\n placeholder=\"Enter value\"\n class=\"py-2.5 \" [(ngModel)]=\"filter._inclusionParamValue\"\n (change)=\"filter.inclusionData = filter._inclusionParam + '=' + filter._inclusionParamValue\"/>\n}\n\n}\n", styles: [":host{display:flex;align-items:flex-start}\n"], dependencies: [{ kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }] }); }
1175
1175
  }
1176
1176
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatasetFilterInclusionComponent, decorators: [{
1177
1177
  type: Component,
1178
- args: [{ selector: 'ki-dataset-filter-inclusion', standalone: false, template: "@if (parameterValues && parameterValues.length) {\n <div class=\"m-2\">\n <mat-checkbox #depends [checked]=\"filter.inclusionCriteria && filter.inclusionCriteria !== 'Always'\"\n (change)=\"filter.inclusionCriteria = depends.checked ? 'ParameterPresent' : 'Always'\">\n <span class=\"font-normal\">{{ dependsString }}</span>\n </mat-checkbox>\n </div>\n @if (filter.inclusionCriteria && filter.inclusionCriteria !== 'Always') {\n <select\n class=\"mr-1 py-2\" [(ngModel)]=\"filter.inclusionCriteria\">\n <option value=\"ParameterPresent\">Parameter Is Set</option>\n <option value=\"ParameterNotPresent\">Parameter Is Not Set</option>\n <option value=\"ParameterValue\">Parameter Has Value</option>\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterPresent' || filter.inclusionCriteria == 'ParameterNotPresent') {\n <select class=\"mr-1 py-2\"\n [(ngModel)]=\"filter._inclusionParam\" (change)=\"filter.inclusionData = filter._inclusionParam\">\n @for (param of parameterValues; track param) {\n <option [ngValue]=\"param.name\">\n {{ param.title }}\n </option>\n }\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterValue') {\n <select class=\"mr-1 py-2\"\n [(ngModel)]=\"filter._inclusionParam\">\n @for (param of parameterValues; track param) {\n <option [ngValue]=\"param.name\">\n {{ param.title }}\n </option>\n }\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterValue') {\n <input\n placeholder=\"Enter value\"\n class=\"py-2\" [(ngModel)]=\"filter._inclusionParamValue\"\n (change)=\"filter.inclusionData = filter._inclusionParam + '=' + filter._inclusionParamValue\"/>\n}\n\n}\n", styles: [":host{display:flex;align-items:flex-start}\n"] }]
1178
+ args: [{ selector: 'ki-dataset-filter-inclusion', standalone: false, template: "@if (parameterValues && parameterValues.length) {\n <div class=\"m-2\">\n <mat-checkbox #depends [checked]=\"filter.inclusionCriteria && filter.inclusionCriteria !== 'Always'\"\n (change)=\"filter.inclusionCriteria = depends.checked ? 'ParameterPresent' : 'Always'\">\n <span class=\"font-normal\">{{ dependsString }}</span>\n </mat-checkbox>\n </div>\n @if (filter.inclusionCriteria && filter.inclusionCriteria !== 'Always') {\n <select\n class=\"mr-1 py-2\" [(ngModel)]=\"filter.inclusionCriteria\">\n <option value=\"ParameterPresent\">Parameter Is Set</option>\n <option value=\"ParameterNotPresent\">Parameter Is Not Set</option>\n <option value=\"ParameterValue\">Parameter Has Value</option>\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterPresent' || filter.inclusionCriteria == 'ParameterNotPresent') {\n <select class=\"mr-1 py-2\"\n [(ngModel)]=\"filter._inclusionParam\" (change)=\"filter.inclusionData = filter._inclusionParam\">\n @for (param of parameterValues; track param) {\n <option [ngValue]=\"param.name\">\n {{ param.title }}\n </option>\n }\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterValue') {\n <select class=\"mr-1 py-2\"\n [(ngModel)]=\"filter._inclusionParam\">\n @for (param of parameterValues; track param) {\n <option [ngValue]=\"param.name\">\n {{ param.title }}\n </option>\n }\n </select>\n }\n @if (filter.inclusionCriteria == 'ParameterValue') {\n <input\n placeholder=\"Enter value\"\n class=\"py-2.5 \" [(ngModel)]=\"filter._inclusionParamValue\"\n (change)=\"filter.inclusionData = filter._inclusionParam + '=' + filter._inclusionParamValue\"/>\n}\n\n}\n", styles: [":host{display:flex;align-items:flex-start}\n"] }]
1179
1179
  }], ctorParameters: () => [], propDecorators: { filter: [{
1180
1180
  type: Input
1181
1181
  }], parameterValues: [{
@@ -1345,11 +1345,11 @@ class DatasetFilterComponent {
1345
1345
  return DatasetFilterComponent.filterTypes;
1346
1346
  }
1347
1347
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatasetFilterComponent, deps: [{ token: i1$1.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
1348
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DatasetFilterComponent, isStandalone: false, selector: "ki-dataset-filter", inputs: { filter: "filter", filterIndex: "filterIndex", filterJunction: "filterJunction", filterFields: "filterFields", joinFilterFields: "joinFilterFields", joinFieldsName: "joinFieldsName", openSide: "openSide", parameterValues: "parameterValues" }, outputs: { filtersRemoved: "filtersRemoved" }, ngImport: i0, template: "@if (!joinFilterFields) {\n <div class=\"w-full mr-4\">\n <div>\n @if (!customLhs) {\n <mat-select [(value)]=\"filter.lhsExpression\" class=\"p-2 mr-4\" name=\"fieldName\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of filterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customLhs) {\n <input type=\"text\" [(ngModel)]=\"filter.lhsExpression\"\n name=\"lhsExpression\" placeholder=\"Custom expression\" class=\"p-2 mr-4 full font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customLhs\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customLhs && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n <mat-select [(ngModel)]=\"filter.filterType\" class=\"p-2 mr-4\" name=\"filterType\"\n (ngModelChange)=\"updateFilterType(filter)\">\n <mat-option value=\"\">-- Select Condition --</mat-option>\n @for (filterType of getFilterTypes(); track filterType) {\n <mat-option [value]=\"filterType.value\">\n {{ filterType.label }}\n </mat-option>\n }\n </mat-select>\n <div class=\"w-full flex items-start\">\n <div class=\"relative w-full\">\n @if (filter.filterType === 'in' || filter.filterType === 'notin') {\n <mat-chip-grid\n class=\"bg-white pl-2 py-0.5 rounded border border-gray-200\" #chipGrid aria-label=\"Enter values\">\n @for (inValue of filter.rhsExpression; track inValue) {\n <mat-chip-row\n class=\"bg-white my-0\"\n (removed)=\"removeInValue(inValue)\"\n [editable]=\"true\"\n (edited)=\"editInValue(inValue, $event)\"\n [aria-description]=\"'press enter to edit ' + inValue\">\n {{inValue}}\n <button matChipRemove [attr.aria-label]=\"'remove ' + inValue\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n <input placeholder=\"Value\" class=\"ml-0 border-0 pl-2 py-1.5 self-center\"\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addInValue($event)\"/>\n </mat-chip-grid>\n }\n @if (!filter._expType && filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[0]\" name=\"filterValue\"\n placeholder=\"Value\"\n class=\"pl-2 py-2 pr-8 mr-4 full\">\n }\n @if (filter._expType === 'date-picker') {\n <input type=\"date\" [(ngModel)]=\"filter.rhsExpression[0]\"\n name=\"filterValue\" placeholder=\"Value\"\n class=\"pl-2 py-2 pr-10 mr-4 full\">\n }\n @if (filter._expType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-32 mr-2 p-2\" min=\"0\" [value]=\"filter._periodValue || 1\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, filter)\">\n <select class=\"param-period-picker w-32 mr-2 p-2\" [value]=\"filter._period || 'DAYS'\"\n #period (change)=\"updatePeriodValue(periodValue.value, period.value, filter)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div class=\"font-medium\">Ago</div>\n </div>\n }\n <button class=\"absolute right-0 -top-0.5\" mat-icon-button [matMenuTriggerFor]=\"menu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, null, [])\">\n <mat-icon>title</mat-icon>\n <span>Text</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item [matMenuTriggerFor]=\"columnMenu\">\n <mat-icon>table_chart</mat-icon>\n <span>Columns</span>\n </button>\n }\n @if (parameterValues && parameterValues.length) {\n <button mat-menu-item\n [matMenuTriggerFor]=\"parameterValuesMenu\">\n <mat-icon>text_fields</mat-icon>\n <span>Parameters</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'date-picker', [])\">\n <mat-icon>calendar_month</mat-icon>\n <span>Date Picker</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'period')\">\n <mat-icon>restore</mat-icon>\n <span>Time Period</span>\n </button>\n }\n </mat-menu>\n <mat-menu #columnMenu=\"matMenu\">\n @for (column of filterFields; track column) {\n <button mat-menu-item\n (click)=\"updateExpressionType(filter, null, '[[' + column.name + ']]')\">\n <span>{{column.title}}</span>\n </button>\n }\n </mat-menu>\n <mat-menu #parameterValuesMenu=\"matMenu\">\n @for (param of parameterValues; track param) {\n <button mat-menu-item\n (click)=\"updateExpressionType(filter, null, '{{' + param.name + '}}')\">\n <span>{{param.title}}</span>\n </button>\n }\n </mat-menu>\n </div>\n @if ((filter.filterType === 'similarto' || filter.filterType === 'between' || filter.filterType === 'like' || filter.filterType === 'notlike')) {\n <div\n class=\"ml-2 relative w-full\">\n @if (filter.filterType === 'similarto') {\n <select class=\"w-full\" name=\"similarityDistance\" [(ngModel)]=\"filter.rhsExpression[1]\">\n @for (val of _.range(10); track val) {\n <option [value]=\"val + 1\">\n {{ val + 1 }}\n </option>\n }\n </select>\n <div class=\"text-xs text-gray-400\">Select Maximum Number of Changes</div>\n }\n @if (filter.filterType === 'like' || filter.filterType === 'notlike') {\n <select class=\"w-full\" name=\"regexp\" [(ngModel)]=\"filter.rhsExpression[1]\">\n <option [value]=\"'likewildcard'\">\n Wildcard pattern\n </option>\n <option [value]=\"'likeregexp'\">\n Regular Expression\n </option>\n </select>\n <div class=\"text-xs text-gray-400\">Select Match Type</div>\n }\n @if (filter.filterType === 'between') {\n <div class=\"relative flex items-center\">\n <div class=\"mr-2 font-medium\">and</div>\n @if (!filter._otherExpType) {\n <input type=\"text\" type=\"text\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"otherbetween\" placeholder=\"To value\"\n class=\"pl-2 py-2 pr-8 full\">\n }\n @if (filter._otherExpType === 'date-picker') {\n <input type=\"date\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"filterValue\" placeholder=\"Value\"\n class=\"pl-2 py-2 pr-10 mr-4 full\">\n }\n @if (filter._otherExpType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-32 mr-2 p-2\" min=\"0\" [value]=\"filter._otherPeriodValue || 1\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, filter,1)\">\n <select class=\"param-period-picker w-32 mr-2 p-2\" [value]=\"filter._otherPeriod || 'DAYS'\"\n #period (change)=\"updatePeriodValue(periodValue.value, period.value, filter,1)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div class=\"font-medium\">Ago</div>\n </div>\n }\n <button class=\"absolute right-0 -top-0.5\" mat-icon-button [matMenuTriggerFor]=\"otherMenu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #otherMenu=\"matMenu\">\n <button mat-menu-item (click)=\"updateExpressionType(filter, null, [], 1)\">\n <mat-icon>title</mat-icon>\n <span>Text</span>\n </button>\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'date-picker', [], 1)\">\n <mat-icon>calendar_month</mat-icon>\n <span>Date Picker</span>\n </button>\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'period', null, 1)\">\n <mat-icon>restore</mat-icon>\n <span>Time Period</span>\n </button>\n </mat-menu>\n </div>\n }\n </div>\n }\n </div>\n}\n\n\n@if (joinFilterFields) {\n <div class=\"w-full mr-4\">\n <div>\n @if (!customLhs) {\n <mat-select [(value)]=\"filter.lhsExpression\" class=\"mr-4 p-2\" name=\"fieldName\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of filterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customLhs) {\n <input type=\"text\" [(ngModel)]=\"filter.lhsExpression\"\n name=\"lhsExpression\" placeholder=\"Custom expression\" class=\"p-2 mr-4 full font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customLhs\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customLhs && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n <mat-select [(ngModel)]=\"filter.filterType\" class=\"mr-4 p-2\" name=\"filterType\"\n (ngModelChange)=\"updateFilterType(filter)\">\n <mat-option value=\"\">-- Select Condition --</mat-option>\n @for (filterType of getFilterTypes(); track filterType) {\n <mat-option [value]=\"filterType.value\">\n {{ filterType.label }}\n </mat-option>\n }\n </mat-select>\n <div class=\"w-full\">\n <div>\n @if (!customValue) {\n <mat-select [(value)]=\"filter.rhsExpression[0]\" class=\"mr-4 p-2\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of joinFilterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customValue) {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[0]\"\n name=\"filterValue\" placeholder=\"Custom value\" class=\"mr-4 full p-2 font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customValue\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customValue && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n @if (filter.filterType === 'like' || filter.filterType === 'notlike') {\n <div class=\"pl-2 pr-8 mr-4 full\">\n <select name=\"regexp\" [(ngModel)]=\"filter.rhsExpression[1]\">\n <option [value]=\"'likewildcard'\">\n Wildcard pattern\n </option>\n <option [value]=\"'likeregexp'\">\n Regular Expression\n </option>\n </select>\n <div class=\"text-xs text-gray-400\">Select Match Type</div>\n </div>\n }\n @if (filter.filterType === 'similarto') {\n <input type=\"number\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"similarityDistance\" placeholder=\"Maximum Distance\"\n class=\"pl-2 py-2 pr-8 mr-4 full\">\n }\n @if (filter.filterType === 'between') {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[1]\" name=\"otherValue\"\n placeholder=\"Other value\"\n class=\"pl-2 py-2 pr-8 mr-4 full\">\n }\n}\n\n@if (!joinFilterFields) {\n <div class=\"flex items-start\">\n <ki-dataset-filter-inclusion [filter]=\"filter\" [parameterValues]=\"parameterValues\"></ki-dataset-filter-inclusion>\n </div>\n}\n\n\n<div>\n <button mat-icon-button color=\"warn\" title=\"Remove filter\" (click)=\"removeFilter()\">\n <mat-icon>remove_circle_outline</mat-icon>\n </button>\n</div>\n\n", styles: [":host{padding:.5rem 0;display:flex;align-items:flex-start;position:relative}.filter{display:flex;flex-direction:column;margin:0;position:relative;background-color:transparent}.group-filters{margin-left:2rem;padding-left:2rem;position:relative}input{padding:.75rem;border-radius:4px;border-color:#dadada;outline:none;border-width:1px;border-style:solid}select{padding:.55rem!important;border-radius:4px;border-color:#dadada;outline:none;border-width:1px;border-style:solid}.custom-checkbox{margin:0;display:flex;align-items:center;min-width:120px}.custom-checkbox mat-checkbox{margin-right:.5rem}\n"], dependencies: [{ kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i7$3.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i7$3.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i7$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i7$3.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i7$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: DatasetFilterInclusionComponent, selector: "ki-dataset-filter-inclusion", inputs: ["filter", "parameterValues", "dependsString"] }] }); }
1348
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DatasetFilterComponent, isStandalone: false, selector: "ki-dataset-filter", inputs: { filter: "filter", filterIndex: "filterIndex", filterJunction: "filterJunction", filterFields: "filterFields", joinFilterFields: "joinFilterFields", joinFieldsName: "joinFieldsName", openSide: "openSide", parameterValues: "parameterValues" }, outputs: { filtersRemoved: "filtersRemoved" }, ngImport: i0, template: "@if (!joinFilterFields) {\n <div class=\"w-full mr-4\">\n <div>\n @if (!customLhs) {\n <mat-select [(value)]=\"filter.lhsExpression\" class=\"p-2 mr-4\" name=\"fieldName\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of filterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customLhs) {\n <input type=\"text\" [(ngModel)]=\"filter.lhsExpression\"\n name=\"lhsExpression\" placeholder=\"Custom expression\" class=\"py-2.5 p-2 mr-4 full font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customLhs\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customLhs && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n <mat-select [(ngModel)]=\"filter.filterType\" class=\"p-2 mr-4\" name=\"filterType\"\n (ngModelChange)=\"updateFilterType(filter)\">\n <mat-option value=\"\">-- Select Condition --</mat-option>\n @for (filterType of getFilterTypes(); track filterType) {\n <mat-option [value]=\"filterType.value\">\n {{ filterType.label }}\n </mat-option>\n }\n </mat-select>\n <div class=\"w-full flex items-start\">\n <div class=\"relative w-full\">\n @if (filter.filterType === 'in' || filter.filterType === 'notin') {\n <mat-chip-grid\n class=\"bg-white pl-2 py-0.5 rounded border border-gray-200\" #chipGrid aria-label=\"Enter values\">\n @for (inValue of filter.rhsExpression; track inValue) {\n <mat-chip-row\n class=\"bg-white my-0\"\n (removed)=\"removeInValue(inValue)\"\n [editable]=\"true\"\n (edited)=\"editInValue(inValue, $event)\"\n [aria-description]=\"'press enter to edit ' + inValue\">\n {{inValue}}\n <button matChipRemove [attr.aria-label]=\"'remove ' + inValue\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n <input placeholder=\"Value\" class=\"ml-0 border-0 pl-2 py-1.5 self-center\"\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addInValue($event)\"/>\n </mat-chip-grid>\n }\n @if (!filter._expType && filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[0]\" name=\"filterValue\"\n placeholder=\"Value\"\n class=\"pl-2 py-2.5 pr-8 mr-4 full\">\n }\n @if (filter._expType === 'date-picker') {\n <input type=\"date\" [(ngModel)]=\"filter.rhsExpression[0]\"\n name=\"filterValue\" placeholder=\"Value\"\n class=\"pl-2 py-2.5 pr-10 mr-4 full\">\n }\n @if (filter._expType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-32 mr-2 p-2 py-2.5 \" min=\"0\" [value]=\"filter._periodValue || 1\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, filter)\">\n <select class=\"param-period-picker w-32 mr-2 p-2\" [value]=\"filter._period || 'DAYS'\"\n #period (change)=\"updatePeriodValue(periodValue.value, period.value, filter)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div class=\"font-medium\">Ago</div>\n </div>\n }\n <button class=\"absolute right-0 -top-0.5\" mat-icon-button [matMenuTriggerFor]=\"menu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, null, [])\">\n <mat-icon>title</mat-icon>\n <span>Text</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item [matMenuTriggerFor]=\"columnMenu\">\n <mat-icon>table_chart</mat-icon>\n <span>Columns</span>\n </button>\n }\n @if (parameterValues && parameterValues.length) {\n <button mat-menu-item\n [matMenuTriggerFor]=\"parameterValuesMenu\">\n <mat-icon>text_fields</mat-icon>\n <span>Parameters</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'date-picker', [])\">\n <mat-icon>calendar_month</mat-icon>\n <span>Date Picker</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'period')\">\n <mat-icon>restore</mat-icon>\n <span>Time Period</span>\n </button>\n }\n </mat-menu>\n <mat-menu #columnMenu=\"matMenu\">\n @for (column of filterFields; track column) {\n <button mat-menu-item\n (click)=\"updateExpressionType(filter, null, '[[' + column.name + ']]')\">\n <span>{{column.title}}</span>\n </button>\n }\n </mat-menu>\n <mat-menu #parameterValuesMenu=\"matMenu\">\n @for (param of parameterValues; track param) {\n <button mat-menu-item\n (click)=\"updateExpressionType(filter, null, '{{' + param.name + '}}')\">\n <span>{{param.title}}</span>\n </button>\n }\n </mat-menu>\n </div>\n @if ((filter.filterType === 'similarto' || filter.filterType === 'between' || filter.filterType === 'like' || filter.filterType === 'notlike')) {\n <div\n class=\"ml-2 relative w-full\">\n @if (filter.filterType === 'similarto') {\n <select class=\"w-full\" name=\"similarityDistance\" [(ngModel)]=\"filter.rhsExpression[1]\">\n @for (val of _.range(10); track val) {\n <option [value]=\"val + 1\">\n {{ val + 1 }}\n </option>\n }\n </select>\n <div class=\"text-xs text-gray-400\">Select Maximum Number of Changes</div>\n }\n @if (filter.filterType === 'like' || filter.filterType === 'notlike') {\n <select class=\"w-full\" name=\"regexp\" [(ngModel)]=\"filter.rhsExpression[1]\">\n <option [value]=\"'likewildcard'\">\n Wildcard pattern\n </option>\n <option [value]=\"'likeregexp'\">\n Regular Expression\n </option>\n </select>\n <div class=\"text-xs text-gray-400\">Select Match Type</div>\n }\n @if (filter.filterType === 'between') {\n <div class=\"relative flex items-center\">\n <div class=\"mr-2 font-medium\">and</div>\n @if (!filter._otherExpType) {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"otherbetween\" placeholder=\"To value\"\n class=\"pl-2 py-2.5 pr-8 full\">\n }\n @if (filter._otherExpType === 'date-picker') {\n <input type=\"date\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"filterValue\" placeholder=\"Value\"\n class=\"pl-2 py-2.5 pr-10 mr-4 full\">\n }\n @if (filter._otherExpType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-32 mr-2 p-2 py-2.5 \" min=\"0\" [value]=\"filter._otherPeriodValue || 1\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, filter,1)\">\n <select class=\"param-period-picker w-32 mr-2 p-2\" [value]=\"filter._otherPeriod || 'DAYS'\"\n #period (change)=\"updatePeriodValue(periodValue.value, period.value, filter,1)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div class=\"font-medium\">Ago</div>\n </div>\n }\n <button class=\"absolute right-0 -top-0.5\" mat-icon-button [matMenuTriggerFor]=\"otherMenu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #otherMenu=\"matMenu\">\n <button mat-menu-item (click)=\"updateExpressionType(filter, null, [], 1)\">\n <mat-icon>title</mat-icon>\n <span>Text</span>\n </button>\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'date-picker', [], 1)\">\n <mat-icon>calendar_month</mat-icon>\n <span>Date Picker</span>\n </button>\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'period', null, 1)\">\n <mat-icon>restore</mat-icon>\n <span>Time Period</span>\n </button>\n </mat-menu>\n </div>\n }\n </div>\n }\n </div>\n}\n\n\n@if (joinFilterFields) {\n <div class=\"w-full mr-4\">\n <div>\n @if (!customLhs) {\n <mat-select [(value)]=\"filter.lhsExpression\" class=\"mr-4 p-2\" name=\"fieldName\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of filterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customLhs) {\n <input type=\"text\" [(ngModel)]=\"filter.lhsExpression\"\n name=\"lhsExpression\" placeholder=\"Custom expression\" class=\"p-2 py-2.5 mr-4 full font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customLhs\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customLhs && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n <mat-select [(ngModel)]=\"filter.filterType\" class=\"mr-4 p-2\" name=\"filterType\"\n (ngModelChange)=\"updateFilterType(filter)\">\n <mat-option value=\"\">-- Select Condition --</mat-option>\n @for (filterType of getFilterTypes(); track filterType) {\n <mat-option [value]=\"filterType.value\">\n {{ filterType.label }}\n </mat-option>\n }\n </mat-select>\n <div class=\"w-full\">\n <div>\n @if (!customValue) {\n <mat-select [(value)]=\"filter.rhsExpression[0]\" class=\"mr-4 p-2\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of joinFilterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customValue) {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[0]\"\n name=\"filterValue\" placeholder=\"Custom value\" class=\"mr-4 full p-2 py-2.5 font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customValue\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customValue && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n @if (filter.filterType === 'like' || filter.filterType === 'notlike') {\n <div class=\"pl-2 pr-8 mr-4 full\">\n <select name=\"regexp\" [(ngModel)]=\"filter.rhsExpression[1]\">\n <option [value]=\"'likewildcard'\">\n Wildcard pattern\n </option>\n <option [value]=\"'likeregexp'\">\n Regular Expression\n </option>\n </select>\n <div class=\"text-xs text-gray-400\">Select Match Type</div>\n </div>\n }\n @if (filter.filterType === 'similarto') {\n <input type=\"number\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"similarityDistance\" placeholder=\"Maximum Distance\"\n class=\"pl-2 py-2.5 pr-8 mr-4 full\">\n }\n @if (filter.filterType === 'between') {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[1]\" name=\"otherValue\"\n placeholder=\"Other value\"\n class=\"pl-2 py-2.5 pr-8 mr-4 full\">\n }\n}\n\n@if (!joinFilterFields) {\n <div class=\"flex items-start\">\n <ki-dataset-filter-inclusion [filter]=\"filter\" [parameterValues]=\"parameterValues\"></ki-dataset-filter-inclusion>\n </div>\n}\n\n\n<div>\n <button mat-icon-button color=\"warn\" title=\"Remove filter\" (click)=\"removeFilter()\">\n <mat-icon>remove_circle_outline</mat-icon>\n </button>\n</div>\n\n", styles: [":host{padding:.5rem 0;display:flex;align-items:flex-start;position:relative}.filter{display:flex;flex-direction:column;margin:0;position:relative;background-color:transparent}.group-filters{margin-left:2rem;padding-left:2rem;position:relative}input{padding:.75rem;border-radius:4px;border-color:#dadada;outline:none;border-width:1px;border-style:solid}select{padding:.55rem!important;border-radius:4px;border-color:#dadada;outline:none;border-width:1px;border-style:solid}.custom-checkbox{margin:0;display:flex;align-items:center;min-width:120px}.custom-checkbox mat-checkbox{margin-right:.5rem}\n"], dependencies: [{ kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i7$3.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i7$3.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i7$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i7$3.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i7$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: DatasetFilterInclusionComponent, selector: "ki-dataset-filter-inclusion", inputs: ["filter", "parameterValues", "dependsString"] }] }); }
1349
1349
  }
1350
1350
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatasetFilterComponent, decorators: [{
1351
1351
  type: Component,
1352
- args: [{ selector: 'ki-dataset-filter', standalone: false, template: "@if (!joinFilterFields) {\n <div class=\"w-full mr-4\">\n <div>\n @if (!customLhs) {\n <mat-select [(value)]=\"filter.lhsExpression\" class=\"p-2 mr-4\" name=\"fieldName\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of filterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customLhs) {\n <input type=\"text\" [(ngModel)]=\"filter.lhsExpression\"\n name=\"lhsExpression\" placeholder=\"Custom expression\" class=\"p-2 mr-4 full font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customLhs\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customLhs && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n <mat-select [(ngModel)]=\"filter.filterType\" class=\"p-2 mr-4\" name=\"filterType\"\n (ngModelChange)=\"updateFilterType(filter)\">\n <mat-option value=\"\">-- Select Condition --</mat-option>\n @for (filterType of getFilterTypes(); track filterType) {\n <mat-option [value]=\"filterType.value\">\n {{ filterType.label }}\n </mat-option>\n }\n </mat-select>\n <div class=\"w-full flex items-start\">\n <div class=\"relative w-full\">\n @if (filter.filterType === 'in' || filter.filterType === 'notin') {\n <mat-chip-grid\n class=\"bg-white pl-2 py-0.5 rounded border border-gray-200\" #chipGrid aria-label=\"Enter values\">\n @for (inValue of filter.rhsExpression; track inValue) {\n <mat-chip-row\n class=\"bg-white my-0\"\n (removed)=\"removeInValue(inValue)\"\n [editable]=\"true\"\n (edited)=\"editInValue(inValue, $event)\"\n [aria-description]=\"'press enter to edit ' + inValue\">\n {{inValue}}\n <button matChipRemove [attr.aria-label]=\"'remove ' + inValue\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n <input placeholder=\"Value\" class=\"ml-0 border-0 pl-2 py-1.5 self-center\"\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addInValue($event)\"/>\n </mat-chip-grid>\n }\n @if (!filter._expType && filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[0]\" name=\"filterValue\"\n placeholder=\"Value\"\n class=\"pl-2 py-2 pr-8 mr-4 full\">\n }\n @if (filter._expType === 'date-picker') {\n <input type=\"date\" [(ngModel)]=\"filter.rhsExpression[0]\"\n name=\"filterValue\" placeholder=\"Value\"\n class=\"pl-2 py-2 pr-10 mr-4 full\">\n }\n @if (filter._expType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-32 mr-2 p-2\" min=\"0\" [value]=\"filter._periodValue || 1\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, filter)\">\n <select class=\"param-period-picker w-32 mr-2 p-2\" [value]=\"filter._period || 'DAYS'\"\n #period (change)=\"updatePeriodValue(periodValue.value, period.value, filter)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div class=\"font-medium\">Ago</div>\n </div>\n }\n <button class=\"absolute right-0 -top-0.5\" mat-icon-button [matMenuTriggerFor]=\"menu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, null, [])\">\n <mat-icon>title</mat-icon>\n <span>Text</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item [matMenuTriggerFor]=\"columnMenu\">\n <mat-icon>table_chart</mat-icon>\n <span>Columns</span>\n </button>\n }\n @if (parameterValues && parameterValues.length) {\n <button mat-menu-item\n [matMenuTriggerFor]=\"parameterValuesMenu\">\n <mat-icon>text_fields</mat-icon>\n <span>Parameters</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'date-picker', [])\">\n <mat-icon>calendar_month</mat-icon>\n <span>Date Picker</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'period')\">\n <mat-icon>restore</mat-icon>\n <span>Time Period</span>\n </button>\n }\n </mat-menu>\n <mat-menu #columnMenu=\"matMenu\">\n @for (column of filterFields; track column) {\n <button mat-menu-item\n (click)=\"updateExpressionType(filter, null, '[[' + column.name + ']]')\">\n <span>{{column.title}}</span>\n </button>\n }\n </mat-menu>\n <mat-menu #parameterValuesMenu=\"matMenu\">\n @for (param of parameterValues; track param) {\n <button mat-menu-item\n (click)=\"updateExpressionType(filter, null, '{{' + param.name + '}}')\">\n <span>{{param.title}}</span>\n </button>\n }\n </mat-menu>\n </div>\n @if ((filter.filterType === 'similarto' || filter.filterType === 'between' || filter.filterType === 'like' || filter.filterType === 'notlike')) {\n <div\n class=\"ml-2 relative w-full\">\n @if (filter.filterType === 'similarto') {\n <select class=\"w-full\" name=\"similarityDistance\" [(ngModel)]=\"filter.rhsExpression[1]\">\n @for (val of _.range(10); track val) {\n <option [value]=\"val + 1\">\n {{ val + 1 }}\n </option>\n }\n </select>\n <div class=\"text-xs text-gray-400\">Select Maximum Number of Changes</div>\n }\n @if (filter.filterType === 'like' || filter.filterType === 'notlike') {\n <select class=\"w-full\" name=\"regexp\" [(ngModel)]=\"filter.rhsExpression[1]\">\n <option [value]=\"'likewildcard'\">\n Wildcard pattern\n </option>\n <option [value]=\"'likeregexp'\">\n Regular Expression\n </option>\n </select>\n <div class=\"text-xs text-gray-400\">Select Match Type</div>\n }\n @if (filter.filterType === 'between') {\n <div class=\"relative flex items-center\">\n <div class=\"mr-2 font-medium\">and</div>\n @if (!filter._otherExpType) {\n <input type=\"text\" type=\"text\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"otherbetween\" placeholder=\"To value\"\n class=\"pl-2 py-2 pr-8 full\">\n }\n @if (filter._otherExpType === 'date-picker') {\n <input type=\"date\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"filterValue\" placeholder=\"Value\"\n class=\"pl-2 py-2 pr-10 mr-4 full\">\n }\n @if (filter._otherExpType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-32 mr-2 p-2\" min=\"0\" [value]=\"filter._otherPeriodValue || 1\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, filter,1)\">\n <select class=\"param-period-picker w-32 mr-2 p-2\" [value]=\"filter._otherPeriod || 'DAYS'\"\n #period (change)=\"updatePeriodValue(periodValue.value, period.value, filter,1)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div class=\"font-medium\">Ago</div>\n </div>\n }\n <button class=\"absolute right-0 -top-0.5\" mat-icon-button [matMenuTriggerFor]=\"otherMenu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #otherMenu=\"matMenu\">\n <button mat-menu-item (click)=\"updateExpressionType(filter, null, [], 1)\">\n <mat-icon>title</mat-icon>\n <span>Text</span>\n </button>\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'date-picker', [], 1)\">\n <mat-icon>calendar_month</mat-icon>\n <span>Date Picker</span>\n </button>\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'period', null, 1)\">\n <mat-icon>restore</mat-icon>\n <span>Time Period</span>\n </button>\n </mat-menu>\n </div>\n }\n </div>\n }\n </div>\n}\n\n\n@if (joinFilterFields) {\n <div class=\"w-full mr-4\">\n <div>\n @if (!customLhs) {\n <mat-select [(value)]=\"filter.lhsExpression\" class=\"mr-4 p-2\" name=\"fieldName\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of filterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customLhs) {\n <input type=\"text\" [(ngModel)]=\"filter.lhsExpression\"\n name=\"lhsExpression\" placeholder=\"Custom expression\" class=\"p-2 mr-4 full font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customLhs\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customLhs && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n <mat-select [(ngModel)]=\"filter.filterType\" class=\"mr-4 p-2\" name=\"filterType\"\n (ngModelChange)=\"updateFilterType(filter)\">\n <mat-option value=\"\">-- Select Condition --</mat-option>\n @for (filterType of getFilterTypes(); track filterType) {\n <mat-option [value]=\"filterType.value\">\n {{ filterType.label }}\n </mat-option>\n }\n </mat-select>\n <div class=\"w-full\">\n <div>\n @if (!customValue) {\n <mat-select [(value)]=\"filter.rhsExpression[0]\" class=\"mr-4 p-2\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of joinFilterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customValue) {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[0]\"\n name=\"filterValue\" placeholder=\"Custom value\" class=\"mr-4 full p-2 font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customValue\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customValue && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n @if (filter.filterType === 'like' || filter.filterType === 'notlike') {\n <div class=\"pl-2 pr-8 mr-4 full\">\n <select name=\"regexp\" [(ngModel)]=\"filter.rhsExpression[1]\">\n <option [value]=\"'likewildcard'\">\n Wildcard pattern\n </option>\n <option [value]=\"'likeregexp'\">\n Regular Expression\n </option>\n </select>\n <div class=\"text-xs text-gray-400\">Select Match Type</div>\n </div>\n }\n @if (filter.filterType === 'similarto') {\n <input type=\"number\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"similarityDistance\" placeholder=\"Maximum Distance\"\n class=\"pl-2 py-2 pr-8 mr-4 full\">\n }\n @if (filter.filterType === 'between') {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[1]\" name=\"otherValue\"\n placeholder=\"Other value\"\n class=\"pl-2 py-2 pr-8 mr-4 full\">\n }\n}\n\n@if (!joinFilterFields) {\n <div class=\"flex items-start\">\n <ki-dataset-filter-inclusion [filter]=\"filter\" [parameterValues]=\"parameterValues\"></ki-dataset-filter-inclusion>\n </div>\n}\n\n\n<div>\n <button mat-icon-button color=\"warn\" title=\"Remove filter\" (click)=\"removeFilter()\">\n <mat-icon>remove_circle_outline</mat-icon>\n </button>\n</div>\n\n", styles: [":host{padding:.5rem 0;display:flex;align-items:flex-start;position:relative}.filter{display:flex;flex-direction:column;margin:0;position:relative;background-color:transparent}.group-filters{margin-left:2rem;padding-left:2rem;position:relative}input{padding:.75rem;border-radius:4px;border-color:#dadada;outline:none;border-width:1px;border-style:solid}select{padding:.55rem!important;border-radius:4px;border-color:#dadada;outline:none;border-width:1px;border-style:solid}.custom-checkbox{margin:0;display:flex;align-items:center;min-width:120px}.custom-checkbox mat-checkbox{margin-right:.5rem}\n"] }]
1352
+ args: [{ selector: 'ki-dataset-filter', standalone: false, template: "@if (!joinFilterFields) {\n <div class=\"w-full mr-4\">\n <div>\n @if (!customLhs) {\n <mat-select [(value)]=\"filter.lhsExpression\" class=\"p-2 mr-4\" name=\"fieldName\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of filterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customLhs) {\n <input type=\"text\" [(ngModel)]=\"filter.lhsExpression\"\n name=\"lhsExpression\" placeholder=\"Custom expression\" class=\"py-2.5 p-2 mr-4 full font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customLhs\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customLhs && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n <mat-select [(ngModel)]=\"filter.filterType\" class=\"p-2 mr-4\" name=\"filterType\"\n (ngModelChange)=\"updateFilterType(filter)\">\n <mat-option value=\"\">-- Select Condition --</mat-option>\n @for (filterType of getFilterTypes(); track filterType) {\n <mat-option [value]=\"filterType.value\">\n {{ filterType.label }}\n </mat-option>\n }\n </mat-select>\n <div class=\"w-full flex items-start\">\n <div class=\"relative w-full\">\n @if (filter.filterType === 'in' || filter.filterType === 'notin') {\n <mat-chip-grid\n class=\"bg-white pl-2 py-0.5 rounded border border-gray-200\" #chipGrid aria-label=\"Enter values\">\n @for (inValue of filter.rhsExpression; track inValue) {\n <mat-chip-row\n class=\"bg-white my-0\"\n (removed)=\"removeInValue(inValue)\"\n [editable]=\"true\"\n (edited)=\"editInValue(inValue, $event)\"\n [aria-description]=\"'press enter to edit ' + inValue\">\n {{inValue}}\n <button matChipRemove [attr.aria-label]=\"'remove ' + inValue\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n <input placeholder=\"Value\" class=\"ml-0 border-0 pl-2 py-1.5 self-center\"\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addInValue($event)\"/>\n </mat-chip-grid>\n }\n @if (!filter._expType && filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[0]\" name=\"filterValue\"\n placeholder=\"Value\"\n class=\"pl-2 py-2.5 pr-8 mr-4 full\">\n }\n @if (filter._expType === 'date-picker') {\n <input type=\"date\" [(ngModel)]=\"filter.rhsExpression[0]\"\n name=\"filterValue\" placeholder=\"Value\"\n class=\"pl-2 py-2.5 pr-10 mr-4 full\">\n }\n @if (filter._expType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-32 mr-2 p-2 py-2.5 \" min=\"0\" [value]=\"filter._periodValue || 1\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, filter)\">\n <select class=\"param-period-picker w-32 mr-2 p-2\" [value]=\"filter._period || 'DAYS'\"\n #period (change)=\"updatePeriodValue(periodValue.value, period.value, filter)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div class=\"font-medium\">Ago</div>\n </div>\n }\n <button class=\"absolute right-0 -top-0.5\" mat-icon-button [matMenuTriggerFor]=\"menu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, null, [])\">\n <mat-icon>title</mat-icon>\n <span>Text</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item [matMenuTriggerFor]=\"columnMenu\">\n <mat-icon>table_chart</mat-icon>\n <span>Columns</span>\n </button>\n }\n @if (parameterValues && parameterValues.length) {\n <button mat-menu-item\n [matMenuTriggerFor]=\"parameterValuesMenu\">\n <mat-icon>text_fields</mat-icon>\n <span>Parameters</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'date-picker', [])\">\n <mat-icon>calendar_month</mat-icon>\n <span>Date Picker</span>\n </button>\n }\n @if (filter.filterType !== 'in' && filter.filterType !== 'notin') {\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'period')\">\n <mat-icon>restore</mat-icon>\n <span>Time Period</span>\n </button>\n }\n </mat-menu>\n <mat-menu #columnMenu=\"matMenu\">\n @for (column of filterFields; track column) {\n <button mat-menu-item\n (click)=\"updateExpressionType(filter, null, '[[' + column.name + ']]')\">\n <span>{{column.title}}</span>\n </button>\n }\n </mat-menu>\n <mat-menu #parameterValuesMenu=\"matMenu\">\n @for (param of parameterValues; track param) {\n <button mat-menu-item\n (click)=\"updateExpressionType(filter, null, '{{' + param.name + '}}')\">\n <span>{{param.title}}</span>\n </button>\n }\n </mat-menu>\n </div>\n @if ((filter.filterType === 'similarto' || filter.filterType === 'between' || filter.filterType === 'like' || filter.filterType === 'notlike')) {\n <div\n class=\"ml-2 relative w-full\">\n @if (filter.filterType === 'similarto') {\n <select class=\"w-full\" name=\"similarityDistance\" [(ngModel)]=\"filter.rhsExpression[1]\">\n @for (val of _.range(10); track val) {\n <option [value]=\"val + 1\">\n {{ val + 1 }}\n </option>\n }\n </select>\n <div class=\"text-xs text-gray-400\">Select Maximum Number of Changes</div>\n }\n @if (filter.filterType === 'like' || filter.filterType === 'notlike') {\n <select class=\"w-full\" name=\"regexp\" [(ngModel)]=\"filter.rhsExpression[1]\">\n <option [value]=\"'likewildcard'\">\n Wildcard pattern\n </option>\n <option [value]=\"'likeregexp'\">\n Regular Expression\n </option>\n </select>\n <div class=\"text-xs text-gray-400\">Select Match Type</div>\n }\n @if (filter.filterType === 'between') {\n <div class=\"relative flex items-center\">\n <div class=\"mr-2 font-medium\">and</div>\n @if (!filter._otherExpType) {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"otherbetween\" placeholder=\"To value\"\n class=\"pl-2 py-2.5 pr-8 full\">\n }\n @if (filter._otherExpType === 'date-picker') {\n <input type=\"date\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"filterValue\" placeholder=\"Value\"\n class=\"pl-2 py-2.5 pr-10 mr-4 full\">\n }\n @if (filter._otherExpType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-32 mr-2 p-2 py-2.5 \" min=\"0\" [value]=\"filter._otherPeriodValue || 1\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, filter,1)\">\n <select class=\"param-period-picker w-32 mr-2 p-2\" [value]=\"filter._otherPeriod || 'DAYS'\"\n #period (change)=\"updatePeriodValue(periodValue.value, period.value, filter,1)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div class=\"font-medium\">Ago</div>\n </div>\n }\n <button class=\"absolute right-0 -top-0.5\" mat-icon-button [matMenuTriggerFor]=\"otherMenu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #otherMenu=\"matMenu\">\n <button mat-menu-item (click)=\"updateExpressionType(filter, null, [], 1)\">\n <mat-icon>title</mat-icon>\n <span>Text</span>\n </button>\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'date-picker', [], 1)\">\n <mat-icon>calendar_month</mat-icon>\n <span>Date Picker</span>\n </button>\n <button mat-menu-item (click)=\"updateExpressionType(filter, 'period', null, 1)\">\n <mat-icon>restore</mat-icon>\n <span>Time Period</span>\n </button>\n </mat-menu>\n </div>\n }\n </div>\n }\n </div>\n}\n\n\n@if (joinFilterFields) {\n <div class=\"w-full mr-4\">\n <div>\n @if (!customLhs) {\n <mat-select [(value)]=\"filter.lhsExpression\" class=\"mr-4 p-2\" name=\"fieldName\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of filterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customLhs) {\n <input type=\"text\" [(ngModel)]=\"filter.lhsExpression\"\n name=\"lhsExpression\" placeholder=\"Custom expression\" class=\"p-2 py-2.5 mr-4 full font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customLhs\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customLhs && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n <mat-select [(ngModel)]=\"filter.filterType\" class=\"mr-4 p-2\" name=\"filterType\"\n (ngModelChange)=\"updateFilterType(filter)\">\n <mat-option value=\"\">-- Select Condition --</mat-option>\n @for (filterType of getFilterTypes(); track filterType) {\n <mat-option [value]=\"filterType.value\">\n {{ filterType.label }}\n </mat-option>\n }\n </mat-select>\n <div class=\"w-full\">\n <div>\n @if (!customValue) {\n <mat-select [(value)]=\"filter.rhsExpression[0]\" class=\"mr-4 p-2\">\n <mat-option value=\"\">-- Select Column Name --</mat-option>\n @for (field of joinFilterFields; track field) {\n <mat-option [value]=\"'[['+field.name+']]'\">{{ field.title }}\n </mat-option>\n }\n </mat-select>\n }\n @if (customValue) {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[0]\"\n name=\"filterValue\" placeholder=\"Custom value\" class=\"mr-4 full p-2 py-2.5 font-mono\">\n }\n </div>\n <div class=\"mt-2 custom-checkbox flex items-center justify-between\">\n <div>\n <mat-checkbox [(ngModel)]=\"customValue\" (ngModelChange)=\"updateCustom($event)\"></mat-checkbox>\n Custom expression\n </div>\n @if (customValue && openSide) {\n <a (click)=\"viewColumns(filterFields)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view docs&nbsp;\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n }\n </div>\n </div>\n @if (filter.filterType === 'like' || filter.filterType === 'notlike') {\n <div class=\"pl-2 pr-8 mr-4 full\">\n <select name=\"regexp\" [(ngModel)]=\"filter.rhsExpression[1]\">\n <option [value]=\"'likewildcard'\">\n Wildcard pattern\n </option>\n <option [value]=\"'likeregexp'\">\n Regular Expression\n </option>\n </select>\n <div class=\"text-xs text-gray-400\">Select Match Type</div>\n </div>\n }\n @if (filter.filterType === 'similarto') {\n <input type=\"number\" [(ngModel)]=\"filter.rhsExpression[1]\"\n name=\"similarityDistance\" placeholder=\"Maximum Distance\"\n class=\"pl-2 py-2.5 pr-8 mr-4 full\">\n }\n @if (filter.filterType === 'between') {\n <input type=\"text\" [(ngModel)]=\"filter.rhsExpression[1]\" name=\"otherValue\"\n placeholder=\"Other value\"\n class=\"pl-2 py-2.5 pr-8 mr-4 full\">\n }\n}\n\n@if (!joinFilterFields) {\n <div class=\"flex items-start\">\n <ki-dataset-filter-inclusion [filter]=\"filter\" [parameterValues]=\"parameterValues\"></ki-dataset-filter-inclusion>\n </div>\n}\n\n\n<div>\n <button mat-icon-button color=\"warn\" title=\"Remove filter\" (click)=\"removeFilter()\">\n <mat-icon>remove_circle_outline</mat-icon>\n </button>\n</div>\n\n", styles: [":host{padding:.5rem 0;display:flex;align-items:flex-start;position:relative}.filter{display:flex;flex-direction:column;margin:0;position:relative;background-color:transparent}.group-filters{margin-left:2rem;padding-left:2rem;position:relative}input{padding:.75rem;border-radius:4px;border-color:#dadada;outline:none;border-width:1px;border-style:solid}select{padding:.55rem!important;border-radius:4px;border-color:#dadada;outline:none;border-width:1px;border-style:solid}.custom-checkbox{margin:0;display:flex;align-items:center;min-width:120px}.custom-checkbox mat-checkbox{margin-right:.5rem}\n"] }]
1353
1353
  }], ctorParameters: () => [{ type: i1$1.MatDialog }], propDecorators: { filter: [{
1354
1354
  type: Input
1355
1355
  }], filterIndex: [{
@@ -3571,11 +3571,11 @@ class DatasetEditorComponent {
3571
3571
  return clonedDatasetInstance;
3572
3572
  }
3573
3573
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatasetEditorComponent, deps: [{ token: i1$1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: i1$1.MatDialog }, { token: DatasetService }, { token: i3.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
3574
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DatasetEditorComponent, isStandalone: false, selector: "ki-dataset-editor", inputs: { datasetInstanceSummary: "datasetInstanceSummary", environment: "environment", admin: "admin", dashboardParameters: "dashboardParameters", dashboardLayoutSettings: "dashboardLayoutSettings", accountId: "accountId", newTitle: "newTitle", newDescription: "newDescription", datasetEditorReadonly: "datasetEditorReadonly", datasetEditorSimpleMode: "datasetEditorSimpleMode", datasetEditorNoTools: "datasetEditorNoTools" }, outputs: { dataLoaded: "dataLoaded", datasetInstanceSummaryChange: "datasetInstanceSummaryChange" }, ngImport: i0, template: "@if (longRunning) {\n <div class=\"long-running flex-col\">\n <div class=\"loading-box\">\n <mat-spinner [diameter]=\"150\"></mat-spinner>\n <div>Loading</div>\n </div>\n <p class=\"text-center\">Please wait while we process this query.</p>\n <p class=\"text-center\">The results will be shown here once it has finished running.</p>\n <div>\n <a class=\"text-primary hover:underline\" (click)=\"cancelEvaluate()\">Cancel query and return to editor.</a>\n </div>\n </div>\n}\n<div class=\"pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10 -z-10\" id=\"sidebarWrapper\">\n <div [class]=\"{'translate-x-0': sideOpen, 'translate-x-full': !sideOpen}\"\n (click)=\"$event.stopPropagation()\"\n class=\"pointer-events-auto w-screen max-w-md transform transition ease-in-out duration-500 sm:duration-700\"\n id=\"docSidebar\">\n <div class=\"flex h-full flex-col overflow-y-scroll bg-white py-6 shadow-xl\">\n <div class=\"px-4 sm:px-6\">\n <div class=\"flex items-start justify-between\">\n <div></div>\n\n <div class=\"ml-3 flex h-7 items-center\">\n <button type=\"button\" (click)=\"openSide.next(false)\"\n class=\"rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none\">\n <span class=\"sr-only\">Close panel</span>\n <!-- Heroicon name: outline/x -->\n <svg class=\"h-6 w-6\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n </button>\n </div>\n </div>\n </div>\n <div class=\"relative flex-1 px-4 sm:px-6\">\n <ki-whitelisted-sql-functions [fields]=\"filterFields\"></ki-whitelisted-sql-functions>\n </div>\n </div>\n </div>\n</div>\n\n@if (!datasetEditorNoTools) {\n <div class=\"border-b cell-header end\">\n <div class=\"leading-5 px-4 text-xs uppercase tracking-wider font-medium border-r-2 text-gray-600\">\n Operations\n </div>\n <div class=\"dataset-data-actions\">\n <button (click)=\"addFilter()\"\n title=\"Filter the set using column based restrictions\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">filter_alt</span>\n filter\n </button>\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"summariseData()\"\n title=\"Summarise this data to produce aggregated totals, sums and other derivations\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">pivot_table_chart</span>\n summarise\n </button>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"joinData()\"\n title=\"Join another data set to the current dataset\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">merge_type</span>\n join\n </button>\n }\n <div class=\"divider\"></div>\n <button (click)=\"createFormula()\"\n title=\"Create a formula column using an expression based on other columns\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">functions</span>\n formula\n </button>\n <button (click)=\"editColumnSettings()\"\n title=\"Switch on and off columns for display\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">table_chart</span>\n columns\n </button>\n @if (!datasetEditorSimpleMode) {\n <div class=\"divider\"></div>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"addParameter()\"\n title=\"Add a parameter to use in filters, expressions etc.\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">text_fields</span>\n parameters\n </button>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"addPagingMarker()\"\n title=\"Insert paging marker to limit results at this stage in the query flow\"\n class=\"w-24 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">skip_next</span>\n paging marker\n </button>\n }\n <div class=\"divider\"></div>\n <button (click)=\"evaluateDataset()\"\n title=\"Reload this query based upon changes you may have made\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">sync</span>\n reload\n </button>\n @if (!datasetEditorReadonly) {\n <button [disabled]=\"!datasetInstanceSummary || !datasetInstanceSummary.id\" (click)=\"shareQuery()\"\n title=\"Share this query with other account holders\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">share</span>\n share\n </button>\n <button (click)=\"saveAsQuery()\"\n title=\"Make a copy of this query\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">file_copy</span>\n copy query\n </button>\n @if (!dashboardLayoutSettings && datasetInstanceSummary.id) {\n <button (click)=\"save()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">save</span>\n save\n </button>\n }\n }\n </div>\n </div>\n}\n\n<div class=\"cell-header\">\n @if (showParameters || parameterValues.length) {\n <div class=\"transformation-listing parameter-listing\">\n <div class=\"list-title\">\n Parameters\n </div>\n <div class=\"flex items-center flex-wrap\">\n @for (parameter of parameterValues; track parameter; let i = $index) {\n <label class=\"pl-4\">\n {{ parameter.title }}\n @if ((parameter.value || '').toString().includes('}}')) {\n <div>\n <mat-chip class=\"bg-gray-50 ml-2\" title=\"Using parameter value from {{parameter.value}}\">\n <div class=\"flex items-center\">\n <span class=\"material-symbols-outlined text-xl mr-1 text-gray-500\">layers</span>\n @if (dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')]) {\n <span\n [innerHTML]=\"dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')].value\"></span>\n }\n @if (!dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')]) {\n <span\n class=\"font-medium text-orange-600\">\n Parameter Not Found !\n </span>\n }\n </div>\n <button matChipRemove (click)=\"parameter.value = ''\" title=\"\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip>\n </div>\n }\n @if (!(parameter.value || '').toString().includes('}}')) {\n <div class=\"parameter-input\">\n @if (!parameter.multiple) {\n @if (parameter.type === 'text') {\n <input class=\"pr-8\" type=\"text\" placeholder=\"Enter {{parameter.title}}\"\n [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n }\n @if (parameter.type === 'numeric') {\n <input class=\"pr-8\" type=\"number\" placeholder=\"Enter {{parameter.title}}\"\n [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n }\n @if (parameter.type === 'list') {\n <select class=\"pr-8 py-1.5 pl-1 self-center\" [(ngModel)]=\"parameter.value\"\n (change)=\"evaluateDataset(true)\" required autofocus>\n <option [value]=\"null\">-- Select Value --</option>\n @for (item of parameter.list; track item) {\n <option [value]=\"item.value\">{{ item.label }}\n </option>\n }\n </select>\n }\n @if (parameter.type === 'date' || parameter.type === 'datetime') {\n @if (!parameter._dateType) {\n <div class=\"flex items-center mr-8\">\n <button (click)=\"changeDateType($event, parameter, 'picker')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n Date Picker\n </button>\n <button (click)=\"changeDateType($event, parameter, 'period')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n Time Period\n </button>\n </div>\n }\n @if (parameter._dateType === 'picker') {\n <input [type]=\"parameter.type === 'date' ? 'date' : 'datetime-local'\"\n placeholder=\"Enter {{parameter.title}}\" [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n <a (click)=\"changeDateType($event, parameter, 'period')\"\n matTooltip=\"Time Period\"\n class=\"mr-10 text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n </a>\n }\n @if (parameter._dateType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-16 mr-2\" min=\"0\" [value]=\"parameter._periodValue\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n <select class=\"param-period-picker mr-2\" [value]=\"parameter._period || 'DAYS'\"\n #period\n (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div>Ago</div>\n </div>\n <a (click)=\"changeDateType($event, parameter, 'picker')\"\n matTooltip=\"Date Picker\"\n class=\"mr-10 text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n </a>\n }\n }\n @if (parameter.type === 'boolean') {\n <mat-slide-toggle class=\"pr-8\" color=\"primary\"\n [checked]=\"parameter.value\" (change)=\"booleanUpdate($event, parameter)\"\n required></mat-slide-toggle>\n }\n }\n @if (parameter.multiple) {\n <mat-chip-grid class=\"pl-2\" #chipGrid aria-label=\"Enter values\">\n @for (paramValue of parameter.value; track paramValue) {\n <mat-chip-row\n class=\"bg-white mr-2\"\n (removed)=\"removeParameterValue(parameter, paramValue)\">\n {{paramValue}}\n <button matChipRemove [attr.aria-label]=\"'remove ' + paramValue\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n @if (parameter.type === 'text') {\n <input class=\"pr-8 py-1 self-center\" type=\"text\" placeholder=\"Enter {{parameter.title}}\"\n required autofocus\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addParameterValue(parameter, $event)\">\n }\n @if (parameter.type === 'numeric') {\n <input class=\"pr-8\" type=\"number\" placeholder=\"Enter {{parameter.title}}\"\n required autofocus\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addParameterValue(parameter, $event)\">\n }\n @if (parameter.type === 'list') {\n <select class=\"pr-8 py-1.5 pl-1 self-center\" matNativeControl\n (change)=\"addParameterValue(parameter, $event)\" required autofocus>\n <option [value]=\"null\">-- Select Value --</option>\n @for (item of parameter.list; track item) {\n <option [value]=\"item.value\">{{ item.label }}\n </option>\n }\n </select>\n }\n </mat-chip-grid>\n }\n @if (!parameter._locked) {\n <button mat-icon-button [matMenuTriggerFor]=\"paramMenu\">\n <mat-icon>settings</mat-icon>\n </button>\n <mat-menu #paramMenu=\"matMenu\">\n <button mat-menu-item (click)=\"addParameter(parameter, i)\">Edit Parameter</button>\n <button mat-menu-item (click)=\"removeParameter(parameter)\">Remove Parameter</button>\n </mat-menu>\n }\n @if (Object.keys(dashboardParameters || {}).length) {\n <button mat-icon-button [matMenuTriggerFor]=\"dashParamMenu\"\n title=\"Bind this parameter value to another\">\n <mat-icon>text_fields</mat-icon>\n </button>\n <mat-menu #dashParamMenu=\"matMenu\">\n @for (dashParamKey of Object.keys(dashboardParameters); track dashParamKey) {\n <button mat-menu-item\n (click)=\"setDashboardParameter(parameter, dashboardParameters[dashParamKey].name)\">{{ dashboardParameters[dashParamKey].title }}\n </button>\n }\n </mat-menu>\n }\n </div>\n }\n </label>\n @if (parameterValues.length) {\n <div class=\"divider ml-2\"></div>\n }\n }\n <button mat-icon-button color=\"primary\" class=\"mx-2\" (click)=\"addParameter()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n @if (parameterValues.length) {\n <button type=\"button\" (click)=\"evaluateDataset(true)\"\n class=\"mr-2 flex items-center whitespace-nowrap justify-center px-4 py-1 border border-transparent text-sm rounded-md shadow-sm text-white bg-primary focus:outline-none\">\n Apply Parameters\n </button>\n }\n </div>\n </div>\n }\n</div>\n\n<div class=\"cell-header\">\n @if (terminatingTransformations.length) {\n <div class=\"transformation-listing py-2\">\n <div class=\"list-title\">\n Transformations\n </div>\n <div class=\"example-list flex flex-wrap\" cdkDropListGroup>\n @for (transformation of terminatingTransformations; track transformation; let i = $index) {\n @if (!transformation.hidden) {\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\" cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"{item:transformation,index:i}\">\n <div class=\"flex items-center\">\n <div class=\"new-transformation flex items-center justify-center w-6 h-6\">\n <a [matMenuTriggerFor]=\"addTransformation\"\n class=\"items-center add-transformation text-primary\">\n <mat-icon class=\"flex items-center w-5 h-5 text-xl\">add_circle</mat-icon>\n </a>\n <mat-menu #addTransformation=\"matMenu\">\n <button mat-menu-item (click)=\"insertTransformation(i, 'columns', transformation)\">\n Insert Column Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'formula', transformation)\">\n Insert Formula Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'join', transformation)\">\n Insert Join Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'summarise', transformation)\">\n Insert Summarise Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'filter', transformation)\">\n Insert Filter Transformation\n </button>\n </mat-menu>\n </div>\n <div cdkDrag class=\"pl-0 example-box badge-item w-auto m-0\" cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [class]=\"{active: transformation._active, 'exclude bg-orange-50 border-orange-200': !!transformation.exclude, 'bg-indigo-50 border-indigo-200': (transformation.type === 'filter' && transformation.hide === false)}\">\n <button class=\"-mt-0.5\" title=\"Show transformation details\" mat-icon-button\n (click)=\"showTransformationDetail(transformation)\">\n @if (transformation.type === 'columns') {\n <span class=\"material-symbols-outlined ml-1 text-xl\"\n >table_chart</span>\n }\n @if (transformation.type === 'formula') {\n <span class=\"material-symbols-outlined text-xl\"\n >functions</span>\n }\n @if (transformation.type === 'join') {\n <span class=\"material-symbols-outlined text-xl\">merge_type</span>\n }\n @if (transformation.type === 'summarise') {\n <span class=\"material-symbols-outlined ml-1 text-xl\"\n >pivot_table_chart</span>\n }\n @if (transformation.type === 'filter') {\n <span class=\"material-symbols-outlined text-xl\"\n >filter_alt</span>\n }\n </button>\n <span class=\"whitespace-nowrap cursor-pointer\"\n (click)=\"editTerminatingTransformation(transformation)\">{{ transformation._label }}</span>\n @if (transformation.exclude) {\n <button class=\"-ml-1\" [title]=\"'Re-enable this transformation'\"\n mat-icon-button (click)=\"disableTransformation(transformation, i)\">\n <mat-icon class=\"text-orange-400\">replay</mat-icon>\n </button>\n }\n @if (!transformation.exclude && i + 1 === terminatingTransformations.length) {\n <button class=\"-ml-1\" [title]=\"'Disable transformation'\"\n mat-icon-button (click)=\"disableTransformation(transformation, i)\">\n <mat-icon>block</mat-icon>\n </button>\n }\n @if (!transformation.exclude && i + 1 !== terminatingTransformations.length) {\n <button class=\"-ml-1\" [matMenuTriggerFor]=\"disableMenu\"\n [title]=\"'Disable transformation'\"\n mat-icon-button>\n <mat-icon>block</mat-icon>\n </button>\n <mat-menu #disableMenu=\"matMenu\">\n <button mat-menu-item (click)=\"disableTransformation(transformation, i)\">\n Disable this transformation\n </button>\n <button mat-menu-item (click)=\"excludeUpstreamTransformations(transformation)\">\n Disable subsequent transformation(s)\n </button>\n </mat-menu>\n }\n <button class=\"-ml-1\" title=\"Remove this transformation\" mat-icon-button color=\"primary\"\n (click)=\"removeTransformation(transformation, true, null, transformation._active)\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"transformation._showDetail\">\n <div class=\"p-4 w-96 bg-white shadow rounded\">\n @if (transformation.type === 'summarise') {\n <p class=\"text-sm text-gray-700 mb-0\">\n <b>SELECT&nbsp;</b>@for (expression of transformation.config.expressions; track expression; let i = $index) {\n <span\n >@if (i > 0) {\n <span\n >, </span>\n }{{ expression.customExpression || expression.expressionType + '(' + (expression.fieldName || '') + ')' }}</span>\n }\n @if (transformation.config.summariseFieldNames.length) {\n <br><b>GROUP\n BY&nbsp;</b> {{ transformation.config.summariseFieldNames.join(', ') }}\n }\n </p>\n }\n @if (transformation.type === 'formula') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>EXPRESSION</b>&nbsp;{{ decodeURIComponent(transformation.config.expressions[0].expression) }}\n </div>\n }\n @if (transformation.type === 'columns') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>COLUMNS</b>&nbsp;{{ _.map(transformation.config.columns, 'title').join(', ') }}\n </div>\n }\n @if (transformation.type === 'join') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>JOIN\n COLUMNS</b>&nbsp;{{ _.map(transformation.config.joinColumns, 'title').join(', ') }}\n </div>\n }\n @if (transformation.type === 'filter') {\n @for (filter of transformation.config.filters; track filter) {\n <div\n class=\"text-sm text-gray-700 mb-0\">\n <b>FILTER</b>&nbsp;{{ filter.lhsExpression }}&nbsp;<b>{{ filter.filterType }}</b>&nbsp;{{ filter.rhsExpression }}\n </div>\n }\n }\n </div>\n </ng-template>\n </div>\n </div>\n }\n @if (_.some(terminatingTransformations, {exclude: true}) && i === terminatingTransformations.length - 1) {\n <button\n class=\"ml-4 flex items-center border-none bg-primary text-sm rounded-md text-white pr-2 pl-1 py-0.5\"\n (click)=\"enableAllTransformation()\">\n <mat-icon class=\"mr-1 text-base\">replay</mat-icon>\n Enable All\n </button>\n }\n }\n </div>\n</div>\n}\n</div>\n\n<div class=\"cell-header\">\n @if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length) {\n <div class=\"transformation-listing py-2 filters-list\"\n >\n <a class=\"list-title flex items-center\" (click)=\"showFilters = !showFilters\">\n Filters&nbsp;\n @if (!showFilters) {\n <mat-icon>expand_more</mat-icon>\n }\n @if (showFilters) {\n <mat-icon>expand_less</mat-icon>\n }\n </a>\n @for (filterTransformation of _.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}); track filterTransformation) {\n @if (_.every(filterTransformation.config.filters[0])) {\n <div class=\"badge-item pl-2 mr-1\"\n (click)=\"showFilters = !showFilters\">\n <span class=\"cursor-pointer\" [innerHtml]=\"getFilterString(filterTransformation.config)\"></span>\n </div>\n }\n }\n </div>\n }\n</div>\n\n@if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length\n && showFilters) {\n <div class=\"dataset-filters\" id=\"datasetFilters\"\n >\n @for (transformation of datasetInstanceSummary.transformationInstances; track transformation; let i = $index) {\n @if (transformation.type === 'filter' && transformation.hide === false) {\n <div class=\"dataset-filter border-b border-gray-200\">\n <button mat-stroked-button class=\"mr-2 bg-white remove-filter\" color=\"warn\"\n (click)=\"removeTransformation(transformation, true, i)\">\n Remove Filter\n </button>\n @if (filterFields.length) {\n <ki-dataset-filters [filterFields]=\"filterFields\"\n [openSide]=\"openSide\" [parameterValues]=\"filterParameterValues\"\n [filterJunction]=\"transformation.config\"></ki-dataset-filters>\n }\n @if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length) {\n <button\n mat-flat-button class=\"apply-filter mr-2\" color=\"primary\"\n (click)=\"applyFilters()\" [disabled]=\"!filterJunction.filters.length\">\n Apply Filters\n </button>\n }\n </div>\n }\n }\n </div>\n}\n\n<div class=\"cell-header\">\n @if (_.find(datasetInstanceSummary.transformationInstances, {type: 'multisort'})) {\n <div class=\"transformation-listing sort\"\n >\n <div class=\"list-title\">\n Sort\n </div>\n <div class=\"flex flex-wrap\">\n @for (sort of _.find(datasetInstanceSummary.transformationInstances, {type: 'multisort'}).config.sorts; track sort; let i = $index) {\n <div class=\"badge-item outline\"\n [class]=\"{'exclude bg-orange-50 border-orange-200': _.find(datasetInstanceSummary.transformationInstances, {exclude: true})}\"\n >\n <span>{{ _.startCase(sort.fieldName) }}&nbsp;<span class=\"uppercase\">{{ sort.direction }}</span></span>\n <button mat-icon-button (click)=\"removeFilter(i)\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<div class=\"h-full table-overflow overflow-scroll\">\n @if (displayedColumns.length) {\n <table mat-table [dataSource]=\"tableData\" matSort (matSortChange)=\"sort($event)\"\n class=\"block sticky\">\n @for (column of filterFields; track column) {\n <ng-container [matColumnDef]=\"column.name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header\n class=\"text-xs font-semibold text-gray-900 py-3.5 px-4\"> {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\" class=\"py-3 px-4\">\n @if (!Array.isArray(element[column.name]) && !_.isPlainObject(element[column.name])) {\n @if (element[column.name] && String(element[column.name]).length <= 100) {\n <div [innerHTML]=\"element[column.name]\"></div>\n }\n @if (element[column.name] && String(element[column.name]).length > 100) {\n <div>{{ element[column.name].substring(0, 100) + '...' }}</div>\n <a (click)=\"viewFullItemData(element[column.name], column.name)\"\n class=\"flex items-center text-sm text-cta\">\n view more\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\n </svg>\n </a>\n }\n @if (!element[column.name]) {\n @if (element[column.name] === null) {\n <span class=\"font-mono text-gray-400\">null</span>\n }\n @if (element[column.name] !== null) {\n <span>{{ element[column.name] }}</span>\n }\n }\n }\n @if (Array.isArray(element[column.name])) {\n Contains {{ element[column.name].length }} items\n }\n @if (_.isPlainObject(element[column.name])) {\n <span [innerHTML]=\"toJSON(element[column.name])\"></span>\n }\n </td>\n </ng-container>\n }\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\" class=\"h-auto\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n }\n</div>\n\n\n<div class=\"border-b border-t bg-gray-50 px-4 py-1 flex align-center justify-end\">\n\n <div class=\"flex items-center\">\n <div class=\"text-sm text-gray-500 mr-10\">\n @if (dataset) {\n Showing {{ offset + 1 }} - {{ (page * limit) - (limit - tableData.length) }}\n }\n </div>\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-1.5\">\n <option [value]=\"1\">1</option>\n <option [value]=\"5\">5</option>\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;position:relative;height:100%}:host>div{flex:0 1 auto}.divider{width:1px;height:17px;background-color:#cecece}.new-transformation .add-transformation{display:none}.new-transformation:hover .add-transformation{display:flex}.long-running{position:fixed;inset:0;background-color:#ffffffb3;z-index:99999;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.long-running .loading-box{position:relative;margin-bottom:2rem}.long-running .loading-box div{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:1.2rem;font-weight:500}.long-running p{font-size:1.1rem}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.cell-header.sorting{min-height:43px}.dataset-data-actions{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;margin-top:-1px}.dataset-data-actions button{min-width:50px;padding:0 13px;color:#505050}.dataset-data-actions .divider{margin:0 .5rem;width:1px;height:36px;background-color:#ddd}.parameter-listing label{flex-direction:row;align-items:center}.parameter-listing label .parameter-input{border-radius:4px;padding-left:.5rem;height:36px;display:flex;align-items:center}.parameter-listing label .parameter-input .param-period-picker{padding:5px}.parameter-listing label .parameter-input button{color:#8e8e8e}.parameter-listing label .parameter-input button.edit-parameter{visibility:hidden}.parameter-listing label .parameter-input button.mat-icon-button{width:30px;height:30px;line-height:30px;align-self:center}.parameter-listing label .parameter-input button.mat-icon-button mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.parameter-listing label .parameter-input input{font-size:.9rem;padding:.25rem .45rem;width:175px}.parameter-listing label .parameter-input:hover .edit-parameter{visibility:visible}.transformation-listing{display:flex;align-items:center;width:100%;background-color:#00000012;border-bottom:1px solid #ddd;min-height:47px}.transformation-listing .list-title{text-transform:uppercase;font-size:.75rem;padding:0 1rem;border-right:2px solid #ddd;color:#4c4c4c;font-weight:500;letter-spacing:1px}.transformation-listing .badge-item{display:flex;align-items:center;margin-left:1rem;padding-left:1rem;border-radius:20px;background-color:#fff;border:1px solid #ddd;height:30px}.transformation-listing .badge-item.exclude{opacity:.8}.transformation-listing .badge-item:hover{background-color:#fcfcfc}.transformation-listing .badge-item span{margin-right:.5rem;color:#0000008a}.transformation-listing .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.transformation-listing .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}.dataset-filters{position:relative;overflow-y:scroll;flex:none!important;max-height:400px}.dataset-filters .dataset-filter{position:relative}.dataset-filters .dataset-filter .apply-filter{position:absolute;bottom:.5rem;right:0;z-index:10}.dataset-filters .dataset-filter .remove-filter{position:absolute;top:.5rem;right:0;z-index:10}.badge-holder{display:flex;align-items:center;margin:.25rem 0}.badge-holder .badge-item{display:flex;align-items:center;padding-left:1rem;border-radius:20px}.badge-holder .badge-item.outline{background-color:#fff;border:1px solid #efefef}.badge-holder .badge-item span{margin-right:.5rem;color:#0000008a}.badge-holder .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.badge-holder .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}table{position:relative;border-collapse:collapse}table.sticky th{position:sticky;top:0;background-color:#f5f5f5;border-top:none!important;border-bottom:none!important;box-shadow:inset 0 -1px #ddd}table th.settings{padding:0}table td{max-width:400px;word-wrap:break-word;padding-top:.5rem;padding-bottom:.5rem;padding-right:1rem;min-width:150px;width:1%}table td.settings{max-width:25px;min-width:25px}table::-webkit-scrollbar{width:.75em;background:transparent}table::-webkit-scrollbar-thumb{background:#d2d2d2}table tbody:nth-of-type(1) tr:nth-of-type(1) td{border-top:none!important}table thead th{border-top:none!important;border-bottom:none!important;box-shadow:inset 0 2px #000,inset 0 -2px #000;padding:2px 0}table thead th{background-clip:padding-box}.table-overflow::-webkit-scrollbar{width:.75em;background:transparent}.table-overflow::-webkit-scrollbar-thumb{background:#d2d2d2}.paging-toolbar{position:sticky;bottom:-20px;left:0;background-color:#fff;right:0;padding:1rem}table{text-align:left;position:relative;border-collapse:collapse}th,td{padding:.25rem}\n"], dependencies: [{ kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i7$4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i7$3.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i7$3.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i7$3.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i7$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i7$3.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i9$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i9$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i10.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i10.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "directive", type: i6.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i6.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i6.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i14.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i12$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i16.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: i16.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "component", type: DatasetFiltersComponent, selector: "ki-dataset-filters", inputs: ["filterJunction", "filterFields", "joinFilterFields", "joinFieldsName", "openSide", "parameterValues"] }, { kind: "component", type: WhitelistedSqlFunctionsComponent, selector: "ki-whitelisted-sql-functions", inputs: ["search", "fields"] }] }); }
3574
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DatasetEditorComponent, isStandalone: false, selector: "ki-dataset-editor", inputs: { datasetInstanceSummary: "datasetInstanceSummary", environment: "environment", admin: "admin", dashboardParameters: "dashboardParameters", dashboardLayoutSettings: "dashboardLayoutSettings", accountId: "accountId", newTitle: "newTitle", newDescription: "newDescription", datasetEditorReadonly: "datasetEditorReadonly", datasetEditorSimpleMode: "datasetEditorSimpleMode", datasetEditorNoTools: "datasetEditorNoTools" }, outputs: { dataLoaded: "dataLoaded", datasetInstanceSummaryChange: "datasetInstanceSummaryChange" }, ngImport: i0, template: "@if (longRunning) {\n <div class=\"long-running flex-col\">\n <div class=\"loading-box\">\n <mat-spinner [diameter]=\"150\"></mat-spinner>\n <div>Loading</div>\n </div>\n <p class=\"text-center\">Please wait while we process this query.</p>\n <p class=\"text-center\">The results will be shown here once it has finished running.</p>\n <div>\n <a class=\"text-primary hover:underline\" (click)=\"cancelEvaluate()\">Cancel query and return to editor.</a>\n </div>\n </div>\n}\n<div class=\"pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10 -z-10\" id=\"sidebarWrapper\">\n <div [class]=\"{'translate-x-0': sideOpen, 'translate-x-full': !sideOpen}\"\n (click)=\"$event.stopPropagation()\"\n class=\"pointer-events-auto w-screen max-w-md transform transition ease-in-out duration-500 sm:duration-700\"\n id=\"docSidebar\">\n <div class=\"flex h-full flex-col overflow-y-scroll bg-white py-6 shadow-xl\">\n <div class=\"px-4 sm:px-6\">\n <div class=\"flex items-start justify-between\">\n <div></div>\n\n <div class=\"ml-3 flex h-7 items-center\">\n <button type=\"button\" (click)=\"openSide.next(false)\"\n class=\"rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none\">\n <span class=\"sr-only\">Close panel</span>\n <!-- Heroicon name: outline/x -->\n <svg class=\"h-6 w-6\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n </button>\n </div>\n </div>\n </div>\n <div class=\"relative flex-1 px-4 sm:px-6\">\n <ki-whitelisted-sql-functions [fields]=\"filterFields\"></ki-whitelisted-sql-functions>\n </div>\n </div>\n </div>\n</div>\n\n@if (!datasetEditorNoTools) {\n <div class=\"border-b cell-header end\">\n <div class=\"leading-5 px-4 text-xs uppercase tracking-wider font-medium border-r-2 text-gray-600\">\n Operations\n </div>\n <div class=\"dataset-data-actions\">\n <button (click)=\"addFilter()\"\n title=\"Filter the set using column based restrictions\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">filter_alt</span>\n filter\n </button>\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"summariseData()\"\n title=\"Summarise this data to produce aggregated totals, sums and other derivations\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">pivot_table_chart</span>\n summarise\n </button>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"joinData()\"\n title=\"Join another data set to the current dataset\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">merge_type</span>\n join\n </button>\n }\n <div class=\"divider\"></div>\n <button (click)=\"createFormula()\"\n title=\"Create a formula column using an expression based on other columns\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">functions</span>\n formula\n </button>\n <button (click)=\"editColumnSettings()\"\n title=\"Switch on and off columns for display\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">table_chart</span>\n columns\n </button>\n @if (!datasetEditorSimpleMode) {\n <div class=\"divider\"></div>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"addParameter()\"\n title=\"Add a parameter to use in filters, expressions etc.\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">text_fields</span>\n parameters\n </button>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"addPagingMarker()\"\n title=\"Insert paging marker to limit results at this stage in the query flow\"\n class=\"w-24 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">skip_next</span>\n paging marker\n </button>\n }\n <div class=\"divider\"></div>\n <button (click)=\"evaluateDataset()\"\n title=\"Reload this query based upon changes you may have made\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">sync</span>\n reload\n </button>\n @if (!datasetEditorReadonly) {\n <button [disabled]=\"!datasetInstanceSummary || !datasetInstanceSummary.id\" (click)=\"shareQuery()\"\n title=\"Share this query with other account holders\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">share</span>\n share\n </button>\n <button (click)=\"saveAsQuery()\"\n title=\"Make a copy of this query\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">file_copy</span>\n copy query\n </button>\n @if (!dashboardLayoutSettings && datasetInstanceSummary.id) {\n <button (click)=\"save()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">save</span>\n save\n </button>\n }\n }\n </div>\n </div>\n}\n\n<div class=\"cell-header\">\n @if (showParameters || parameterValues.length) {\n <div class=\"transformation-listing parameter-listing\">\n <div class=\"list-title\">\n Parameters\n </div>\n <div class=\"flex items-center flex-wrap\">\n @for (parameter of parameterValues; track parameter; let i = $index) {\n <label class=\"pl-4\">\n {{ parameter.title }}\n @if ((parameter.value || '').toString().includes('}}')) {\n <div>\n <mat-chip class=\"bg-gray-50 ml-2\" title=\"Using parameter value from {{parameter.value}}\">\n <div class=\"flex items-center\">\n <span class=\"material-symbols-outlined text-xl mr-1 text-gray-500\">layers</span>\n @if (dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')]) {\n <span\n [innerHTML]=\"dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')].value\"></span>\n }\n @if (!dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')]) {\n <span\n class=\"font-medium text-orange-600\">\n Parameter Not Found !\n </span>\n }\n </div>\n <button matChipRemove (click)=\"parameter.value = ''\" title=\"\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip>\n </div>\n }\n @if (!(parameter.value || '').toString().includes('}}')) {\n <div class=\"parameter-input\">\n @if (!parameter.multiple) {\n @if (parameter.type === 'text') {\n <input class=\"pr-8 py-1.5\" type=\"text\" placeholder=\"Enter {{parameter.title}}\"\n [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n }\n @if (parameter.type === 'numeric') {\n <input class=\"pr-8 py-1.5\" type=\"number\" placeholder=\"Enter {{parameter.title}}\"\n [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n }\n @if (parameter.type === 'list') {\n <select class=\"pr-8 py-1.5 pl-1 self-center\" [(ngModel)]=\"parameter.value\"\n (change)=\"evaluateDataset(true)\" required autofocus>\n <option [value]=\"null\">-- Select Value --</option>\n @for (item of parameter.list; track item) {\n <option [value]=\"item.value\">{{ item.label }}\n </option>\n }\n </select>\n }\n @if (parameter.type === 'date' || parameter.type === 'datetime') {\n @if (!parameter._dateType) {\n <div class=\"flex items-center mr-8\">\n <button (click)=\"changeDateType($event, parameter, 'picker')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n Date Picker\n </button>\n <button (click)=\"changeDateType($event, parameter, 'period')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n Time Period\n </button>\n </div>\n }\n @if (parameter._dateType === 'picker') {\n <input [type]=\"parameter.type === 'date' ? 'date' : 'datetime-local'\"\n class=\" py-1.5\"\n placeholder=\"Enter {{parameter.title}}\" [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n <a (click)=\"changeDateType($event, parameter, 'period')\"\n matTooltip=\"Time Period\"\n class=\"mr-10 text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n </a>\n }\n @if (parameter._dateType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-16 mr-2 py-1.5\" min=\"0\" [value]=\"parameter._periodValue\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n <select class=\"param-period-picker mr-2\" [value]=\"parameter._period || 'DAYS'\"\n #period\n (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div>Ago</div>\n </div>\n <a (click)=\"changeDateType($event, parameter, 'picker')\"\n matTooltip=\"Date Picker\"\n class=\"mr-10 text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n </a>\n }\n }\n @if (parameter.type === 'boolean') {\n <mat-slide-toggle class=\"pr-8\" color=\"primary\"\n [checked]=\"parameter.value\" (change)=\"booleanUpdate($event, parameter)\"\n required></mat-slide-toggle>\n }\n }\n @if (parameter.multiple) {\n <mat-chip-grid class=\"pl-2\" #chipGrid aria-label=\"Enter values\">\n @for (paramValue of parameter.value; track paramValue) {\n <mat-chip-row\n class=\"bg-white mr-2\"\n (removed)=\"removeParameterValue(parameter, paramValue)\">\n {{paramValue}}\n <button matChipRemove [attr.aria-label]=\"'remove ' + paramValue\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n @if (parameter.type === 'text') {\n <input class=\"pr-8 py-1.5 self-center\" type=\"text\" placeholder=\"Enter {{parameter.title}}\"\n required autofocus\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addParameterValue(parameter, $event)\">\n }\n @if (parameter.type === 'numeric') {\n <input class=\"pr-8 py-1.5\" type=\"number\" placeholder=\"Enter {{parameter.title}}\"\n required autofocus\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addParameterValue(parameter, $event)\">\n }\n @if (parameter.type === 'list') {\n <select class=\"pr-8 py-1.5 pl-1 self-center\" matNativeControl\n (change)=\"addParameterValue(parameter, $event)\" required autofocus>\n <option [value]=\"null\">-- Select Value --</option>\n @for (item of parameter.list; track item) {\n <option [value]=\"item.value\">{{ item.label }}\n </option>\n }\n </select>\n }\n </mat-chip-grid>\n }\n @if (!parameter._locked) {\n <button mat-icon-button [matMenuTriggerFor]=\"paramMenu\">\n <mat-icon>settings</mat-icon>\n </button>\n <mat-menu #paramMenu=\"matMenu\">\n <button mat-menu-item (click)=\"addParameter(parameter, i)\">Edit Parameter</button>\n <button mat-menu-item (click)=\"removeParameter(parameter)\">Remove Parameter</button>\n </mat-menu>\n }\n @if (Object.keys(dashboardParameters || {}).length) {\n <button mat-icon-button [matMenuTriggerFor]=\"dashParamMenu\"\n title=\"Bind this parameter value to another\">\n <mat-icon>text_fields</mat-icon>\n </button>\n <mat-menu #dashParamMenu=\"matMenu\">\n @for (dashParamKey of Object.keys(dashboardParameters); track dashParamKey) {\n <button mat-menu-item\n (click)=\"setDashboardParameter(parameter, dashboardParameters[dashParamKey].name)\">{{ dashboardParameters[dashParamKey].title }}\n </button>\n }\n </mat-menu>\n }\n </div>\n }\n </label>\n @if (parameterValues.length) {\n <div class=\"divider ml-2\"></div>\n }\n }\n <button mat-icon-button color=\"primary\" class=\"mx-2\" (click)=\"addParameter()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n @if (parameterValues.length) {\n <button type=\"button\" (click)=\"evaluateDataset(true)\"\n class=\"mr-2 flex items-center whitespace-nowrap justify-center px-4 py-1 border border-transparent text-sm rounded-md shadow-sm text-white bg-primary focus:outline-none\">\n Apply Parameters\n </button>\n }\n </div>\n </div>\n }\n</div>\n\n<div class=\"cell-header\">\n @if (terminatingTransformations.length) {\n <div class=\"transformation-listing py-2\">\n <div class=\"list-title\">\n Transformations\n </div>\n <div class=\"example-list flex flex-wrap\" cdkDropListGroup>\n @for (transformation of terminatingTransformations; track transformation; let i = $index) {\n @if (!transformation.hidden) {\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\" cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"{item:transformation,index:i}\">\n <div class=\"flex items-center\">\n <div class=\"new-transformation flex items-center justify-center w-6 h-6\">\n <a [matMenuTriggerFor]=\"addTransformation\"\n class=\"items-center add-transformation text-primary\">\n <mat-icon class=\"flex items-center w-5 h-5 text-xl\">add_circle</mat-icon>\n </a>\n <mat-menu #addTransformation=\"matMenu\">\n <button mat-menu-item (click)=\"insertTransformation(i, 'columns', transformation)\">\n Insert Column Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'formula', transformation)\">\n Insert Formula Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'join', transformation)\">\n Insert Join Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'summarise', transformation)\">\n Insert Summarise Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'filter', transformation)\">\n Insert Filter Transformation\n </button>\n </mat-menu>\n </div>\n <div cdkDrag class=\"pl-0 example-box badge-item w-auto m-0\" cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [class.active]=\"transformation._active\"\n [class.exclude]=\"!!transformation.exclude\"\n [class.bg-orange-50]=\"!!transformation.exclude\"\n [class.border-orange-200]=\"!!transformation.exclude\"\n [class.bg-indigo-50]=\"(transformation.type === 'filter' && transformation.hide === false)\"\n [class.border-indigo-200]=\"(transformation.type === 'filter' && transformation.hide === false)\">\n <button class=\"-mt-0.5\" title=\"Show transformation details\" mat-icon-button\n (click)=\"showTransformationDetail(transformation)\">\n @if (transformation.type === 'columns') {\n <span class=\"material-symbols-outlined ml-1 text-xl\"\n >table_chart</span>\n }\n @if (transformation.type === 'formula') {\n <span class=\"material-symbols-outlined text-xl\"\n >functions</span>\n }\n @if (transformation.type === 'join') {\n <span class=\"material-symbols-outlined text-xl\">merge_type</span>\n }\n @if (transformation.type === 'summarise') {\n <span class=\"material-symbols-outlined ml-1 text-xl\"\n >pivot_table_chart</span>\n }\n @if (transformation.type === 'filter') {\n <span class=\"material-symbols-outlined text-xl\"\n >filter_alt</span>\n }\n </button>\n <span class=\"whitespace-nowrap cursor-pointer\"\n (click)=\"editTerminatingTransformation(transformation)\">{{ transformation._label }}</span>\n @if (transformation.exclude) {\n <button class=\"-ml-1\" [title]=\"'Re-enable this transformation'\"\n mat-icon-button (click)=\"disableTransformation(transformation, i)\">\n <mat-icon class=\"text-xl leading-6 text-orange-400\">replay</mat-icon>\n </button>\n }\n @if (!transformation.exclude && i + 1 === terminatingTransformations.length) {\n <button class=\"-ml-1\" [title]=\"'Disable transformation'\"\n mat-icon-button (click)=\"disableTransformation(transformation, i)\">\n <mat-icon class=\"text-xl leading-6\">block</mat-icon>\n </button>\n }\n @if (!transformation.exclude && i + 1 !== terminatingTransformations.length) {\n <button class=\"-ml-1\" [matMenuTriggerFor]=\"disableMenu\"\n [title]=\"'Disable transformation'\"\n mat-icon-button>\n <mat-icon class=\"text-xl leading-6\">block</mat-icon>\n </button>\n <mat-menu #disableMenu=\"matMenu\">\n <button mat-menu-item (click)=\"disableTransformation(transformation, i)\">\n Disable this transformation\n </button>\n <button mat-menu-item (click)=\"excludeUpstreamTransformations(transformation)\">\n Disable subsequent transformation(s)\n </button>\n </mat-menu>\n }\n <button class=\"-ml-1\" title=\"Remove this transformation\" mat-icon-button color=\"primary\"\n (click)=\"removeTransformation(transformation, true, null, transformation._active)\">\n <mat-icon class=\"text-xl leading-6\">cancel</mat-icon>\n </button>\n </div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"transformation._showDetail\">\n <div class=\"p-4 w-96 bg-white shadow rounded\">\n @if (transformation.type === 'summarise') {\n <p class=\"text-sm text-gray-700 mb-0\">\n <b>SELECT&nbsp;</b>@for (expression of transformation.config.expressions; track expression; let i = $index) {\n <span\n >@if (i > 0) {\n <span\n >, </span>\n }{{ expression.customExpression || expression.expressionType + '(' + (expression.fieldName || '') + ')' }}</span>\n }\n @if (transformation.config.summariseFieldNames.length) {\n <br><b>GROUP\n BY&nbsp;</b> {{ transformation.config.summariseFieldNames.join(', ') }}\n }\n </p>\n }\n @if (transformation.type === 'formula') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>EXPRESSION</b>&nbsp;{{ decodeURIComponent(transformation.config.expressions[0].expression) }}\n </div>\n }\n @if (transformation.type === 'columns') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>COLUMNS</b>&nbsp;{{ _.map(transformation.config.columns, 'title').join(', ') }}\n </div>\n }\n @if (transformation.type === 'join') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>JOIN\n COLUMNS</b>&nbsp;{{ _.map(transformation.config.joinColumns, 'title').join(', ') }}\n </div>\n }\n @if (transformation.type === 'filter') {\n @for (filter of transformation.config.filters; track filter) {\n <div\n class=\"text-sm text-gray-700 mb-0\">\n <b>FILTER</b>&nbsp;{{ filter.lhsExpression }}&nbsp;<b>{{ filter.filterType }}</b>&nbsp;{{ filter.rhsExpression }}\n </div>\n }\n }\n </div>\n </ng-template>\n </div>\n </div>\n }\n @if (_.some(terminatingTransformations, {exclude: true}) && i === terminatingTransformations.length - 1) {\n <button\n class=\"ml-4 flex items-center border-none bg-primary text-sm rounded-md text-white pr-2 pl-1 py-0.5\"\n (click)=\"enableAllTransformation()\">\n <mat-icon class=\"mr-1 text-base\">replay</mat-icon>\n Enable All\n </button>\n }\n }\n </div>\n</div>\n}\n</div>\n\n<div class=\"cell-header\">\n @if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length) {\n <div class=\"transformation-listing py-2 filters-list\"\n >\n <a class=\"list-title flex items-center\" (click)=\"showFilters = !showFilters\">\n Filters&nbsp;\n @if (!showFilters) {\n <mat-icon>expand_more</mat-icon>\n }\n @if (showFilters) {\n <mat-icon>expand_less</mat-icon>\n }\n </a>\n @for (filterTransformation of _.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}); track filterTransformation) {\n @if (_.every(filterTransformation.config.filters[0])) {\n <div class=\"badge-item pl-2 mr-1\"\n (click)=\"showFilters = !showFilters\">\n <span class=\"cursor-pointer\" [innerHtml]=\"getFilterString(filterTransformation.config)\"></span>\n </div>\n }\n }\n </div>\n }\n</div>\n\n@if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length\n && showFilters) {\n <div class=\"dataset-filters\" id=\"datasetFilters\"\n >\n @for (transformation of datasetInstanceSummary.transformationInstances; track transformation; let i = $index) {\n @if (transformation.type === 'filter' && transformation.hide === false) {\n <div class=\"dataset-filter border-b border-gray-200\">\n <button mat-stroked-button class=\"mr-2 bg-white remove-filter\" color=\"warn\"\n (click)=\"removeTransformation(transformation, true, i)\">\n Remove Filter\n </button>\n @if (filterFields.length) {\n <ki-dataset-filters [filterFields]=\"filterFields\"\n [openSide]=\"openSide\" [parameterValues]=\"filterParameterValues\"\n [filterJunction]=\"transformation.config\"></ki-dataset-filters>\n }\n @if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length) {\n <button\n mat-flat-button class=\"apply-filter mr-2\" color=\"primary\"\n (click)=\"applyFilters()\" [disabled]=\"!filterJunction.filters.length\">\n Apply Filters\n </button>\n }\n </div>\n }\n }\n </div>\n}\n\n<div class=\"cell-header\">\n @if (_.find(datasetInstanceSummary.transformationInstances, {type: 'multisort'})) {\n <div class=\"transformation-listing sort\"\n >\n <div class=\"list-title\">\n Sort\n </div>\n <div class=\"flex flex-wrap\">\n @for (sort of _.find(datasetInstanceSummary.transformationInstances, {type: 'multisort'}).config.sorts; track sort; let i = $index) {\n <div class=\"badge-item outline\"\n [class]=\"{'exclude bg-orange-50 border-orange-200': _.find(datasetInstanceSummary.transformationInstances, {exclude: true})}\"\n >\n <span>{{ _.startCase(sort.fieldName) }}&nbsp;<span class=\"uppercase\">{{ sort.direction }}</span></span>\n <button mat-icon-button (click)=\"removeFilter(i)\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<div class=\"h-full table-overflow overflow-scroll\">\n @if (displayedColumns.length) {\n <table mat-table [dataSource]=\"tableData\" matSort (matSortChange)=\"sort($event)\"\n class=\"block sticky\">\n @for (column of filterFields; track column) {\n <ng-container [matColumnDef]=\"column.name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header\n class=\"text-xs font-semibold text-gray-900 py-3.5 px-4\"> {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\" class=\"py-3 px-4\">\n @if (!Array.isArray(element[column.name]) && !_.isPlainObject(element[column.name])) {\n @if (element[column.name] && String(element[column.name]).length <= 100) {\n <div [innerHTML]=\"element[column.name]\"></div>\n }\n @if (element[column.name] && String(element[column.name]).length > 100) {\n <div>{{ element[column.name].substring(0, 100) + '...' }}</div>\n <a (click)=\"viewFullItemData(element[column.name], column.name)\"\n class=\"flex items-center text-sm text-cta\">\n view more\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\n </svg>\n </a>\n }\n @if (!element[column.name]) {\n @if (element[column.name] === null) {\n <span class=\"font-mono text-gray-400\">null</span>\n }\n @if (element[column.name] !== null) {\n <span>{{ element[column.name] }}</span>\n }\n }\n }\n @if (Array.isArray(element[column.name])) {\n Contains {{ element[column.name].length }} items\n }\n @if (_.isPlainObject(element[column.name])) {\n <span class=\"text-xs font-mono\" [innerHTML]=\"toJSON(element[column.name])\"></span>\n }\n </td>\n </ng-container>\n }\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\" class=\"h-auto\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n }\n</div>\n\n\n<div class=\"border-b border-t bg-gray-50 px-4 py-1 flex align-center justify-end\">\n\n <div class=\"flex items-center\">\n <div class=\"text-sm text-gray-500 mr-10\">\n @if (dataset) {\n Showing {{ offset + 1 }} - {{ (page * limit) - (limit - tableData.length) }}\n }\n </div>\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-1.5\">\n <option [value]=\"1\">1</option>\n <option [value]=\"5\">5</option>\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;position:relative;height:100%}:host>div{flex:0 1 auto}.divider{width:1px;height:17px;background-color:#cecece}.new-transformation .add-transformation{display:none}.new-transformation:hover .add-transformation{display:flex}.long-running{position:fixed;inset:0;background-color:#ffffffb3;z-index:99999;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.long-running .loading-box{position:relative;margin-bottom:2rem}.long-running .loading-box div{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:1.2rem;font-weight:500}.long-running p{font-size:1.1rem}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.cell-header.sorting{min-height:43px}.dataset-data-actions{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;margin-top:-1px}.dataset-data-actions button{min-width:50px;padding:0 13px;color:#505050}.dataset-data-actions .divider{margin:0 .5rem;width:1px;height:36px;background-color:#ddd}.parameter-listing label{flex-direction:row;align-items:center}.parameter-listing label .parameter-input{border-radius:4px;padding-left:.5rem;height:36px;display:flex;align-items:center}.parameter-listing label .parameter-input .param-period-picker{padding:5px}.parameter-listing label .parameter-input button{color:#8e8e8e}.parameter-listing label .parameter-input button.edit-parameter{visibility:hidden}.parameter-listing label .parameter-input button.mat-icon-button{width:30px;height:30px;line-height:30px;align-self:center}.parameter-listing label .parameter-input button.mat-icon-button mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.parameter-listing label .parameter-input input{font-size:.9rem;padding:.25rem .45rem;width:175px}.parameter-listing label .parameter-input:hover .edit-parameter{visibility:visible}.transformation-listing{display:flex;align-items:center;width:100%;background-color:#00000012;border-bottom:1px solid #ddd;min-height:47px}.transformation-listing .list-title{text-transform:uppercase;font-size:.75rem;padding:0 1rem;border-right:2px solid #ddd;color:#4c4c4c;font-weight:500;letter-spacing:1px}.transformation-listing .badge-item{display:flex;align-items:center;margin-left:1rem;padding-left:1rem;border-radius:20px;background-color:#fff;border:1px solid #ddd;height:30px}.transformation-listing .badge-item.exclude{opacity:.8}.transformation-listing .badge-item:hover{background-color:#fcfcfc}.transformation-listing .badge-item span{margin-right:.5rem;color:#0000008a}.transformation-listing .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.transformation-listing .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}.dataset-filters{position:relative;overflow-y:scroll;flex:none!important;max-height:400px}.dataset-filters .dataset-filter{position:relative}.dataset-filters .dataset-filter .apply-filter{position:absolute;bottom:.5rem;right:0;z-index:10}.dataset-filters .dataset-filter .remove-filter{position:absolute;top:.5rem;right:0;z-index:10}.badge-holder{display:flex;align-items:center;margin:.25rem 0}.badge-holder .badge-item{display:flex;align-items:center;padding-left:1rem;border-radius:20px}.badge-holder .badge-item.outline{background-color:#fff;border:1px solid #efefef}.badge-holder .badge-item span{margin-right:.5rem;color:#0000008a}.badge-holder .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.badge-holder .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}table{position:relative;border-collapse:collapse}table.sticky th{position:sticky;top:0;background-color:#f5f5f5;border-top:none!important;border-bottom:none!important;box-shadow:inset 0 -1px #ddd}table th.settings{padding:0}table td{max-width:400px;word-wrap:break-word;padding-top:.5rem;padding-bottom:.5rem;padding-right:1rem;min-width:150px;width:1%}table td.settings{max-width:25px;min-width:25px}table::-webkit-scrollbar{width:.75em;background:transparent}table::-webkit-scrollbar-thumb{background:#d2d2d2}table tbody:nth-of-type(1) tr:nth-of-type(1) td{border-top:none!important}table thead th{border-top:none!important;border-bottom:none!important;box-shadow:inset 0 2px #000,inset 0 -2px #000;padding:2px 0}table thead th{background-clip:padding-box}.table-overflow::-webkit-scrollbar{width:.75em;background:transparent}.table-overflow::-webkit-scrollbar-thumb{background:#d2d2d2}.paging-toolbar{position:sticky;bottom:-20px;left:0;background-color:#fff;right:0;padding:1rem}table{text-align:left;position:relative;border-collapse:collapse}th,td{padding:.25rem}\n"], dependencies: [{ kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i7$4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i7$3.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i7$3.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i7$3.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i7$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i7$3.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i9$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i9$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i10.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i10.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "directive", type: i6.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i6.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i6.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i14.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i12$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i16.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: i16.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "component", type: DatasetFiltersComponent, selector: "ki-dataset-filters", inputs: ["filterJunction", "filterFields", "joinFilterFields", "joinFieldsName", "openSide", "parameterValues"] }, { kind: "component", type: WhitelistedSqlFunctionsComponent, selector: "ki-whitelisted-sql-functions", inputs: ["search", "fields"] }] }); }
3575
3575
  }
3576
3576
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatasetEditorComponent, decorators: [{
3577
3577
  type: Component,
3578
- args: [{ selector: 'ki-dataset-editor', standalone: false, template: "@if (longRunning) {\n <div class=\"long-running flex-col\">\n <div class=\"loading-box\">\n <mat-spinner [diameter]=\"150\"></mat-spinner>\n <div>Loading</div>\n </div>\n <p class=\"text-center\">Please wait while we process this query.</p>\n <p class=\"text-center\">The results will be shown here once it has finished running.</p>\n <div>\n <a class=\"text-primary hover:underline\" (click)=\"cancelEvaluate()\">Cancel query and return to editor.</a>\n </div>\n </div>\n}\n<div class=\"pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10 -z-10\" id=\"sidebarWrapper\">\n <div [class]=\"{'translate-x-0': sideOpen, 'translate-x-full': !sideOpen}\"\n (click)=\"$event.stopPropagation()\"\n class=\"pointer-events-auto w-screen max-w-md transform transition ease-in-out duration-500 sm:duration-700\"\n id=\"docSidebar\">\n <div class=\"flex h-full flex-col overflow-y-scroll bg-white py-6 shadow-xl\">\n <div class=\"px-4 sm:px-6\">\n <div class=\"flex items-start justify-between\">\n <div></div>\n\n <div class=\"ml-3 flex h-7 items-center\">\n <button type=\"button\" (click)=\"openSide.next(false)\"\n class=\"rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none\">\n <span class=\"sr-only\">Close panel</span>\n <!-- Heroicon name: outline/x -->\n <svg class=\"h-6 w-6\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n </button>\n </div>\n </div>\n </div>\n <div class=\"relative flex-1 px-4 sm:px-6\">\n <ki-whitelisted-sql-functions [fields]=\"filterFields\"></ki-whitelisted-sql-functions>\n </div>\n </div>\n </div>\n</div>\n\n@if (!datasetEditorNoTools) {\n <div class=\"border-b cell-header end\">\n <div class=\"leading-5 px-4 text-xs uppercase tracking-wider font-medium border-r-2 text-gray-600\">\n Operations\n </div>\n <div class=\"dataset-data-actions\">\n <button (click)=\"addFilter()\"\n title=\"Filter the set using column based restrictions\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">filter_alt</span>\n filter\n </button>\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"summariseData()\"\n title=\"Summarise this data to produce aggregated totals, sums and other derivations\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">pivot_table_chart</span>\n summarise\n </button>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"joinData()\"\n title=\"Join another data set to the current dataset\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">merge_type</span>\n join\n </button>\n }\n <div class=\"divider\"></div>\n <button (click)=\"createFormula()\"\n title=\"Create a formula column using an expression based on other columns\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">functions</span>\n formula\n </button>\n <button (click)=\"editColumnSettings()\"\n title=\"Switch on and off columns for display\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">table_chart</span>\n columns\n </button>\n @if (!datasetEditorSimpleMode) {\n <div class=\"divider\"></div>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"addParameter()\"\n title=\"Add a parameter to use in filters, expressions etc.\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">text_fields</span>\n parameters\n </button>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"addPagingMarker()\"\n title=\"Insert paging marker to limit results at this stage in the query flow\"\n class=\"w-24 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">skip_next</span>\n paging marker\n </button>\n }\n <div class=\"divider\"></div>\n <button (click)=\"evaluateDataset()\"\n title=\"Reload this query based upon changes you may have made\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">sync</span>\n reload\n </button>\n @if (!datasetEditorReadonly) {\n <button [disabled]=\"!datasetInstanceSummary || !datasetInstanceSummary.id\" (click)=\"shareQuery()\"\n title=\"Share this query with other account holders\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">share</span>\n share\n </button>\n <button (click)=\"saveAsQuery()\"\n title=\"Make a copy of this query\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">file_copy</span>\n copy query\n </button>\n @if (!dashboardLayoutSettings && datasetInstanceSummary.id) {\n <button (click)=\"save()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">save</span>\n save\n </button>\n }\n }\n </div>\n </div>\n}\n\n<div class=\"cell-header\">\n @if (showParameters || parameterValues.length) {\n <div class=\"transformation-listing parameter-listing\">\n <div class=\"list-title\">\n Parameters\n </div>\n <div class=\"flex items-center flex-wrap\">\n @for (parameter of parameterValues; track parameter; let i = $index) {\n <label class=\"pl-4\">\n {{ parameter.title }}\n @if ((parameter.value || '').toString().includes('}}')) {\n <div>\n <mat-chip class=\"bg-gray-50 ml-2\" title=\"Using parameter value from {{parameter.value}}\">\n <div class=\"flex items-center\">\n <span class=\"material-symbols-outlined text-xl mr-1 text-gray-500\">layers</span>\n @if (dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')]) {\n <span\n [innerHTML]=\"dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')].value\"></span>\n }\n @if (!dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')]) {\n <span\n class=\"font-medium text-orange-600\">\n Parameter Not Found !\n </span>\n }\n </div>\n <button matChipRemove (click)=\"parameter.value = ''\" title=\"\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip>\n </div>\n }\n @if (!(parameter.value || '').toString().includes('}}')) {\n <div class=\"parameter-input\">\n @if (!parameter.multiple) {\n @if (parameter.type === 'text') {\n <input class=\"pr-8\" type=\"text\" placeholder=\"Enter {{parameter.title}}\"\n [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n }\n @if (parameter.type === 'numeric') {\n <input class=\"pr-8\" type=\"number\" placeholder=\"Enter {{parameter.title}}\"\n [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n }\n @if (parameter.type === 'list') {\n <select class=\"pr-8 py-1.5 pl-1 self-center\" [(ngModel)]=\"parameter.value\"\n (change)=\"evaluateDataset(true)\" required autofocus>\n <option [value]=\"null\">-- Select Value --</option>\n @for (item of parameter.list; track item) {\n <option [value]=\"item.value\">{{ item.label }}\n </option>\n }\n </select>\n }\n @if (parameter.type === 'date' || parameter.type === 'datetime') {\n @if (!parameter._dateType) {\n <div class=\"flex items-center mr-8\">\n <button (click)=\"changeDateType($event, parameter, 'picker')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n Date Picker\n </button>\n <button (click)=\"changeDateType($event, parameter, 'period')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n Time Period\n </button>\n </div>\n }\n @if (parameter._dateType === 'picker') {\n <input [type]=\"parameter.type === 'date' ? 'date' : 'datetime-local'\"\n placeholder=\"Enter {{parameter.title}}\" [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n <a (click)=\"changeDateType($event, parameter, 'period')\"\n matTooltip=\"Time Period\"\n class=\"mr-10 text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n </a>\n }\n @if (parameter._dateType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-16 mr-2\" min=\"0\" [value]=\"parameter._periodValue\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n <select class=\"param-period-picker mr-2\" [value]=\"parameter._period || 'DAYS'\"\n #period\n (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div>Ago</div>\n </div>\n <a (click)=\"changeDateType($event, parameter, 'picker')\"\n matTooltip=\"Date Picker\"\n class=\"mr-10 text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n </a>\n }\n }\n @if (parameter.type === 'boolean') {\n <mat-slide-toggle class=\"pr-8\" color=\"primary\"\n [checked]=\"parameter.value\" (change)=\"booleanUpdate($event, parameter)\"\n required></mat-slide-toggle>\n }\n }\n @if (parameter.multiple) {\n <mat-chip-grid class=\"pl-2\" #chipGrid aria-label=\"Enter values\">\n @for (paramValue of parameter.value; track paramValue) {\n <mat-chip-row\n class=\"bg-white mr-2\"\n (removed)=\"removeParameterValue(parameter, paramValue)\">\n {{paramValue}}\n <button matChipRemove [attr.aria-label]=\"'remove ' + paramValue\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n @if (parameter.type === 'text') {\n <input class=\"pr-8 py-1 self-center\" type=\"text\" placeholder=\"Enter {{parameter.title}}\"\n required autofocus\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addParameterValue(parameter, $event)\">\n }\n @if (parameter.type === 'numeric') {\n <input class=\"pr-8\" type=\"number\" placeholder=\"Enter {{parameter.title}}\"\n required autofocus\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addParameterValue(parameter, $event)\">\n }\n @if (parameter.type === 'list') {\n <select class=\"pr-8 py-1.5 pl-1 self-center\" matNativeControl\n (change)=\"addParameterValue(parameter, $event)\" required autofocus>\n <option [value]=\"null\">-- Select Value --</option>\n @for (item of parameter.list; track item) {\n <option [value]=\"item.value\">{{ item.label }}\n </option>\n }\n </select>\n }\n </mat-chip-grid>\n }\n @if (!parameter._locked) {\n <button mat-icon-button [matMenuTriggerFor]=\"paramMenu\">\n <mat-icon>settings</mat-icon>\n </button>\n <mat-menu #paramMenu=\"matMenu\">\n <button mat-menu-item (click)=\"addParameter(parameter, i)\">Edit Parameter</button>\n <button mat-menu-item (click)=\"removeParameter(parameter)\">Remove Parameter</button>\n </mat-menu>\n }\n @if (Object.keys(dashboardParameters || {}).length) {\n <button mat-icon-button [matMenuTriggerFor]=\"dashParamMenu\"\n title=\"Bind this parameter value to another\">\n <mat-icon>text_fields</mat-icon>\n </button>\n <mat-menu #dashParamMenu=\"matMenu\">\n @for (dashParamKey of Object.keys(dashboardParameters); track dashParamKey) {\n <button mat-menu-item\n (click)=\"setDashboardParameter(parameter, dashboardParameters[dashParamKey].name)\">{{ dashboardParameters[dashParamKey].title }}\n </button>\n }\n </mat-menu>\n }\n </div>\n }\n </label>\n @if (parameterValues.length) {\n <div class=\"divider ml-2\"></div>\n }\n }\n <button mat-icon-button color=\"primary\" class=\"mx-2\" (click)=\"addParameter()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n @if (parameterValues.length) {\n <button type=\"button\" (click)=\"evaluateDataset(true)\"\n class=\"mr-2 flex items-center whitespace-nowrap justify-center px-4 py-1 border border-transparent text-sm rounded-md shadow-sm text-white bg-primary focus:outline-none\">\n Apply Parameters\n </button>\n }\n </div>\n </div>\n }\n</div>\n\n<div class=\"cell-header\">\n @if (terminatingTransformations.length) {\n <div class=\"transformation-listing py-2\">\n <div class=\"list-title\">\n Transformations\n </div>\n <div class=\"example-list flex flex-wrap\" cdkDropListGroup>\n @for (transformation of terminatingTransformations; track transformation; let i = $index) {\n @if (!transformation.hidden) {\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\" cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"{item:transformation,index:i}\">\n <div class=\"flex items-center\">\n <div class=\"new-transformation flex items-center justify-center w-6 h-6\">\n <a [matMenuTriggerFor]=\"addTransformation\"\n class=\"items-center add-transformation text-primary\">\n <mat-icon class=\"flex items-center w-5 h-5 text-xl\">add_circle</mat-icon>\n </a>\n <mat-menu #addTransformation=\"matMenu\">\n <button mat-menu-item (click)=\"insertTransformation(i, 'columns', transformation)\">\n Insert Column Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'formula', transformation)\">\n Insert Formula Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'join', transformation)\">\n Insert Join Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'summarise', transformation)\">\n Insert Summarise Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'filter', transformation)\">\n Insert Filter Transformation\n </button>\n </mat-menu>\n </div>\n <div cdkDrag class=\"pl-0 example-box badge-item w-auto m-0\" cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [class]=\"{active: transformation._active, 'exclude bg-orange-50 border-orange-200': !!transformation.exclude, 'bg-indigo-50 border-indigo-200': (transformation.type === 'filter' && transformation.hide === false)}\">\n <button class=\"-mt-0.5\" title=\"Show transformation details\" mat-icon-button\n (click)=\"showTransformationDetail(transformation)\">\n @if (transformation.type === 'columns') {\n <span class=\"material-symbols-outlined ml-1 text-xl\"\n >table_chart</span>\n }\n @if (transformation.type === 'formula') {\n <span class=\"material-symbols-outlined text-xl\"\n >functions</span>\n }\n @if (transformation.type === 'join') {\n <span class=\"material-symbols-outlined text-xl\">merge_type</span>\n }\n @if (transformation.type === 'summarise') {\n <span class=\"material-symbols-outlined ml-1 text-xl\"\n >pivot_table_chart</span>\n }\n @if (transformation.type === 'filter') {\n <span class=\"material-symbols-outlined text-xl\"\n >filter_alt</span>\n }\n </button>\n <span class=\"whitespace-nowrap cursor-pointer\"\n (click)=\"editTerminatingTransformation(transformation)\">{{ transformation._label }}</span>\n @if (transformation.exclude) {\n <button class=\"-ml-1\" [title]=\"'Re-enable this transformation'\"\n mat-icon-button (click)=\"disableTransformation(transformation, i)\">\n <mat-icon class=\"text-orange-400\">replay</mat-icon>\n </button>\n }\n @if (!transformation.exclude && i + 1 === terminatingTransformations.length) {\n <button class=\"-ml-1\" [title]=\"'Disable transformation'\"\n mat-icon-button (click)=\"disableTransformation(transformation, i)\">\n <mat-icon>block</mat-icon>\n </button>\n }\n @if (!transformation.exclude && i + 1 !== terminatingTransformations.length) {\n <button class=\"-ml-1\" [matMenuTriggerFor]=\"disableMenu\"\n [title]=\"'Disable transformation'\"\n mat-icon-button>\n <mat-icon>block</mat-icon>\n </button>\n <mat-menu #disableMenu=\"matMenu\">\n <button mat-menu-item (click)=\"disableTransformation(transformation, i)\">\n Disable this transformation\n </button>\n <button mat-menu-item (click)=\"excludeUpstreamTransformations(transformation)\">\n Disable subsequent transformation(s)\n </button>\n </mat-menu>\n }\n <button class=\"-ml-1\" title=\"Remove this transformation\" mat-icon-button color=\"primary\"\n (click)=\"removeTransformation(transformation, true, null, transformation._active)\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"transformation._showDetail\">\n <div class=\"p-4 w-96 bg-white shadow rounded\">\n @if (transformation.type === 'summarise') {\n <p class=\"text-sm text-gray-700 mb-0\">\n <b>SELECT&nbsp;</b>@for (expression of transformation.config.expressions; track expression; let i = $index) {\n <span\n >@if (i > 0) {\n <span\n >, </span>\n }{{ expression.customExpression || expression.expressionType + '(' + (expression.fieldName || '') + ')' }}</span>\n }\n @if (transformation.config.summariseFieldNames.length) {\n <br><b>GROUP\n BY&nbsp;</b> {{ transformation.config.summariseFieldNames.join(', ') }}\n }\n </p>\n }\n @if (transformation.type === 'formula') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>EXPRESSION</b>&nbsp;{{ decodeURIComponent(transformation.config.expressions[0].expression) }}\n </div>\n }\n @if (transformation.type === 'columns') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>COLUMNS</b>&nbsp;{{ _.map(transformation.config.columns, 'title').join(', ') }}\n </div>\n }\n @if (transformation.type === 'join') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>JOIN\n COLUMNS</b>&nbsp;{{ _.map(transformation.config.joinColumns, 'title').join(', ') }}\n </div>\n }\n @if (transformation.type === 'filter') {\n @for (filter of transformation.config.filters; track filter) {\n <div\n class=\"text-sm text-gray-700 mb-0\">\n <b>FILTER</b>&nbsp;{{ filter.lhsExpression }}&nbsp;<b>{{ filter.filterType }}</b>&nbsp;{{ filter.rhsExpression }}\n </div>\n }\n }\n </div>\n </ng-template>\n </div>\n </div>\n }\n @if (_.some(terminatingTransformations, {exclude: true}) && i === terminatingTransformations.length - 1) {\n <button\n class=\"ml-4 flex items-center border-none bg-primary text-sm rounded-md text-white pr-2 pl-1 py-0.5\"\n (click)=\"enableAllTransformation()\">\n <mat-icon class=\"mr-1 text-base\">replay</mat-icon>\n Enable All\n </button>\n }\n }\n </div>\n</div>\n}\n</div>\n\n<div class=\"cell-header\">\n @if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length) {\n <div class=\"transformation-listing py-2 filters-list\"\n >\n <a class=\"list-title flex items-center\" (click)=\"showFilters = !showFilters\">\n Filters&nbsp;\n @if (!showFilters) {\n <mat-icon>expand_more</mat-icon>\n }\n @if (showFilters) {\n <mat-icon>expand_less</mat-icon>\n }\n </a>\n @for (filterTransformation of _.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}); track filterTransformation) {\n @if (_.every(filterTransformation.config.filters[0])) {\n <div class=\"badge-item pl-2 mr-1\"\n (click)=\"showFilters = !showFilters\">\n <span class=\"cursor-pointer\" [innerHtml]=\"getFilterString(filterTransformation.config)\"></span>\n </div>\n }\n }\n </div>\n }\n</div>\n\n@if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length\n && showFilters) {\n <div class=\"dataset-filters\" id=\"datasetFilters\"\n >\n @for (transformation of datasetInstanceSummary.transformationInstances; track transformation; let i = $index) {\n @if (transformation.type === 'filter' && transformation.hide === false) {\n <div class=\"dataset-filter border-b border-gray-200\">\n <button mat-stroked-button class=\"mr-2 bg-white remove-filter\" color=\"warn\"\n (click)=\"removeTransformation(transformation, true, i)\">\n Remove Filter\n </button>\n @if (filterFields.length) {\n <ki-dataset-filters [filterFields]=\"filterFields\"\n [openSide]=\"openSide\" [parameterValues]=\"filterParameterValues\"\n [filterJunction]=\"transformation.config\"></ki-dataset-filters>\n }\n @if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length) {\n <button\n mat-flat-button class=\"apply-filter mr-2\" color=\"primary\"\n (click)=\"applyFilters()\" [disabled]=\"!filterJunction.filters.length\">\n Apply Filters\n </button>\n }\n </div>\n }\n }\n </div>\n}\n\n<div class=\"cell-header\">\n @if (_.find(datasetInstanceSummary.transformationInstances, {type: 'multisort'})) {\n <div class=\"transformation-listing sort\"\n >\n <div class=\"list-title\">\n Sort\n </div>\n <div class=\"flex flex-wrap\">\n @for (sort of _.find(datasetInstanceSummary.transformationInstances, {type: 'multisort'}).config.sorts; track sort; let i = $index) {\n <div class=\"badge-item outline\"\n [class]=\"{'exclude bg-orange-50 border-orange-200': _.find(datasetInstanceSummary.transformationInstances, {exclude: true})}\"\n >\n <span>{{ _.startCase(sort.fieldName) }}&nbsp;<span class=\"uppercase\">{{ sort.direction }}</span></span>\n <button mat-icon-button (click)=\"removeFilter(i)\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<div class=\"h-full table-overflow overflow-scroll\">\n @if (displayedColumns.length) {\n <table mat-table [dataSource]=\"tableData\" matSort (matSortChange)=\"sort($event)\"\n class=\"block sticky\">\n @for (column of filterFields; track column) {\n <ng-container [matColumnDef]=\"column.name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header\n class=\"text-xs font-semibold text-gray-900 py-3.5 px-4\"> {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\" class=\"py-3 px-4\">\n @if (!Array.isArray(element[column.name]) && !_.isPlainObject(element[column.name])) {\n @if (element[column.name] && String(element[column.name]).length <= 100) {\n <div [innerHTML]=\"element[column.name]\"></div>\n }\n @if (element[column.name] && String(element[column.name]).length > 100) {\n <div>{{ element[column.name].substring(0, 100) + '...' }}</div>\n <a (click)=\"viewFullItemData(element[column.name], column.name)\"\n class=\"flex items-center text-sm text-cta\">\n view more\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\n </svg>\n </a>\n }\n @if (!element[column.name]) {\n @if (element[column.name] === null) {\n <span class=\"font-mono text-gray-400\">null</span>\n }\n @if (element[column.name] !== null) {\n <span>{{ element[column.name] }}</span>\n }\n }\n }\n @if (Array.isArray(element[column.name])) {\n Contains {{ element[column.name].length }} items\n }\n @if (_.isPlainObject(element[column.name])) {\n <span [innerHTML]=\"toJSON(element[column.name])\"></span>\n }\n </td>\n </ng-container>\n }\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\" class=\"h-auto\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n }\n</div>\n\n\n<div class=\"border-b border-t bg-gray-50 px-4 py-1 flex align-center justify-end\">\n\n <div class=\"flex items-center\">\n <div class=\"text-sm text-gray-500 mr-10\">\n @if (dataset) {\n Showing {{ offset + 1 }} - {{ (page * limit) - (limit - tableData.length) }}\n }\n </div>\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-1.5\">\n <option [value]=\"1\">1</option>\n <option [value]=\"5\">5</option>\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;position:relative;height:100%}:host>div{flex:0 1 auto}.divider{width:1px;height:17px;background-color:#cecece}.new-transformation .add-transformation{display:none}.new-transformation:hover .add-transformation{display:flex}.long-running{position:fixed;inset:0;background-color:#ffffffb3;z-index:99999;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.long-running .loading-box{position:relative;margin-bottom:2rem}.long-running .loading-box div{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:1.2rem;font-weight:500}.long-running p{font-size:1.1rem}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.cell-header.sorting{min-height:43px}.dataset-data-actions{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;margin-top:-1px}.dataset-data-actions button{min-width:50px;padding:0 13px;color:#505050}.dataset-data-actions .divider{margin:0 .5rem;width:1px;height:36px;background-color:#ddd}.parameter-listing label{flex-direction:row;align-items:center}.parameter-listing label .parameter-input{border-radius:4px;padding-left:.5rem;height:36px;display:flex;align-items:center}.parameter-listing label .parameter-input .param-period-picker{padding:5px}.parameter-listing label .parameter-input button{color:#8e8e8e}.parameter-listing label .parameter-input button.edit-parameter{visibility:hidden}.parameter-listing label .parameter-input button.mat-icon-button{width:30px;height:30px;line-height:30px;align-self:center}.parameter-listing label .parameter-input button.mat-icon-button mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.parameter-listing label .parameter-input input{font-size:.9rem;padding:.25rem .45rem;width:175px}.parameter-listing label .parameter-input:hover .edit-parameter{visibility:visible}.transformation-listing{display:flex;align-items:center;width:100%;background-color:#00000012;border-bottom:1px solid #ddd;min-height:47px}.transformation-listing .list-title{text-transform:uppercase;font-size:.75rem;padding:0 1rem;border-right:2px solid #ddd;color:#4c4c4c;font-weight:500;letter-spacing:1px}.transformation-listing .badge-item{display:flex;align-items:center;margin-left:1rem;padding-left:1rem;border-radius:20px;background-color:#fff;border:1px solid #ddd;height:30px}.transformation-listing .badge-item.exclude{opacity:.8}.transformation-listing .badge-item:hover{background-color:#fcfcfc}.transformation-listing .badge-item span{margin-right:.5rem;color:#0000008a}.transformation-listing .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.transformation-listing .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}.dataset-filters{position:relative;overflow-y:scroll;flex:none!important;max-height:400px}.dataset-filters .dataset-filter{position:relative}.dataset-filters .dataset-filter .apply-filter{position:absolute;bottom:.5rem;right:0;z-index:10}.dataset-filters .dataset-filter .remove-filter{position:absolute;top:.5rem;right:0;z-index:10}.badge-holder{display:flex;align-items:center;margin:.25rem 0}.badge-holder .badge-item{display:flex;align-items:center;padding-left:1rem;border-radius:20px}.badge-holder .badge-item.outline{background-color:#fff;border:1px solid #efefef}.badge-holder .badge-item span{margin-right:.5rem;color:#0000008a}.badge-holder .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.badge-holder .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}table{position:relative;border-collapse:collapse}table.sticky th{position:sticky;top:0;background-color:#f5f5f5;border-top:none!important;border-bottom:none!important;box-shadow:inset 0 -1px #ddd}table th.settings{padding:0}table td{max-width:400px;word-wrap:break-word;padding-top:.5rem;padding-bottom:.5rem;padding-right:1rem;min-width:150px;width:1%}table td.settings{max-width:25px;min-width:25px}table::-webkit-scrollbar{width:.75em;background:transparent}table::-webkit-scrollbar-thumb{background:#d2d2d2}table tbody:nth-of-type(1) tr:nth-of-type(1) td{border-top:none!important}table thead th{border-top:none!important;border-bottom:none!important;box-shadow:inset 0 2px #000,inset 0 -2px #000;padding:2px 0}table thead th{background-clip:padding-box}.table-overflow::-webkit-scrollbar{width:.75em;background:transparent}.table-overflow::-webkit-scrollbar-thumb{background:#d2d2d2}.paging-toolbar{position:sticky;bottom:-20px;left:0;background-color:#fff;right:0;padding:1rem}table{text-align:left;position:relative;border-collapse:collapse}th,td{padding:.25rem}\n"] }]
3578
+ args: [{ selector: 'ki-dataset-editor', standalone: false, template: "@if (longRunning) {\n <div class=\"long-running flex-col\">\n <div class=\"loading-box\">\n <mat-spinner [diameter]=\"150\"></mat-spinner>\n <div>Loading</div>\n </div>\n <p class=\"text-center\">Please wait while we process this query.</p>\n <p class=\"text-center\">The results will be shown here once it has finished running.</p>\n <div>\n <a class=\"text-primary hover:underline\" (click)=\"cancelEvaluate()\">Cancel query and return to editor.</a>\n </div>\n </div>\n}\n<div class=\"pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10 -z-10\" id=\"sidebarWrapper\">\n <div [class]=\"{'translate-x-0': sideOpen, 'translate-x-full': !sideOpen}\"\n (click)=\"$event.stopPropagation()\"\n class=\"pointer-events-auto w-screen max-w-md transform transition ease-in-out duration-500 sm:duration-700\"\n id=\"docSidebar\">\n <div class=\"flex h-full flex-col overflow-y-scroll bg-white py-6 shadow-xl\">\n <div class=\"px-4 sm:px-6\">\n <div class=\"flex items-start justify-between\">\n <div></div>\n\n <div class=\"ml-3 flex h-7 items-center\">\n <button type=\"button\" (click)=\"openSide.next(false)\"\n class=\"rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none\">\n <span class=\"sr-only\">Close panel</span>\n <!-- Heroicon name: outline/x -->\n <svg class=\"h-6 w-6\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n </button>\n </div>\n </div>\n </div>\n <div class=\"relative flex-1 px-4 sm:px-6\">\n <ki-whitelisted-sql-functions [fields]=\"filterFields\"></ki-whitelisted-sql-functions>\n </div>\n </div>\n </div>\n</div>\n\n@if (!datasetEditorNoTools) {\n <div class=\"border-b cell-header end\">\n <div class=\"leading-5 px-4 text-xs uppercase tracking-wider font-medium border-r-2 text-gray-600\">\n Operations\n </div>\n <div class=\"dataset-data-actions\">\n <button (click)=\"addFilter()\"\n title=\"Filter the set using column based restrictions\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">filter_alt</span>\n filter\n </button>\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"summariseData()\"\n title=\"Summarise this data to produce aggregated totals, sums and other derivations\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">pivot_table_chart</span>\n summarise\n </button>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"joinData()\"\n title=\"Join another data set to the current dataset\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">merge_type</span>\n join\n </button>\n }\n <div class=\"divider\"></div>\n <button (click)=\"createFormula()\"\n title=\"Create a formula column using an expression based on other columns\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">functions</span>\n formula\n </button>\n <button (click)=\"editColumnSettings()\"\n title=\"Switch on and off columns for display\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">table_chart</span>\n columns\n </button>\n @if (!datasetEditorSimpleMode) {\n <div class=\"divider\"></div>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"addParameter()\"\n title=\"Add a parameter to use in filters, expressions etc.\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">text_fields</span>\n parameters\n </button>\n }\n @if (!datasetEditorSimpleMode) {\n <button (click)=\"addPagingMarker()\"\n title=\"Insert paging marker to limit results at this stage in the query flow\"\n class=\"w-24 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">skip_next</span>\n paging marker\n </button>\n }\n <div class=\"divider\"></div>\n <button (click)=\"evaluateDataset()\"\n title=\"Reload this query based upon changes you may have made\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">sync</span>\n reload\n </button>\n @if (!datasetEditorReadonly) {\n <button [disabled]=\"!datasetInstanceSummary || !datasetInstanceSummary.id\" (click)=\"shareQuery()\"\n title=\"Share this query with other account holders\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">share</span>\n share\n </button>\n <button (click)=\"saveAsQuery()\"\n title=\"Make a copy of this query\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">file_copy</span>\n copy query\n </button>\n @if (!dashboardLayoutSettings && datasetInstanceSummary.id) {\n <button (click)=\"save()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <span class=\"material-symbols-outlined text-xl\">save</span>\n save\n </button>\n }\n }\n </div>\n </div>\n}\n\n<div class=\"cell-header\">\n @if (showParameters || parameterValues.length) {\n <div class=\"transformation-listing parameter-listing\">\n <div class=\"list-title\">\n Parameters\n </div>\n <div class=\"flex items-center flex-wrap\">\n @for (parameter of parameterValues; track parameter; let i = $index) {\n <label class=\"pl-4\">\n {{ parameter.title }}\n @if ((parameter.value || '').toString().includes('}}')) {\n <div>\n <mat-chip class=\"bg-gray-50 ml-2\" title=\"Using parameter value from {{parameter.value}}\">\n <div class=\"flex items-center\">\n <span class=\"material-symbols-outlined text-xl mr-1 text-gray-500\">layers</span>\n @if (dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')]) {\n <span\n [innerHTML]=\"dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')].value\"></span>\n }\n @if (!dashboardParameters[parameter.value.replace('{{', '').replace('}}', '')]) {\n <span\n class=\"font-medium text-orange-600\">\n Parameter Not Found !\n </span>\n }\n </div>\n <button matChipRemove (click)=\"parameter.value = ''\" title=\"\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip>\n </div>\n }\n @if (!(parameter.value || '').toString().includes('}}')) {\n <div class=\"parameter-input\">\n @if (!parameter.multiple) {\n @if (parameter.type === 'text') {\n <input class=\"pr-8 py-1.5\" type=\"text\" placeholder=\"Enter {{parameter.title}}\"\n [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n }\n @if (parameter.type === 'numeric') {\n <input class=\"pr-8 py-1.5\" type=\"number\" placeholder=\"Enter {{parameter.title}}\"\n [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n }\n @if (parameter.type === 'list') {\n <select class=\"pr-8 py-1.5 pl-1 self-center\" [(ngModel)]=\"parameter.value\"\n (change)=\"evaluateDataset(true)\" required autofocus>\n <option [value]=\"null\">-- Select Value --</option>\n @for (item of parameter.list; track item) {\n <option [value]=\"item.value\">{{ item.label }}\n </option>\n }\n </select>\n }\n @if (parameter.type === 'date' || parameter.type === 'datetime') {\n @if (!parameter._dateType) {\n <div class=\"flex items-center mr-8\">\n <button (click)=\"changeDateType($event, parameter, 'picker')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n Date Picker\n </button>\n <button (click)=\"changeDateType($event, parameter, 'period')\"\n class=\"hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-2 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n Time Period\n </button>\n </div>\n }\n @if (parameter._dateType === 'picker') {\n <input [type]=\"parameter.type === 'date' ? 'date' : 'datetime-local'\"\n class=\" py-1.5\"\n placeholder=\"Enter {{parameter.title}}\" [(ngModel)]=\"parameter.value\"\n (keyup.enter)=\"evaluateDataset(true)\" required autofocus>\n <a (click)=\"changeDateType($event, parameter, 'period')\"\n matTooltip=\"Time Period\"\n class=\"mr-10 text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">restore</mat-icon>\n </a>\n }\n @if (parameter._dateType === 'period') {\n <div class=\"flex items-center\">\n <input #periodValue type=\"number\" placeholder=\"No.\" required autofocus\n class=\"w-16 mr-2 py-1.5\" min=\"0\" [value]=\"parameter._periodValue\"\n (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n <select class=\"param-period-picker mr-2\" [value]=\"parameter._period || 'DAYS'\"\n #period\n (change)=\"updatePeriodValue(periodValue.value, period.value, parameter)\">\n <option value=\"DAYS\">Days</option>\n <option value=\"HOURS\">Hours</option>\n </select>\n <div>Ago</div>\n </div>\n <a (click)=\"changeDateType($event, parameter, 'picker')\"\n matTooltip=\"Date Picker\"\n class=\"mr-10 text-center ml-2 hover:bg-gray-50 text-gray-800 border border-gray-300 py-0.5 pr-0.5 rounded mr-2 bg-white flex items-center\">\n <mat-icon class=\"text-base\">calendar_month</mat-icon>\n </a>\n }\n }\n @if (parameter.type === 'boolean') {\n <mat-slide-toggle class=\"pr-8\" color=\"primary\"\n [checked]=\"parameter.value\" (change)=\"booleanUpdate($event, parameter)\"\n required></mat-slide-toggle>\n }\n }\n @if (parameter.multiple) {\n <mat-chip-grid class=\"pl-2\" #chipGrid aria-label=\"Enter values\">\n @for (paramValue of parameter.value; track paramValue) {\n <mat-chip-row\n class=\"bg-white mr-2\"\n (removed)=\"removeParameterValue(parameter, paramValue)\">\n {{paramValue}}\n <button matChipRemove [attr.aria-label]=\"'remove ' + paramValue\">\n <mat-icon>cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n @if (parameter.type === 'text') {\n <input class=\"pr-8 py-1.5 self-center\" type=\"text\" placeholder=\"Enter {{parameter.title}}\"\n required autofocus\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addParameterValue(parameter, $event)\">\n }\n @if (parameter.type === 'numeric') {\n <input class=\"pr-8 py-1.5\" type=\"number\" placeholder=\"Enter {{parameter.title}}\"\n required autofocus\n [matChipInputFor]=\"chipGrid\"\n [matChipInputSeparatorKeyCodes]=\"[ENTER, COMMA]\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addParameterValue(parameter, $event)\">\n }\n @if (parameter.type === 'list') {\n <select class=\"pr-8 py-1.5 pl-1 self-center\" matNativeControl\n (change)=\"addParameterValue(parameter, $event)\" required autofocus>\n <option [value]=\"null\">-- Select Value --</option>\n @for (item of parameter.list; track item) {\n <option [value]=\"item.value\">{{ item.label }}\n </option>\n }\n </select>\n }\n </mat-chip-grid>\n }\n @if (!parameter._locked) {\n <button mat-icon-button [matMenuTriggerFor]=\"paramMenu\">\n <mat-icon>settings</mat-icon>\n </button>\n <mat-menu #paramMenu=\"matMenu\">\n <button mat-menu-item (click)=\"addParameter(parameter, i)\">Edit Parameter</button>\n <button mat-menu-item (click)=\"removeParameter(parameter)\">Remove Parameter</button>\n </mat-menu>\n }\n @if (Object.keys(dashboardParameters || {}).length) {\n <button mat-icon-button [matMenuTriggerFor]=\"dashParamMenu\"\n title=\"Bind this parameter value to another\">\n <mat-icon>text_fields</mat-icon>\n </button>\n <mat-menu #dashParamMenu=\"matMenu\">\n @for (dashParamKey of Object.keys(dashboardParameters); track dashParamKey) {\n <button mat-menu-item\n (click)=\"setDashboardParameter(parameter, dashboardParameters[dashParamKey].name)\">{{ dashboardParameters[dashParamKey].title }}\n </button>\n }\n </mat-menu>\n }\n </div>\n }\n </label>\n @if (parameterValues.length) {\n <div class=\"divider ml-2\"></div>\n }\n }\n <button mat-icon-button color=\"primary\" class=\"mx-2\" (click)=\"addParameter()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n @if (parameterValues.length) {\n <button type=\"button\" (click)=\"evaluateDataset(true)\"\n class=\"mr-2 flex items-center whitespace-nowrap justify-center px-4 py-1 border border-transparent text-sm rounded-md shadow-sm text-white bg-primary focus:outline-none\">\n Apply Parameters\n </button>\n }\n </div>\n </div>\n }\n</div>\n\n<div class=\"cell-header\">\n @if (terminatingTransformations.length) {\n <div class=\"transformation-listing py-2\">\n <div class=\"list-title\">\n Transformations\n </div>\n <div class=\"example-list flex flex-wrap\" cdkDropListGroup>\n @for (transformation of terminatingTransformations; track transformation; let i = $index) {\n @if (!transformation.hidden) {\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\" cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"{item:transformation,index:i}\">\n <div class=\"flex items-center\">\n <div class=\"new-transformation flex items-center justify-center w-6 h-6\">\n <a [matMenuTriggerFor]=\"addTransformation\"\n class=\"items-center add-transformation text-primary\">\n <mat-icon class=\"flex items-center w-5 h-5 text-xl\">add_circle</mat-icon>\n </a>\n <mat-menu #addTransformation=\"matMenu\">\n <button mat-menu-item (click)=\"insertTransformation(i, 'columns', transformation)\">\n Insert Column Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'formula', transformation)\">\n Insert Formula Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'join', transformation)\">\n Insert Join Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'summarise', transformation)\">\n Insert Summarise Transformation\n </button>\n <button mat-menu-item (click)=\"insertTransformation(i, 'filter', transformation)\">\n Insert Filter Transformation\n </button>\n </mat-menu>\n </div>\n <div cdkDrag class=\"pl-0 example-box badge-item w-auto m-0\" cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [class.active]=\"transformation._active\"\n [class.exclude]=\"!!transformation.exclude\"\n [class.bg-orange-50]=\"!!transformation.exclude\"\n [class.border-orange-200]=\"!!transformation.exclude\"\n [class.bg-indigo-50]=\"(transformation.type === 'filter' && transformation.hide === false)\"\n [class.border-indigo-200]=\"(transformation.type === 'filter' && transformation.hide === false)\">\n <button class=\"-mt-0.5\" title=\"Show transformation details\" mat-icon-button\n (click)=\"showTransformationDetail(transformation)\">\n @if (transformation.type === 'columns') {\n <span class=\"material-symbols-outlined ml-1 text-xl\"\n >table_chart</span>\n }\n @if (transformation.type === 'formula') {\n <span class=\"material-symbols-outlined text-xl\"\n >functions</span>\n }\n @if (transformation.type === 'join') {\n <span class=\"material-symbols-outlined text-xl\">merge_type</span>\n }\n @if (transformation.type === 'summarise') {\n <span class=\"material-symbols-outlined ml-1 text-xl\"\n >pivot_table_chart</span>\n }\n @if (transformation.type === 'filter') {\n <span class=\"material-symbols-outlined text-xl\"\n >filter_alt</span>\n }\n </button>\n <span class=\"whitespace-nowrap cursor-pointer\"\n (click)=\"editTerminatingTransformation(transformation)\">{{ transformation._label }}</span>\n @if (transformation.exclude) {\n <button class=\"-ml-1\" [title]=\"'Re-enable this transformation'\"\n mat-icon-button (click)=\"disableTransformation(transformation, i)\">\n <mat-icon class=\"text-xl leading-6 text-orange-400\">replay</mat-icon>\n </button>\n }\n @if (!transformation.exclude && i + 1 === terminatingTransformations.length) {\n <button class=\"-ml-1\" [title]=\"'Disable transformation'\"\n mat-icon-button (click)=\"disableTransformation(transformation, i)\">\n <mat-icon class=\"text-xl leading-6\">block</mat-icon>\n </button>\n }\n @if (!transformation.exclude && i + 1 !== terminatingTransformations.length) {\n <button class=\"-ml-1\" [matMenuTriggerFor]=\"disableMenu\"\n [title]=\"'Disable transformation'\"\n mat-icon-button>\n <mat-icon class=\"text-xl leading-6\">block</mat-icon>\n </button>\n <mat-menu #disableMenu=\"matMenu\">\n <button mat-menu-item (click)=\"disableTransformation(transformation, i)\">\n Disable this transformation\n </button>\n <button mat-menu-item (click)=\"excludeUpstreamTransformations(transformation)\">\n Disable subsequent transformation(s)\n </button>\n </mat-menu>\n }\n <button class=\"-ml-1\" title=\"Remove this transformation\" mat-icon-button color=\"primary\"\n (click)=\"removeTransformation(transformation, true, null, transformation._active)\">\n <mat-icon class=\"text-xl leading-6\">cancel</mat-icon>\n </button>\n </div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"transformation._showDetail\">\n <div class=\"p-4 w-96 bg-white shadow rounded\">\n @if (transformation.type === 'summarise') {\n <p class=\"text-sm text-gray-700 mb-0\">\n <b>SELECT&nbsp;</b>@for (expression of transformation.config.expressions; track expression; let i = $index) {\n <span\n >@if (i > 0) {\n <span\n >, </span>\n }{{ expression.customExpression || expression.expressionType + '(' + (expression.fieldName || '') + ')' }}</span>\n }\n @if (transformation.config.summariseFieldNames.length) {\n <br><b>GROUP\n BY&nbsp;</b> {{ transformation.config.summariseFieldNames.join(', ') }}\n }\n </p>\n }\n @if (transformation.type === 'formula') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>EXPRESSION</b>&nbsp;{{ decodeURIComponent(transformation.config.expressions[0].expression) }}\n </div>\n }\n @if (transformation.type === 'columns') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>COLUMNS</b>&nbsp;{{ _.map(transformation.config.columns, 'title').join(', ') }}\n </div>\n }\n @if (transformation.type === 'join') {\n <div class=\"text-sm text-gray-700 mb-0\">\n <b>JOIN\n COLUMNS</b>&nbsp;{{ _.map(transformation.config.joinColumns, 'title').join(', ') }}\n </div>\n }\n @if (transformation.type === 'filter') {\n @for (filter of transformation.config.filters; track filter) {\n <div\n class=\"text-sm text-gray-700 mb-0\">\n <b>FILTER</b>&nbsp;{{ filter.lhsExpression }}&nbsp;<b>{{ filter.filterType }}</b>&nbsp;{{ filter.rhsExpression }}\n </div>\n }\n }\n </div>\n </ng-template>\n </div>\n </div>\n }\n @if (_.some(terminatingTransformations, {exclude: true}) && i === terminatingTransformations.length - 1) {\n <button\n class=\"ml-4 flex items-center border-none bg-primary text-sm rounded-md text-white pr-2 pl-1 py-0.5\"\n (click)=\"enableAllTransformation()\">\n <mat-icon class=\"mr-1 text-base\">replay</mat-icon>\n Enable All\n </button>\n }\n }\n </div>\n</div>\n}\n</div>\n\n<div class=\"cell-header\">\n @if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length) {\n <div class=\"transformation-listing py-2 filters-list\"\n >\n <a class=\"list-title flex items-center\" (click)=\"showFilters = !showFilters\">\n Filters&nbsp;\n @if (!showFilters) {\n <mat-icon>expand_more</mat-icon>\n }\n @if (showFilters) {\n <mat-icon>expand_less</mat-icon>\n }\n </a>\n @for (filterTransformation of _.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}); track filterTransformation) {\n @if (_.every(filterTransformation.config.filters[0])) {\n <div class=\"badge-item pl-2 mr-1\"\n (click)=\"showFilters = !showFilters\">\n <span class=\"cursor-pointer\" [innerHtml]=\"getFilterString(filterTransformation.config)\"></span>\n </div>\n }\n }\n </div>\n }\n</div>\n\n@if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length\n && showFilters) {\n <div class=\"dataset-filters\" id=\"datasetFilters\"\n >\n @for (transformation of datasetInstanceSummary.transformationInstances; track transformation; let i = $index) {\n @if (transformation.type === 'filter' && transformation.hide === false) {\n <div class=\"dataset-filter border-b border-gray-200\">\n <button mat-stroked-button class=\"mr-2 bg-white remove-filter\" color=\"warn\"\n (click)=\"removeTransformation(transformation, true, i)\">\n Remove Filter\n </button>\n @if (filterFields.length) {\n <ki-dataset-filters [filterFields]=\"filterFields\"\n [openSide]=\"openSide\" [parameterValues]=\"filterParameterValues\"\n [filterJunction]=\"transformation.config\"></ki-dataset-filters>\n }\n @if (_.filter(datasetInstanceSummary.transformationInstances, {type: 'filter', hide: false}).length) {\n <button\n mat-flat-button class=\"apply-filter mr-2\" color=\"primary\"\n (click)=\"applyFilters()\" [disabled]=\"!filterJunction.filters.length\">\n Apply Filters\n </button>\n }\n </div>\n }\n }\n </div>\n}\n\n<div class=\"cell-header\">\n @if (_.find(datasetInstanceSummary.transformationInstances, {type: 'multisort'})) {\n <div class=\"transformation-listing sort\"\n >\n <div class=\"list-title\">\n Sort\n </div>\n <div class=\"flex flex-wrap\">\n @for (sort of _.find(datasetInstanceSummary.transformationInstances, {type: 'multisort'}).config.sorts; track sort; let i = $index) {\n <div class=\"badge-item outline\"\n [class]=\"{'exclude bg-orange-50 border-orange-200': _.find(datasetInstanceSummary.transformationInstances, {exclude: true})}\"\n >\n <span>{{ _.startCase(sort.fieldName) }}&nbsp;<span class=\"uppercase\">{{ sort.direction }}</span></span>\n <button mat-icon-button (click)=\"removeFilter(i)\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<div class=\"h-full table-overflow overflow-scroll\">\n @if (displayedColumns.length) {\n <table mat-table [dataSource]=\"tableData\" matSort (matSortChange)=\"sort($event)\"\n class=\"block sticky\">\n @for (column of filterFields; track column) {\n <ng-container [matColumnDef]=\"column.name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header\n class=\"text-xs font-semibold text-gray-900 py-3.5 px-4\"> {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\" class=\"py-3 px-4\">\n @if (!Array.isArray(element[column.name]) && !_.isPlainObject(element[column.name])) {\n @if (element[column.name] && String(element[column.name]).length <= 100) {\n <div [innerHTML]=\"element[column.name]\"></div>\n }\n @if (element[column.name] && String(element[column.name]).length > 100) {\n <div>{{ element[column.name].substring(0, 100) + '...' }}</div>\n <a (click)=\"viewFullItemData(element[column.name], column.name)\"\n class=\"flex items-center text-sm text-cta\">\n view more\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\n </svg>\n </a>\n }\n @if (!element[column.name]) {\n @if (element[column.name] === null) {\n <span class=\"font-mono text-gray-400\">null</span>\n }\n @if (element[column.name] !== null) {\n <span>{{ element[column.name] }}</span>\n }\n }\n }\n @if (Array.isArray(element[column.name])) {\n Contains {{ element[column.name].length }} items\n }\n @if (_.isPlainObject(element[column.name])) {\n <span class=\"text-xs font-mono\" [innerHTML]=\"toJSON(element[column.name])\"></span>\n }\n </td>\n </ng-container>\n }\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\" class=\"h-auto\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n }\n</div>\n\n\n<div class=\"border-b border-t bg-gray-50 px-4 py-1 flex align-center justify-end\">\n\n <div class=\"flex items-center\">\n <div class=\"text-sm text-gray-500 mr-10\">\n @if (dataset) {\n Showing {{ offset + 1 }} - {{ (page * limit) - (limit - tableData.length) }}\n }\n </div>\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-1.5\">\n <option [value]=\"1\">1</option>\n <option [value]=\"5\">5</option>\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;position:relative;height:100%}:host>div{flex:0 1 auto}.divider{width:1px;height:17px;background-color:#cecece}.new-transformation .add-transformation{display:none}.new-transformation:hover .add-transformation{display:flex}.long-running{position:fixed;inset:0;background-color:#ffffffb3;z-index:99999;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.long-running .loading-box{position:relative;margin-bottom:2rem}.long-running .loading-box div{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:1.2rem;font-weight:500}.long-running p{font-size:1.1rem}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.cell-header.sorting{min-height:43px}.dataset-data-actions{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;margin-top:-1px}.dataset-data-actions button{min-width:50px;padding:0 13px;color:#505050}.dataset-data-actions .divider{margin:0 .5rem;width:1px;height:36px;background-color:#ddd}.parameter-listing label{flex-direction:row;align-items:center}.parameter-listing label .parameter-input{border-radius:4px;padding-left:.5rem;height:36px;display:flex;align-items:center}.parameter-listing label .parameter-input .param-period-picker{padding:5px}.parameter-listing label .parameter-input button{color:#8e8e8e}.parameter-listing label .parameter-input button.edit-parameter{visibility:hidden}.parameter-listing label .parameter-input button.mat-icon-button{width:30px;height:30px;line-height:30px;align-self:center}.parameter-listing label .parameter-input button.mat-icon-button mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.parameter-listing label .parameter-input input{font-size:.9rem;padding:.25rem .45rem;width:175px}.parameter-listing label .parameter-input:hover .edit-parameter{visibility:visible}.transformation-listing{display:flex;align-items:center;width:100%;background-color:#00000012;border-bottom:1px solid #ddd;min-height:47px}.transformation-listing .list-title{text-transform:uppercase;font-size:.75rem;padding:0 1rem;border-right:2px solid #ddd;color:#4c4c4c;font-weight:500;letter-spacing:1px}.transformation-listing .badge-item{display:flex;align-items:center;margin-left:1rem;padding-left:1rem;border-radius:20px;background-color:#fff;border:1px solid #ddd;height:30px}.transformation-listing .badge-item.exclude{opacity:.8}.transformation-listing .badge-item:hover{background-color:#fcfcfc}.transformation-listing .badge-item span{margin-right:.5rem;color:#0000008a}.transformation-listing .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.transformation-listing .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}.dataset-filters{position:relative;overflow-y:scroll;flex:none!important;max-height:400px}.dataset-filters .dataset-filter{position:relative}.dataset-filters .dataset-filter .apply-filter{position:absolute;bottom:.5rem;right:0;z-index:10}.dataset-filters .dataset-filter .remove-filter{position:absolute;top:.5rem;right:0;z-index:10}.badge-holder{display:flex;align-items:center;margin:.25rem 0}.badge-holder .badge-item{display:flex;align-items:center;padding-left:1rem;border-radius:20px}.badge-holder .badge-item.outline{background-color:#fff;border:1px solid #efefef}.badge-holder .badge-item span{margin-right:.5rem;color:#0000008a}.badge-holder .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.badge-holder .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}table{position:relative;border-collapse:collapse}table.sticky th{position:sticky;top:0;background-color:#f5f5f5;border-top:none!important;border-bottom:none!important;box-shadow:inset 0 -1px #ddd}table th.settings{padding:0}table td{max-width:400px;word-wrap:break-word;padding-top:.5rem;padding-bottom:.5rem;padding-right:1rem;min-width:150px;width:1%}table td.settings{max-width:25px;min-width:25px}table::-webkit-scrollbar{width:.75em;background:transparent}table::-webkit-scrollbar-thumb{background:#d2d2d2}table tbody:nth-of-type(1) tr:nth-of-type(1) td{border-top:none!important}table thead th{border-top:none!important;border-bottom:none!important;box-shadow:inset 0 2px #000,inset 0 -2px #000;padding:2px 0}table thead th{background-clip:padding-box}.table-overflow::-webkit-scrollbar{width:.75em;background:transparent}.table-overflow::-webkit-scrollbar-thumb{background:#d2d2d2}.paging-toolbar{position:sticky;bottom:-20px;left:0;background-color:#fff;right:0;padding:1rem}table{text-align:left;position:relative;border-collapse:collapse}th,td{padding:.25rem}\n"] }]
3579
3579
  }], ctorParameters: () => [{ type: i1$1.MatDialogRef }, { type: undefined, decorators: [{
3580
3580
  type: Inject,
3581
3581
  args: [MAT_DIALOG_DATA]
@@ -6562,6 +6562,9 @@ class TaskTimePeriodsComponent {
6562
6562
  this.showNewTaskTimePeriod = true;
6563
6563
  }
6564
6564
  addTimePeriod() {
6565
+ if (!this.taskTimePeriods) {
6566
+ this.taskTimePeriods = [];
6567
+ }
6565
6568
  this.taskTimePeriods.push(this.newTaskTimePeriod);
6566
6569
  this.showNewTaskTimePeriod = false;
6567
6570
  this.newTaskTimePeriod = {};
@@ -6638,6 +6641,9 @@ class SnapshotProfileDialogComponent {
6638
6641
  readChunkSize: 50000
6639
6642
  }
6640
6643
  };
6644
+ if (!this.snapshot.config.taskTimePeriods) {
6645
+ this.snapshot.config.taskTimePeriods = [];
6646
+ }
6641
6647
  if (!this.snapshot.config.indexes) {
6642
6648
  this.snapshot.config.indexes = [];
6643
6649
  }
@@ -10990,11 +10996,11 @@ class TabularDatasourceComponent {
10990
10996
  }
10991
10997
  }
10992
10998
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabularDatasourceComponent, deps: [{ token: DatasourceService }], target: i0.ɵɵFactoryTarget.Component }); }
10993
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TabularDatasourceComponent, isStandalone: false, selector: "ki-tabular-datasource", ngImport: i0, template: "<div class=\"border-b w-full flex items-center justify-between \">\n <div class=\"leading-5 px-4 text-xs uppercase tracking-wider font-medium border-r-2 text-gray-600\">\n Operations\n </div>\n <div class=\"flex items-center flex-wrap w-full justify-end bg-white\">\n <button (click)=\"apiAccess()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">api</mat-icon>\n api access\n </button>\n <button (click)=\"import()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">upload_file</mat-icon>\n upload\n </button>\n <button (click)=\"save()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">save</mat-icon>\n save\n </button>\n </div>\n</div>\n<div class=\"flex create-datasource-container\">\n <div class=\"flex-1 relative overflow-y-scroll table-scroll\">\n\n <div class=\"create-datasource\">\n <div id=\"tableWrapper\" class=\"flex-1 overflow-y-scroll relative\">\n <revo-grid [columns]=\"columns\" [source]=\"rows\" theme=\"material\"/>\n </div>\n\n <div class=\"border-t bg-gray-50 py-2 flex align-center justify-between\">\n <button (click)=\"addRow()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n <div class=\"flex items-center\">\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-2\">\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"border-l border-r bg-gray-50 -ml-2.5\">\n <button mat-icon-button color=\"primary\" (click)=\"addColumn()\"\n class=\"-mt-0.5\">\n <mat-icon>add_circle</mat-icon>\n </button>\n </div>\n\n <div class=\"bg-gray-100 w-72 h-full p-3 flex justify-between flex-col\">\n <div>\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Settings\n </div>\n <label class=\"mb-4\">\n Datasource Name\n <input type=\"text\" class=\"w-full\" placeholder=\"Enter datasource name\"\n [class]=\"{'border border-red-500': !datasourceUpdate.title}\"\n [(ngModel)]=\"datasourceUpdate.title\">\n @if (!datasourceUpdate.title) {\n <div class=\"text-xs text-red-500\">\n Please enter a name for this datasource\n </div>\n }\n </label>\n\n <mat-checkbox class=\"mb-4\" [checked]=\"_.find(columns, {type: 'id'})\"\n (change)=\"updateAutoIncrementColumn($event.checked)\">\n Add ID Column\n </mat-checkbox>\n\n <div>\n <button mat-button class=\"text-red-500\" (click)=\"resetTable()\">\n Reset Table\n </button>\n </div>\n\n <hr class=\"my-4\">\n\n @if (selectedItem && selectedItem._tableType) {\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Column\n </div>\n <label class=\"mb-4\">\n Column Title\n <input type=\"text\" [(ngModel)]=\"selectedItem.title\" placeholder=\"Enter column title\"\n (change)=\"updateColumnName()\">\n </label>\n @if (selectedItem.type === 'id') {\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" disabled>\n <option [value]=\"'id'\">ID</option>\n </select>\n </label>\n <mat-checkbox class=\"mb-4\" [checked]=\"true\" disabled>\n {{_.filter(columns, 'keyField').length > 1 ? 'Part of Unique Identifier' : 'Unique Identifier'}}\n </mat-checkbox>\n }\n @if (selectedItem.type !== 'id') {\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" class=\"capitalize\">\n <option [value]=\"null\">-- Select column type --</option>\n @for (type of datasourceTypes; track type) {\n <option [value]=\"type\">\n {{type}}\n </option>\n }\n </select>\n </label>\n <mat-checkbox class=\"mb-4\" [(ngModel)]=\"selectedItem.keyField\"\n [disabled]=\"_.find(columns, {type:'id'})\">\n {{_.filter(columns, 'keyField').length > 1 ? 'Part of Unique Identifier' : 'Unique Identifier'}}\n </mat-checkbox>\n }\n <div>\n <button mat-button color=\"warn\" (click)=\"deleteSelectedColumn()\">Delete Column</button>\n </div>\n <hr class=\"my-4\">\n }\n\n\n <table class=\"datasource-table w-full\">\n <tbody>\n <tr class=\"bg-indigo-100\">\n <td class=\"pl-2\">Updated</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.updates.length || ''}}</td>\n </tr>\n <tr class=\"bg-gray-200 opacity-30\">\n <td class=\"pl-2\">Deleted</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.deletes.length || ''}}</td>\n </tr>\n <tr class=\"bg-green-50\">\n <td class=\"pl-2\">Added</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.adds.length || ''}}</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"save(true)\">\n Save & Exit\n </button>\n </div>\n</div>\n\n\n", styles: [":host{display:block;background-color:#fff;height:calc(100vh - 104px)}.action-toolbar{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;border-bottom:1px solid #ddd}.action-toolbar button{min-width:50px;padding:0 13px;color:#505050}.create-datasource-container{min-width:1024px;height:calc(100% - 49px)}.create-datasource-container .table-scroll::-webkit-scrollbar{width:.75em;background:transparent}.create-datasource-container .table-scroll::-webkit-scrollbar-thumb{background:#d2d2d2}.create-datasource-container .add-column{position:absolute;top:0;right:0}.create-datasource-container .create-datasource{margin-left:-1px;margin-top:-1px;display:flex;flex-direction:column;justify-content:space-between;height:100%}.create-datasource-container .create-datasource table.datasource-table td,.create-datasource-container .create-datasource table.datasource-table th{border:1px solid #ddd;vertical-align:middle;padding:.5rem}.create-datasource-container .create-datasource table.datasource-table th{font-weight:500}.create-datasource-container .create-datasource table.datasource-table th .header-title{min-height:20px;display:flex;align-items:center}.create-datasource-container .create-datasource table.datasource-table th .header-title mat-icon{height:20px;width:20px;font-size:20px;line-height:20px;color:#ffc400b3}.create-datasource-container .create-datasource table.datasource-table th button.header-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray}.create-datasource-container .create-datasource table.datasource-table th button.header-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray;display:none}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper:hover button.cell-actions{display:block}\n"], dependencies: [{ kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }] }); }
10999
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TabularDatasourceComponent, isStandalone: false, selector: "ki-tabular-datasource", ngImport: i0, template: "<div class=\"border-b w-full flex items-center justify-between \">\n <div class=\"leading-5 px-4 text-xs uppercase tracking-wider font-medium border-r-2 text-gray-600\">\n Operations\n </div>\n <div class=\"flex items-center flex-wrap w-full justify-end bg-white\">\n <button (click)=\"apiAccess()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">api</mat-icon>\n api access\n </button>\n <button (click)=\"import()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">upload_file</mat-icon>\n upload\n </button>\n <button (click)=\"save()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">save</mat-icon>\n save\n </button>\n </div>\n</div>\n<div class=\"flex create-datasource-container\">\n <div class=\"flex-1 relative overflow-y-scroll table-scroll\">\n\n <div class=\"create-datasource\">\n <div id=\"tableWrapper\" class=\"flex-1 overflow-y-scroll relative\">\n <revo-grid [columns]=\"columns\" [source]=\"rows\" theme=\"material\"/>\n </div>\n\n <div class=\"border-t bg-gray-50 py-2 flex align-center justify-between\">\n <button (click)=\"addRow()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n <div class=\"flex items-center\">\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-2\">\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"border-l border-r bg-gray-50 -ml-2.5\">\n <button mat-icon-button color=\"primary\" (click)=\"addColumn()\"\n class=\"-mt-0.5\">\n <mat-icon>add_circle</mat-icon>\n </button>\n </div>\n\n <div class=\"bg-gray-100 w-72 h-full p-3 flex justify-between flex-col\">\n <div>\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Settings\n </div>\n <label class=\"mb-4\">\n Datasource Name\n <input type=\"text\" class=\"w-full\" placeholder=\"Enter datasource name\"\n [class]=\"{'border border-red-500': !datasourceUpdate.title}\"\n [(ngModel)]=\"datasourceUpdate.title\">\n @if (!datasourceUpdate.title) {\n <div class=\"text-xs text-red-500\">\n Please enter a name for this datasource\n </div>\n }\n </label>\n\n <mat-checkbox class=\"mb-4\" [checked]=\"_.find(columns, {type: 'id'})\"\n (change)=\"updateAutoIncrementColumn($event.checked)\">\n Add ID Column\n </mat-checkbox>\n\n <div>\n <button mat-button class=\"text-red-500\" (click)=\"resetTable()\">\n Reset Table\n </button>\n </div>\n\n <hr class=\"my-4\">\n\n @if (selectedItem && selectedItem._tableType) {\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Column\n </div>\n <label class=\"mb-4\">\n Column Title\n <input type=\"text\" [(ngModel)]=\"selectedItem.title\" placeholder=\"Enter column title\"\n (change)=\"updateColumnName()\">\n </label>\n @if (selectedItem.type === 'id') {\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" disabled>\n <option [value]=\"'id'\">ID</option>\n </select>\n </label>\n <mat-checkbox class=\"mb-4\" [checked]=\"true\" disabled>\n {{_.filter(columns, 'keyField').length > 1 ? 'Part of Unique Identifier' : 'Unique Identifier'}}\n </mat-checkbox>\n }\n @if (selectedItem.type !== 'id') {\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" class=\"capitalize\">\n <option [value]=\"null\">-- Select column type --</option>\n @for (type of datasourceTypes; track type) {\n <option [value]=\"type\">\n {{type}}\n </option>\n }\n </select>\n </label>\n <mat-checkbox class=\"mb-4\" [(ngModel)]=\"selectedItem.keyField\"\n [disabled]=\"_.find(columns, {type:'id'})\">\n {{_.filter(columns, 'keyField').length > 1 ? 'Part of Unique Identifier' : 'Unique Identifier'}}\n </mat-checkbox>\n }\n <div>\n <button mat-button color=\"warn\" (click)=\"deleteSelectedColumn()\">Delete Column</button>\n </div>\n <hr class=\"my-4\">\n }\n\n\n <table class=\"datasource-table w-full\">\n <tbody>\n <tr class=\"bg-indigo-100\">\n <td class=\"pl-2\">Updated</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.updates.length || ''}}</td>\n </tr>\n <tr class=\"bg-gray-200 opacity-30\">\n <td class=\"pl-2\">Deleted</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.deletes.length || ''}}</td>\n </tr>\n <tr class=\"bg-green-50\">\n <td class=\"pl-2\">Added</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.adds.length || ''}}</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"save(true)\">\n Save & Exit\n </button>\n </div>\n</div>\n\n\n", styles: [":host{display:block;background-color:#fff;height:calc(100vh - 104px)}.action-toolbar{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;border-bottom:1px solid #ddd}.action-toolbar button{min-width:50px;padding:0 13px;color:#505050}.create-datasource-container{min-width:1024px;height:calc(100% - 49px)}.create-datasource-container .table-scroll::-webkit-scrollbar{width:.75em;background:transparent}.create-datasource-container .table-scroll::-webkit-scrollbar-thumb{background:#d2d2d2}.create-datasource-container .add-column{position:absolute;top:0;right:0}.create-datasource-container .create-datasource{margin-left:-1px;margin-top:-1px;display:flex;flex-direction:column;justify-content:space-between;height:100%}.create-datasource-container .create-datasource table.datasource-table td,.create-datasource-container .create-datasource table.datasource-table th{border:1px solid #ddd;vertical-align:middle;padding:.5rem}.create-datasource-container .create-datasource table.datasource-table th{font-weight:500}.create-datasource-container .create-datasource table.datasource-table th .header-title{min-height:20px;display:flex;align-items:center}.create-datasource-container .create-datasource table.datasource-table th .header-title mat-icon{height:20px;width:20px;font-size:20px;line-height:20px;color:#ffc400b3}.create-datasource-container .create-datasource table.datasource-table th button.header-actions{top:50%;transform:translateY(-50%);right:0;color:gray}.create-datasource-container .create-datasource table.datasource-table th button.header-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions{top:50%;transform:translateY(-50%);right:0;color:gray;display:none}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper:hover button.cell-actions{display:block}\n"], dependencies: [{ kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }] }); }
10994
11000
  }
10995
11001
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabularDatasourceComponent, decorators: [{
10996
11002
  type: Component,
10997
- args: [{ selector: 'ki-tabular-datasource', standalone: false, template: "<div class=\"border-b w-full flex items-center justify-between \">\n <div class=\"leading-5 px-4 text-xs uppercase tracking-wider font-medium border-r-2 text-gray-600\">\n Operations\n </div>\n <div class=\"flex items-center flex-wrap w-full justify-end bg-white\">\n <button (click)=\"apiAccess()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">api</mat-icon>\n api access\n </button>\n <button (click)=\"import()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">upload_file</mat-icon>\n upload\n </button>\n <button (click)=\"save()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">save</mat-icon>\n save\n </button>\n </div>\n</div>\n<div class=\"flex create-datasource-container\">\n <div class=\"flex-1 relative overflow-y-scroll table-scroll\">\n\n <div class=\"create-datasource\">\n <div id=\"tableWrapper\" class=\"flex-1 overflow-y-scroll relative\">\n <revo-grid [columns]=\"columns\" [source]=\"rows\" theme=\"material\"/>\n </div>\n\n <div class=\"border-t bg-gray-50 py-2 flex align-center justify-between\">\n <button (click)=\"addRow()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n <div class=\"flex items-center\">\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-2\">\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"border-l border-r bg-gray-50 -ml-2.5\">\n <button mat-icon-button color=\"primary\" (click)=\"addColumn()\"\n class=\"-mt-0.5\">\n <mat-icon>add_circle</mat-icon>\n </button>\n </div>\n\n <div class=\"bg-gray-100 w-72 h-full p-3 flex justify-between flex-col\">\n <div>\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Settings\n </div>\n <label class=\"mb-4\">\n Datasource Name\n <input type=\"text\" class=\"w-full\" placeholder=\"Enter datasource name\"\n [class]=\"{'border border-red-500': !datasourceUpdate.title}\"\n [(ngModel)]=\"datasourceUpdate.title\">\n @if (!datasourceUpdate.title) {\n <div class=\"text-xs text-red-500\">\n Please enter a name for this datasource\n </div>\n }\n </label>\n\n <mat-checkbox class=\"mb-4\" [checked]=\"_.find(columns, {type: 'id'})\"\n (change)=\"updateAutoIncrementColumn($event.checked)\">\n Add ID Column\n </mat-checkbox>\n\n <div>\n <button mat-button class=\"text-red-500\" (click)=\"resetTable()\">\n Reset Table\n </button>\n </div>\n\n <hr class=\"my-4\">\n\n @if (selectedItem && selectedItem._tableType) {\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Column\n </div>\n <label class=\"mb-4\">\n Column Title\n <input type=\"text\" [(ngModel)]=\"selectedItem.title\" placeholder=\"Enter column title\"\n (change)=\"updateColumnName()\">\n </label>\n @if (selectedItem.type === 'id') {\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" disabled>\n <option [value]=\"'id'\">ID</option>\n </select>\n </label>\n <mat-checkbox class=\"mb-4\" [checked]=\"true\" disabled>\n {{_.filter(columns, 'keyField').length > 1 ? 'Part of Unique Identifier' : 'Unique Identifier'}}\n </mat-checkbox>\n }\n @if (selectedItem.type !== 'id') {\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" class=\"capitalize\">\n <option [value]=\"null\">-- Select column type --</option>\n @for (type of datasourceTypes; track type) {\n <option [value]=\"type\">\n {{type}}\n </option>\n }\n </select>\n </label>\n <mat-checkbox class=\"mb-4\" [(ngModel)]=\"selectedItem.keyField\"\n [disabled]=\"_.find(columns, {type:'id'})\">\n {{_.filter(columns, 'keyField').length > 1 ? 'Part of Unique Identifier' : 'Unique Identifier'}}\n </mat-checkbox>\n }\n <div>\n <button mat-button color=\"warn\" (click)=\"deleteSelectedColumn()\">Delete Column</button>\n </div>\n <hr class=\"my-4\">\n }\n\n\n <table class=\"datasource-table w-full\">\n <tbody>\n <tr class=\"bg-indigo-100\">\n <td class=\"pl-2\">Updated</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.updates.length || ''}}</td>\n </tr>\n <tr class=\"bg-gray-200 opacity-30\">\n <td class=\"pl-2\">Deleted</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.deletes.length || ''}}</td>\n </tr>\n <tr class=\"bg-green-50\">\n <td class=\"pl-2\">Added</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.adds.length || ''}}</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"save(true)\">\n Save & Exit\n </button>\n </div>\n</div>\n\n\n", styles: [":host{display:block;background-color:#fff;height:calc(100vh - 104px)}.action-toolbar{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;border-bottom:1px solid #ddd}.action-toolbar button{min-width:50px;padding:0 13px;color:#505050}.create-datasource-container{min-width:1024px;height:calc(100% - 49px)}.create-datasource-container .table-scroll::-webkit-scrollbar{width:.75em;background:transparent}.create-datasource-container .table-scroll::-webkit-scrollbar-thumb{background:#d2d2d2}.create-datasource-container .add-column{position:absolute;top:0;right:0}.create-datasource-container .create-datasource{margin-left:-1px;margin-top:-1px;display:flex;flex-direction:column;justify-content:space-between;height:100%}.create-datasource-container .create-datasource table.datasource-table td,.create-datasource-container .create-datasource table.datasource-table th{border:1px solid #ddd;vertical-align:middle;padding:.5rem}.create-datasource-container .create-datasource table.datasource-table th{font-weight:500}.create-datasource-container .create-datasource table.datasource-table th .header-title{min-height:20px;display:flex;align-items:center}.create-datasource-container .create-datasource table.datasource-table th .header-title mat-icon{height:20px;width:20px;font-size:20px;line-height:20px;color:#ffc400b3}.create-datasource-container .create-datasource table.datasource-table th button.header-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray}.create-datasource-container .create-datasource table.datasource-table th button.header-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray;display:none}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper:hover button.cell-actions{display:block}\n"] }]
11003
+ args: [{ selector: 'ki-tabular-datasource', standalone: false, template: "<div class=\"border-b w-full flex items-center justify-between \">\n <div class=\"leading-5 px-4 text-xs uppercase tracking-wider font-medium border-r-2 text-gray-600\">\n Operations\n </div>\n <div class=\"flex items-center flex-wrap w-full justify-end bg-white\">\n <button (click)=\"apiAccess()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">api</mat-icon>\n api access\n </button>\n <button (click)=\"import()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">upload_file</mat-icon>\n upload\n </button>\n <button (click)=\"save()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">save</mat-icon>\n save\n </button>\n </div>\n</div>\n<div class=\"flex create-datasource-container\">\n <div class=\"flex-1 relative overflow-y-scroll table-scroll\">\n\n <div class=\"create-datasource\">\n <div id=\"tableWrapper\" class=\"flex-1 overflow-y-scroll relative\">\n <revo-grid [columns]=\"columns\" [source]=\"rows\" theme=\"material\"/>\n </div>\n\n <div class=\"border-t bg-gray-50 py-2 flex align-center justify-between\">\n <button (click)=\"addRow()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n <div class=\"flex items-center\">\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-2\">\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"border-l border-r bg-gray-50 -ml-2.5\">\n <button mat-icon-button color=\"primary\" (click)=\"addColumn()\"\n class=\"-mt-0.5\">\n <mat-icon>add_circle</mat-icon>\n </button>\n </div>\n\n <div class=\"bg-gray-100 w-72 h-full p-3 flex justify-between flex-col\">\n <div>\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Settings\n </div>\n <label class=\"mb-4\">\n Datasource Name\n <input type=\"text\" class=\"w-full\" placeholder=\"Enter datasource name\"\n [class]=\"{'border border-red-500': !datasourceUpdate.title}\"\n [(ngModel)]=\"datasourceUpdate.title\">\n @if (!datasourceUpdate.title) {\n <div class=\"text-xs text-red-500\">\n Please enter a name for this datasource\n </div>\n }\n </label>\n\n <mat-checkbox class=\"mb-4\" [checked]=\"_.find(columns, {type: 'id'})\"\n (change)=\"updateAutoIncrementColumn($event.checked)\">\n Add ID Column\n </mat-checkbox>\n\n <div>\n <button mat-button class=\"text-red-500\" (click)=\"resetTable()\">\n Reset Table\n </button>\n </div>\n\n <hr class=\"my-4\">\n\n @if (selectedItem && selectedItem._tableType) {\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Column\n </div>\n <label class=\"mb-4\">\n Column Title\n <input type=\"text\" [(ngModel)]=\"selectedItem.title\" placeholder=\"Enter column title\"\n (change)=\"updateColumnName()\">\n </label>\n @if (selectedItem.type === 'id') {\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" disabled>\n <option [value]=\"'id'\">ID</option>\n </select>\n </label>\n <mat-checkbox class=\"mb-4\" [checked]=\"true\" disabled>\n {{_.filter(columns, 'keyField').length > 1 ? 'Part of Unique Identifier' : 'Unique Identifier'}}\n </mat-checkbox>\n }\n @if (selectedItem.type !== 'id') {\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" class=\"capitalize\">\n <option [value]=\"null\">-- Select column type --</option>\n @for (type of datasourceTypes; track type) {\n <option [value]=\"type\">\n {{type}}\n </option>\n }\n </select>\n </label>\n <mat-checkbox class=\"mb-4\" [(ngModel)]=\"selectedItem.keyField\"\n [disabled]=\"_.find(columns, {type:'id'})\">\n {{_.filter(columns, 'keyField').length > 1 ? 'Part of Unique Identifier' : 'Unique Identifier'}}\n </mat-checkbox>\n }\n <div>\n <button mat-button color=\"warn\" (click)=\"deleteSelectedColumn()\">Delete Column</button>\n </div>\n <hr class=\"my-4\">\n }\n\n\n <table class=\"datasource-table w-full\">\n <tbody>\n <tr class=\"bg-indigo-100\">\n <td class=\"pl-2\">Updated</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.updates.length || ''}}</td>\n </tr>\n <tr class=\"bg-gray-200 opacity-30\">\n <td class=\"pl-2\">Deleted</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.deletes.length || ''}}</td>\n </tr>\n <tr class=\"bg-green-50\">\n <td class=\"pl-2\">Added</td>\n <td class=\"pl-2 text-right\">{{datasourceUpdate.adds.length || ''}}</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"save(true)\">\n Save & Exit\n </button>\n </div>\n</div>\n\n\n", styles: [":host{display:block;background-color:#fff;height:calc(100vh - 104px)}.action-toolbar{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;border-bottom:1px solid #ddd}.action-toolbar button{min-width:50px;padding:0 13px;color:#505050}.create-datasource-container{min-width:1024px;height:calc(100% - 49px)}.create-datasource-container .table-scroll::-webkit-scrollbar{width:.75em;background:transparent}.create-datasource-container .table-scroll::-webkit-scrollbar-thumb{background:#d2d2d2}.create-datasource-container .add-column{position:absolute;top:0;right:0}.create-datasource-container .create-datasource{margin-left:-1px;margin-top:-1px;display:flex;flex-direction:column;justify-content:space-between;height:100%}.create-datasource-container .create-datasource table.datasource-table td,.create-datasource-container .create-datasource table.datasource-table th{border:1px solid #ddd;vertical-align:middle;padding:.5rem}.create-datasource-container .create-datasource table.datasource-table th{font-weight:500}.create-datasource-container .create-datasource table.datasource-table th .header-title{min-height:20px;display:flex;align-items:center}.create-datasource-container .create-datasource table.datasource-table th .header-title mat-icon{height:20px;width:20px;font-size:20px;line-height:20px;color:#ffc400b3}.create-datasource-container .create-datasource table.datasource-table th button.header-actions{top:50%;transform:translateY(-50%);right:0;color:gray}.create-datasource-container .create-datasource table.datasource-table th button.header-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions{top:50%;transform:translateY(-50%);right:0;color:gray;display:none}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper:hover button.cell-actions{display:block}\n"] }]
10998
11004
  }], ctorParameters: () => [{ type: DatasourceService }] });
10999
11005
 
11000
11006
  class MarketplaceComponent {