JSPM

sdk-datagrid

1.3.17
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 38
  • Score
    100M100P100Q80049F
  • License MIT

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

Package Exports

  • sdk-datagrid
  • sdk-datagrid/package.json

Readme

Video Demo

Description:

Mobile-friendly customizable (Angular) datagrid with data options for manipulation, and charts for visualization.

INSTALLATION:

Using NPM:

npm install --save sdk-datagrid

CONFIGURATION:

To configure the sdk-datagrid for your application, add the following lines to your app.module.ts file:

import { SDKDatagridModule } from 'sdk-datagrid';

@NgModule({
    imports: [
        SDKDatagridModule
    ]
})
export class AppModule { }

USAGE:

To use the sdk-datagrid, follow the code options below. It can be embedded as a component on any page, or used as the ONLY component on any page.

HTML for partially loading large datasets

<sdk-datagrid
    [datasets]="datasets"
    [name]="activeView"
    [data]="data"
    [fullData]="fullData"
    [dbPage]="dbPage"
    [dbTotal]="dbTotal"
    [dbMAXRECORDS]="MAXRECORDS"
    [isLoading]="isLoading"
    [error]="error"
    (loadDataEvent)="loadData($event)">
</sdk-datagrid>

HTML for fully loading small datasets

<sdk-datagrid
    [datasets]="datasets"
    [name]="activeView"
    [data]="data"
    [isLoading]="isLoading"
    [error]="error"
    (loadDataEvent)="loadData($event)">
</sdk-datagrid>

.ts file

public isLoading: boolean = true;
public MAXRECORDS: number = 1000;
public activeView: string = "vwMyData";
public datasets: SDKDataGridDataset[] = [
    {
        Title: "My Data",
        DbName: "vwMyData",
        Source: "api/path/for/vxMyData"
    },
    {
        Title: "My Other Data",
        DbName: "vwMyOtherData",
        Source: "api/path/for/vwMyOtherData"
    }
];
public data: string = "";
public fullData: string = "";
public dbPage: number = 0;
public dbTotal: number = 0;
public error: string = "";

// Dynamically load datasets (optional).
private async loadDatasets() {
    this.isLoading = true;

    await this.httpService.Get("api/path/for/dynamic/datasets").then((data: any) => {
        if (data) {
            if (this.activeView === "" || !data.find((d: any) => d.DbName === this.activeView)) {
                this.activeView = data[0].DbName;
            }

            this.datasets = data;
        }
    });
}

// Callback function for loading data (required).
public async loadData(event: any = null) {
    this.isLoading = true;

    let body: string = this.buildBody(event);
    let fullLoad: boolean = false;

    if (event && (event.chart !== undefined || event.export !== undefined)) {
        fullLoad = true;
    }

    try {
        let ndx: number = this.datasets.findIndex((ds: any) => ds.DbName === this.activeView);

        if (ndx > -1) {
            let dataSource: string = this.datasets[ndx].Source;

            await this.httpService.Post(dataSource, body).then((data: any) => {
                this.resetVariables();

                if (data) {
                    if (fullLoad) {
                        this.fullData = data["Data"];
                    } else {
                        this.data = data["Data"];
                        this.dbPage = parseInt(data["Page"]);
                        this.dbTotal = parseInt(data["Total"]);
                        this.error = data["Error"];
                    }
                }
            });
        }
    } catch (error: any) {
        this.error = error.message;
    }

    this.isLoading = false;
}

// Change the body parameters to fit your API call.
private buildBody(event: any = null): string {
    let page: number = 1;
    let rows: number = this.MAXRECORDS;
    let sorts: any = [];
    let filters: any = [];

    if (event) {
        if (event.name && event.name !== "") {
            this.activeView = event.name;
        }

        if (event.page) {
            page = parseInt(event.page);
        }

        if (event.sorts) {
            event.sorts.forEach((element: any) => {
                sorts.push({ ColumnName: element.Name, Direction: element.Sort });
            });
        }

        if (event.filters) {
            event.filters.forEach((element: any) => {
                filters.push({ ColumnName: element.Name, Operation: element.Operation, Value: element.Value });
            });
        }

        if (event.chart || event.export) {
            page = 0;
            rows = 999999999;
        }

        if (event.addon) {
            // do addon stuff here
        }
    }

    let parameters: any = {
        page: page,
        rows: rows,
        filters: filters,
        sorts: sorts
    };

    return JSON.stringify(parameters);
}

