UNPKG

sdk-datagrid

Version:

Customizable (Angular) datagrid with data options for manipulation, and charts for visualization.

1 lines 264 kB
{"version":3,"file":"sdk-datagrid.mjs","sources":["../../../projects/sdk-datagrid/src/lib/enums/sorts.ts","../../../projects/sdk-datagrid/src/lib/utils/clone.ts","../../../projects/sdk-datagrid/src/lib/models/datagrid-settings.ts","../../../projects/sdk-datagrid/src/lib/models/datagrid-message.ts","../../../projects/sdk-datagrid/src/lib/options/settings/settings-option.component.ts","../../../projects/sdk-datagrid/src/lib/options/settings/settings-option.component.html","../../../projects/sdk-datagrid/src/lib/options/columns/columns-option.component.ts","../../../projects/sdk-datagrid/src/lib/options/columns/columns-option.component.html","../../../projects/sdk-datagrid/src/lib/options/sort/sort-option.component.ts","../../../projects/sdk-datagrid/src/lib/options/sort/sort-option.component.html","../../../projects/sdk-datagrid/src/lib/enums/filters.ts","../../../projects/sdk-datagrid/src/lib/options/filter/filter-option.component.ts","../../../projects/sdk-datagrid/src/lib/options/filter/filter-option.component.html","../../../projects/sdk-datagrid/src/lib/models/datagrid-formula.ts","../../../projects/sdk-datagrid/src/lib/options/formula/formula-option.component.ts","../../../projects/sdk-datagrid/src/lib/options/formula/formula-option.component.html","../../../projects/sdk-datagrid/src/lib/options/export/export-option.component.ts","../../../projects/sdk-datagrid/src/lib/options/export/export-option.component.html","../../../projects/sdk-datagrid/src/lib/options/chart/chart-option.component.ts","../../../projects/sdk-datagrid/src/lib/options/chart/chart-option.component.html","../../../projects/sdk-datagrid/src/lib/models/datagrid-column.ts","../../../projects/sdk-datagrid/src/lib/models/datagrid-options.ts","../../../projects/sdk-datagrid/src/lib/models/datagrid-custom-filter.ts","../../../projects/sdk-datagrid/src/lib/sdk-datagrid.component.ts","../../../projects/sdk-datagrid/src/lib/sdk-datagrid.component.html","../../../projects/sdk-datagrid/src/lib/sdk-datagrid.module.ts","../../../projects/sdk-datagrid/src/lib/models/datagrid-filter.ts","../../../projects/sdk-datagrid/src/lib/models/datagrid-sort.ts","../../../projects/sdk-datagrid/src/lib/classes/colors.ts","../../../projects/sdk-datagrid/src/public-api.ts","../../../projects/sdk-datagrid/src/sdk-datagrid.ts"],"sourcesContent":["export enum Sorts {\n ASC = \"asc\",\n DESC = \"desc\",\n}","export class Clone {\n public static deepCopy<T>(source: T): T {\n if (Array.isArray(source)) {\n return this.copyArray(source) as unknown as T;\n }\n \n if (source instanceof Date) {\n return this.copyDate(source) as unknown as T;\n }\n \n if (source && typeof source === 'object') {\n return this.copyObject(source);\n }\n \n return source;\n }\n \n private static copyArray<T>(source: T[]): T[] {\n return source.map(item => this.deepCopy(item));\n }\n \n private static copyDate(source: Date): Date {\n return new Date(source.getTime());\n }\n \n private static copyObject<T>(source: T): T {\n const copy = Object.create(Object.getPrototypeOf(source));\n \n Object.getOwnPropertyNames(source).forEach(prop => {\n const descriptor = Object.getOwnPropertyDescriptor(source, prop);\n if (descriptor) {\n Object.defineProperty(copy, prop, descriptor);\n (copy as { [key: string]: any })[prop] = this.deepCopy((source as { [key: string]: any })[prop]);\n }\n });\n \n return copy as T;\n }\n }\n ","import { SDKDataGridColumn } from \"./datagrid-column\";\nimport { SDKDataGridCustomFilter } from \"./datagrid-custom-filter\";\n\nexport class SDKDataGridSettings {\n Name: string = \"\";\n Columns: SDKDataGridColumn[] = [];\n CustomFilters: SDKDataGridCustomFilter[] = [];\n Active?: boolean = false;\n}\n","export class SDKDataGridMessage {\n public Title: string = \"\";\n public Text: string = \"\";\n public OKText: string = \"\";\n public CancelText?: string = \"\";\n public OK: any = () => {};\n public Cancel?: any = () => {};\n}\n","import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';\r\n\r\nimport { Clone } from '../../utils/clone';\r\n\r\nimport { SDKDataGridSettings } from '../../models/datagrid-settings';\r\nimport { SDKDataGridColumn } from '../../models/datagrid-column';\r\nimport { SDKDataGridCustomFilter } from '../../models/datagrid-custom-filter';\r\nimport { SDKDataGridMessage } from '../../models/datagrid-message';\r\nimport { SDKMessageModule } from 'sdk-message';\r\nimport { SDKTextboxModule } from 'sdk-textbox';\r\nimport { SDKSelectModule } from 'sdk-select';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'sdk-datagrid-settings-option',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n SDKSelectModule,\r\n SDKMessageModule,\r\n SDKTextboxModule\r\n ],\r\n templateUrl: './settings-option.component.html',\r\n styleUrls: ['./settings-option.component.scss'],\r\n encapsulation: ViewEncapsulation.None // Used for innerHtml formatting on 'viewerText' property.\r\n})\r\n\r\nexport class SDKDataGridSettingsOptionComponent {\r\n /**************************************************************************\r\n * Input/Output Parameters\r\n **************************************************************************/\r\n @Input() settings: SDKDataGridSettings[] = [];\r\n @Input() columns: SDKDataGridColumn[] = [];\r\n @Input() customFilters: SDKDataGridCustomFilter[] = [];\r\n @Output() closeEvent = new EventEmitter();\r\n @Output() saveEvent = new EventEmitter();\r\n @Output() applyEvent = new EventEmitter();\r\n\r\n /**************************************************************************\r\n * Component Variables\r\n **************************************************************************/\r\n protected activeSetting: SDKDataGridSettings = new SDKDataGridSettings();\r\n protected settingsList: SDKDataGridSettings[] = [];\r\n protected name: string = \"\";\r\n protected viewerText: string = \"\";\r\n protected msg: string = \"\";\r\n protected error: string = \"\";\r\n\r\n private activeIndex: number = 0;\r\n\r\n private _settings: SDKDataGridSettings[] = [];\r\n private _columns: SDKDataGridColumn[] = [];\r\n private _customFilters: SDKDataGridCustomFilter[] = [];\r\n\r\n /**************************************************************************\r\n * Message Variables\r\n **************************************************************************/\r\n protected showMessage: boolean = false;\r\n protected message: SDKDataGridMessage = new SDKDataGridMessage();\r\n\r\n protected ngOnChanges(_args: any) {\r\n this._settings = Clone.deepCopy(this.settings);\r\n this._columns = Clone.deepCopy(this.columns);\r\n this._customFilters = Clone.deepCopy(this.customFilters);\r\n\r\n this.initialze();\r\n }\r\n\r\n /**************************************************************************\r\n * Setup Methods\r\n **************************************************************************/\r\n private initialze() {\r\n this.settingsList = this._settings;\r\n\r\n // Reset current settings based on columns and custom filters.\r\n let currentSetting: SDKDataGridSettings = {\r\n Name: \"[Current Settings]\",\r\n Columns: this._columns,\r\n CustomFilters: this._customFilters,\r\n Active: false\r\n }\r\n\r\n let ndx = this.settingsList.findIndex((settings: SDKDataGridSettings) => settings.Name === \"[Current Settings]\");\r\n\r\n if (ndx === -1) {\r\n this.settingsList.unshift(currentSetting);\r\n } else {\r\n this.settingsList[ndx] = currentSetting;\r\n }\r\n\r\n // Pre-load any settings that are flagged as 'active'.\r\n let activeNdx = this.settingsList.findIndex((setting: SDKDataGridSettings) => setting.Active === true);\r\n\r\n if (activeNdx > -1) {\r\n this.activeIndex = activeNdx;\r\n }\r\n\r\n this.activeSetting = this.settingsList[this.activeIndex];\r\n this.name = this.activeSetting.Name;\r\n\r\n this.validateSettings();\r\n this.setViewerText();\r\n }\r\n\r\n private saveSetting() {\r\n this.settingsList[this.activeIndex].Name = this.name;\r\n\r\n if (this.activeIndex === 0) {\r\n let currentSetting: SDKDataGridSettings = Clone.deepCopy(this.settingsList[this.activeIndex]);\r\n\r\n currentSetting.Name = \"[Current Settings]\";\r\n\r\n this.settingsList.unshift(currentSetting);\r\n }\r\n\r\n this.resetProperties();\r\n\r\n this.activeIndex = this.settingsList.findIndex((setting: any) => setting.Name === this.name) + 1;\r\n\r\n this.saveEvent.emit(this.settingsList);\r\n\r\n this.msg = \"Settings have been saved.\";\r\n }\r\n\r\n private sortSettings() {\r\n this.settingsList.sort((a: SDKDataGridSettings, b: SDKDataGridSettings) => {\r\n const aName = a.Name.toUpperCase();\r\n const bName = b.Name.toUpperCase();\r\n\r\n if (aName > bName) {\r\n return 1;\r\n }\r\n\r\n if (aName < bName) {\r\n return -1;\r\n }\r\n\r\n return 0;\r\n });\r\n }\r\n\r\n private resetProperties() {\r\n this.sortSettings();\r\n\r\n this.settingsList.forEach((setting: SDKDataGridSettings) => {\r\n setting.Active = false;\r\n });\r\n }\r\n\r\n private setViewerText() {\r\n setTimeout(() => {\r\n this.viewerText = `Columns:<br />`;\r\n\r\n this.viewerText += \"<ul>\";\r\n this.activeSetting.Columns.filter((column: SDKDataGridColumn) => !column.isAction).forEach((column: SDKDataGridColumn) => {\r\n this.viewerText += `<li>${(column.FriendlyName !== \"\") ? column.FriendlyName : (column.DisplayName !== \"\") ? column.DisplayName : column.Name} (${column.isVisible ? \"visible\" : \"hidden\"})</li>`;\r\n });\r\n this.viewerText += \"</ul>\";\r\n\r\n this.viewerText += `<br />Sorts:<br />`;\r\n\r\n this.viewerText += \"<ul>\";\r\n this.activeSetting.Columns.forEach((column: SDKDataGridColumn) => {\r\n if (column.Sort) {\r\n this.viewerText += `<li>${(column.DisplayName !== \"\") ? column.DisplayName : column.Name} (${column.Sort.direction})</li>`;\r\n }\r\n });\r\n this.viewerText += \"</ul>\";\r\n\r\n this.viewerText += `<br />Filters:<br />`;\r\n\r\n this.viewerText += \"<ul>\";\r\n this.activeSetting.CustomFilters.forEach((filter: SDKDataGridCustomFilter) => {\r\n if (filter.Filter) {\r\n if (filter.Filter.operation) {\r\n this.viewerText += `<li>${(filter.DisplayName !== \"\") ? filter.DisplayName : filter.Name} (${filter.Filter.operation}: ${filter.Filter.value})</li>`;\r\n } else {\r\n this.viewerText += `<li>${(filter.DisplayName !== \"\") ? filter.DisplayName : filter.Name} (${filter.Filter.value})</li>`;\r\n }\r\n }\r\n });\r\n this.activeSetting.Columns.forEach((column: SDKDataGridColumn) => {\r\n if (column.Filter) {\r\n if (column.Filter.operation) {\r\n this.viewerText += `<li>${(column.DisplayName !== \"\") ? column.DisplayName : column.Name} (${column.Filter.operation}: ${column.Filter.value})</li>`;\r\n } else {\r\n this.viewerText += `<li>${(column.DisplayName !== \"\") ? column.DisplayName : column.Name} (${column.Filter.value})</li>`;\r\n }\r\n }\r\n });\r\n this.viewerText += \"</ul>\";\r\n\r\n this.viewerText += `<br />Formulas:<br />`;\r\n\r\n this.viewerText += \"<ul>\";\r\n this.activeSetting.Columns.forEach((column: SDKDataGridColumn) => {\r\n if (column.Formulas) {\r\n column.Formulas.forEach((formula: any) => {\r\n this.viewerText += `<li>${(column.DisplayName !== \"\") ? column.DisplayName : column.Name} (${formula.Operation}: #.${formula.Format})</li>`;\r\n });\r\n }\r\n });\r\n this.viewerText += \"</ul>\";\r\n }, 10);\r\n }\r\n\r\n private validateSettings() {\r\n let issue: boolean = false;\r\n this.error = \"\";\r\n\r\n if (this._columns.length !== this.activeSetting.Columns.length) {\r\n issue = true;\r\n }\r\n\r\n this.activeSetting.Columns.forEach((column: SDKDataGridColumn) => {\r\n let ndx = this._columns.findIndex((c: SDKDataGridColumn) => c.Name === column.Name);\r\n\r\n if (ndx === -1) {\r\n issue = true;\r\n column.FriendlyName = column.Name + '<span> <-- Does NOT exist!</span>';\r\n }\r\n });\r\n\r\n this._columns.forEach((column: SDKDataGridColumn) => {\r\n let ndx = this.activeSetting.Columns.findIndex((c: SDKDataGridColumn) => c.Name === column.Name);\r\n\r\n if (ndx === -1) {\r\n issue = true;\r\n this.activeSetting.Columns.push({\r\n Name: column.Name,\r\n DisplayName: \"\",\r\n FriendlyName: column.Name + '<span> <-- Missing!</span>',\r\n isVisible: column.isVisible\r\n });\r\n }\r\n });\r\n\r\n if (this._customFilters.length !== this.activeSetting.CustomFilters.length) {\r\n issue = true;\r\n }\r\n\r\n this.activeSetting.CustomFilters.forEach((filter: SDKDataGridCustomFilter) => {\r\n let ndx = this._customFilters.findIndex((f: SDKDataGridCustomFilter) => f.Name === filter.Name);\r\n\r\n if (ndx === -1) {\r\n issue = true;\r\n filter.DisplayName = filter.Name + '<span> <-- Does NOT exist!</span>';\r\n }\r\n });\r\n\r\n this._customFilters.forEach((filter: SDKDataGridCustomFilter) => {\r\n let ndx = this.activeSetting.CustomFilters.findIndex((f: SDKDataGridCustomFilter) => f.Name === filter.Name);\r\n\r\n if (ndx === -1) {\r\n issue = true;\r\n this.activeSetting.CustomFilters.push({\r\n Name: filter.Name,\r\n DisplayName: filter.Name = '<span> <-- Missing!</span>',\r\n Type: filter.Type,\r\n Filter: {\r\n operation: [],\r\n value: \"\"\r\n }\r\n });\r\n }\r\n });\r\n\r\n if (issue) {\r\n this.error = \"There are issues with these settings!\";\r\n }\r\n }\r\n\r\n /**************************************************************************\r\n * User Action Methods\r\n **************************************************************************/\r\n protected setName(event: any) {\r\n this.name = event.trim();\r\n }\r\n\r\n protected save() {\r\n if (this.name !== \"\") {\r\n let dup = this.settingsList.findIndex((setting: SDKDataGridSettings) => setting.Name === this.name);\r\n\r\n if (dup > -1) {\r\n this.message = {\r\n Title: \"Duplicate Settings\",\r\n Text: `'${this.name}' already exists. Would you like to override it?`,\r\n OKText: \"YES\",\r\n CancelText: \"NO\",\r\n OK: () => {\r\n this.showMessage = false;\r\n\r\n this.settingsList.splice(dup, 1);\r\n\r\n this.saveSetting();\r\n },\r\n Cancel: () => {\r\n this.showMessage = false;\r\n }\r\n };\r\n\r\n this.showMessage = true;\r\n } else {\r\n this.saveSetting();\r\n }\r\n }\r\n }\r\n\r\n protected remove() {\r\n if (this.activeSetting.Name !== \"[Current Settings]\") {\r\n this.message = {\r\n Title: \"Delete Settings\",\r\n Text: `Are you sure you want to delete the '${this.name}' settings?`,\r\n OKText: \"YES\",\r\n CancelText: \"NO\",\r\n OK: () => {\r\n this.showMessage = false;\r\n\r\n this.settingsList.splice(this.activeIndex, 1);\r\n\r\n this.activeIndex = 0;\r\n\r\n this.saveEvent.emit(this.settingsList);\r\n\r\n this.msg = \"Settings have been deleted.\";\r\n },\r\n Cancel: () => {\r\n this.showMessage = false;\r\n }\r\n };\r\n\r\n this.showMessage = true;\r\n }\r\n }\r\n\r\n protected load(event: any) {\r\n this.activeIndex = this.settingsList.findIndex((setting: SDKDataGridSettings) => setting.Name === event[0].Name);\r\n this.activeSetting = this.settingsList[this.activeIndex];\r\n this.name = this.activeSetting.Name;\r\n\r\n this.validateSettings();\r\n this.setViewerText();\r\n }\r\n\r\n protected apply() {\r\n this.resetProperties();\r\n\r\n // Set selected settings as active.\r\n if (this.activeSetting.Name !== \"[Current Settings]\") {\r\n this.activeSetting.Active = true;\r\n }\r\n\r\n this.saveEvent.emit(this.settingsList);\r\n this.applyEvent.emit({ columns: this.activeSetting.Columns, customFilters: this.activeSetting.CustomFilters });\r\n }\r\n\r\n protected close() {\r\n this.closeEvent.emit();\r\n }\r\n}\r\n","<div class=\"sdk-datagrid-window\">\r\n <sdk-message [(message)]=\"msg\"></sdk-message>\r\n <div class=\"header\">\r\n <span class=\"title\">Settings</span>\r\n <span title=\"Close\" class=\"sdk-icon close\" (click)=\"close()\">close</span>\r\n </div>\r\n <div class=\"actions\">\r\n <sdk-select\r\n [options]=\"settingsList\"\r\n optionStyle=\"border-radius: 4px;\"\r\n [optionValuesStyle]=\"'max-height: 150px; overflow: hidden; overflow-y: auto;'\"\r\n displayValue=\"Name\"\r\n [selectedOptions]=\"[activeSetting]\"\r\n (selectChangeEvent)=\"load($event)\">\r\n </sdk-select>\r\n </div>\r\n <div class=\"content\">\r\n <div class=\"settings\">\r\n <div class=\"name\">\r\n <label *ngIf=\"error !== ''\" class=\"error\">{{ error }}</label>\r\n <sdk-textbox *ngIf=\"error === ''\" hint=\"Enter Settings Name...\" [value]=\"name === '[Current Settings]' ? '' : name\" (changeCallBackEvent)=\"setName($event)\"></sdk-textbox>\r\n </div>\r\n <div class=\"values\" [ngClass]=\"{ adjusted: activeSetting.Active }\">\r\n <div [innerHTML]=\"viewerText\"></div>\r\n </div>\r\n <div *ngIf=\"activeSetting.Active\" class=\"notes\">\r\n * Indicates active settings.\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"footer\">\r\n <button class=\"sdk-button delete\" [disabled]=\"activeSetting.Name === '[Current Settings]' ? 'disabled' : ''\" [ngClass]=\"{ 'disabled': activeSetting.Name === '[Current Settings]' }\" (click)=\"remove()\">Delete</button>\r\n <button *ngIf=\"error === ''\" class=\"sdk-button\" (click)=\"save()\">Save</button>\r\n <button *ngIf=\"error === ''\" class=\"sdk-button\" (click)=\"apply()\">Apply</button>\r\n </div>\r\n</div>\r\n\r\n<!-- Lock -->\r\n<div *ngIf=\"showMessage\" title=\"\" class=\"sdk-datagrid-windows-lock\"></div>\r\n\r\n<!-- Message -->\r\n<div *ngIf=\"showMessage\" title=\"\" class=\"sdk-datagrid-message\">\r\n <div class=\"title\">{{ message.Title }}</div>\r\n <div class=\"text\" [innerHtml]=\"message.Text\"></div>\r\n <div class=\"action\">\r\n <button class=\"sdk-button\" (click)=\"message.OK()\">{{ message.OKText }}</button>\r\n <button class=\"sdk-button cancel\" (click)=\"message.Cancel()\">{{ message.CancelText }}</button>\r\n </div>\r\n</div>\r\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\r\nimport { DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';\r\n\r\nimport { SDKDataGridColumn } from '../../models/datagrid-column';\r\nimport { SDKDataGridMessage } from '../../models/datagrid-message';\r\n\r\nimport { Clone } from '../../utils/clone';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'sdk-datagrid-columns-option',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n DragDropModule,\r\n ],\r\n templateUrl: './columns-option.component.html',\r\n styleUrls: ['./columns-option.component.scss']\r\n})\r\n\r\nexport class SDKDataGridColumnsOptionComponent {\r\n /**************************************************************************\r\n * Input/Output Parameters\r\n **************************************************************************/\r\n @Input() columns: SDKDataGridColumn[] = [];\r\n @Output() closeEvent = new EventEmitter();\r\n @Output() applyEvent = new EventEmitter();\r\n\r\n /**************************************************************************\r\n * Component Variables\r\n **************************************************************************/\r\n protected columnList: SDKDataGridColumn[] = [];\r\n protected allVisible: boolean = true;\r\n\r\n private _columns: SDKDataGridColumn[] = [];\r\n\r\n /**************************************************************************\r\n * Message Variables\r\n **************************************************************************/\r\n protected showMessage: boolean = false;\r\n protected message: SDKDataGridMessage = new SDKDataGridMessage();\r\n\r\n /**************************************************************************\r\n * Component Lifecycle Methods\r\n **************************************************************************/\r\n protected ngOnChanges(_args: any) {\r\n if (_args.columns?.currentValue !== undefined) {\r\n this._columns = Clone.deepCopy(this.columns);\r\n\r\n this.initialize();\r\n }\r\n }\r\n\r\n /**************************************************************************\r\n * Setup Methods\r\n **************************************************************************/\r\n private initialize() {\r\n // Remove any \"Action\" columns. They are NOT available for user updates.\r\n this.columnList = this._columns.filter((column: SDKDataGridColumn) => !column.isAction);\r\n this.allVisible = this.columnList.filter((column: SDKDataGridColumn) => !column.isVisible).length > 0 ? false : true;\r\n }\r\n\r\n protected getColumnName(column: SDKDataGridColumn) {\r\n let name: string = column.Name;\r\n\r\n name = (column.DisplayName && column.DisplayName !== \"\") ? column.DisplayName : name;\r\n name = (column.FriendlyName && column.FriendlyName !== \"\") ? column.FriendlyName : name;\r\n\r\n return name;\r\n }\r\n\r\n protected setFriendlyName(event: any, column: SDKDataGridColumn) {\r\n column.FriendlyName = event.target.value;\r\n }\r\n\r\n /**************************************************************************\r\n * User Action Methods\r\n **************************************************************************/\r\n protected groupVisibleColumns() {\r\n let visible: SDKDataGridColumn[] = this.columnList.filter((column: SDKDataGridColumn) => column.isVisible);\r\n let hidden: SDKDataGridColumn[] = this.columnList.filter((column: SDKDataGridColumn) => !column.isVisible);\r\n\r\n this.columnList = visible.concat(hidden);\r\n }\r\n\r\n protected toggleAllColumns(event: any) {\r\n this.allVisible = event.target.checked;\r\n\r\n this.columnList.forEach((column: SDKDataGridColumn) => {\r\n column.isVisible = this.allVisible;\r\n });\r\n }\r\n\r\n protected toggleColumn(event: any, column: SDKDataGridColumn) {\r\n column.isVisible = event.target.checked;\r\n }\r\n\r\n protected drop(event: any) {\r\n moveItemInArray(this.columnList, event.previousIndex, event.currentIndex);\r\n }\r\n\r\n protected reset() {\r\n this.message = {\r\n Title: \"Reset Columns\",\r\n Text: \"Are you sure?\",\r\n OKText: \"YES\",\r\n CancelText: \"NO\",\r\n OK: () => {\r\n this.showMessage = false;\r\n\r\n this.columnList.sort((a: SDKDataGridColumn, b: SDKDataGridColumn) => (a._original.index > b._original.index) ? 1 : -1);\r\n\r\n this.columnList.forEach((column: SDKDataGridColumn) => {\r\n column.FriendlyName = column._original.FriendlyName;\r\n column.isVisible = column._original.isVisible;\r\n });\r\n\r\n this.initialize();\r\n },\r\n Cancel: () => {\r\n this.showMessage = false;\r\n }\r\n };\r\n\r\n this.showMessage = true;\r\n }\r\n\r\n protected apply() {\r\n // Add 'left' action columns back into list.\r\n this._columns.filter((column: SDKDataGridColumn) => column.isAction && column.actionSide === \"left\").forEach((column: SDKDataGridColumn) => {\r\n this.columnList.unshift({ ...column });\r\n });\r\n\r\n // Add 'right' action columns back into list.\r\n this._columns.filter((column: SDKDataGridColumn) => column.isAction && column.actionSide === \"right\").forEach((column: SDKDataGridColumn) => {\r\n this.columnList.push({ ...column });\r\n });\r\n\r\n // Remove any sorting/filtering for columns that are no longer visible.\r\n this.columnList.forEach((column: SDKDataGridColumn) => {\r\n if (!column.isVisible) {\r\n column.Filter = column._original.Filter;\r\n column.Sort = column._original.Sort;\r\n }\r\n });\r\n\r\n this.applyEvent.emit({ option: \"Columns\", columns: this.columnList });\r\n }\r\n\r\n protected close() {\r\n this.closeEvent.emit();\r\n }\r\n}\r\n","<div class=\"sdk-datagrid-window\">\r\n <div class=\"header\">\r\n <span class=\"title\">Columns</span>\r\n <span title=\"Close\" class=\"sdk-icon close\" (click)=\"close()\">close</span>\r\n </div>\r\n <div class=\"actions\">\r\n <div class=\"all-select\">\r\n <input type=\"checkbox\" class=\"select\" [checked]=\"allVisible\" (change)=\"toggleAllColumns($event)\" />\r\n <span>All</span>\r\n </div>\r\n <button class=\"sdk-button button-right\" (click)=\"groupVisibleColumns()\">Group Visible</button>\r\n </div>\r\n <div cdkDropList class=\"content\" (cdkDropListDropped)=\"drop($event)\">\r\n <div class=\"box\" *ngFor=\"let column of columnList\" cdkDragBoundary=\".list\" cdkDrag>\r\n <div class=\"select\">\r\n <input type=\"checkbox\" [checked]=\"column.isVisible\" (change)=\"toggleColumn($event, column)\" />\r\n </div>\r\n <div class=\"name\">\r\n <input (input)=\"setFriendlyName($event, column);\" [value]=\"getColumnName(column)\" />\r\n </div>\r\n <div class=\"move\" cdkDragHandle>\r\n <span class=\"sdk-icon\">drag_handle</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"footer\">\r\n <button class=\"sdk-button delete\" (click)=\"reset()\">Reset</button>\r\n <button class=\"sdk-button\" (click)=\"apply()\">Apply</button>\r\n </div>\r\n</div>\r\n\r\n<!-- Lock -->\r\n<div *ngIf=\"showMessage\" title=\"\" class=\"sdk-datagrid-windows-lock\"></div>\r\n\r\n<!-- Message -->\r\n<div *ngIf=\"showMessage\" title=\"\" class=\"sdk-datagrid-message\">\r\n <div class=\"title\">{{ message.Title }}</div>\r\n <div class=\"text\" [innerHtml]=\"message.Text\"></div>\r\n <div class=\"action\">\r\n <button class=\"sdk-button\" (click)=\"message.OK()\">{{ message.OKText }}</button>\r\n <button class=\"sdk-button cancel\" (click)=\"message.Cancel()\">{{ message.CancelText }}</button>\r\n </div>\r\n</div>\r\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\r\nimport { moveItemInArray } from '@angular/cdk/drag-drop';\r\n\r\nimport { SDKDataGridColumn } from '../../models/datagrid-column';\r\nimport { SDKDataGridMessage } from '../../models/datagrid-message';\r\nimport { SDKDataGridSort } from '../../models/datagrid-sort';\r\n\r\nimport { Clone } from '../../utils/clone';\r\nimport { Sorts } from '../../enums/sorts';\r\nimport { CommonModule } from '@angular/common';\r\nimport { SDKSelectModule } from 'sdk-select';\r\n\r\n@Component({\r\n selector: 'sdk-datagrid-sort-option',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n SDKSelectModule,\r\n ],\r\n templateUrl: './sort-option.component.html',\r\n styleUrls: ['./sort-option.component.scss']\r\n})\r\n\r\nexport class SDKDataGridSortOptionComponent {\r\n /**************************************************************************\r\n * Input/Output Parameters\r\n **************************************************************************/\r\n @Input() columns: SDKDataGridColumn[] = [];\r\n @Output() closeEvent = new EventEmitter();\r\n @Output() applyEvent = new EventEmitter();\r\n\r\n /**************************************************************************\r\n * Component Variables\r\n **************************************************************************/\r\n protected sortList: any[] = [];\r\n protected columnList: any[] = [];\r\n protected selectedValue: any = [];\r\n\r\n private _columns: SDKDataGridColumn[] = [];\r\n\r\n /**************************************************************************\r\n * Message Variables\r\n **************************************************************************/\r\n protected showMessage: boolean = false;\r\n protected message: SDKDataGridMessage = new SDKDataGridMessage();\r\n\r\n /**************************************************************************\r\n * Component Lifecycle Methods\r\n **************************************************************************/\r\n protected ngOnChanges(_args: any) {\r\n if (_args.columns?.currentValue !== undefined) {\r\n this._columns = Clone.deepCopy(this.columns);\r\n\r\n this.initialize();\r\n }\r\n }\r\n\r\n /**************************************************************************\r\n * Setup Methods\r\n **************************************************************************/\r\n private initialize() {\r\n this.sortList = [];\r\n\r\n this._columns\r\n .filter((column: SDKDataGridColumn) => column.showSort && column.isVisible && !column.isAction && column.Sort)\r\n .sort((a: any, b: any) => (a.Sort.position > b.Sort.position) ? 1 : -1)\r\n .forEach((column: SDKDataGridColumn) => {\r\n this.sortList.push({ Name: column.Name, DisplayName: column.DisplayName, FriendlyName: column.FriendlyName, Sort: { position: column.Sort?.position, direction: column.Sort?.direction } });\r\n });\r\n\r\n this.setColumnList();\r\n }\r\n\r\n private setColumnList() {\r\n this.columnList = [];\r\n\r\n this._columns\r\n .filter((column: SDKDataGridColumn) => column.showSort && column.isVisible && !column.isAction)\r\n .forEach((column: any) => {\r\n if (this.sortList.filter((s: any) => s.Name === column.Name).length === 0) {\r\n this.columnList.push({ Name: column.Name, DisplayName: column.DisplayName, FriendlyName: column.FriendlyName, Value: this.getColumnName(column) });\r\n }\r\n });\r\n }\r\n\r\n protected getColumnName(column: SDKDataGridColumn) {\r\n let name: string = column.Name;\r\n\r\n name = (column.DisplayName && column.DisplayName !== \"\") ? column.DisplayName : name;\r\n name = (column.FriendlyName && column.FriendlyName !== \"\") ? column.FriendlyName : name;\r\n\r\n return name;\r\n }\r\n\r\n /**************************************************************************\r\n * User Action Methods\r\n **************************************************************************/\r\n protected addSort(event: any) {\r\n let ndx: number = this._columns.findIndex((column: SDKDataGridColumn) => column.Name === event[0].Name);\r\n\r\n if (ndx > -1) {\r\n let column: SDKDataGridColumn = this._columns[ndx];\r\n\r\n this.sortList.push({ Name: column.Name, DisplayName: column.DisplayName, FriendlyName: column.FriendlyName, Sort: { position: 0, direction: Sorts.ASC } });\r\n }\r\n\r\n this.selectedValue = [];\r\n this.setColumnList();\r\n }\r\n\r\n protected deleteSort(sort: any) {\r\n this.sortList = this.sortList.filter((f: any) => f.Name !== sort.Name);\r\n\r\n this.setColumnList();\r\n }\r\n\r\n protected drop(event: any) {\r\n moveItemInArray(this.sortList, event.previousIndex, event.currentIndex);\r\n }\r\n\r\n protected reset() {\r\n this.message = {\r\n Title: \"Reset Sorts\",\r\n Text: \"Are you sure?\",\r\n OKText: \"YES\",\r\n CancelText: \"NO\",\r\n OK: () => {\r\n this.showMessage = false;\r\n\r\n this._columns.forEach((column: SDKDataGridColumn) => {\r\n column.Sort = column._original.Sort;\r\n });\r\n\r\n this.initialize();\r\n },\r\n Cancel: () => {\r\n this.showMessage = false;\r\n }\r\n };\r\n\r\n this.showMessage = true;\r\n }\r\n\r\n protected apply() {\r\n this._columns.forEach((column: SDKDataGridColumn) => {\r\n column.Sort = column._original.Sort;\r\n });\r\n\r\n this.sortList.forEach((sort: any, index: number) => {\r\n let ndx = this._columns.findIndex((column: SDKDataGridColumn) => column.Name === sort.Name);\r\n\r\n if (ndx > -1) {\r\n this._columns[ndx].Sort = { position: index, direction: sort.Sort.direction };\r\n }\r\n })\r\n\r\n this.applyEvent.emit({ option: \"Sorts\", columns: this._columns });\r\n }\r\n\r\n protected close() {\r\n this.closeEvent.emit();\r\n }\r\n}\r\n","<div class=\"sdk-datagrid-window\">\r\n <div class=\"header\">\r\n <span class=\"title\">Sorts</span>\r\n <span title=\"Close\" class=\"sdk-icon close\" (click)=\"close()\">close</span>\r\n </div>\r\n <div class=\"actions\">\r\n <sdk-select\r\n [options]=\"columnList\"\r\n optionStyle=\"border-radius: 4px;\"\r\n [optionValuesStyle]=\"'max-height: 150px; overflow: hidden; overflow-y: auto;'\"\r\n [forceOptionBottom]=\"true\"\r\n noValueLabel=\"ADD SORT...\"\r\n displayValue=\"Value\"\r\n [selectedOptions]=\"selectedValue\"\r\n (selectChangeEvent)=\"addSort($event)\">\r\n </sdk-select>\r\n </div>\r\n <div cdkDropList class=\"content\" (cdkDropListDropped)=\"drop($event)\">\r\n <div *ngIf=\"sortList.length === 0\" class=\"no-records\">\r\n <span>Add a sort.</span>\r\n </div>\r\n <div class=\"box\" *ngFor=\"let sort of sortList\" cdkDragBoundary=\".list\" cdkDrag>\r\n <div class=\"delete\">\r\n <span class=\"sdk-icon\" (click)=\"deleteSort(sort)\">delete</span>\r\n </div>\r\n <div class=\"name\" [title]=\"getColumnName(sort)\">{{ getColumnName(sort) }}</div>\r\n <div class=\"select\">\r\n <div style=\"display: inline-flex;\" (click)=\"sort.Sort.direction = 'asc'\">\r\n <input type=\"radio\" class=\"data-option\" (click)=\"sort.Sort.direction = 'asc'\" [id]=\"sort.Name + '_asc'\" [name]=\"sort.Name\" [checked]=\"(sort.Sort.direction === 'asc') ? 'checked' : ''\" value=\"asc\">\r\n <span class=\"data-label\" [attr.for]=\"sort.Name + '_asc'\">ASC</span>\r\n </div>\r\n <div style=\"display: inline-flex;\" (click)=\"sort.Sort.direction = 'desc'\">\r\n <input type=\"radio\" class=\"data-option\" (click)=\"sort.Sort.direction = 'desc'\" [id]=\"sort.Name + '_desc'\" [name]=\"sort.Name\" [checked]=\"(sort.Sort.direction === 'desc') ? 'checked' : ''\" value=\"desc\">\r\n <span class=\"data-label\" [attr.for]=\"sort.Name + '_desc'\">DESC</span>\r\n </div>\r\n </div>\r\n <div class=\"move\" cdkDragHandle>\r\n <span class=\"sdk-icon\">drag_handle</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"footer\">\r\n <button class=\"sdk-button delete\" (click)=\"reset()\">Reset</button>\r\n <button class=\"sdk-button\" (click)=\"apply()\">Apply</button>\r\n </div>\r\n</div>\r\n\r\n<!-- Lock -->\r\n<div *ngIf=\"showMessage\" title=\"\" class=\"sdk-datagrid-windows-lock\"></div>\r\n\r\n<!-- Message -->\r\n<div *ngIf=\"showMessage\" title=\"\" class=\"sdk-datagrid-message\">\r\n <div class=\"title\">{{ message.Title }}</div>\r\n <div class=\"text\" [innerHtml]=\"message.Text\"></div>\r\n <div class=\"action\">\r\n <button class=\"sdk-button\" (click)=\"message.OK()\">{{ message.OKText }}</button>\r\n <button class=\"sdk-button cancel\" (click)=\"message.Cancel()\">{{ message.CancelText }}</button>\r\n </div>\r\n</div>\r\n","export enum Filters {\n Equals = \"Equals (=)\",\n NotEquals = \"Not Equals (!=)\",\n Empty = \"Empty\",\n NotEmpty = \"Not Empty\",\n Contains = \"Contains\",\n NotContains = \"Not Contains\",\n GreaterThan = \"Greater Than (>)\",\n GreaterThanOrEqual = \"Greater Than/Equal To (>=)\",\n LessThan = \"Less Than (<)\",\n LessThanOrEqual = \"Less Than/Equal To (<=)\",\n InList = \"In List\"\n}\n\nexport enum FilterType {\n Textbox = \"text\",\n TextboxOnly = \"text-only\",\n Checkbox = \"checkbox\",\n Dropdown = \"list\"\n}\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\r\n\r\nimport { SDKDataGridColumn } from '../../models/datagrid-column';\r\nimport { SDKDataGridCustomFilter } from '../../models/datagrid-custom-filter';\r\nimport { SDKDataGridMessage } from '../../models/datagrid-message';\r\n\r\nimport { Filters, FilterType } from '../../enums/filters';\r\nimport { Clone } from '../../utils/clone';\r\nimport { SDKSelectModule } from 'sdk-select';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'sdk-datagrid-filter-option',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n SDKSelectModule\r\n ],\r\n templateUrl: './filter-option.component.html',\r\n styleUrls: ['./filter-option.component.scss']\r\n})\r\n\r\nexport class SDKDataGridFilterOptionComponent {\r\n /**************************************************************************\r\n * Input/Output Parameters\r\n **************************************************************************/\r\n @Input() columns: SDKDataGridColumn[] = [];\r\n @Input() customFilters: SDKDataGridCustomFilter[] = [];\r\n @Output() closeEvent = new EventEmitter();\r\n @Output() applyEvent = new EventEmitter();\r\n\r\n /**************************************************************************\r\n * Component Variables\r\n **************************************************************************/\r\n protected columnList: SDKDataGridColumn[] = [];\r\n protected filterList: any[] = [];\r\n\r\n private _columns: SDKDataGridColumn[] = [];\r\n private _customFilters: SDKDataGridColumn[] = [];\r\n\r\n /**************************************************************************\r\n * Message Variables\r\n **************************************************************************/\r\n protected showMessage: boolean = false;\r\n protected message: SDKDataGridMessage = new SDKDataGridMessage();\r\n\r\n /**************************************************************************\r\n * Component Lifecycle Methods\r\n **************************************************************************/\r\n protected ngOnChanges(_args: any) {\r\n this._columns = Clone.deepCopy(this.columns);\r\n this._customFilters = Clone.deepCopy(this.customFilters);\r\n\r\n Promise.all([\r\n this._columns.filter((column: SDKDataGridColumn) => column.setFilterValues !== undefined).forEach(async (fv: any) => {\r\n await fv.setFilterValues().then((results: any) => {\r\n fv.FilterValues = results;\r\n });\r\n }),\r\n\r\n this._customFilters.filter((custom: SDKDataGridColumn) => custom.setFilterValues !== undefined).forEach(async (fv: any) => {\r\n await fv.setFilterValues().then((results: any) => {\r\n fv.FilterValues = results;\r\n });\r\n })\r\n ]).then(() => {\r\n this.initialize();\r\n });\r\n }\r\n\r\n /**************************************************************************\r\n * Setup Methods\r\n **************************************************************************/\r\n protected initialize() {\r\n this.filterList = [];\r\n this.columnList = [];\r\n\r\n this._customFilters.forEach((filter: any) => {\r\n if (filter.Type === FilterType.Dropdown && (!filter.FilterTypes || filter.FilterTypes.length === 0)) {\r\n filter.FilterTypes = [Filters.Contains, Filters.Empty, Filters.Equals, Filters.GreaterThan, Filters.GreaterThanOrEqual, Filters.InList, Filters.LessThan, Filters.LessThanOrEqual, Filters.NotContains, Filters.NotEmpty, Filters.NotEquals];\r\n }\r\n if (filter.FilterMultiSelect && filter.FilterValues && filter.FilterValues.length > 0) {\r\n filter.FilterTypes = [Filters.Equals, Filters.NotEquals];\r\n }\r\n\r\n let operation = filter.Filter?.operation;\r\n\r\n if (!operation) {\r\n if (filter.FilterTypes.length === 1) {\r\n operation = [filter.FilterTypes[0]];\r\n } else if (filter.FilterValueDefault) {\r\n operation = [filter.FilterValueDefault];\r\n }\r\n }\r\n\r\n this.filterList.push({\r\n Type: \"Custom\",\r\n Name: filter.Name,\r\n DisplayName: filter.DisplayName,\r\n Operation: operation,\r\n ValueType: filter.Type,\r\n ValueList: filter.FilterValues,\r\n MultiSelect: filter.FilterMultiSelect,\r\n Value: filter.Filter?.value ?? \"\"\r\n });\r\n });\r\n\r\n this._columns.filter((column: SDKDataGridColumn) => column.showFilter && column.isVisible && !column.isAction).forEach((column: SDKDataGridColumn) => {\r\n if (!column.FilterTypes || column.FilterTypes.length === 0) {\r\n column.FilterTypes = [Filters.Contains, Filters.Empty, Filters.Equals, Filters.GreaterThan, Filters.GreaterThanOrEqual, Filters.InList, Filters.LessThan, Filters.LessThanOrEqual, Filters.NotContains, Filters.NotEmpty, Filters.NotEquals];\r\n }\r\n if (column.FilterMultiSelect && column.FilterValues && column.FilterValues.length > 0) {\r\n column.FilterTypes = [Filters.Equals, Filters.NotEquals];\r\n }\r\n\r\n let operation = column.Filter?.operation;\r\n\r\n if (!operation) {\r\n if (column.FilterTypes.length === 1) {\r\n operation = [column.FilterTypes[0]];\r\n } else if (column.FilterValueDefault) {\r\n operation = [column.FilterValueDefault];\r\n }\r\n }\r\n\r\n this.filterList.push({\r\n Type: \"System\",\r\n Name: column.Name,\r\n DisplayName: this.getColumnName(column),\r\n Operation: operation,\r\n ValueType: column.FilterType,\r\n ValueList: column.FilterValues,\r\n MultiSelect: column.FilterMultiSelect,\r\n Value: column.Filter?.value ?? \"\"\r\n });\r\n\r\n this.columnList.push(column);\r\n });\r\n }\r\n\r\n protected getFilters(filter: any) {\r\n let obj: any;\r\n let options: any = [];\r\n\r\n if (filter.Type === \"Custom\") {\r\n obj = this._customFilters.find((o: SDKDataGridCustomFilter) => o.Name === filter.Name);\r\n } else {\r\n obj = this._columns.find((o: SDKDataGridColumn) => o.Name === filter.Name);\r\n }\r\n\r\n obj.FilterTypes.forEach((type: any) => {\r\n options.push(type);\r\n })\r\n\r\n return options;\r\n }\r\n\r\n protected filterExists(value: any, filter: any) {\r\n let obj: any;\r\n\r\n if (filter.Type === \"Custom\") {\r\n obj = this._customFilters.find((o: SDKDataGridCustomFilter) => o.Name === filter.Name);\r\n } else {\r\n obj = this._columns.find((o: SDKDataGridColumn) => o.Name === filter.Name);\r\n }\r\n\r\n if (obj?.FilterTypes && obj.FilterTypes.length > 0) {\r\n if (Object.values(obj.FilterTypes).includes(value)) {\r\n return true;\r\n }\r\n } else {\r\n if (!obj.FilterTypes || obj.FilterTypes.length === 0 || Object.values(obj.FilterTypes).includes(value)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n protected getColumnName(column: SDKDataGridColumn) {\r\n let originalName = column.Name;\r\n\r\n if (column.FriendlyName && column.FriendlyName !== \"\") {\r\n originalName = column.FriendlyName;\r\n } else if (column.DisplayName && column.DisplayName !== \"\") {\r\n originalName = column.DisplayName;\r\n }\r\n\r\n return originalName;\r\n }\r\n\r\n private validate() {\r\n let valid: boolean = true;\r\n\r\n this.filterList.forEach((filter: any) => {\r\n if (![FilterType.Checkbox, FilterType.TextboxOnly].includes(filter.ValueType) && filter.Value.length > 0 && !filter.Operation) valid = false;\r\n })\r\n\r\n return valid;\r\n }\r\n\r\n /**************************************************************************\r\n * User Action Methods\r\n **************************************************************************/\r\n protected addOperation(event: any, filter: any) {\r\n let item: any = this.filterList.find(f => f.Name === filter.Name);\r\n\r\n if (item) {\r\n item.Operation = event;\r\n }\r\n }\r\n\r\n protected addValue(event: any, filter: any) {\r\n let item: any = this.filterList.find(f => f.Name === filter.Name);\r\n\r\n if (item) {\r\n item.Value = event.target.value;\r\n }\r\n }\r\n\r\n protected selectedValue(event: any, filter: any) {\r\n let item: any = this.filterList.find(f => f.Name === filter.Name);\r\n\r\n if (item) {\r\n item.Value = event;\r\n }\r\n\r\n filter.Value = event;\r\n }\r\n\r\n protected toggleAny(filter: any) {\r\n let item: any = this.filterList.find((f: any) => f.Type === \"Custom\" && f.ValueType === \"checkbox\" && f.Name === filter.Name);\r\n\r\n if (item) {\r\n if (item.Value === \"true\") {\r\n item.Value = \"\";\r\n } else {\r\n item.Value = \"true\";\r\n }\r\n }\r\n }\r\n\r\n protected reset() {\r\n this.message = {\r\n Title: \"Reset Filters\",\r\n Text: \"Are you sure?\",\r\n OKText: \"YES\",\r\n CancelText: \"NO\",\r\n OK: () => {\r\n this.showMessage = false;\r\n\r\n this._columns.forEach((column: SDKDataGridColumn) => {\r\n column.Filter = column._original.Filter;\r\n });\r\n\r\n this._customFilters.forEach(