angular-slickgrid 4.1.2 → 4.2.0
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.
- package/.browserslistrc +12 -0
- package/.codecov.yml +17 -0
- package/.editorconfig +18 -0
- package/.eslintrc.json +50 -0
- package/.github/CODE_OF_CONDUCT.md +76 -0
- package/.github/FUNDING.yml +8 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +54 -0
- package/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +44 -0
- package/.github/renovate.json5 +26 -0
- package/.github/stale.yml +7 -0
- package/.github/workflows/main.yml +83 -0
- package/.vscode/extensions.json +9 -0
- package/.vscode/launch.json +72 -0
- package/.vscode/settings.json +7 -0
- package/.vscode/tasks.json +77 -0
- package/CHANGELOG.md +1172 -0
- package/LICENSE +20 -20
- package/README.md +9 -7
- package/angular.json +148 -0
- package/dist/LICENSE +20 -0
- package/dist/README.md +182 -0
- package/{angular-slickgrid.d.ts → dist/angular-slickgrid.d.ts} +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/components/angular-slickgrid.component.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/constants.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/extensions/index.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/extensions/slickRowDetailView.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/global-grid-options.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/index.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/models/angularComponentOutput.interface.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/models/angularGridInstance.interface.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/models/externalTestingDependencies.interface.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/models/gridOption.interface.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/models/index.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/models/rowDetailView.interface.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/models/slickGrid.interface.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/modules/angular-slickgrid.module.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/services/angularUtil.service.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/services/bsDropdown.service.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/services/container.service.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/services/index.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/services/translater.service.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/services/utilities.d.ts +0 -0
- package/{app → dist/app}/modules/angular-slickgrid/slickgrid-config.d.ts +0 -0
- package/{esm2020 → dist/esm2020}/angular-slickgrid.mjs +0 -0
- package/dist/esm2020/app/modules/angular-slickgrid/components/angular-slickgrid.component.mjs +1171 -0
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/constants.mjs +1 -1
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/extensions/index.mjs +1 -1
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/extensions/slickRowDetailView.mjs +2 -2
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/global-grid-options.mjs +1 -1
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/index.mjs +1 -1
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/models/angularComponentOutput.interface.mjs +1 -1
- package/dist/esm2020/app/modules/angular-slickgrid/models/angularGridInstance.interface.mjs +2 -0
- package/dist/esm2020/app/modules/angular-slickgrid/models/externalTestingDependencies.interface.mjs +2 -0
- package/dist/esm2020/app/modules/angular-slickgrid/models/gridOption.interface.mjs +2 -0
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/models/index.mjs +1 -1
- package/dist/esm2020/app/modules/angular-slickgrid/models/rowDetailView.interface.mjs +2 -0
- package/dist/esm2020/app/modules/angular-slickgrid/models/slickGrid.interface.mjs +2 -0
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/modules/angular-slickgrid.module.mjs +5 -5
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/angularUtil.service.mjs +4 -4
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/bsDropdown.service.mjs +4 -4
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/container.service.mjs +4 -4
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/index.mjs +1 -1
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/translater.service.mjs +4 -4
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/utilities.mjs +1 -1
- package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/slickgrid-config.mjs +1 -1
- package/{esm2020 → dist/esm2020}/public_api.mjs +1 -1
- package/{fesm2015 → dist/fesm2015}/angular-slickgrid.mjs +25 -22
- package/dist/fesm2015/angular-slickgrid.mjs.map +1 -0
- package/{fesm2020 → dist/fesm2020}/angular-slickgrid.mjs +25 -22
- package/dist/fesm2020/angular-slickgrid.mjs.map +1 -0
- package/{i18n → dist/i18n}/en.json +89 -89
- package/{i18n → dist/i18n}/fr.json +90 -90
- package/dist/package.json +79 -0
- package/{public_api.d.ts → dist/public_api.d.ts} +0 -0
- package/global.d.ts +1 -0
- package/ngcc.config.js +13 -0
- package/package.json +124 -37
- package/screenshots/column-picker.png +0 -0
- package/screenshots/composite-editor.png +0 -0
- package/screenshots/draggable-grouping.png +0 -0
- package/screenshots/editors.png +0 -0
- package/screenshots/export-to-file.png +0 -0
- package/screenshots/filter_and_sort.png +0 -0
- package/screenshots/formatters.png +0 -0
- package/screenshots/frozen.png +0 -0
- package/screenshots/multipleSelectFilter.png +0 -0
- package/screenshots/pagination.png +0 -0
- package/screenshots/selectFilter.png +0 -0
- package/screenshots/singleFilter.png +0 -0
- package/src/app/app-routing.module.ts +83 -0
- package/src/app/app.component.html +160 -0
- package/src/app/app.component.scss +65 -0
- package/src/app/app.component.ts +10 -0
- package/src/app/app.module.ts +175 -0
- package/src/app/examples/custom-angularComponentEditor.ts +184 -0
- package/src/app/examples/custom-angularComponentFilter.ts +126 -0
- package/src/app/examples/custom-inputEditor.ts +124 -0
- package/src/app/examples/custom-inputFilter.ts +142 -0
- package/src/app/examples/custom-titleFormatter.component.ts +8 -0
- package/src/app/examples/editor-ng-select.component.ts +37 -0
- package/src/app/examples/filter-ng-select.component.ts +32 -0
- package/src/app/examples/grid-additem.component.html +48 -0
- package/src/app/examples/grid-additem.component.ts +272 -0
- package/src/app/examples/grid-angular.component.html +79 -0
- package/src/app/examples/grid-angular.component.scss +28 -0
- package/src/app/examples/grid-angular.component.ts +370 -0
- package/src/app/examples/grid-autoheight.component.html +52 -0
- package/src/app/examples/grid-autoheight.component.ts +147 -0
- package/src/app/examples/grid-basic.component.html +29 -0
- package/src/app/examples/grid-basic.component.ts +82 -0
- package/src/app/examples/grid-clientside.component.html +51 -0
- package/src/app/examples/grid-clientside.component.ts +293 -0
- package/src/app/examples/grid-colspan.component.html +39 -0
- package/src/app/examples/grid-colspan.component.scss +11 -0
- package/src/app/examples/grid-colspan.component.ts +155 -0
- package/src/app/examples/grid-composite-editor.component.html +79 -0
- package/src/app/examples/grid-composite-editor.component.scss +19 -0
- package/src/app/examples/grid-composite-editor.component.ts +948 -0
- package/src/app/examples/grid-contextmenu.component.html +62 -0
- package/src/app/examples/grid-contextmenu.component.scss +44 -0
- package/src/app/examples/grid-contextmenu.component.ts +473 -0
- package/src/app/examples/grid-custom-tooltip.component.html +25 -0
- package/src/app/examples/grid-custom-tooltip.component.scss +77 -0
- package/src/app/examples/grid-custom-tooltip.component.ts +483 -0
- package/src/app/examples/grid-draggrouping.component.html +93 -0
- package/src/app/examples/grid-draggrouping.component.ts +397 -0
- package/src/app/examples/grid-editor.component.html +88 -0
- package/src/app/examples/grid-editor.component.ts +699 -0
- package/src/app/examples/grid-formatter.component.html +26 -0
- package/src/app/examples/grid-formatter.component.ts +162 -0
- package/src/app/examples/grid-frozen.component.html +65 -0
- package/src/app/examples/grid-frozen.component.scss +11 -0
- package/src/app/examples/grid-frozen.component.ts +303 -0
- package/src/app/examples/grid-graphql-nopage.component.html +33 -0
- package/src/app/examples/grid-graphql-nopage.component.scss +9 -0
- package/src/app/examples/grid-graphql-nopage.component.ts +242 -0
- package/src/app/examples/grid-graphql.component.html +87 -0
- package/src/app/examples/grid-graphql.component.ts +304 -0
- package/src/app/examples/grid-grouping.component.html +80 -0
- package/src/app/examples/grid-grouping.component.ts +313 -0
- package/src/app/examples/grid-headerbutton.component.html +31 -0
- package/src/app/examples/grid-headerbutton.component.scss +10 -0
- package/src/app/examples/grid-headerbutton.component.ts +233 -0
- package/src/app/examples/grid-headermenu.component.html +31 -0
- package/src/app/examples/grid-headermenu.component.scss +25 -0
- package/src/app/examples/grid-headermenu.component.ts +159 -0
- package/src/app/examples/grid-localization.component.html +54 -0
- package/src/app/examples/grid-localization.component.ts +293 -0
- package/src/app/examples/grid-menu.component.html +37 -0
- package/src/app/examples/grid-menu.component.scss +28 -0
- package/src/app/examples/grid-menu.component.ts +229 -0
- package/src/app/examples/grid-odata.component.html +116 -0
- package/src/app/examples/grid-odata.component.ts +441 -0
- package/src/app/examples/grid-range.component.html +74 -0
- package/src/app/examples/grid-range.component.ts +291 -0
- package/src/app/examples/grid-remote.component.html +37 -0
- package/src/app/examples/grid-remote.component.ts +153 -0
- package/src/app/examples/grid-resize-by-content.component.html +62 -0
- package/src/app/examples/grid-resize-by-content.component.scss +19 -0
- package/src/app/examples/grid-resize-by-content.component.ts +780 -0
- package/src/app/examples/grid-rowdetail.component.html +35 -0
- package/src/app/examples/grid-rowdetail.component.ts +205 -0
- package/src/app/examples/grid-rowmove.component.html +49 -0
- package/src/app/examples/grid-rowmove.component.ts +234 -0
- package/src/app/examples/grid-rowselection.component.html +76 -0
- package/src/app/examples/grid-rowselection.component.ts +267 -0
- package/src/app/examples/grid-state.component.html +36 -0
- package/src/app/examples/grid-state.component.ts +259 -0
- package/src/app/examples/grid-tabs.component.html +35 -0
- package/src/app/examples/grid-tabs.component.ts +115 -0
- package/src/app/examples/grid-trading.component.html +58 -0
- package/src/app/examples/grid-trading.component.scss +49 -0
- package/src/app/examples/grid-trading.component.ts +319 -0
- package/src/app/examples/grid-tree-data-hierarchical.component.html +79 -0
- package/src/app/examples/grid-tree-data-hierarchical.component.scss +47 -0
- package/src/app/examples/grid-tree-data-hierarchical.component.ts +311 -0
- package/src/app/examples/grid-tree-data-parent-child.component.html +108 -0
- package/src/app/examples/grid-tree-data-parent-child.component.scss +10 -0
- package/src/app/examples/grid-tree-data-parent-child.component.ts +351 -0
- package/src/app/examples/home.component.html +41 -0
- package/src/app/examples/home.component.ts +9 -0
- package/src/app/examples/rowdetail-preload.component.ts +10 -0
- package/src/app/examples/rowdetail-view.component.html +36 -0
- package/src/app/examples/rowdetail-view.component.ts +54 -0
- package/src/app/examples/swt-common-grid-pagination.component.ts +156 -0
- package/src/app/examples/swt-common-grid-test.component.html +30 -0
- package/src/app/examples/swt-common-grid-test.component.ts +219 -0
- package/src/app/examples/swt-common-grid.component.ts +436 -0
- package/src/app/examples/swt-logger.service.ts +165 -0
- package/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.html +4 -0
- package/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts +1395 -0
- package/src/app/modules/angular-slickgrid/constants.ts +97 -0
- package/src/app/modules/angular-slickgrid/extensions/index.ts +1 -0
- package/src/app/modules/angular-slickgrid/extensions/slickRowDetailView.ts +375 -0
- package/src/app/modules/angular-slickgrid/global-grid-options.ts +245 -0
- package/src/app/modules/angular-slickgrid/index.ts +11 -0
- package/src/app/modules/angular-slickgrid/models/angularComponentOutput.interface.ts +6 -0
- package/src/app/modules/angular-slickgrid/models/angularGridInstance.interface.ts +68 -0
- package/src/app/modules/angular-slickgrid/models/externalTestingDependencies.interface.ts +37 -0
- package/src/app/modules/angular-slickgrid/models/gridOption.interface.ts +12 -0
- package/src/app/modules/angular-slickgrid/models/index.ts +6 -0
- package/src/app/modules/angular-slickgrid/models/rowDetailView.interface.ts +33 -0
- package/src/app/modules/angular-slickgrid/models/slickGrid.interface.ts +7 -0
- package/src/app/modules/angular-slickgrid/modules/angular-slickgrid.module.ts +37 -0
- package/src/app/modules/angular-slickgrid/services/angularUtil.service.ts +48 -0
- package/src/app/modules/angular-slickgrid/services/bsDropdown.service.ts +142 -0
- package/src/app/modules/angular-slickgrid/services/container.service.ts +24 -0
- package/src/app/modules/angular-slickgrid/services/index.ts +5 -0
- package/src/app/modules/angular-slickgrid/services/translater.service.ts +38 -0
- package/src/app/modules/angular-slickgrid/services/utilities.ts +19 -0
- package/src/app/modules/angular-slickgrid/slickgrid-config.ts +10 -0
- package/src/app/slickgrid-custom-variables.scss +10 -0
- package/src/assets/.gitkeep +0 -0
- package/src/assets/data/collection_100_numbers.json +12 -0
- package/src/assets/data/collection_500_numbers.json +52 -0
- package/src/assets/data/countries.json +245 -0
- package/src/assets/data/country_names.json +245 -0
- package/src/assets/data/customers_100.json +102 -0
- package/src/assets/i18n/en.json +90 -0
- package/src/assets/i18n/fr.json +91 -0
- package/src/environments/environment.prod.ts +3 -0
- package/src/environments/environment.ts +8 -0
- package/src/favicon.ico +0 -0
- package/src/index.html +18 -0
- package/src/main.ts +13 -0
- package/src/polyfills.ts +52 -0
- package/src/public_api.ts +1 -0
- package/src/styles.scss +66 -0
- package/src/typings.d.ts +10 -0
- package/tsconfig.app.json +25 -0
- package/tsconfig.json +40 -0
- package/tsconfig.spec.json +23 -0
- package/docs/assets/lib/multiple-select/README.md +0 -17
- package/esm2020/app/modules/angular-slickgrid/components/angular-slickgrid.component.mjs +0 -1168
- package/esm2020/app/modules/angular-slickgrid/models/angularGridInstance.interface.mjs +0 -2
- package/esm2020/app/modules/angular-slickgrid/models/externalTestingDependencies.interface.mjs +0 -2
- package/esm2020/app/modules/angular-slickgrid/models/gridOption.interface.mjs +0 -2
- package/esm2020/app/modules/angular-slickgrid/models/rowDetailView.interface.mjs +0 -2
- package/esm2020/app/modules/angular-slickgrid/models/slickGrid.interface.mjs +0 -2
- package/fesm2015/angular-slickgrid.mjs.map +0 -1
- package/fesm2020/angular-slickgrid.mjs.map +0 -1
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
|
2
|
+
import { ExcelExportService } from '@slickgrid-universal/excel-export';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
AngularGridInstance,
|
|
6
|
+
Column,
|
|
7
|
+
FieldType,
|
|
8
|
+
Filters,
|
|
9
|
+
Formatters,
|
|
10
|
+
GridOption,
|
|
11
|
+
GridStateChange,
|
|
12
|
+
GridStateType,
|
|
13
|
+
TreeToggledItem,
|
|
14
|
+
TreeToggleStateChange,
|
|
15
|
+
} from './../modules/angular-slickgrid';
|
|
16
|
+
|
|
17
|
+
const NB_ITEMS = 500;
|
|
18
|
+
|
|
19
|
+
@Component({
|
|
20
|
+
templateUrl: './grid-tree-data-parent-child.component.html',
|
|
21
|
+
styleUrls: ['grid-tree-data-parent-child.component.scss'],
|
|
22
|
+
encapsulation: ViewEncapsulation.None
|
|
23
|
+
})
|
|
24
|
+
export class GridTreeDataParentChildComponent implements OnInit {
|
|
25
|
+
title = 'Example 28: Tree Data <small> <span class="mdi mdi-file-tree mdi-27px"></span> (from a flat dataset with <code>parentId</code> references - <a href="https://github.com/ghiscoding/Angular-Slickgrid/wiki/Tree-Data-Grid" target="_blank">Wiki</a>)</small>';
|
|
26
|
+
subTitle = `<ul>
|
|
27
|
+
<li>It is assumed that your dataset will have Parent/Child references AND also Tree Level (indent) property.</li>
|
|
28
|
+
<ul>
|
|
29
|
+
<li>If you do not have the Tree Level (indent), you could call "convertParentChildArrayToHierarchicalView()" then call "convertHierarchicalViewToParentChildArray()"</li>
|
|
30
|
+
<li>You could also pass the result of "convertParentChildArrayToHierarchicalView()" to "dataset-hierarchical.bind" as defined in the next Hierarchical Example</li>
|
|
31
|
+
</ul>
|
|
32
|
+
<li><b>Styling - Material Theme</b></li>
|
|
33
|
+
<ul>
|
|
34
|
+
<li>The Material Theme was created with SASS and compiled in CSS (<a href="https://github.com/ghiscoding/Angular-Slickgrid/blob/master/src/app/modules/angular-slickgrid/styles/slickgrid-theme-material.scss" target="_blank">slickgrid-theme-material.scss</a>), you can override any of its SASS variables</li>
|
|
35
|
+
<li>We use a small subset of <a href="https://materialdesignicons.com/" target="_blank">Material Design Icons</a></li>
|
|
36
|
+
<li>you might need to refresh the page to clear the browser cache and see the correct theme</li>
|
|
37
|
+
</ul>
|
|
38
|
+
</ul>`;
|
|
39
|
+
|
|
40
|
+
angularGrid!: AngularGridInstance;
|
|
41
|
+
dataViewObj: any;
|
|
42
|
+
gridObj: any;
|
|
43
|
+
gridOptions!: GridOption;
|
|
44
|
+
columnDefinitions!: Column[];
|
|
45
|
+
dataset!: any[];
|
|
46
|
+
datasetHierarchical: any[] = [];
|
|
47
|
+
loadingClass = '';
|
|
48
|
+
isLargeDataset = false;
|
|
49
|
+
hasNoExpandCollapseChanged = true;
|
|
50
|
+
treeToggleItems: TreeToggledItem[] = [];
|
|
51
|
+
|
|
52
|
+
constructor() { }
|
|
53
|
+
|
|
54
|
+
ngOnInit(): void {
|
|
55
|
+
// define the grid options & columns and then create the grid itself
|
|
56
|
+
this.defineGrid();
|
|
57
|
+
|
|
58
|
+
// mock a dataset
|
|
59
|
+
this.dataset = this.loadData(NB_ITEMS);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
defineGrid() {
|
|
63
|
+
this.columnDefinitions = [
|
|
64
|
+
{
|
|
65
|
+
id: 'title', name: 'Title', field: 'title', width: 220, cssClass: 'cell-title',
|
|
66
|
+
filterable: true, sortable: true, exportWithFormatter: false,
|
|
67
|
+
queryFieldSorter: 'id', type: FieldType.string,
|
|
68
|
+
formatter: Formatters.tree, exportCustomFormatter: Formatters.treeExport
|
|
69
|
+
|
|
70
|
+
},
|
|
71
|
+
{ id: 'duration', name: 'Duration', field: 'duration', minWidth: 90, filterable: true },
|
|
72
|
+
{
|
|
73
|
+
id: 'percentComplete', name: '% Complete', field: 'percentComplete',
|
|
74
|
+
minWidth: 120, maxWidth: 200, exportWithFormatter: false,
|
|
75
|
+
sortable: true, filterable: true, filter: { model: Filters.compoundSlider, operator: '>=' },
|
|
76
|
+
formatter: Formatters.percentCompleteBarWithText, type: FieldType.number,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: 'start', name: 'Start', field: 'start', minWidth: 60,
|
|
80
|
+
type: FieldType.dateIso, filterable: true, sortable: true,
|
|
81
|
+
filter: { model: Filters.compoundDate },
|
|
82
|
+
formatter: Formatters.dateIso,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'finish', name: 'Finish', field: 'finish', minWidth: 60,
|
|
86
|
+
type: FieldType.dateIso, filterable: true, sortable: true,
|
|
87
|
+
filter: { model: Filters.compoundDate },
|
|
88
|
+
formatter: Formatters.dateIso,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: 'effortDriven', name: 'Effort Driven', width: 80, minWidth: 20, maxWidth: 80, cssClass: 'cell-effort-driven', field: 'effortDriven',
|
|
92
|
+
exportWithFormatter: false,
|
|
93
|
+
formatter: Formatters.checkmark, cannotTriggerInsert: true,
|
|
94
|
+
filterable: true,
|
|
95
|
+
filter: {
|
|
96
|
+
collection: [{ value: '', label: '' }, { value: true, label: 'True' }, { value: false, label: 'False' }],
|
|
97
|
+
model: Filters.singleSelect
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
this.gridOptions = {
|
|
103
|
+
autoResize: {
|
|
104
|
+
container: '#demo-container',
|
|
105
|
+
rightPadding: 10
|
|
106
|
+
},
|
|
107
|
+
enableAutoSizeColumns: true,
|
|
108
|
+
enableAutoResize: true,
|
|
109
|
+
enableExcelExport: true,
|
|
110
|
+
excelExportOptions: { exportWithFormatter: true, sanitizeDataExport: true },
|
|
111
|
+
registerExternalResources: [new ExcelExportService()],
|
|
112
|
+
enableFiltering: true,
|
|
113
|
+
showCustomFooter: true, // display some metrics in the bottom custom footer
|
|
114
|
+
enableTreeData: true, // you must enable this flag for the filtering & sorting to work as expected
|
|
115
|
+
treeDataOptions: {
|
|
116
|
+
columnId: 'title',
|
|
117
|
+
parentPropName: 'parentId',
|
|
118
|
+
// this is optional, you can define the tree level property name that will be used for the sorting/indentation, internally it will use "__treeLevel"
|
|
119
|
+
levelPropName: 'treeLevel',
|
|
120
|
+
indentMarginLeft: 15,
|
|
121
|
+
initiallyCollapsed: true,
|
|
122
|
+
|
|
123
|
+
// you can optionally sort by a different column and/or sort direction
|
|
124
|
+
// this is the recommend approach, unless you are 100% that your original array is already sorted (in most cases it's not)
|
|
125
|
+
initialSort: {
|
|
126
|
+
columnId: 'title',
|
|
127
|
+
direction: 'ASC'
|
|
128
|
+
},
|
|
129
|
+
// we can also add a custom Formatter just for the title text portion
|
|
130
|
+
titleFormatter: (_row, _cell, value, _def, dataContext) => {
|
|
131
|
+
let prefix = '';
|
|
132
|
+
if (dataContext.treeLevel > 0) {
|
|
133
|
+
prefix = `<span class="mdi mdi-subdirectory-arrow-right mdi-v-align-sub color-se-secondary"></span>`;
|
|
134
|
+
}
|
|
135
|
+
return `${prefix}<span class="bold">${value}</span> <span style="font-size:11px; margin-left: 15px;">(parentId: ${dataContext.parentId})</span>`;
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
multiColumnSort: false, // multi-column sorting is not supported with Tree Data, so you need to disable it
|
|
139
|
+
presets: {
|
|
140
|
+
filters: [{ columnId: 'percentComplete', searchTerms: [25], operator: '>=' }],
|
|
141
|
+
// treeData: { toggledItems: [{ itemId: 1, isCollapsed: false }] },
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
// change header/cell row height for material design theme
|
|
145
|
+
headerRowHeight: 45,
|
|
146
|
+
rowHeight: 40,
|
|
147
|
+
// if you're dealing with lots of data, it is recommended to use the filter debounce
|
|
148
|
+
filterTypingDebounce: 250,
|
|
149
|
+
|
|
150
|
+
// use Material Design SVG icons
|
|
151
|
+
contextMenu: {
|
|
152
|
+
iconCollapseAllGroupsCommand: 'mdi mdi-arrow-collapse',
|
|
153
|
+
iconExpandAllGroupsCommand: 'mdi mdi-arrow-expand',
|
|
154
|
+
iconClearGroupingCommand: 'mdi mdi-close',
|
|
155
|
+
iconCopyCellValueCommand: 'mdi mdi-content-copy',
|
|
156
|
+
iconExportCsvCommand: 'mdi mdi-download',
|
|
157
|
+
iconExportExcelCommand: 'mdi mdi-file-excel-outline',
|
|
158
|
+
iconExportTextDelimitedCommand: 'mdi mdi-download',
|
|
159
|
+
},
|
|
160
|
+
gridMenu: {
|
|
161
|
+
iconCssClass: 'mdi mdi-menu',
|
|
162
|
+
iconClearAllFiltersCommand: 'mdi mdi-filter-remove-outline',
|
|
163
|
+
iconClearAllSortingCommand: 'mdi mdi-swap-vertical',
|
|
164
|
+
iconExportCsvCommand: 'mdi mdi-download',
|
|
165
|
+
iconExportExcelCommand: 'mdi mdi-file-excel-outline',
|
|
166
|
+
iconExportTextDelimitedCommand: 'mdi mdi-download',
|
|
167
|
+
iconRefreshDatasetCommand: 'mdi mdi-sync',
|
|
168
|
+
iconToggleFilterCommand: 'mdi mdi-flip-vertical',
|
|
169
|
+
iconTogglePreHeaderCommand: 'mdi mdi-flip-vertical',
|
|
170
|
+
},
|
|
171
|
+
headerMenu: {
|
|
172
|
+
iconClearFilterCommand: 'mdi mdi mdi-filter-remove-outline',
|
|
173
|
+
iconClearSortCommand: 'mdi mdi-swap-vertical',
|
|
174
|
+
iconSortAscCommand: 'mdi mdi-sort-ascending',
|
|
175
|
+
iconSortDescCommand: 'mdi mdi-flip-v mdi-sort-descending',
|
|
176
|
+
iconColumnHideCommand: 'mdi mdi-close',
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
angularGridReady(angularGrid: AngularGridInstance) {
|
|
182
|
+
this.angularGrid = angularGrid;
|
|
183
|
+
this.gridObj = angularGrid.slickGrid;
|
|
184
|
+
this.dataViewObj = angularGrid.dataView;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* A simple method to add a new item inside the first group that we find (it's random and is only for demo purposes).
|
|
189
|
+
* After adding the item, it will sort by parent/child recursively
|
|
190
|
+
*/
|
|
191
|
+
addNewRow() {
|
|
192
|
+
const newId = this.dataViewObj.getItemCount();
|
|
193
|
+
const parentPropName = 'parentId';
|
|
194
|
+
const treeLevelPropName = 'treeLevel'; // if undefined in your options, the default prop name is "__treeLevel"
|
|
195
|
+
const newTreeLevel = 1;
|
|
196
|
+
|
|
197
|
+
// find first parent object and add the new item as a child
|
|
198
|
+
const childItemFound = this.dataViewObj.getItems().find((item: any) => item[treeLevelPropName] === newTreeLevel);
|
|
199
|
+
const parentItemFound = this.dataViewObj.getItemByIdx(childItemFound[parentPropName]);
|
|
200
|
+
|
|
201
|
+
if (childItemFound && parentItemFound) {
|
|
202
|
+
const newItem = {
|
|
203
|
+
id: newId,
|
|
204
|
+
parentId: parentItemFound.id,
|
|
205
|
+
title: `Task ${newId}`,
|
|
206
|
+
duration: '1 day',
|
|
207
|
+
percentComplete: 99,
|
|
208
|
+
start: new Date(),
|
|
209
|
+
finish: new Date(),
|
|
210
|
+
effortDriven: false
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// use the Grid Service to insert the item,
|
|
214
|
+
// it will also internally take care of updating & resorting the hierarchical dataset
|
|
215
|
+
this.angularGrid.gridService.addItem(newItem);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
collapseAll() {
|
|
220
|
+
this.angularGrid.treeDataService.toggleTreeDataCollapse(true);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
collapseAllWithoutEvent() {
|
|
224
|
+
this.angularGrid.treeDataService.toggleTreeDataCollapse(true, false);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
expandAll() {
|
|
228
|
+
this.angularGrid.treeDataService.toggleTreeDataCollapse(false);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
dynamicallyChangeFilter() {
|
|
232
|
+
// const randomPercentage = Math.floor((Math.random() * 99));
|
|
233
|
+
this.angularGrid.filterService.updateFilters([{ columnId: 'percentComplete', operator: '<', searchTerms: [40] }]);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
hideSpinner() {
|
|
237
|
+
setTimeout(() => this.loadingClass = '', 200); // delay the hide spinner a bit to avoid show/hide too quickly
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
showSpinner() {
|
|
241
|
+
if (this.isLargeDataset) {
|
|
242
|
+
this.loadingClass = 'mdi mdi-load mdi-spin-1s mdi-24px color-alt-success';
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
logHierarchicalStructure() {
|
|
247
|
+
console.log('exploded array', this.angularGrid.treeDataService.datasetHierarchical);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
logFlatStructure() {
|
|
251
|
+
console.log('flat array', this.angularGrid.treeDataService.dataset);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
loadData(rowCount: number) {
|
|
255
|
+
this.isLargeDataset = rowCount > 5000; // we'll show a spinner when it's large, else don't show show since it should be fast enough
|
|
256
|
+
let indent = 0;
|
|
257
|
+
const parents = [];
|
|
258
|
+
const data = [];
|
|
259
|
+
// prepare the data
|
|
260
|
+
for (let i = 0; i < rowCount; i++) {
|
|
261
|
+
const randomYear = 2000 + Math.floor(Math.random() * 10);
|
|
262
|
+
const randomMonth = Math.floor(Math.random() * 11);
|
|
263
|
+
const randomDay = Math.floor((Math.random() * 29));
|
|
264
|
+
const item: any = (data[i] = {});
|
|
265
|
+
let parentId;
|
|
266
|
+
|
|
267
|
+
/*
|
|
268
|
+
for demo & E2E testing purposes, let's make "Task 0" empty and then "Task 1" a parent that contains at least "Task 2" and "Task 3" which the latter will also contain "Task 4" (as shown below)
|
|
269
|
+
also for all other rows don't go over indent tree level depth of 2
|
|
270
|
+
Task 0
|
|
271
|
+
Task 1
|
|
272
|
+
Task 2
|
|
273
|
+
Task 3
|
|
274
|
+
Task 4
|
|
275
|
+
...
|
|
276
|
+
*/
|
|
277
|
+
if (i === 1 || i === 0) {
|
|
278
|
+
indent = 0;
|
|
279
|
+
parents.pop();
|
|
280
|
+
} if (i === 3) {
|
|
281
|
+
indent = 1;
|
|
282
|
+
} else if (i === 2 || i === 4 || (Math.random() > 0.8 && i > 0 && indent < 3 && i - 1 !== 0 && i - 1 !== 2)) { // also make sure Task 0, 2 remains empty
|
|
283
|
+
indent++;
|
|
284
|
+
parents.push(i - 1);
|
|
285
|
+
} else if ((Math.random() < 0.3 && indent > 0)) {
|
|
286
|
+
indent--;
|
|
287
|
+
parents.pop();
|
|
288
|
+
}
|
|
289
|
+
if (parents.length > 0) {
|
|
290
|
+
parentId = parents[parents.length - 1];
|
|
291
|
+
} else {
|
|
292
|
+
parentId = null;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
item['id'] = i;
|
|
296
|
+
item['parentId'] = parentId;
|
|
297
|
+
item['title'] = `Task ${i}`;
|
|
298
|
+
item['duration'] = '5 days';
|
|
299
|
+
item['percentComplete'] = Math.round(Math.random() * 100);
|
|
300
|
+
item['start'] = new Date(randomYear, randomMonth, randomDay);
|
|
301
|
+
item['finish'] = new Date(randomYear, (randomMonth + 1), randomDay);
|
|
302
|
+
item['effortDriven'] = (i % 5 === 0);
|
|
303
|
+
}
|
|
304
|
+
this.dataset = data;
|
|
305
|
+
return data;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
handleOnTreeFullToggleEnd(treeToggleExecution: TreeToggleStateChange) {
|
|
309
|
+
console.log('Tree Data changes', treeToggleExecution);
|
|
310
|
+
this.hideSpinner();
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/** Whenever a parent is being toggled, we'll keep a reference of all of these changes so that we can reapply them whenever we want */
|
|
314
|
+
handleOnTreeItemToggled(treeToggleExecution: TreeToggleStateChange) {
|
|
315
|
+
this.hasNoExpandCollapseChanged = false;
|
|
316
|
+
this.treeToggleItems = treeToggleExecution.toggledItems as TreeToggledItem[];
|
|
317
|
+
console.log('Tree Data changes', treeToggleExecution);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
handleOnGridStateChanged(gridStateChange: GridStateChange) {
|
|
321
|
+
this.hasNoExpandCollapseChanged = false;
|
|
322
|
+
|
|
323
|
+
if (gridStateChange?.change?.type === GridStateType.treeData) {
|
|
324
|
+
console.log('Tree Data gridStateChange', gridStateChange?.gridState?.treeData);
|
|
325
|
+
this.treeToggleItems = gridStateChange?.gridState?.treeData?.toggledItems as TreeToggledItem[];
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
logTreeDataToggledItems() {
|
|
330
|
+
console.log(this.angularGrid.treeDataService.getToggledItems());
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
dynamicallyToggledFirstParent() {
|
|
334
|
+
const parentPropName = 'parentId';
|
|
335
|
+
const treeLevelPropName = 'treeLevel'; // if undefined in your options, the default prop name is "__treeLevel"
|
|
336
|
+
const newTreeLevel = 1;
|
|
337
|
+
|
|
338
|
+
// find first parent object and toggle it
|
|
339
|
+
const childItemFound = this.dataset.find((item) => item[treeLevelPropName] === newTreeLevel);
|
|
340
|
+
const parentItemFound = this.angularGrid.dataView.getItemByIdx(childItemFound[parentPropName]);
|
|
341
|
+
|
|
342
|
+
if (childItemFound && parentItemFound) {
|
|
343
|
+
this.angularGrid.treeDataService.dynamicallyToggleItemState([{ itemId: parentItemFound.id, isCollapsed: !parentItemFound.__collapsed }]);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
reapplyToggledItems() {
|
|
348
|
+
this.angularGrid.treeDataService.applyToggledItemStateChanges(this.treeToggleItems);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<div class="container">
|
|
2
|
+
<h2>{{title}}</h2>
|
|
3
|
+
<div class="subtitle" [innerHTML]="subTitle"></div>
|
|
4
|
+
|
|
5
|
+
<hr />
|
|
6
|
+
|
|
7
|
+
<h4>Description</h4>
|
|
8
|
+
<p>
|
|
9
|
+
One of the best javascript datagrid
|
|
10
|
+
<a href="https://github.com/mleibman/SlickGrid"
|
|
11
|
+
target="_blank">SlickGrid</a> which was originally developed by @mleibman is now available to Angular. I have
|
|
12
|
+
tried and used a few datagrids and SlickGrid beats most of them in terms of functionalities
|
|
13
|
+
and performance (it can easily deal with even a million row).
|
|
14
|
+
</p>
|
|
15
|
+
<h4>Wiki / Documentation</h4>
|
|
16
|
+
<p>
|
|
17
|
+
The Wiki is where all the documentation and instructions will go, so please consult the
|
|
18
|
+
<a href="https://github.com/ghiscoding/Angular-Slickgrid/wiki"
|
|
19
|
+
target="_blank">Angular-Slickgrid - Wiki</a>
|
|
20
|
+
before opening any issues.
|
|
21
|
+
<br />
|
|
22
|
+
The
|
|
23
|
+
<a href="https://github.com/ghiscoding/angular-slickgrid/wiki/HOWTO---Step-by-Step"
|
|
24
|
+
target="_blank">HOWTO - Wiki</a>
|
|
25
|
+
is the best starting point to get going with this library.
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
<hr />
|
|
29
|
+
Like my work? You can support me with caffeine :)
|
|
30
|
+
|
|
31
|
+
<br /><br />
|
|
32
|
+
|
|
33
|
+
<a href='https://ko-fi.com/N4N679OT'
|
|
34
|
+
target='_blank'>
|
|
35
|
+
<img height='36'
|
|
36
|
+
style='border:0px;height:36px;'
|
|
37
|
+
src='https://az743702.vo.msecnd.net/cdn/kofi2.png?v=0'
|
|
38
|
+
border='0'
|
|
39
|
+
alt='Buy Me a Coffee at ko-fi.com' />
|
|
40
|
+
</a>
|
|
41
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
templateUrl: './home.component.html'
|
|
5
|
+
})
|
|
6
|
+
export class HomeComponent {
|
|
7
|
+
title = 'Angular-Slickgrid - Demo Site';
|
|
8
|
+
subTitle = 'This site is to demo multiple usage of Angular-Slickgrid, choose an example from left side menu';
|
|
9
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<div class="container-fluid">
|
|
2
|
+
<h3>{{model?.title}}</h3>
|
|
3
|
+
<div class="row">
|
|
4
|
+
<div class="col-3"><label>Assignee:</label> <input class="form-control" [(ngModel)]="model.assignee" /></div>
|
|
5
|
+
<div class="col-3"><label>Reporter:</label> <span>{{model?.reporter}}</span></div>
|
|
6
|
+
<div class="col-2"><label>Duration:</label> <span>{{model?.duration | number : '1.2-2'}}</span></div>
|
|
7
|
+
<div class="col-2"><label>% Complete:</label> <span>{{model?.percentComplete}}</span></div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="row">
|
|
11
|
+
<div class="col-3"><label>Start:</label> <span>{{model?.start | date: 'yyyy-MM-dd'}}</span></div>
|
|
12
|
+
<div class="col-3"><label>Finish:</label> <span>{{model?.finish | date: 'yyyy-MM-dd'}}</span></div>
|
|
13
|
+
<div class="col-2"><label>Effort Driven:</label> <i [class]="model?.effortDriven ? 'fa fa-check' : ''"></i></div>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<hr>
|
|
17
|
+
|
|
18
|
+
<div class="col-sm-8">
|
|
19
|
+
<h4>
|
|
20
|
+
Find out who is the Assignee
|
|
21
|
+
<small>
|
|
22
|
+
<button class="btn btn-primary btn-sm" (click)="alertAssignee(model?.assignee)" data-test="assignee-btn">
|
|
23
|
+
Click Me
|
|
24
|
+
</button>
|
|
25
|
+
</small>
|
|
26
|
+
</h4>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="col-sm-4">
|
|
29
|
+
<button class="btn btn-primary btn-danger btn-sm" (click)="deleteRow(model)" data-test="delete-btn">
|
|
30
|
+
Delete Row
|
|
31
|
+
</button>
|
|
32
|
+
<button class="btn btn-outline-secondary btn-sm" (click)="callParentMethod(model)" data-test="parent-btn">
|
|
33
|
+
Call Parent Method
|
|
34
|
+
</button>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { SlickDataView, SlickGrid } from '../modules/angular-slickgrid';
|
|
3
|
+
import { GridRowDetailComponent } from './grid-rowdetail.component';
|
|
4
|
+
|
|
5
|
+
@Component({
|
|
6
|
+
templateUrl: './rowdetail-view.component.html'
|
|
7
|
+
})
|
|
8
|
+
export class RowDetailViewComponent {
|
|
9
|
+
model!: {
|
|
10
|
+
duration: Date;
|
|
11
|
+
percentComplete: number;
|
|
12
|
+
reporter: string;
|
|
13
|
+
start: Date;
|
|
14
|
+
finish: Date;
|
|
15
|
+
effortDriven: boolean;
|
|
16
|
+
assignee: string;
|
|
17
|
+
title: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// you also have access to the following objects (it must match the exact property names shown below)
|
|
21
|
+
addon: any; // row detail addon instance
|
|
22
|
+
grid!: SlickGrid;
|
|
23
|
+
dataView!: SlickDataView;
|
|
24
|
+
|
|
25
|
+
// you can also optionally use the Parent Component reference
|
|
26
|
+
// NOTE that you MUST provide it through the "parent" property in your "rowDetail" grid options
|
|
27
|
+
parent!: GridRowDetailComponent;
|
|
28
|
+
|
|
29
|
+
constructor() { }
|
|
30
|
+
|
|
31
|
+
alertAssignee(name: string) {
|
|
32
|
+
if (typeof name === 'string') {
|
|
33
|
+
alert(`Assignee on this task is: ${name.toUpperCase()}`);
|
|
34
|
+
} else {
|
|
35
|
+
alert('No one is assigned to this task.');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
deleteRow(model: any) {
|
|
40
|
+
if (confirm(`Are you sure that you want to delete ${model.title}?`)) {
|
|
41
|
+
// you first need to collapse all rows (via the 3rd party addon instance)
|
|
42
|
+
this.addon.collapseAll();
|
|
43
|
+
|
|
44
|
+
// then you can delete the item from the dataView
|
|
45
|
+
this.dataView.deleteItem(model.rowId);
|
|
46
|
+
|
|
47
|
+
this.parent.showFlashMessage(`Deleted row with ${model.title}`, 'danger');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
callParentMethod(model: any) {
|
|
52
|
+
this.parent.showFlashMessage(`We just called Parent Method from the Row Detail Child Component on ${model.title}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Component, OnInit, Input, } from '@angular/core';
|
|
2
|
+
import { SwtCommonGridComponent } from './swt-common-grid.component';
|
|
3
|
+
import { Logger } from './swt-logger.service';
|
|
4
|
+
import { HttpClient } from '@angular/common/http';
|
|
5
|
+
import { GridOption } from '../modules/angular-slickgrid';
|
|
6
|
+
/**
|
|
7
|
+
* Custom pagination component: It allows editing the page number manually
|
|
8
|
+
* << < Page [1] of 5 > >>
|
|
9
|
+
*
|
|
10
|
+
* @author Saber Chebka, saber.chebka@gmail.com
|
|
11
|
+
*/
|
|
12
|
+
@Component({
|
|
13
|
+
selector: 'swt-common-grid-pagination',
|
|
14
|
+
template: `
|
|
15
|
+
<div class="slick-pagination">
|
|
16
|
+
<div class="slick-pagination-nav">
|
|
17
|
+
<nav aria-label="Page navigation">
|
|
18
|
+
<ul class="pagination">
|
|
19
|
+
<li class="page-item" [ngClass]="pageNumber === 1 ? 'disabled' : ''">
|
|
20
|
+
<a class="page-link icon-seek-first fa fa-angle-double-left"
|
|
21
|
+
aria-label="First" (click)="changeToFirstPage($event)"> </a>
|
|
22
|
+
</li>
|
|
23
|
+
<li class="page-item" [ngClass]="pageNumber === 1 ? 'disabled' : ''">
|
|
24
|
+
<a class="page-link icon-seek-prev fa fa-angle-left"
|
|
25
|
+
aria-label="Previous" (click)="changeToPreviousPage($event)"> </a>
|
|
26
|
+
</li>
|
|
27
|
+
</ul>
|
|
28
|
+
</nav>
|
|
29
|
+
|
|
30
|
+
<div class="slick-page-number">
|
|
31
|
+
<span [translate]="'PAGE'"></span>
|
|
32
|
+
<input type="text" value="{{pageNumber}}" size="1" (change)="changeToCurrentPage($event)">
|
|
33
|
+
<span [translate]="'OF'"></span><span> {{pageCount}}</span>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<nav aria-label="Page navigation">
|
|
37
|
+
<ul class="pagination">
|
|
38
|
+
<li class="page-item"
|
|
39
|
+
[ngClass]="pageNumber === pageCount ? 'disabled' : ''"><a
|
|
40
|
+
class="page-link icon-seek-next text-center fa fa-lg fa-angle-right"
|
|
41
|
+
aria-label="Next" (click)="changeToNextPage($event)"> </a></li>
|
|
42
|
+
<li class="page-item"
|
|
43
|
+
[ngClass]="pageNumber === pageCount ? 'disabled' : ''"><a
|
|
44
|
+
class="page-link icon-seek-end fa fa-lg fa-angle-double-right"
|
|
45
|
+
aria-label="Last" (click)="changeToLastPage($event)"> </a></li>
|
|
46
|
+
</ul>
|
|
47
|
+
</nav>
|
|
48
|
+
<nav>
|
|
49
|
+
<ul class="pagination">
|
|
50
|
+
<li class="">
|
|
51
|
+
<span [hidden]="!processing" class="page-spin">
|
|
52
|
+
<i class="fa fa-refresh fa-spin fa-lg fa-fw"></i>
|
|
53
|
+
</span>
|
|
54
|
+
</li>
|
|
55
|
+
</ul>
|
|
56
|
+
</nav>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
`,
|
|
60
|
+
styles: [`.page-spin {
|
|
61
|
+
border: none;
|
|
62
|
+
height: 32px;
|
|
63
|
+
background-color: transparent;
|
|
64
|
+
cursor: default;
|
|
65
|
+
animation: fa-spin 1.2s infinite linear !important;
|
|
66
|
+
}
|
|
67
|
+
.page-spin:hover {
|
|
68
|
+
background-color: transparent;
|
|
69
|
+
}
|
|
70
|
+
`]
|
|
71
|
+
})
|
|
72
|
+
export class SwtCommonGridPaginationComponent implements OnInit {
|
|
73
|
+
private logger: Logger;
|
|
74
|
+
|
|
75
|
+
@Input() pageCount = 1;
|
|
76
|
+
@Input() pageNumber = 1;
|
|
77
|
+
|
|
78
|
+
totalItems = 0;
|
|
79
|
+
processing = false;
|
|
80
|
+
|
|
81
|
+
// Reference to the real pagination component
|
|
82
|
+
realPagination = true;
|
|
83
|
+
_gridPaginationOptions!: GridOption;
|
|
84
|
+
commonGrid!: SwtCommonGridComponent;
|
|
85
|
+
|
|
86
|
+
@Input()
|
|
87
|
+
set gridPaginationOptions(gridPaginationOptions: GridOption) {
|
|
88
|
+
this._gridPaginationOptions = gridPaginationOptions;
|
|
89
|
+
|
|
90
|
+
// The backendServiceApi is itself the SwtCommonGridComponent (This is a hack)
|
|
91
|
+
this.commonGrid = <SwtCommonGridComponent>this.gridPaginationOptions!.backendServiceApi!.service;
|
|
92
|
+
}
|
|
93
|
+
get gridPaginationOptions(): GridOption {
|
|
94
|
+
return this._gridPaginationOptions;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
constructor(private httpClient: HttpClient) {
|
|
100
|
+
this.logger = new Logger('grid-pagination', httpClient);
|
|
101
|
+
this.logger.info('method [constructor] - START/END');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
ngOnInit() {
|
|
106
|
+
this.logger.info('init: ');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
changeToFirstPage(event: any) {
|
|
112
|
+
this.logger.info('method [changeToFirstPage] - START/END');
|
|
113
|
+
this.pageNumber = 1;
|
|
114
|
+
this.onPageChanged(event, this.pageNumber);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
changeToLastPage(event: any) {
|
|
118
|
+
this.logger.info('method [changeToLastPage] - START/END');
|
|
119
|
+
this.pageNumber = this.pageCount;
|
|
120
|
+
this.onPageChanged(event, this.pageNumber);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
changeToNextPage(event: any) {
|
|
124
|
+
this.logger.info('method [changeToNextPage] - START/END');
|
|
125
|
+
if (this.pageNumber < this.pageCount) {
|
|
126
|
+
this.pageNumber++;
|
|
127
|
+
this.onPageChanged(event, this.pageNumber);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
changeToPreviousPage(event: any) {
|
|
132
|
+
this.logger.info('method [changeToNextPage] - START/END');
|
|
133
|
+
if (this.pageNumber > 1) {
|
|
134
|
+
this.pageNumber--;
|
|
135
|
+
this.onPageChanged(event, this.pageNumber);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
changeToCurrentPage(event: any) {
|
|
141
|
+
this.logger.info('method [changeToCurrentPage] - START/END');
|
|
142
|
+
this.pageNumber = event.currentTarget.value;
|
|
143
|
+
if (this.pageNumber < 1) {
|
|
144
|
+
this.pageNumber = 1;
|
|
145
|
+
} else if (this.pageNumber > this.pageCount) {
|
|
146
|
+
this.pageNumber = this.pageCount;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
this.onPageChanged(event, this.pageNumber);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
onPageChanged(event?: Event, pageNumber?: number) {
|
|
153
|
+
this.logger.info('method [onPageChanged] - START/END', this.commonGrid);
|
|
154
|
+
this.commonGrid.processOnPaginationChanged(event, { newPage: pageNumber as number, pageSize: -1 });
|
|
155
|
+
}
|
|
156
|
+
}
|