private resetVariables() {
    this.data = "";
    this.fullData = "";
    this.dbPage = 0;
    this.dbTotal = 0;
    this.error = "";
}

Columns

If you want to specify the columns, use the columns option in the sdk-datagrid.

.ts file

@ViewChild('category') category!: TemplateRef<any>;
@ViewChild('dataTemplate') dataTemplate!: TemplateRef<any>;
@ViewChild('actionRight') actionRight!: TemplateRef<any>;

public columns: SDKDataGridColumn[] = [
    { Name: 'category', DisplayName: 'Category', required: true, requiredColor: 'red', notes: 'MUST be a valid Category.', editTemplate: () => this.category },
    { Name: 'air_date', DisplayName: 'Date', required: true, validCharacters: 'calendar', pattern: 'YYYY-MM-DD' },
    { Name: 'question', DisplayName: 'Question', height: '50px', width: '100px', dataTemplate: () => this.dataTemplate },
    { Name: 'value', DisplayName: 'Value', required: true, notes: 'Between 100 - 1000.', validCharacters: 'numeric' },
    { Name: 'answer', DisplayName: 'Answer', dataTemplate: () => this.dataTemplate },
    { Name: 'round', DisplayName: 'Round' },
    { Name: 'show_number', DisplayName: 'Show', validCharacters: 'custom', pattern: '^[0-9]{4}$' },
    { Name: 'fin', DisplayName: 'Completed' },
    { Name: 'Edit', DisplayName: 'Edit', actionSide: "right", actionTemplate: () => this.actionRight }
];

// If editing is enabled...
public editData(index: any) {
    this.editRowIndex = index;
}

public saveData(rowItem: any, activeRow: any) {
    for (let key in activeRow) {
        if (Object.prototype.hasOwnProperty.call(activeRow, key)) {
            rowItem[key] = activeRow[key];
        }
    }

    // Save to database and show message.

    this.editRowIndex = -1;
}

public cancelData() {
    this.editRowIndex = -1;
}

.html file

<sdk-datagrid
    [datasets]="datasets"
    [name]="activeView"
    [data]="data"
    [fullData]="fullData"
    [columns]="columns"
    [dbPage]="dbPage"
    [dbTotal]="dbTotal"
    [dbMAXRECORDS]="MAXRECORDS"
    [isLoading]="isLoading"
    [error]="error"
    (loadDataEvent)="loadData($event)">
</sdk-datagrid>

<ng-template #category let-rowItem="rowItem" let-index="index">
    <div>
        <select style="margin-left: 10px;">
            <option value="">...</option>
            <option value="HISTORY">HISTORY</option>
            <option value="3-LETTER WORDS">3-LETTER WORDS</option>
            <option value="THE COMPANY LINE">THE COMPANY LINE</option>
            <option value="EPITAPHS & TRIBUTES">EPITAPHS & TRIBUTES</option>
            <option value="ESPN's TOP 10 ALL-TIME ATHLETES">ESPN's TOP 10 ALL-TIME ATHLETES</option>
        </select>
    </div>
</ng-template>

<ng-template #dataTemplate let-value="value">
    <div>{{ value }}</div>
</ng-template>

<ng-template #actionRight let-rowItem="rowItem" let-activeRow="activeRow" let-index="index">
    <div *ngIf="!rowItem.isEdit">
        <div title="Edit" class="dg-icon material-symbols-outlined cursor" (click)="editData(index)">edit</div>
        <div title="Delete" class="dg-icon material-symbols-outlined cursor delete">delete</div>
    </div>
    <div *ngIf="rowItem.isEdit">
        <div title="Save" class="dg-icon material-symbols-outlined cursor done" (click)="saveData(rowItem, activeRow)">done</div>
        <div title="Cancel" class="dg-icon material-symbols-outlined cursor delete" (click)="cancelData()">close</div>
    </div>
</ng-template>

Custom Options

If you want to add a custom option to the sdk-datagrid, use the optionAddons/windowAddons parameters. First, create your "custom" option and window components.

mycustom-option.component

.html file

<div (click)="showDataOptions('myCustom')">
    <div title="My Custom Option" class="icon material-symbols-outlined" [ngClass]="optionTitle === 'myCustom' ? 'active' : ''">file_download</div>
    <div *ngIf="myCustomBadge !== ''" class="badge">
        <div class="label">{{ myCustomBadge }}</div>
    </div>
</div>

.scss/.css file

.icon {
    font-size: 2em;
    cursor: pointer;

    &.active {
        color: blue;
    }

    &:hover {
        color: blue;
    }
}

.badge {
    position: absolute;
    top: -5px;
    right: 0;

    height: 16px;
    width: 16px;

    border-radius: 50%;
    background: red;

    text-align: start;

    .label {
        position: absolute;
        top: 0;

        height: 16px;
        width: 16px;
        margin: 2px auto;

        text-align: center;
        font-size: 0.75em;
        color: white;
    }
}

.ts file

import { Component, EventEmitter, Input, Output } from '@angular/core';

@Component({
    selector: 'mycustom-option',
    templateUrl: './mycustom-option.component.html',
    styleUrls: ['./mycustom-option.component.scss']
})
export class MyCustomOptionComponent {
    @Input() optionTitle: string = ""; // Unique name for option.
    @Output() showDataOptionsEvent = new EventEmitter<any>(); // Method to show option window.

    public myCustomBadge: string = ""; // Used to add badge to custom option.

    public showDataOptions(type: string) {
        this.showDataOptionsEvent.emit(type);
    }
}

mycustom-window.component

.html file

<div *ngIf="dataClass === 'expand' && optionTitle === 'mycustom'" class="window">
    <div class="header">
        <span class="title">My Custom Option</span>
        <span title="Close" class="icon material-symbols-outlined close" (click)="close()">close</span>
    </div>
    <div class="content">
        // Add your custom option functionality here.
    </div>
    <div class="footer">
        <button class="button" type="button" (click)="apply()">Apply</button>
    </div>
</div>

.scss/.css file

.window {
    position: absolute;
    top: 10px;
    right: 10px;
    bottom: 10px;
    left: 10px;
    overflow: hidden;

    .header {
        position: absolute;
        top: 0;
        right: 0;
        left: 0;

        height: 50px;

        .title {
            position: absolute;
            top: 0;
            left: 0;
            font-size: large;
            font-weight: 600;
        }

        .close {
            position: absolute;
            top: 0;
            right: 0;

            &.icon {
                cursor: pointer;
                font-size: xx-large;

                &:hover {
                    color: blue;
                }
            }
        }
    }

    .actions {
        position: absolute;
        top: 50px;
        right: 0;
        left: 0;

        margin-top: 5px;

        height: 50px;
        width: 100%;

        .button-left {
            float: left;
            margin: 0;
        }

        .button-right {
            float: right;
            margin: 0;
            margin-right: 5px;
        }
    }

    .content {
        position: absolute;
        top: 50px;
        right: 0;
        bottom: 50px;
        left: 0;

        border: 1px solid gray;
        display: block;
        background: white;
        border-radius: 4px;
        margin-top: 0;
        overflow: auto;

        text-align: left;
    }

    .footer {
        position: absolute;
        right: 0;
        left: 0;
        bottom: 0;

        height: 40px;
        width: 100%;

        text-align: center;
    }

    button {
        box-shadow: 1px 1px 2px 1px rgb(140, 140, 140);
        border-radius: 5px;
    }
}

.ts file

import { Component, EventEmitter, Input, Output } from '@angular/core';

import { SDKDataGridColumn } from 'sdk-datagrid';

@Component({
    selector: 'mycustom-window',
    templateUrl: './mycustom-window.component.html',
    styleUrls: ['./mycustom-window.component.scss']
})
export class MyCustomWindowComponent {
    @Input() dataClass: string = ""; // Used to indicate if window is open/closed.
    @Input() optionTitle: string = ""; // Unique name for option.
    @Input() datasets: any[] = []; // Data array.
    @Input() columns: SDKDataGridColumn[] = []; // Columns defines for data.
    @Input() filters: any[] = []; // Filters defines for data.
    @Input() sorts: any[] = []; // Sorting defines for data.

    @Output() applyEvent = new EventEmitter<any>(); // Apply option.
    @Output() closeEvent = new EventEmitter<any>(); // Close window.

    public close() {
        this.closeEvent.emit();
    }

    public async apply() {
        this.applyEvent.emit();
        this.closeEvent.emit();
    }
}

Then add those components to your datagrid.

.ts file

import { MyCustomOptionComponent } from './mycustom/option/mycustom-option.component';
import { MyCustomWindowComponent } from './mycustom/window/mycustom-window.component';

public myCustomOptionComponent = MyCustomOptionComponent;
public myCustomWindowComponent = MyCustomWindowComponent;

.html file

<sdk-datagrid
    [datasets]="datasets"
    [name]="activeView"
    [data]="data"
    [fullData]="fullData"
    [columns]="columns"
    [optionAddons]="[myCustomOptionComponent]"
    [windowAddons]="[myCustomWindowComponent]"
    [dbPage]="dbPage"
    [dbTotal]="dbTotal"
    [dbMAXRECORDS]="MAXRECORDS"
    [isLoading]="isLoading"
    [error]="error"
    (loadDataEvent)="loadData($event)">
</sdk-datagrid>

NOTES:

  • The loadData() method is NOT directly called from your component. The sdk-datagrid will handle calling the method - including the initial load.

  • SDKDataGridDataset object is defined as:

    [
        {
            Title: "My Dataset", <-- Display name for UI (Text, Dropdown, Tab).
            DbName: "myDataset", <-- The name of the view/table.
            Source: "api/datasource" <-- The source of the data (optional).
        }
    ]
  • In order for the sdk-datagrid to handle data defined in the above example, your APIs should return the following object:

    {
        Data: {}, <-- The actual data in JSON form
        Page: 1, <-- Current page it is returning
        Total: 33, <-- Total records for entire query
        Error: "" <-- Any errors from API call
    }

    However, you can change the parameters in the API body to fit your specific needs.

    • If you are displaying a simple grid with data ONLY (no options/functionality), you can simply return and set the "this.data" parameter ONLY, and turn off the Header and Footer areas:
    <sdk-datagrid
        [datasets]="datasets"
        [name]="activeView"
        [data]="data"
        [showHeader]=false
        [showFooter]=false
        [isLoading]="isLoading"
        [error]="error"
        (loadDataEvent)="loadData($event)">
    </sdk-datagrid>
  • To use sorting, your APIs SHOULD be able to accept/handle an array of objects defining the columns/direction for sorting:

    sorts: [
        {
            ColumnName: "column",
            Direction: "asc" <-- See list below
        }
    ]

    Sort Direction List:

    - asc
    - desc
  • To use filtering, your APIs SHOULD be able to accept/handle an array of objects defining the columns/operators/values for filtering:

    filters: [
        {
            ColumnName: "column",
            Operation: "Equals", <-- See list below
            Value: "column_value"
        }
    ]

    Filter Operation List:

    - Equals
    - NotEquals
    - Empty (value is null)
    - NotEmpty (value is NOT null)
    - Contains
    - NotContains
    - GreaterThan
    - GreaterThanOrEqual
    - LessThan
    - LessThanOrEqual
    - InList
  • To customize filtering for a column:

    Define the FilterTypes and FilterValues in the columns object.

    public columns: SDKDataGridColumn[] = [
        { Name: 'category', DisplayName: 'Category', required: true, requiredColor: 'red', notes: 'MUST be a valid Category.', editTemplate: () => this.category },
        { Name: 'air_date', DisplayName: 'Date', required: true, validCharacters: 'calendar', pattern: 'YYYY-MM-DD' },
        { Name: 'question', DisplayName: 'Question', height: '50px', width: '100px', dataTemplate: () => this.dataTemplate },
        { Name: 'value', DisplayName: 'Value', required: true, notes: 'Between 100 - 1000.', validCharacters: 'numeric' },
        { Name: 'answer', DisplayName: 'Answer', dataTemplate: () => this.dataTemplate },
        { Name: 'round', DisplayName: 'Round', FilterTypes: [ Filters.Equals ], FilterValues: [ 'Jeopardy!', 'Double Jeopardy!' ] },
        { Name: 'show_number', DisplayName: 'Show', FilterTypes: [ Filters.LessThanOrEqual, Filters.GreaterThanOrEqual ], FilterValues: [ 4000, 4500, 5000 ], validCharacters: 'custom', pattern: '^[0-9]{4}$' },
        { Name: 'fin', DisplayName: 'Completed', FilterTypes: [ Filters.Equals ], FilterValues: [ true, false ] },
        { Name: 'Edit', DisplayName: 'Edit', actionSide: "right", actionTemplate: () => this.actionRight }
    ];

    To use a multi-select dropdown as your filter, define the FilterMultiSelect and FilterValues in the columns object.

    public columns: SDKDataGridColumn[] = [
        { Name: 'category', DisplayName: 'Category', required: true, requiredColor: 'red', notes: 'MUST be a valid Category.', editTemplate: () => this.category },
        { Name: 'air_date', DisplayName: 'Date', required: true, validCharacters: 'calendar', pattern: 'YYYY-MM-DD' },
        { Name: 'question', DisplayName: 'Question', isVisible: false, height: '50px', width: '100px', dataTemplate: () => this.dataTemplate },
        { Name: 'value', DisplayName: 'Value', required: true, notes: 'Between 100 - 1000.', validCharacters: 'numeric' },
        { Name: 'answer', DisplayName: 'Answer', showSort: false, showFilter: false, dataTemplate: () => this.dataTemplate },
        { Name: 'round', DisplayName: 'Round', FilterMultiSelect: true, FilterValues: [ 'Jeopardy!', 'Double Jeopardy!', 'Final Jeopardy!', 'Tiebreaker' ] },
        { Name: 'show_number', DisplayName: 'Show', FilterTypes: [ Filters.GreaterThanOrEqual, Filters.LessThanOrEqual ], FilterValues: [ 4000, 4500, 5000, 6000 ] },
        { Name: 'fin', DisplayName: 'Completed', FilterTypes: [ Filters.Equals ], FilterValues: [ true, false ]},
        { Name: 'Edit', DisplayName: 'Edit', actionSide: "right", actionTemplate: () => this.actionRight }
    ];
  • To create custom filters (SDKDataGridCustomFilter), the following properties are available:

    Name: string = ""; // Unique filter name.
    DisplayName?: string = "";  // Name to display to user.
    Type?: FilterType = FilterType.Textbox; <-- See list below
    
    // START: sdk-select properties for Dropdown filters.
    FilterMultiSelect?: boolean = false; // Allows multiple filter values to be selected.
    FilterTypes?: Filters[] = []; // Allows you to define specific filter types. NOTE: If FilterMultiSelect = true, this property is forced to [Filters.Equals, Filters.NotEquals].
    FilterValues?: any[] = []; // Allows you to define specific filter values.
    // END: sdk-select properties for Dropdown filters.

    FilterType Enums:

    - Textbox
    - Checkbox
    - Dropdown

    NOTE: If Type = FilterType.Textbox and is used with FilterTypes, the custom filter will have an Operation/Value layout. If FilterTypes is NOT used, the layout will ONLY have a Value.

  • To use formulas, the following properties are available:

    formulas: [
        {
            Name: string = "";
            Format: number = 0; <-- The number of digits for precision.
            Operation: FormulaOperation = "Avg"; <-- See list below
        }
    ]

    Formula Operation List:

    - Avg
    - Rng
    - Sum
  • To use columns (SDKDataGridColumn), the following properties are available:

    Name: string = ""; // Original db name.
    DisplayName?: string = "";  // System override of db name (Name).
    FriendlyName?: string = "";  // User provides. Produces * indicator.
    Sort?: string = "";
    
    ColumnSort?: boolean = false;
    showSort?: boolean = true; // Allows you to turn on/off sorting capabilities.
    showFilter?: boolean = true; // Allows you to turn on/off filtering capabilities.
    showTooltip?: boolean = false;
    isAction?: boolean = false; // Is the column associated to an action.
    isVisible?: boolean = true; // Allows you to turn on/off the visibility of the column.
    
    actionSide?: string = "right" // right or left
    
    // START: sdk-select properties
    FilterMultiSelect?: boolean = false; // Allows multiple filter values to be selected.
    FilterTypes?: any[] = []; // Allows you to define specific filter types. NOTE: If FilterMultiSelect = true, this property is forced to [Filters.Equals, Filters.NotEquals].
    FilterValues?: any[] = []; // Allows you to define specific filter values.
    // END: sdk-select properties
    
    // START: editTemplate option
    allowEdit?: boolean = true;
    required?: boolean = false;
    requiredColor?: string = "";
    notes?: string = "";
    validCharacters?: string = "";
    hint?: string = "";
    pattern?: string = "";
    height?: string = "";
    width?: string = "";
    border?: string = "";
    style?: string = "";
    // END: editTemplate option
    
    actionTemplate?: () => TemplateRef<any>; // Used to add "sticky" column for actions (i.e., Edit);
    editTemplate?: () => TemplateRef<any>; // Used to enable row-level edits.
    dataTemplate?: () => TemplateRef<any>; // Used to customize columns.
    
    formatter?: (value: any) => string; // Optional callback method to format the data.
    setFilterValues?: () => Promise<any[]>; // Optional callback method to load filter values.

List of properties for the sdk-datagrid:

/**************************************************************************
* Required Input Parameters
**************************************************************************/
datasets: SDKDataGridDataset[] = []; // Once provided, the loadDataEvent will be triggered.

/**************************************************************************
* Required Output Parameters
**************************************************************************/
loadDataEvent = new EventEmitter<any>(); // This is a callback to load data.

/**************************************************************************
* Optional Input/Output Parameters
**************************************************************************/
name: string = ""; // This value will be set by the loadDataEvent callback and will be the active dataset (view).
data: string = ""; // This value will be set by the loadDataEvent callback and contain the actual data.
fullData: string = ""; // This value will be set by the loadDataEvent callback when chart or export options are selected.

title: string = ""; // Add a title to the page if only 1 dataset (view) is being used.
titleStyle: string = ""; // Add a style to the title.
uniqueIdentifier: string = ""; // This value is ONLY used for creating the storage (saved session) name.
options: SDKDataGridOptions | null = null; // You can turn on/off data options.
columns: SDKDataGridColumn[] = []; // You can specify certain columns to be set.
customFilters: SDKDataGridCustomFilter[] = []; // Custom filters added to standard filter provided in loaddata callback (filters).
formulas: SDKDataGridFormula[] = []; // You can specify default formulas.
settings: SDKDataGridSettings[] = []; // Options that are saved outside the grid. This value should be set to the value retieved from the datagrid @Output method "settingsSavedEvent". Consider it a passthrough value.
includeAllColumns: boolean = false; // You can specify whether or not to include all columns in dataset.
isDataWrapped: boolean = false; // You can specify whether or not to wrap data within a column.
forceReload: boolean = false; // You can reload the current data.
fontFamily: string = ""; // Applies a given font-family to entire grid.
columnHeaderStyle: string = ""; // You can set the column header style for the grid.
filterTypes: Filters[] = []; // Limits the filtering list to provided types.
rowValues: [10, 25, 50, 100, 500, 1000]; // Allows you to override the values in the Rows dropdown.
defaultRow: 100; // Sets the default value of the Rows dropdown.

loadingStyle: string = ""; // Adjust the loading style when the datagrid is embedded on the page with other components.
error: string = ""; // Any errors that occur during processing.

useTabs: boolean = false; // This option shows the list of datasets in a tabular format (instead of the default dropdown).
isLoading: boolean = false; // Parent controlled variable for the entire grid.
showLoadingTimer: boolean = false; // Shows a timer while the loading component is running.

/**************************************************************************
* Edit Mode
**************************************************************************/
editRowIndex: any; // Required for editing rows. This is the current row index that is being edited.

/**************************************************************************
* Addon Parameters (Option Icon/Modal Window)
**************************************************************************/
optionAddons: Type<any>[] = [];
windowAddons: Type<any>[] = [];

/**************************************************************************
* Database Parameters
**************************************************************************/
dbMAXRECORDS: number = 1000; // Total records to retrieve from db on any given pull (skip/take).
dbPage: number | undefined; // Current db page (for partial loads).
dbTotal: number | undefined; // Total db records (based on filters).

/**************************************************************************
* UI Section Parameters
**************************************************************************/
showHeader: boolean = true; // Enable/disable the header section of the grid.
showOptions: boolean = true; // Enable/disable options section of the grid.
showFooter: boolean = true; // Enable/disable the footer section of the grid.
showPaging: boolean = true; // Enable/disable the paging section (within the footer) of the grid.
showPanelOverlay: boolean = false; // Enable/disable the overlay of the options panel.
autoClosePanel: boolean = false; // Enable/disable automatically closing panel after action.
minimizeOptions: boolean | undefined; // Minimize the 'options' section on the right-side of the grid.

detailTemplate!: TemplateRef<any> | undefined; // Embedded component for row detail.

/**************************************************************************
* Version - Used for local storage across ALL grids. This should be based
* on the version (whatever that may be) associated with your data model.
**************************************************************************/
version: string = "";

/**************************************************************************
* Optional Output Parameters
**************************************************************************/
columnSettingsChangedEvent: EventEmitter<SDKDataGridColumn[]> = new EventEmitter(); // Used as a callback for column changes.
settingsSavedEvent: EventEmitter<SDKDataGridSettings[]> = new EventEmitter(); // Used as a callback to save settings externally.
selectedRowsChangedEvent: EventEmitter<any[]> = new EventEmitter(); // Used as a callback for row changes.
selectedRowActionEvent: EventEmitter<any> = new EventEmitter(); // Used as a callback for row actions. NOTE: The return object is { data: [the row], index: [the row index] }