├── .browserslistrc ├── .gitignore ├── README.md ├── angular.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── projects └── angular-material-data-grid │ ├── README.md │ ├── karma.conf.js │ ├── ng-package.json │ ├── package.json │ ├── src │ ├── lib │ │ ├── angular-material-data-grid-interfaces.ts │ │ ├── angular-material-data-grid-utilities.scss │ │ ├── angular-material-data-grid.module.ts │ │ ├── angular-material-data-grid.service.ts │ │ ├── api-response.model.ts │ │ ├── components │ │ │ ├── confirmation │ │ │ │ ├── confirmation.component.html │ │ │ │ ├── confirmation.component.scss │ │ │ │ └── confirmation.component.ts │ │ │ ├── date-filter │ │ │ │ ├── date-filter.component.html │ │ │ │ ├── date-filter.component.scss │ │ │ │ └── date-filter.component.ts │ │ │ ├── filter-header │ │ │ │ ├── filter-header.component.html │ │ │ │ ├── filter-header.component.scss │ │ │ │ └── filter-header.component.ts │ │ │ ├── multi-select │ │ │ │ ├── multi-select.component.html │ │ │ │ ├── multi-select.component.scss │ │ │ │ └── multi-select.component.ts │ │ │ ├── number-filter │ │ │ │ ├── number-filter.component.html │ │ │ │ ├── number-filter.component.scss │ │ │ │ └── number-filter.component.ts │ │ │ ├── pagination │ │ │ │ ├── pagination.component.html │ │ │ │ ├── pagination.component.scss │ │ │ │ └── pagination.component.ts │ │ │ ├── pipes │ │ │ │ ├── column-filter.pipe.ts │ │ │ │ ├── column-search-filter.pipe.ts │ │ │ │ └── search.pipe.ts │ │ │ ├── sort-header │ │ │ │ ├── sort-header.component.html │ │ │ │ ├── sort-header.component.scss │ │ │ │ └── sort-header.component.ts │ │ │ ├── string-filter │ │ │ │ ├── string-filter.component.html │ │ │ │ ├── string-filter.component.scss │ │ │ │ └── string-filter.component.ts │ │ │ └── tag-filter │ │ │ │ ├── tag-filter.component.html │ │ │ │ ├── tag-filter.component.scss │ │ │ │ ├── tag-filter.component.spec.ts │ │ │ │ └── tag-filter.component.ts │ │ ├── grids │ │ │ ├── child-grid │ │ │ │ ├── child-grid.component.html │ │ │ │ ├── child-grid.component.scss │ │ │ │ ├── child-grid.component.spec.ts │ │ │ │ └── child-grid.component.ts │ │ │ ├── grid.service.ts │ │ │ └── server-bind-grid │ │ │ │ ├── server-bind-grid.component.html │ │ │ │ ├── server-bind-grid.component.scss │ │ │ │ ├── server-bind-grid.component.spec.ts │ │ │ │ ├── server-bind-grid.component.ts │ │ │ │ ├── template.pipe.ts │ │ │ │ └── template_object.pipe.ts │ │ ├── interfaces │ │ │ ├── button-list-config-type.ts │ │ │ ├── child-grid-config-type.ts │ │ │ ├── grid-button-click-interface.ts │ │ │ ├── grid-filter-item.ts │ │ │ ├── grid-heading-type.ts │ │ │ ├── grid-master-detail-config-type.ts │ │ │ ├── grid-request.ts │ │ │ ├── grid-response.ts │ │ │ ├── grid-sort-item.ts │ │ │ ├── multi-select-options-type.ts │ │ │ └── other-config-type.ts │ │ └── variables.scss │ ├── public-api.ts │ └── test.ts │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ └── tsconfig.spec.json ├── src ├── app │ ├── app.component.html │ ├── app.component.scss │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── components │ │ └── container │ │ │ ├── container.component.html │ │ │ ├── container.component.scss │ │ │ ├── container.component.spec.ts │ │ │ ├── container.component.ts │ │ │ └── navigation.ts │ ├── pages │ │ ├── button-group-builder │ │ │ ├── button-group-builder.component.html │ │ │ ├── button-group-builder.component.scss │ │ │ ├── button-group-builder.component.spec.ts │ │ │ └── button-group-builder.component.ts │ │ ├── cell-styles-example │ │ │ ├── cell-styles-example.component.html │ │ │ ├── cell-styles-example.component.scss │ │ │ ├── cell-styles-example.component.spec.ts │ │ │ └── cell-styles-example.component.ts │ │ ├── change-log │ │ │ ├── change-log.component.html │ │ │ ├── change-log.component.scss │ │ │ ├── change-log.component.spec.ts │ │ │ └── change-log.component.ts │ │ ├── client-side-pagination-grid-example │ │ │ ├── client-side-pagination-grid-example.component.html │ │ │ ├── client-side-pagination-grid-example.component.scss │ │ │ ├── client-side-pagination-grid-example.component.spec.ts │ │ │ └── client-side-pagination-grid-example.component.ts │ │ ├── column-control │ │ │ ├── column-control.component.html │ │ │ ├── column-control.component.scss │ │ │ ├── column-control.component.spec.ts │ │ │ └── column-control.component.ts │ │ ├── columns-and-filters │ │ │ ├── columns-and-filters.component.html │ │ │ ├── columns-and-filters.component.scss │ │ │ ├── columns-and-filters.component.spec.ts │ │ │ └── columns-and-filters.component.ts │ │ ├── custom-demo │ │ │ ├── custom-demo.component.html │ │ │ ├── custom-demo.component.scss │ │ │ └── custom-demo.component.ts │ │ ├── date-range-filter │ │ │ ├── date-range-filter.component.html │ │ │ ├── date-range-filter.component.scss │ │ │ ├── date-range-filter.component.spec.ts │ │ │ └── date-range-filter.component.ts │ │ ├── demo │ │ │ ├── demo.component.html │ │ │ ├── demo.component.scss │ │ │ └── demo.component.ts │ │ ├── detail │ │ │ ├── detail.component.html │ │ │ ├── detail.component.scss │ │ │ ├── detail.component.spec.ts │ │ │ └── detail.component.ts │ │ ├── dynamic-headings-example │ │ │ ├── dynamic-headings-example.component.html │ │ │ ├── dynamic-headings-example.component.scss │ │ │ ├── dynamic-headings-example.component.spec.ts │ │ │ └── dynamic-headings-example.component.ts │ │ ├── fixed-header │ │ │ ├── fixed-header.component.html │ │ │ ├── fixed-header.component.scss │ │ │ ├── fixed-header.component.spec.ts │ │ │ └── fixed-header.component.ts │ │ ├── image-type │ │ │ ├── image-type.component.html │ │ │ ├── image-type.component.scss │ │ │ ├── image-type.component.spec.ts │ │ │ └── image-type.component.ts │ │ ├── installation │ │ │ ├── installation.component.html │ │ │ ├── installation.component.scss │ │ │ └── installation.component.ts │ │ ├── introduction │ │ │ ├── introduction.component.html │ │ │ ├── introduction.component.scss │ │ │ └── introduction.component.ts │ │ ├── item-selection │ │ │ ├── item-selection.component.html │ │ │ ├── item-selection.component.scss │ │ │ ├── item-selection.component.spec.ts │ │ │ └── item-selection.component.ts │ │ ├── master-detail-breakdown-grid-example │ │ │ ├── master-detail-breakdown-grid-example.component.html │ │ │ ├── master-detail-breakdown-grid-example.component.scss │ │ │ ├── master-detail-breakdown-grid-example.component.spec.ts │ │ │ └── master-detail-breakdown-grid-example.component.ts │ │ ├── master-detail-child-grid-example │ │ │ ├── master-detail-child-grid-example.component.html │ │ │ ├── master-detail-child-grid-example.component.scss │ │ │ ├── master-detail-child-grid-example.component.spec.ts │ │ │ └── master-detail-child-grid-example.component.ts │ │ ├── master-detail-example │ │ │ ├── master-detail-example.component.html │ │ │ ├── master-detail-example.component.scss │ │ │ ├── master-detail-example.component.spec.ts │ │ │ └── master-detail-example.component.ts │ │ ├── master-detail-html-example │ │ │ ├── master-detail-html-example.component.html │ │ │ ├── master-detail-html-example.component.scss │ │ │ ├── master-detail-html-example.component.spec.ts │ │ │ └── master-detail-html-example.component.ts │ │ ├── multi-select-filter │ │ │ ├── multi-select-filter.component.html │ │ │ ├── multi-select-filter.component.scss │ │ │ ├── multi-select-filter.component.spec.ts │ │ │ └── multi-select-filter.component.ts │ │ ├── numeric-filter │ │ │ ├── numeric-filter.component.html │ │ │ ├── numeric-filter.component.scss │ │ │ ├── numeric-filter.component.spec.ts │ │ │ └── numeric-filter.component.ts │ │ ├── open-dialog │ │ │ ├── grid-within-dialog │ │ │ │ ├── grid-within-dialog.component.html │ │ │ │ ├── grid-within-dialog.component.scss │ │ │ │ ├── grid-within-dialog.component.spec.ts │ │ │ │ └── grid-within-dialog.component.ts │ │ │ ├── open-dialog.component.html │ │ │ ├── open-dialog.component.scss │ │ │ ├── open-dialog.component.spec.ts │ │ │ └── open-dialog.component.ts │ │ ├── overview │ │ │ ├── overview.component.html │ │ │ ├── overview.component.scss │ │ │ ├── overview.component.spec.ts │ │ │ └── overview.component.ts │ │ ├── preconfigured-filters-example │ │ │ ├── preconfigured-filters-example.component.html │ │ │ ├── preconfigured-filters-example.component.scss │ │ │ └── preconfigured-filters-example.component.ts │ │ ├── properties-and-events │ │ │ ├── properties-and-events.component.html │ │ │ ├── properties-and-events.component.scss │ │ │ └── properties-and-events.component.ts │ │ ├── reinitialize-grid-example │ │ │ ├── reinitialize-grid-example.component.html │ │ │ ├── reinitialize-grid-example.component.scss │ │ │ ├── reinitialize-grid-example.component.spec.ts │ │ │ └── reinitialize-grid-example.component.ts │ │ ├── server-bind-grid-example │ │ │ ├── server-bind-grid-example.component.html │ │ │ ├── server-bind-grid-example.component.scss │ │ │ ├── server-bind-grid-example.component.spec.ts │ │ │ └── server-bind-grid-example.component.ts │ │ ├── string-filter │ │ │ ├── string-filter.component.html │ │ │ ├── string-filter.component.scss │ │ │ ├── string-filter.component.spec.ts │ │ │ └── string-filter.component.ts │ │ ├── tag-filter │ │ │ ├── tag-filter.component.html │ │ │ ├── tag-filter.component.scss │ │ │ ├── tag-filter.component.spec.ts │ │ │ └── tag-filter.component.ts │ │ ├── theming │ │ │ ├── theming.component.html │ │ │ ├── theming.component.scss │ │ │ ├── theming.component.spec.ts │ │ │ └── theming.component.ts │ │ ├── top-right-buttons-example │ │ │ ├── top-right-buttons-example.component.html │ │ │ ├── top-right-buttons-example.component.scss │ │ │ ├── top-right-buttons-example.component.spec.ts │ │ │ └── top-right-buttons-example.component.ts │ │ ├── transparency-example │ │ │ ├── transparency-example.component.html │ │ │ ├── transparency-example.component.scss │ │ │ ├── transparency-example.component.spec.ts │ │ │ └── transparency-example.component.ts │ │ ├── url-builder │ │ │ ├── url-builder.component.html │ │ │ ├── url-builder.component.scss │ │ │ ├── url-builder.component.spec.ts │ │ │ └── url-builder.component.ts │ │ └── virtual-scrolling │ │ │ ├── virtual-scrolling.component.html │ │ │ ├── virtual-scrolling.component.scss │ │ │ ├── virtual-scrolling.component.spec.ts │ │ │ └── virtual-scrolling.component.ts │ └── routing │ │ └── app.routing.module.ts ├── assets │ ├── .gitkeep │ ├── color-circle.png │ ├── column_reordering.png │ ├── data.json │ ├── favicons │ │ ├── android-icon-144x144.png │ │ ├── android-icon-192x192.png │ │ ├── android-icon-36x36.png │ │ ├── android-icon-48x48.png │ │ ├── android-icon-72x72.png │ │ ├── android-icon-96x96.png │ │ ├── apple-icon-114x114.png │ │ ├── apple-icon-120x120.png │ │ ├── apple-icon-144x144.png │ │ ├── apple-icon-152x152.png │ │ ├── apple-icon-180x180.png │ │ ├── apple-icon-57x57.png │ │ ├── apple-icon-60x60.png │ │ ├── apple-icon-72x72.png │ │ ├── apple-icon-76x76.png │ │ ├── apple-icon-precomposed.png │ │ ├── apple-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── favicon.ico │ │ ├── ms-icon-144x144.png │ │ ├── ms-icon-150x150.png │ │ ├── ms-icon-310x310.png │ │ └── ms-icon-70x70.png │ ├── filters.png │ ├── game_images │ │ ├── Assassins-Creed-Valhalla.jpeg │ │ ├── DIRT-5.jpeg │ │ ├── F1-2021.jpeg │ │ ├── Hunting-Simulator-2.jpeg │ │ ├── Marvels-Avengers.jpeg │ │ ├── Marvels-Spider.jpeg │ │ ├── Mortal-Kombat-11-Ultimate.jpeg │ │ ├── Outriders-Day-One-Edition.jpeg │ │ ├── Ratchet-Clank-Rift-Apart.jpeg │ │ ├── Resident-Evil-Village.jpeg │ │ ├── Returnal-PlayStation.jpeg │ │ ├── Sniper-Ghost-Warrior-Contracts-2.jpeg │ │ ├── Tennis-2.jpeg │ │ ├── Tom-Clancys-Rainbow-Six-Siege-Deluxe-Edition.jpeg │ │ ├── WRC-9.jpeg │ │ └── hitman-3.jpeg │ ├── grid_background.png │ ├── logo.png │ ├── master-detail-child-grid.png │ ├── master-detail-html.png │ ├── selection.mp4 │ ├── virtual_scrolling.png │ └── youtube.png ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── main.ts ├── polyfills.ts ├── scss │ ├── material-overrides.scss │ └── theme.scss ├── styles.scss └── test.ts ├── tsconfig.app.json ├── tsconfig.json └── tsconfig.spec.json /.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line. 18 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | .angular 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Advanced Angular Material Data Grid System 2 | 3 | #### Inspired by Kendo UI Grid 4 | 5 | This is an advanced data grid which is free to use with features and customizability only available on paid data grids. 6 | 7 | ![Sample UI](https://angular-grid.onrender.com/assets/grid_background.png) 8 | 9 | #### Features 10 | 11 | - Easy to integrate server-side pagination (Tested with very large data sets) 12 | - Built in virtual scrolling 13 | - Advanced multi-filtering features 14 | - Customizable theming 15 | - Optional columns with re-ordering 16 | - Master Detail Grid 17 | 18 | The initial purpose of creating this data grid was to make it easy for developers to easily create highly advanced data grids with server-side pagination along with multiple filters and sorting with minimum effort and time. (Client Side Pagination is also present.) In order to make this possible a tight integration between the back-end data-source and the front-end component should be agreed upon. This gives the ability to stay focused on advanced functionality and the creation of data grids with only configurations while staying opinionated. Moreover, the solutions provided by reputed vendors were expensive which makes open-source software more attractive to many clients. This product is 100% open source. Check [Repository here](https://github.com/dillyboy/angular_material_data_grid). 19 | 20 | Refer to the [Documentation](https://angular-grid.onrender.com/) page. 21 | 22 |
23 | 24 | #### Installation 25 | 26 | 1. Install Angular Material 27 | 28 | - `ng add @angular/material` 29 | 30 | 2. Install Angular Material Data Grid 31 | 32 | - `npm i angular-material-data-grid@0.6.1`\ 33 | \ 34 | or if your project uses Angular 14.0.0 and above 35 | 36 | - `npm i angular-material-data-grid` 37 | 38 | 3. Import Module 39 | 40 | - `import { AngularMaterialDataGridModule } from 'angular-material-data-grid';` 41 | 42 | - `imports: [ .., AngularMaterialDataGridModule]` 43 | 44 | 4. Usage (Basic) 45 | 46 | ###### HTML 47 | 48 | - 49 |     [headings]="headings"
50 |     [url]="url"
51 |     [serverSidePagination]="true"
52 |     (responseEmit)="responseReceived($event)">
53 |
54 | 55 | ###### TypeScript 56 | 57 | [Check here](https://angular-grid.onrender.com/gettingStarted/installation) 58 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | jasmine: { 17 | // you can add configuration options for Jasmine here 18 | // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html 19 | // for example, you can disable the random execution with `random: false` 20 | // or set a specific seed with `seed: 4321` 21 | }, 22 | clearContext: false // leave Jasmine Spec Runner output visible in browser 23 | }, 24 | jasmineHtmlReporter: { 25 | suppressAll: true // removes the duplicated traces 26 | }, 27 | coverageReporter: { 28 | dir: require('path').join(__dirname, './coverage/grid-example'), 29 | subdir: '.', 30 | reporters: [ 31 | { type: 'html' }, 32 | { type: 'text-summary' } 33 | ] 34 | }, 35 | reporters: ['progress', 'kjhtml'], 36 | port: 9876, 37 | colors: true, 38 | logLevel: config.LOG_INFO, 39 | autoWatch: true, 40 | browsers: ['Chrome'], 41 | singleRun: false, 42 | restartOnFileChange: true 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grid-example", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "watch": "ng build --watch --configuration development", 9 | "test": "ng test", 10 | "lib:build": "ng build angular-material-data-grid --configuration=production", 11 | "lib:package": "cd dist/angular-material-data-grid && npm publish", 12 | "lint": "ng lint" 13 | }, 14 | "private": true, 15 | "dependencies": { 16 | "@angular/animations": "^15.0.1", 17 | "@angular/cdk": "^15.0.0", 18 | "@angular/common": "^15.0.1", 19 | "@angular/compiler": "^15.0.1", 20 | "@angular/core": "^15.0.1", 21 | "@angular/forms": "^15.0.1", 22 | "@angular/material": "^15.0.0", 23 | "@angular/platform-browser": "^15.0.1", 24 | "@angular/platform-browser-dynamic": "^15.0.1", 25 | "@angular/router": "^15.0.1", 26 | "ng-packagr": "^15.0.1", 27 | "ngx-highlightjs": "^6.1.0", 28 | "rxjs": "~7.4.0", 29 | "tslib": "^2.3.0", 30 | "zone.js": "~0.11.4" 31 | }, 32 | "devDependencies": { 33 | "@angular-devkit/build-angular": "^15.0.1", 34 | "@angular-eslint/builder": "15.1.0", 35 | "@angular-eslint/eslint-plugin": "15.1.0", 36 | "@angular-eslint/eslint-plugin-template": "15.1.0", 37 | "@angular-eslint/schematics": "15.1.0", 38 | "@angular-eslint/template-parser": "15.1.0", 39 | "@angular/cli": "^15.0.1", 40 | "@angular/compiler-cli": "^15.0.1", 41 | "@types/jasmine": "~3.10.0", 42 | "@types/node": "^12.11.1", 43 | "@typescript-eslint/eslint-plugin": "^5.43.0", 44 | "@typescript-eslint/parser": "^5.43.0", 45 | "eslint": "^8.28.0", 46 | "jasmine-core": "~3.10.0", 47 | "karma": "~6.3.0", 48 | "karma-chrome-launcher": "~3.1.0", 49 | "karma-coverage": "~2.0.3", 50 | "karma-jasmine": "~4.0.0", 51 | "karma-jasmine-html-reporter": "~1.7.0", 52 | "typescript": "~4.8.4" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/README.md: -------------------------------------------------------------------------------- 1 | # Advanced Angular Material Data Grid System 2 | 3 | #### Inspired by Kendo UI Grid 4 | 5 | This is an advanced data grid which is free to use with features and customizability only available on paid data grids. 6 | 7 | ![Sample UI](https://angular-grid.onrender.com/assets/grid_background.png) 8 | 9 | #### Features 10 | 11 | - Easy to integrate server-side pagination (Tested with very large data sets) 12 | - Built in virtual scrolling 13 | - Advanced multi-filtering features 14 | - Customizable theming 15 | - Optional columns with re-ordering 16 | - Master Detail Grid 17 | 18 | The initial purpose of creating this data grid was to make it easy for developers to easily create highly advanced data grids with server-side pagination along with multiple filters and sorting with minimum effort and time. (Client Side Pagination is also present.) In order to make this possible a tight integration between the back-end data-source and the front-end component should be agreed upon. This gives the ability to stay focused on advanced functionality and the creation of data grids with only configurations while staying opinionated. Moreover, the solutions provided by reputed vendors were expensive which makes open-source software more attractive to many clients. This product is 100% open source. Check [Repository here](https://github.com/dillyboy/angular_material_data_grid). 19 | 20 | Refer to the [Documentation](https://angular-grid.onrender.com/) page. 21 | 22 |
23 | 24 | #### Installation 25 | 26 | 1. Install Angular Material 27 | 28 | - `ng add @angular/material` 29 | 30 | 2. Install Angular Material Data Grid 31 | 32 | - `npm i angular-material-data-grid@0.6.1`\ 33 | \ 34 | or if your project uses Angular 14.0.0 and above 35 | 36 | - `npm i angular-material-data-grid` 37 | 38 | 3. Import Module 39 | 40 | - `import { AngularMaterialDataGridModule } from 'angular-material-data-grid';` 41 | 42 | - `imports: [ .., AngularMaterialDataGridModule]` 43 | 44 | 4. Usage (Basic) 45 | ###### HTML 46 | - 47 |     [headings]="headings"
48 |     [url]="url"
49 |     [serverSidePagination]="true"
50 |     (responseEmit)="responseReceived($event)">
51 |
52 | ###### TypeScript 53 | [Check here](https://angular-grid.onrender.com/gettingStarted/installation) 54 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | jasmine: { 17 | // you can add configuration options for Jasmine here 18 | // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html 19 | // for example, you can disable the random execution with `random: false` 20 | // or set a specific seed with `seed: 4321` 21 | }, 22 | clearContext: false // leave Jasmine Spec Runner output visible in browser 23 | }, 24 | jasmineHtmlReporter: { 25 | suppressAll: true // removes the duplicated traces 26 | }, 27 | coverageReporter: { 28 | dir: require('path').join(__dirname, '../../coverage/angular-material-data-grid'), 29 | subdir: '.', 30 | reporters: [ 31 | { type: 'html' }, 32 | { type: 'text-summary' } 33 | ] 34 | }, 35 | reporters: ['progress', 'kjhtml'], 36 | port: 9876, 37 | colors: true, 38 | logLevel: config.LOG_INFO, 39 | autoWatch: true, 40 | browsers: ['Chrome'], 41 | singleRun: false, 42 | restartOnFileChange: true 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/angular-material-data-grid", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | } 7 | } -------------------------------------------------------------------------------- /projects/angular-material-data-grid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-material-data-grid", 3 | "version": "0.9.1", 4 | "peerDependencies": {}, 5 | "dependencies": { 6 | "tslib": "^2.3.0" 7 | }, 8 | "keywords": [ 9 | "angular", 10 | "angular material", 11 | "material design", 12 | "angular material data grid", 13 | "data grid", 14 | "server side pagination", 15 | "kendo grid", 16 | "kendo", 17 | "virtual scrolling", 18 | "column reordering", 19 | "material theming" 20 | ], 21 | "author": { 22 | "name" : "Dilshan Nadeesha Liyanage", 23 | "email" : "dilshan.liyanage@hotmail.co.uk", 24 | "url" : "https://dilshan.pro" 25 | }, 26 | "license": "MIT" 27 | } 28 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/angular-material-data-grid-interfaces.ts: -------------------------------------------------------------------------------- 1 | import GridHeadingInterface from './interfaces/grid-heading-type'; 2 | import GridFilterItemInterface from './interfaces/grid-filter-item'; 3 | import GridSortItemInterface from './interfaces/grid-sort-item'; 4 | import GridRequestInterface from './interfaces/grid-request'; 5 | import GridResponseInterface from './interfaces/grid-response'; 6 | import GridButtonClickInterface from './interfaces/grid-button-click-interface'; 7 | import GridMasterDetailConfigInterface from './interfaces/grid-master-detail-config-type'; 8 | 9 | export { 10 | GridHeadingInterface as GridHeading, 11 | GridFilterItemInterface as GridFilterItem, 12 | GridSortItemInterface as GridSortItem, 13 | GridRequestInterface as GridRequest, 14 | GridResponseInterface as GridResponse, 15 | GridButtonClickInterface as GridButtonClick, 16 | GridMasterDetailConfigInterface as GridMasterDetailConfig 17 | }; 18 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/angular-material-data-grid.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root' 5 | }) 6 | export class AngularMaterialDataGridService { 7 | 8 | constructor() { } 9 | } 10 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/api-response.model.ts: -------------------------------------------------------------------------------- 1 | export class ApiResponseModel { 2 | constructor( 3 | public statusCode: number, 4 | public payload: any, 5 | public success: boolean, 6 | public message: string, 7 | public code: number 8 | ) { } 9 | } 10 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/confirmation/confirmation.component.html: -------------------------------------------------------------------------------- 1 |

{{content.title}}

2 |

{{content.content}}

3 | 4 |
5 | 6 | 7 |
8 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/confirmation/confirmation.component.scss: -------------------------------------------------------------------------------- 1 | #amdg-dialog-confirmation-title { 2 | font: 500 20px / 32px Roboto, "Helvetica Neue", sans-serif; 3 | margin-bottom: 0.75rem; 4 | } 5 | 6 | #amdg-dialog-confirmation-paragraph { 7 | margin-bottom: 0.75rem; 8 | } 9 | 10 | .amdg-text-right { 11 | text-align: right; 12 | } 13 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/confirmation/confirmation.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject, OnInit } from '@angular/core'; 2 | import { MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA, MatLegacyDialogRef as MatDialogRef } from '@angular/material/legacy-dialog'; 3 | 4 | @Component({ 5 | selector: 'amdg-confirmation', 6 | templateUrl: './confirmation.component.html', 7 | styleUrls: ['./confirmation.component.scss'] 8 | }) 9 | export class ConfirmationComponent implements OnInit { 10 | 11 | content = { 12 | title: null, 13 | content: null, 14 | cancel_text: null, 15 | ok_text: null 16 | }; 17 | 18 | constructor(public dialogRef: MatDialogRef, 19 | @Inject(MAT_DIALOG_DATA) public data: any) { } 20 | 21 | ngOnInit(): void { 22 | this.content = this.data; 23 | } 24 | 25 | close(): void { 26 | this.dialogRef.close(); 27 | } 28 | 29 | ok(): void { 30 | this.dialogRef.close(true); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/date-filter/date-filter.component.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 |
9 |
10 | 11 | 12 |
13 |
14 | 15 | 16 | {{item.text}} 17 | 18 | 19 |
20 | 21 |
22 | 23 | Enter a date range 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | Invalid start date 32 | Invalid end date 33 | 34 |
35 |
36 | Invalid value entered 37 |
38 |
39 |
40 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/date-filter/date-filter.component.scss: -------------------------------------------------------------------------------- 1 | @import './../../variables'; 2 | 3 | .amdg-placeholder { 4 | opacity: .6; 5 | } 6 | 7 | .amdg-filter-container { 8 | width: 260px; 9 | min-height: 60px; 10 | display: block; 11 | border-radius: 4px; 12 | overflow: hidden; 13 | font-size: 12px; 14 | } 15 | 16 | .amdg-filter-open-btn { 17 | line-height: 26px !important; 18 | font-size: inherit; 19 | padding: 0 4px; 20 | width: 100%; 21 | background: white; 22 | ::ng-deep .mat-button-wrapper { 23 | display: flex !important; 24 | justify-content: space-between; 25 | align-items: center; 26 | width: 100%; 27 | } 28 | } 29 | 30 | .amdg-select-arrow { 31 | width: 0; 32 | height: 0; 33 | border-left: 5px solid transparent; 34 | border-right: 5px solid transparent; 35 | border-top: 5px solid; 36 | margin: 0 4px; 37 | } 38 | 39 | .amdg-invalid-error { 40 | color: $warn; 41 | font-size: 12px; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/filter-header/filter-header.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 14 | 15 | 16 | 22 | 23 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 46 | 47 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
59 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/filter-header/filter-header.component.scss: -------------------------------------------------------------------------------- 1 | @import './../../variables'; 2 | 3 | .amdg-filter-component { 4 | //margin: 0 -8px; 5 | padding: 3px 0; 6 | display: inline-flex !important; 7 | white-space: nowrap !important; 8 | width: 100%; 9 | position: relative; 10 | align-items: center; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/filter-header/filter-header.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; 2 | import GridFilterItemInterface from '../../interfaces/grid-filter-item'; 3 | 4 | @Component({ 5 | selector: 'amdg-filter-header', 6 | templateUrl: './filter-header.component.html', 7 | styleUrls: ['./filter-header.component.scss'] 8 | }) 9 | export class FilterHeaderComponent implements OnInit { 10 | 11 | @Input() heading: any = { 12 | display: null, 13 | type: 'string', 14 | sort: '', 15 | filterType: null, 16 | disableSorting: false, 17 | disableFiltering: false, 18 | other: {} 19 | }; 20 | @Input() initialFilters: GridFilterItemInterface[] = []; 21 | @Input() resetFilters = null; 22 | @Output() filter = new EventEmitter(); 23 | 24 | initialFilter?: GridFilterItemInterface; 25 | 26 | constructor() { } 27 | 28 | ngOnInit(): void { 29 | const i = this.initialFilters.findIndex((filter: GridFilterItemInterface) => filter.field === this.heading.fieldName); 30 | if (i !== -1) { 31 | this.initialFilter = this.initialFilters[i]; 32 | } 33 | } 34 | 35 | filterObjCreated(ev: GridFilterItemInterface): void { 36 | this.filter.emit({field: this.heading.fieldName, operator: ev.operator, value: ev.value}); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/multi-select/multi-select.component.html: -------------------------------------------------------------------------------- 1 | 12 | 13 | Unfiltered 14 | {{selectionValuesApplied[0]}} 15 | 16 | (+{{selectionValuesApplied.length - 1}} {{selectionValuesApplied.length === 2 ? 'other' : 'others'}}) 17 | 18 | 19 |
20 |
21 | 22 | 23 |
24 | 25 | 26 |
27 |
28 | 29 | 30 | 33 | 34 |
35 |
36 | {{item.text}} 37 |
38 |
39 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/multi-select/multi-select.component.scss: -------------------------------------------------------------------------------- 1 | @import './../../variables'; 2 | 3 | .amdg-filter-value { 4 | padding: 0; 5 | display: inline; 6 | min-width: auto; 7 | font-size: 12px; 8 | line-height: normal; 9 | &:hover { 10 | text-decoration: none !important; 11 | } 12 | } 13 | 14 | .amdg-modified-mat-select { 15 | border: 1px solid $highlight-dark-color; 16 | border-radius: 4px; 17 | padding: 0 4px; 18 | height: 28px; 19 | line-height: 28px !important; 20 | background: white; 21 | box-sizing: border-box; 22 | } 23 | 24 | .amdg-additional-selection { 25 | opacity: 0.75; 26 | font-size: 0.75em; 27 | } 28 | 29 | #amdg-list-container { 30 | max-height: 160px; 31 | overflow-y: scroll; 32 | } 33 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/number-filter/number-filter.component.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 |
9 |
10 | 11 | 12 |
13 |
14 | 15 | 16 | {{item.text}} 17 | 18 | 19 |
20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 | 31 | 32 | 33 |
34 |
35 | Invalid range entered 36 | Invalid value entered 37 |
38 |
39 |
40 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/number-filter/number-filter.component.scss: -------------------------------------------------------------------------------- 1 | @import './../../variables'; 2 | 3 | .amdg-placeholder { 4 | opacity: .6; 5 | } 6 | 7 | .amdg-filter-container { 8 | width: 260px; 9 | min-height: 60px; 10 | display: block; 11 | border-radius: 4px; 12 | overflow: hidden; 13 | font-size: 12px; 14 | } 15 | 16 | .amdg-filter-open-btn { 17 | line-height: 26px !important; 18 | font-size: inherit; 19 | padding: 0 4px; 20 | width: 100%; 21 | background: white; 22 | ::ng-deep .mat-button-wrapper { 23 | display: flex !important; 24 | justify-content: space-between; 25 | align-items: center; 26 | width: 100%; 27 | } 28 | } 29 | 30 | .amdg-select-arrow { 31 | width: 0; 32 | height: 0; 33 | border-left: 5px solid transparent; 34 | border-right: 5px solid transparent; 35 | border-top: 5px solid; 36 | margin: 0 4px; 37 | } 38 | 39 | mat-form-field { 40 | width: calc(50% - 4px); 41 | margin: 0; 42 | } 43 | 44 | .amdg-invalid-range-error { 45 | color: $warn; 46 | font-size: 12px; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/pagination/pagination.component.scss: -------------------------------------------------------------------------------- 1 | @import './../../variables'; 2 | 3 | .amdg-layout-container { 4 | border-top: 1px solid $highlight-dark-color; 5 | background: $highlight-color; 6 | 7 | 8 | .mat-icon-button, .mat-flat-button { 9 | width: 26px; 10 | height: 26px; 11 | line-height: 26px !important; 12 | border-radius: 2px; 13 | margin-right: 4px; 14 | font-weight: 400; 15 | min-width: 26px; 16 | padding: 0; 17 | &.amdg-active { 18 | color: white; 19 | } 20 | 21 | &.amdg-larger-page-btn { 22 | width: 40px; 23 | } 24 | 25 | } 26 | 27 | } 28 | 29 | .amdg-grid-filter-applied-color { 30 | padding: 0; 31 | display: inline; 32 | min-width: auto; 33 | font-size: 12px; 34 | line-height: normal; 35 | cursor: inherit; 36 | } 37 | 38 | .amdg-pagination-selector { 39 | font-size: 12px; 40 | width: 70px; 41 | height: 42px; 42 | } 43 | 44 | @media screen and (max-width: 768px) { 45 | .amdg-desktop { 46 | display: none !important; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/pipes/column-filter.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'columnFilter' 5 | }) 6 | export class ColumnFilterPipe implements PipeTransform { 7 | 8 | transform(value: any[], ...args: unknown[]): any[] { 9 | const headings: string[] = []; 10 | value.forEach(heading => { 11 | if (heading.show || heading.show === undefined) { 12 | headings.push(heading); 13 | } 14 | }); 15 | return headings; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/pipes/column-search-filter.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'columnSearchFilter' 5 | }) 6 | export class ColumnSearchFilterPipe implements PipeTransform { 7 | 8 | transform(values: any[], args: any): any[] { 9 | if (args === undefined) { 10 | return values; 11 | } 12 | 13 | return values.filter(value => { 14 | return value.display.toLowerCase().includes(args.toLowerCase()); 15 | }); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/pipes/search.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'search' 5 | }) 6 | export class SearchPipe implements PipeTransform { 7 | 8 | transform(values: any, args?: any): any { 9 | if (args === undefined) { 10 | return values; 11 | } 12 | 13 | return values.filter((value: any) => { 14 | return value.text.toLowerCase().includes(args.toLowerCase()); 15 | }); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/sort-header/sort-header.component.html: -------------------------------------------------------------------------------- 1 |
2 | {{heading.display}} 3 | 4 | sort 5 | arrow_upward 6 | arrow_downward 7 | 8 |
9 | 10 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/sort-header/sort-header.component.scss: -------------------------------------------------------------------------------- 1 | .amdg-layout-container { 2 | margin: 0 -8px; 3 | height: 35px; 4 | 5 | #amdg-header-text { 6 | font-weight: bold; 7 | max-width: calc(100% - 28px); 8 | } 9 | 10 | .amdg-sort-icon { 11 | font-size: 18px; 12 | width: 18px; 13 | height: 18px; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/sort-header/sort-header.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'amdg-sort-header', 5 | templateUrl: './sort-header.component.html', 6 | styleUrls: ['./sort-header.component.scss'] 7 | }) 8 | export class SortHeaderComponent { 9 | 10 | @Input() heading: any = { display: null, type: 'string', sort: '', disableSorting: false, headerTooltip: null}; 11 | @Output() filter = new EventEmitter(); 12 | constructor() { } 13 | 14 | sort(): void { 15 | if (!this.heading.disableSorting) { 16 | switch (this.heading.sort) { 17 | case 'asc': 18 | this.heading.sort = 'desc'; 19 | break; 20 | case 'desc': 21 | this.heading.sort = null; 22 | break; 23 | default: 24 | this.heading.sort = 'asc'; 25 | } 26 | 27 | this.filter.emit(this.heading); 28 | } 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/string-filter/string-filter.component.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 |
9 |
10 | 11 | 12 |
13 |
14 | 15 | 16 | {{item.text}} 17 | 18 | 19 |
20 | 21 |
22 | 23 | 24 | 25 |
26 |
27 | Invalid value entered 28 |
29 |
30 |
31 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/string-filter/string-filter.component.scss: -------------------------------------------------------------------------------- 1 | @import './../../variables'; 2 | 3 | .amdg-placeholder { 4 | opacity: .6; 5 | } 6 | 7 | .amdg-filter-container { 8 | width: 260px; 9 | min-height: 60px; 10 | display: block; 11 | border-radius: 4px; 12 | overflow: hidden; 13 | font-size: 12px; 14 | } 15 | 16 | .amdg-filter-open-btn { 17 | line-height: 26px !important; 18 | font-size: inherit; 19 | padding: 0 4px; 20 | width: 100%; 21 | background: white; 22 | ::ng-deep .mat-button-wrapper { 23 | display: flex !important; 24 | justify-content: space-between; 25 | align-items: center; 26 | width: 100%; 27 | } 28 | } 29 | 30 | .amdg-select-arrow { 31 | width: 0; 32 | height: 0; 33 | border-left: 5px solid transparent; 34 | border-right: 5px solid transparent; 35 | border-top: 5px solid; 36 | margin: 0 4px; 37 | } 38 | 39 | .amdg-invalid-error { 40 | color: $warn; 41 | font-size: 12px; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/tag-filter/tag-filter.component.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 |
12 |
13 | 14 | 15 |
16 |
17 | 18 | Add Tag 19 | 20 | {{error}} 21 | 22 | add 23 |
24 |
25 | 26 |
27 |

No Tags entered

28 |
29 | 30 | 31 | {{tag}} cancel 32 | 33 | 34 |
35 | 36 |
37 |
38 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/tag-filter/tag-filter.component.scss: -------------------------------------------------------------------------------- 1 | @import './../../variables'; 2 | 3 | .amdg-placeholder { 4 | opacity: .6; 5 | } 6 | 7 | .amdg-filter-container { 8 | width: 260px; 9 | min-height: 60px; 10 | display: block; 11 | border-radius: 4px; 12 | overflow: hidden; 13 | font-size: 12px; 14 | 15 | .amdg-tags-container { 16 | max-height: 300px; 17 | overflow-y: auto; 18 | } 19 | } 20 | 21 | .amdg-filter-open-btn { 22 | line-height: 26px !important; 23 | font-size: inherit; 24 | padding: 0 4px; 25 | width: 100%; 26 | background: white; 27 | ::ng-deep .mat-button-wrapper { 28 | display: flex !important; 29 | justify-content: space-between; 30 | align-items: center; 31 | width: 100%; 32 | } 33 | } 34 | 35 | .amdg-select-arrow { 36 | width: 0; 37 | height: 0; 38 | border-left: 5px solid transparent; 39 | border-right: 5px solid transparent; 40 | border-top: 5px solid; 41 | margin: 0 4px; 42 | } 43 | 44 | .amdg-tag-input { 45 | width: calc(100% - 30px); 46 | } 47 | 48 | .amdg-additional-selection { 49 | opacity: 0.75; 50 | font-size: 0.75em; 51 | color: rgba(0, 0, 0, 0.87); 52 | } 53 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/components/tag-filter/tag-filter.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TagFilterComponent } from './tag-filter.component'; 4 | 5 | describe('TagFilterComponent', () => { 6 | let component: TagFilterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ TagFilterComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(TagFilterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/grids/child-grid/child-grid.component.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/grids/child-grid/child-grid.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ChildGridComponent } from './child-grid.component'; 4 | 5 | describe('ChildGridComponent', () => { 6 | let component: ChildGridComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ChildGridComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ChildGridComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/grids/grid.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { ApiResponseModel } from '../api-response.model'; 4 | import { Observable } from 'rxjs'; 5 | 6 | @Injectable({ 7 | providedIn: 'root' 8 | }) 9 | export class GridService { 10 | 11 | constructor(private http: HttpClient) { } 12 | 13 | getAny(url: string): Observable { 14 | return this.http.get(url); 15 | } 16 | 17 | getAnyPost(url: string, body: any): Observable { 18 | return this.http.post(url, body); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/grids/server-bind-grid/server-bind-grid.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ServerBindGridComponent } from './server-bind-grid.component'; 4 | 5 | describe('ServerBindGridComponent', () => { 6 | let component: ServerBindGridComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ServerBindGridComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ServerBindGridComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/grids/server-bind-grid/template.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; 3 | 4 | @Pipe({ 5 | name: 'template' 6 | }) 7 | export class TemplatePipe implements PipeTransform { 8 | 9 | constructor(private sanitizer: DomSanitizer) {} 10 | 11 | transform(value: any, args: any): SafeHtml { 12 | let modifiedTemplate = value; 13 | const splitOne = value.split('{{'); 14 | splitOne.splice(0, 1); // remove first element 15 | splitOne.forEach((item: string) => { 16 | const [customVariable] = item.split('}}'); 17 | modifiedTemplate = modifiedTemplate.replaceAll( '{{' + customVariable + '}}', args[customVariable]); 18 | }); 19 | return this.sanitizer.bypassSecurityTrustHtml(modifiedTemplate); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/grids/server-bind-grid/template_object.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'template_object' 5 | }) 6 | export class TemplateObjectPipe implements PipeTransform { 7 | 8 | constructor() {} 9 | 10 | transform(value: any, args: any): JSON { 11 | let modifiedTemplate: any = JSON.stringify(value); 12 | const splitOne = modifiedTemplate.split('{{'); 13 | splitOne.splice(0, 1); // remove first element 14 | splitOne.forEach((item: string) => { 15 | const [customVariable] = item.split('}}'); 16 | modifiedTemplate = modifiedTemplate.replaceAll( '{{' + customVariable + '}}', args[customVariable]); 17 | }); 18 | return JSON.parse(modifiedTemplate); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/interfaces/button-list-config-type.ts: -------------------------------------------------------------------------------- 1 | export interface ButtonConfigType { 2 | /** 3 | * display - Button Text 4 | */ 5 | display: string; 6 | /** 7 | * icon - Button icon from the material icons list 8 | * https://material.io/resources/icons 9 | */ 10 | icon: string; 11 | /** 12 | * disableField - If there is a reason to disable a given button based on a certain calculation or a certain logic, a row's 13 | * field can be given which will contain a boolean value. If it is true this button will get disabled. 14 | * Eg: a user object may have a field called 'archived' which if true this button can be disabled. 15 | */ 16 | disableField?: string; 17 | } 18 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/interfaces/child-grid-config-type.ts: -------------------------------------------------------------------------------- 1 | import GridHeadingInterface from './grid-heading-type'; 2 | 3 | export default interface ChildGridConfigType { 4 | 5 | headings: GridHeadingInterface[]; 6 | url: string; 7 | entity: any; 8 | serverSidePagination: boolean; 9 | } 10 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/interfaces/grid-button-click-interface.ts: -------------------------------------------------------------------------------- 1 | export default interface GridButtonClickInterface { 2 | fieldName: string; 3 | click: string; 4 | item: any; 5 | } 6 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/interfaces/grid-filter-item.ts: -------------------------------------------------------------------------------- 1 | export default interface GridFilterItemInterface { 2 | field: string; 3 | operator: string; 4 | value: string; 5 | } 6 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/interfaces/grid-master-detail-config-type.ts: -------------------------------------------------------------------------------- 1 | import ChildGridConfigType from './child-grid-config-type'; 2 | 3 | export default interface GridMasterDetailConfigInterface { 4 | 5 | /** 6 | * type - Master detail grid type determines if the row is expanded the container will 7 | * contain a custom template or a child grid. 8 | */ 9 | type: 'table' | 'html' | 'breakdown'; 10 | 11 | /** 12 | * multipleExpansion - This allows multiple rows to be expanded at a given time or not 13 | */ 14 | multipleExpansion: boolean; 15 | 16 | /** 17 | * template - If the Master detail grid type is 'html' pass the template through here 18 | */ 19 | template?: string; 20 | 21 | /** 22 | * template - If the Master detail grid type is 'table' pass the child table configuration through here 23 | */ 24 | childGrid?: ChildGridConfigType; 25 | } 26 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/interfaces/grid-request.ts: -------------------------------------------------------------------------------- 1 | import GridFilterItemInterface from './grid-filter-item'; 2 | 3 | export default interface GridRequestInterface { 4 | entity?: any; 5 | page?: number; 6 | perPage?: number; 7 | filters?: GridFilterItemInterface[]; 8 | sort?: null | '' | undefined | 'desc' | 'asc'; 9 | sortField?: null | '' | undefined | string; 10 | } 11 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/interfaces/grid-response.ts: -------------------------------------------------------------------------------- 1 | export default interface GridResponseInterface { 2 | gridData: any[]; 3 | totalCount?: number; 4 | other?: any; 5 | } 6 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/interfaces/grid-sort-item.ts: -------------------------------------------------------------------------------- 1 | export default interface GridSortItemInterface { 2 | sort: null | '' | undefined | 'desc' | 'asc'; 3 | sortField: null | '' | undefined | string; 4 | } 5 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/interfaces/multi-select-options-type.ts: -------------------------------------------------------------------------------- 1 | export interface MultiSelectOptionsType { 2 | text: string; 3 | value: string; 4 | } 5 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/interfaces/other-config-type.ts: -------------------------------------------------------------------------------- 1 | import { ButtonConfigType } from './button-list-config-type'; 2 | import { MultiSelectOptionsType } from './multi-select-options-type'; 3 | 4 | export interface OtherConfigType { 5 | /** 6 | * URL BUILDER 7 | * urlTemplate - This refers to the internal route (url) of the angular application. Eg: '/detail/:id'. If the character ':' is 8 | * used within the url provided the word next to it will be treated as a variable which will be replaced by the 9 | * data retrieved. For example '/detail/:id' will be replaced with '/detail/1' or '/detail/2' depending on the 10 | * id value 11 | */ 12 | urlTemplate?: string; 13 | /** 14 | * URL BUILDER 15 | * queryParams - This is an optional object that can be provided to build query params. Eg: {userEmail: 'email'} 16 | * The url may end like this '?userEmail=fzute0@reverbnation.com' 17 | */ 18 | queryParams?: object; 19 | /** 20 | * URL BUILDER 21 | * openTab - An optional feature which determines if there is an open tab icon next to the url which will open the url in a 22 | * separate tab in the browser (if clicked) 23 | */ 24 | openTab?: boolean; 25 | 26 | 27 | 28 | /** 29 | * MULTI-SELECT CONFIGURATION 30 | * selectionMode - Multi-select can be configured to have a single selection or multiple selection of filter values 31 | */ 32 | selectionMode?: 'single' | 'multiple'; 33 | /** 34 | * MULTI-SELECT CONFIGURATION 35 | * source - Multi-select source can either be internal or external. If the source is internal; 36 | * url, key and value fields are not needed. However, optionsObject is essential when the source is internal 37 | * IMPORTANT - source can also be used for url builder - if external is given external links can be opened 38 | */ 39 | source?: 'internal' | 'external'; 40 | /** 41 | * MULTI-SELECT CONFIGURATION 42 | * optionsObject - This contains the filter values and their display names which is essential when source is internal 43 | */ 44 | optionsObject?: MultiSelectOptionsType[]; 45 | /** 46 | * MULTI-SELECT CONFIGURATION 47 | * url - The url of a GET request needed if the source is external which should return an array of objects. 48 | */ 49 | url?: string; 50 | /** 51 | * MULTI-SELECT CONFIGURATION 52 | * key - The key is needed if the source is external, this refers to the display name of the filter value 53 | */ 54 | key?: string; 55 | /** 56 | * MULTI-SELECT CONFIGURATION 57 | * value - The value is needed if the source is external, this refers to the actual filter value 58 | */ 59 | value?: string; 60 | 61 | 62 | 63 | 64 | /** 65 | * GRID ACTION BUTTONS CONFIGURATION 66 | * mainButton - if buttons array has more than one object (button) this is essential, This refers to the menu button which will 67 | * contain the buttons if there are more than one button. It uses MatMenu for this purpose 68 | */ 69 | mainButton?: ButtonConfigType; 70 | /** 71 | * GRID ACTION BUTTONS CONFIGURATION 72 | * buttons - This array contains the button elements. If one button is there it will be displayed in the column, if multiple are 73 | * there it will be inside the mat menu. 74 | */ 75 | buttons?: ButtonConfigType[]; 76 | } 77 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/lib/variables.scss: -------------------------------------------------------------------------------- 1 | @use '@angular/material' as mat; 2 | 3 | $warn: mat.get-color-from-palette(mat.$red-palette, 600); 4 | $highlight-color: rgba(118, 118, 118, 0.1); 5 | $highlight-dark-color: rgba(118, 118, 118, 0.3); 6 | $font-size: 12px; 7 | 8 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of angular-material-data-grid 3 | */ 4 | 5 | export * from './lib/angular-material-data-grid.service'; 6 | export * from './lib/grids/server-bind-grid/server-bind-grid.component'; 7 | export * from './lib/angular-material-data-grid.module'; 8 | export * from './lib/angular-material-data-grid-interfaces'; 9 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js'; 4 | import 'zone.js/testing'; 5 | import { getTestBed } from '@angular/core/testing'; 6 | import { 7 | BrowserDynamicTestingModule, 8 | platformBrowserDynamicTesting 9 | } from '@angular/platform-browser-dynamic/testing'; 10 | 11 | // First, initialize the Angular testing environment. 12 | getTestBed().initTestEnvironment( 13 | BrowserDynamicTestingModule, 14 | platformBrowserDynamicTesting(), 15 | ); 16 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/lib", 6 | "declaration": true, 7 | "declarationMap": true, 8 | "inlineSources": true, 9 | "types": [] 10 | }, 11 | "exclude": [ 12 | "src/test.ts", 13 | "**/*.spec.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.lib.json", 4 | "compilerOptions": { 5 | "declarationMap": false 6 | }, 7 | "angularCompilerOptions": { 8 | "compilationMode": "partial" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /projects/angular-material-data-grid/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/app/app.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/app.component.scss -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, waitForAsync } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(waitForAsync(() => { 6 | TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | })); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it('should render title', () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | fixture.detectChanges(); 22 | const compiled = fixture.nativeElement; 23 | expect(compiled.querySelector('.content span').textContent).toContain('serverbind-grid app is running!'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavigationEnd, Router } from '@angular/router'; 3 | import { Subscription } from 'rxjs'; 4 | import { environment } from '../environments/environment'; 5 | declare var gtag: any; 6 | declare var ga: any; 7 | 8 | 9 | @Component({ 10 | selector: 'app-root', 11 | templateUrl: './app.component.html', 12 | styleUrls: ['./app.component.scss'] 13 | }) 14 | export class AppComponent { 15 | 16 | routerEvents: Subscription = new Subscription(); 17 | 18 | constructor(private router: Router) { 19 | this.routerEvents = this.router.events.subscribe(event => { 20 | if (event instanceof NavigationEnd) { 21 | if (environment.production) { 22 | gtag('config', 'G-ZM8GVWTZ4E', { 23 | page_path: event.urlAfterRedirects 24 | }); 25 | ga('create', 'G-ZM8GVWTZ4E', {cookieDomain: 'none'}); 26 | ga('send', 'pageview'); 27 | } 28 | } 29 | }); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/app/components/container/container.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 7 | 10 |
11 | 12 |
13 | 14 | wb_sunnyLight 15 | nights_stayDark 16 | 17 |
18 | 19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | {{panel.panelHeading}} 28 | 29 | 30 |
35 | {{item.headingName}} 36 |
37 |
38 |
39 |
40 |
41 | 42 |
43 |
44 | -------------------------------------------------------------------------------- /src/app/components/container/container.component.scss: -------------------------------------------------------------------------------- 1 | $highlight-dark-color: rgba(118, 118, 118, 0.26); 2 | 3 | .header { 4 | height: 45px; 5 | width: 100%; 6 | padding: 4px 0 4px 0; 7 | z-index: 3; 8 | position: fixed; 9 | top: 0; 10 | border-radius: 0; 11 | } 12 | 13 | mat-drawer-container { 14 | padding-top: 53px; 15 | background-color: white; 16 | .sidenav { 17 | background: #42a5f5 linear-gradient(145deg, #0d47a1, #1976d2); 18 | border-right: none; 19 | width: 205px; 20 | border-top-right-radius: 60px; 21 | // z-index: 0 !important; 22 | position: fixed; 23 | top: 53px; 24 | color: white; 25 | padding-top: 50px; 26 | } 27 | } 28 | 29 | mat-expansion-panel { 30 | background-color: transparent !important; 31 | box-shadow: none !important; 32 | color: white; 33 | .mat-expansion-panel-header-title { 34 | color: white; 35 | } 36 | } 37 | 38 | .sidenav-option { 39 | height: 36px; 40 | line-height: 36px; 41 | color: white; 42 | padding: 0 16px; 43 | border-radius: 50px; 44 | cursor: pointer; 45 | font-size: 12px; 46 | 47 | &:hover { 48 | background: $highlight-dark-color; 49 | } 50 | &.selected { 51 | background: white; 52 | color: black !important; 53 | } 54 | } 55 | 56 | .align-items-center { 57 | align-items: center; 58 | } 59 | 60 | .radio-button { 61 | display: block; 62 | margin-bottom: 5px; 63 | } 64 | -------------------------------------------------------------------------------- /src/app/components/container/container.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ContainerComponent } from './container.component'; 4 | 5 | describe('ContainerComponent', () => { 6 | let component: ContainerComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ContainerComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ContainerComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/components/container/container.component.ts: -------------------------------------------------------------------------------- 1 | import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, Renderer2, ViewChild } from '@angular/core'; 2 | import { navigation } from './navigation'; 3 | import { NavigationEnd, Router } from '@angular/router'; 4 | import { Platform } from '@angular/cdk/platform'; 5 | import { MatDrawer } from '@angular/material/sidenav'; 6 | import { MediaMatcher } from '@angular/cdk/layout'; 7 | import { Subscription } from 'rxjs'; 8 | 9 | @Component({ 10 | selector: 'app-container', 11 | templateUrl: './container.component.html', 12 | styleUrls: ['./container.component.scss'] 13 | }) 14 | export class ContainerComponent implements AfterViewInit , OnDestroy { 15 | darkMode = false; 16 | sidePanelNavigation = navigation; 17 | routerEvents: Subscription = new Subscription(); 18 | currentNav = ''; 19 | links = ['Demo', 'Introduction', 'Installation', 'Basic Usage']; 20 | // Client Side Pagination 21 | // Server Side Pagination 22 | // Filters & Sorting 23 | // Column reordering and optional columns 24 | selectedLink = 'Demo'; 25 | mobile = false; 26 | @ViewChild('drawer') drawer!: MatDrawer; 27 | mobileQuery: MediaQueryList; 28 | private mobileQueryListener: () => void; 29 | 30 | constructor(private renderer: Renderer2, 31 | private router: Router, 32 | private platform: Platform, 33 | changeDetectorRef: ChangeDetectorRef, 34 | media: MediaMatcher) { 35 | this.darkMode = (localStorage.getItem('darkMode') === 'true'); 36 | if (this.darkMode) { 37 | this.renderer.addClass(document.body, 'darkMode'); 38 | } 39 | 40 | this.routerEvents = this.router.events.subscribe(event => { 41 | if (event instanceof NavigationEnd) { 42 | const urlWithoutQueryParams = event.url.split('?')[0]; 43 | const [levelOne, levelTwo] = urlWithoutQueryParams.split('/').filter(item => item); 44 | this.currentNav = '/' + levelOne + '/' + levelTwo; 45 | window.scrollTo(0, 0); 46 | } 47 | }); 48 | 49 | this.mobileQuery = media.matchMedia('(max-width: 600px)'); 50 | this.mobileQueryListener = () => changeDetectorRef.detectChanges(); 51 | this.mobileQuery.addListener(this.mobileQueryListener); 52 | // this.mobileQuery.addEventListener('change', this.mobileQueryListener); 53 | } 54 | 55 | ngAfterViewInit(): void { 56 | if (this.platform.ANDROID || this.platform.IOS || this.mobileQuery.matches) { 57 | this.mobile = true; 58 | this.drawer.close(); 59 | } 60 | } 61 | 62 | themeChanged(): void { 63 | localStorage.setItem('darkMode', this.darkMode.toString()); 64 | if (this.darkMode) { 65 | this.renderer.addClass(document.body, 'darkMode'); 66 | } else { 67 | this.renderer.removeClass(document.body, 'darkMode'); 68 | } 69 | } 70 | 71 | goToRoute(item: any): void { 72 | this.selectedLink = item.headingName; 73 | this.router.navigate([item.route]); 74 | if (this.mobile) { 75 | this.drawer.close(); 76 | } 77 | } 78 | 79 | ngOnDestroy(): void { 80 | this.routerEvents.unsubscribe(); 81 | this.mobileQuery.removeListener(this.mobileQueryListener); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/app/pages/button-group-builder/button-group-builder.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Button Group Builder

3 | 4 |

Buttons can be configured if the column's type is button-group. 5 | The grid system makes it really easy to configure buttons within a column. If one button is configured it will 6 | be shown as intended, however if multiple buttons are configured it will be contained within a MatMenu. 7 | Buttons can be individually disabled based on a row item's field that will be a boolean. 8 | To get the Button click events refer to the 9 | Properties & Events section's @Output buttonClickEmit.

10 | 11 |
12 |

interface:

13 |
14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 31 | 32 |
NameDescription
If buttons array (see below) has more than one object (button) mainButton configuration is essential, 24 | This refers to the menu button which will contain the buttons if there are more than one button. 25 | It uses MatMenu for this purpose.
This array contains the button elements. If one button is there it will be displayed in the column, 30 | if multiple are there it will be inside the mat menu.
33 |
34 |
35 |

36 | 37 |
38 |

interface:

39 |
40 | 41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 60 | 61 |
NameDescription
Button Text.
Button icon from the material icons list. https://material.io/resources/icons
If there is a reason to disable a given button based on a certain calculation or a certain logic, a row's 58 | field can be given which will contain a boolean value. If it is true this button will get disabled. 59 | Eg: a user object may have a field called 'archived' which if true this button can be disabled.
62 |
63 |
64 |

65 | 66 |

Example of an internal and external source url type configuration.

67 |
68 |
69 | -------------------------------------------------------------------------------- /src/app/pages/button-group-builder/button-group-builder.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/button-group-builder/button-group-builder.component.scss -------------------------------------------------------------------------------- /src/app/pages/button-group-builder/button-group-builder.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ButtonGroupBuilderComponent } from './button-group-builder.component'; 4 | 5 | describe('ButtonGroupBuilderComponent', () => { 6 | let component: ButtonGroupBuilderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ButtonGroupBuilderComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ButtonGroupBuilderComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/button-group-builder/button-group-builder.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-button-group-builder', 5 | templateUrl: './button-group-builder.component.html', 6 | styleUrls: ['./button-group-builder.component.scss'] 7 | }) 8 | export class ButtonGroupBuilderComponent implements OnInit { 9 | 10 | ts = ` 11 | headings: GridHeading[] = [ 12 | ... 13 | { fieldName: 'actions', display: '', type: 'button-group', width: '100px', 14 | other: { 15 | mainButton: { 16 | display: 'Options', 17 | icon: 'expand_more', 18 | disableField: 'archived' 19 | }, 20 | buttons: [ 21 | {display: 'Edit User', icon: 'edit', disableField: 'disableEdit'}, 22 | {display: 'Delete User', icon: 'delete', disableField: 'archived'}, 23 | ] 24 | }, 25 | textAlign: 'center', disableSorting: true, 26 | } 27 | ]`; 28 | 29 | constructor() { } 30 | 31 | ngOnInit(): void { 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/app/pages/cell-styles-example/cell-styles-example.component.html: -------------------------------------------------------------------------------- 1 |
2 | 7 | 8 | 9 |
10 | Code 11 |
12 | 13 | 14 | 15 |
16 |
17 | 18 |
19 | 20 |
21 | 22 | 23 |
24 |
25 | 26 |
27 |
28 |
29 |
30 | 31 | -------------------------------------------------------------------------------- /src/app/pages/cell-styles-example/cell-styles-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/cell-styles-example/cell-styles-example.component.scss -------------------------------------------------------------------------------- /src/app/pages/cell-styles-example/cell-styles-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CellStylesExampleComponent } from './cell-styles-example.component'; 4 | 5 | describe('CellStylesExampleComponent', () => { 6 | let component: CellStylesExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ CellStylesExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(CellStylesExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/change-log/change-log.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/change-log/change-log.component.scss -------------------------------------------------------------------------------- /src/app/pages/change-log/change-log.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ChangeLogComponent } from './change-log.component'; 4 | 5 | describe('ChangeLogComponent', () => { 6 | let component: ChangeLogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ChangeLogComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ChangeLogComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/change-log/change-log.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-change-log', 5 | templateUrl: './change-log.component.html', 6 | styleUrls: ['./change-log.component.scss'] 7 | }) 8 | export class ChangeLogComponent { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/app/pages/client-side-pagination-grid-example/client-side-pagination-grid-example.component.html: -------------------------------------------------------------------------------- 1 |
2 | 16 | 17 | 18 |
19 | Code 20 |
21 | 22 | 23 | 24 |
25 |
26 | 27 |
28 | 29 |
30 | 31 | 32 |
33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/app/pages/client-side-pagination-grid-example/client-side-pagination-grid-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/client-side-pagination-grid-example/client-side-pagination-grid-example.component.scss -------------------------------------------------------------------------------- /src/app/pages/client-side-pagination-grid-example/client-side-pagination-grid-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ClientSidePaginationGridExampleComponent } from './client-side-pagination-grid-example.component'; 4 | 5 | describe('ClientSidePaginationGridExampleComponent', () => { 6 | let component: ClientSidePaginationGridExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ClientSidePaginationGridExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ClientSidePaginationGridExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/column-control/column-control.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Column Preferences

3 | 4 |

When data grids have a large number of columns, some can be made optional so the users would not get 5 | overwhelmed. These can be shown if the user wishes and the user can also customize the view by re-ordering 6 | the columns. These options are given if the columnControl 7 | input is set to true, by default it is false. Changes made using the column control are emitted to the parent 8 | component with the output columnPreferencesChangedEmit or columnPreferencesChangeEndedEmit which can be used to save the user's column preference. 9 | All the given preferences can be reset if the user clicks the Reset button which will output resetColumnPreferencesEmit. 10 |

11 | 12 |

As per the example above,

13 |

* The disabled checkboxes are fields that will be always shown - this is if 14 | the show attribute is not given in the column configuration.

15 |

* The enabled checkboxes are fields that can be shown if the user wishes to. It may also be preconfigured 16 | this way if the show attribute is true or false.

17 |

* Any of the fields can be dragged and dropped in a particular order which will help the user to 18 | customize the grid. This configuration can also be saved as a user preference later.

19 |
20 |
21 | -------------------------------------------------------------------------------- /src/app/pages/column-control/column-control.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/column-control/column-control.component.scss -------------------------------------------------------------------------------- /src/app/pages/column-control/column-control.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ColumnControlComponent } from './column-control.component'; 4 | 5 | describe('ColumnControlComponent', () => { 6 | let component: ColumnControlComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ColumnControlComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ColumnControlComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/column-control/column-control.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-column-control', 5 | templateUrl: './column-control.component.html', 6 | styleUrls: ['./column-control.component.scss'] 7 | }) 8 | export class ColumnControlComponent implements OnInit { 9 | 10 | ts = ` 11 | headings: GridHeading[] = [ 12 | ... 13 | {fieldName: 'phone', display: 'Phone', type: 'string', width: '150px'}, 14 | {fieldName: 'movie_taste', display: 'Movie Taste', type: 'string', width: '150px', show: false}, 15 | {fieldName: 'country', display: 'Country', type: 'string', width: '130px', show: true}, 16 | ]`; 17 | constructor() { } 18 | 19 | ngOnInit(): void { 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/app/pages/columns-and-filters/columns-and-filters.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/columns-and-filters/columns-and-filters.component.scss -------------------------------------------------------------------------------- /src/app/pages/columns-and-filters/columns-and-filters.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ColumnsAndFiltersComponent } from './columns-and-filters.component'; 4 | 5 | describe('ColumnsAndFiltersComponent', () => { 6 | let component: ColumnsAndFiltersComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ColumnsAndFiltersComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ColumnsAndFiltersComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/columns-and-filters/columns-and-filters.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-columns-and-filters', 5 | templateUrl: './columns-and-filters.component.html', 6 | styleUrls: ['./columns-and-filters.component.scss'] 7 | }) 8 | export class ColumnsAndFiltersComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/pages/custom-demo/custom-demo.component.html: -------------------------------------------------------------------------------- 1 |

Custom Demo

2 | -------------------------------------------------------------------------------- /src/app/pages/custom-demo/custom-demo.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/custom-demo/custom-demo.component.scss -------------------------------------------------------------------------------- /src/app/pages/custom-demo/custom-demo.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-custom-demo', 5 | templateUrl: './custom-demo.component.html', 6 | styleUrls: ['./custom-demo.component.scss'] 7 | }) 8 | export class CustomDemoComponent { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/app/pages/date-range-filter/date-range-filter.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Date Range Filter

3 | 4 |

The date-range filter can be used to select a range between two days with the MatDatepicker. 5 | This filter will be set by default when the column type is date.

6 | 7 |
8 |

Example of a date-range filter configuration.

9 |
10 |
11 |

This is a sample filter object sent through the date-range filter within the filters array in the grid request.

12 | 13 |
14 | -------------------------------------------------------------------------------- /src/app/pages/date-range-filter/date-range-filter.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/date-range-filter/date-range-filter.component.scss -------------------------------------------------------------------------------- /src/app/pages/date-range-filter/date-range-filter.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DateRangeFilterComponent } from './date-range-filter.component'; 4 | 5 | describe('DateRangeFilterComponent', () => { 6 | let component: DateRangeFilterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ DateRangeFilterComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DateRangeFilterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/date-range-filter/date-range-filter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-date-range-filter', 5 | templateUrl: './date-range-filter.component.html', 6 | styleUrls: ['./date-range-filter.component.scss'] 7 | }) 8 | export class DateRangeFilterComponent implements OnInit { 9 | 10 | ts = ` 11 | headings: GridHeading[] = [ 12 | ... 13 | { fieldName: 'date_of_birth', display: 'Date Of Birth', type: 'date' }, 14 | ]`; 15 | 16 | constructor() { } 17 | 18 | ngOnInit(): void { 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/app/pages/demo/demo.component.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/app/pages/demo/demo.component.scss: -------------------------------------------------------------------------------- 1 | .position-relative { 2 | background: url("/assets/logo.png"); 3 | } 4 | -------------------------------------------------------------------------------- /src/app/pages/detail/detail.component.html: -------------------------------------------------------------------------------- 1 |
2 |

User Detail Sample Page

3 | 4 |

This page is a demonstration to exhibit the power of the URL builder 5 | with extremely little effort.

6 | 7 |

Params: {{urlExtracts.params | json}}

8 |

Query Params: {{urlExtracts.queryParams | json}}

9 | 10 | 11 |
12 | -------------------------------------------------------------------------------- /src/app/pages/detail/detail.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/detail/detail.component.scss -------------------------------------------------------------------------------- /src/app/pages/detail/detail.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DetailComponent } from './detail.component'; 4 | 5 | describe('DetailComponent', () => { 6 | let component: DetailComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ DetailComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DetailComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/detail/detail.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ActivatedRoute } from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'app-detail', 6 | templateUrl: './detail.component.html', 7 | styleUrls: ['./detail.component.scss'] 8 | }) 9 | export class DetailComponent { 10 | 11 | urlExtracts: any = {params: null, queryParams: null}; 12 | constructor(private route: ActivatedRoute) { 13 | const {params, queryParams} = route.snapshot; 14 | this.urlExtracts.params = params; 15 | this.urlExtracts.queryParams = queryParams; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/app/pages/dynamic-headings-example/dynamic-headings-example.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 14 | 15 | 16 |
17 | 18 | -------------------------------------------------------------------------------- /src/app/pages/dynamic-headings-example/dynamic-headings-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/dynamic-headings-example/dynamic-headings-example.component.scss -------------------------------------------------------------------------------- /src/app/pages/dynamic-headings-example/dynamic-headings-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DynamicHeadingsExampleComponent } from './dynamic-headings-example.component'; 4 | 5 | describe('DynamicHeadingsExampleComponent', () => { 6 | let component: DynamicHeadingsExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ DynamicHeadingsExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DynamicHeadingsExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/dynamic-headings-example/dynamic-headings-example.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { environment } from '../../../environments/environment'; 3 | import { GridFilterItem, GridHeading } from '../../../../projects/angular-material-data-grid/src/lib/angular-material-data-grid-interfaces'; 4 | 5 | @Component({ 6 | selector: 'app-dynamic-headings-example', 7 | templateUrl: './dynamic-headings-example.component.html', 8 | styleUrls: ['./dynamic-headings-example.component.scss'] 9 | }) 10 | export class DynamicHeadingsExampleComponent { 11 | 12 | /* POST endpoint URL */ 13 | url = `${environment.api}getUsers`; 14 | 15 | 16 | headings: GridHeading[] = []; 17 | /* Original column configuration */ 18 | headingsCopy: GridHeading[] = [ 19 | {fieldName: 'id', display: 'ID', type: 'number', width: '100px', disableSorting: true, textAlign: 'right'}, 20 | {fieldName: 'full_name', display: 'Full Name', type: 'string', width: '160px', clickable: 'url', 21 | other: { 22 | openTab: true, 23 | urlTemplate: '/gettingStarted/demo/:id', 24 | queryParams: {userEmail: 'email'} 25 | }, 26 | filterType: 'tag' 27 | }, 28 | {fieldName: 'first_name', display: 'First Name', type: 'string', width: '120px', filterType: 'tag'}, 29 | {fieldName: 'last_name', display: 'Last Name', type: 'string', width: '120px', filterType: 'tag'}, 30 | {fieldName: 'email', display: 'Email', type: 'string', width: '180px'}, 31 | {fieldName: 'gender', display: 'Gender', type: 'string', width: '100px', 32 | filterType: 'multi-select', 33 | other: { 34 | selectionMode: 'single', 35 | source: 'internal', 36 | optionsObject: [ 37 | {text : 'Female', value: 'FEMALE'}, 38 | {text : 'Male', value: 'MALE'} 39 | ] 40 | } 41 | } 42 | ]; 43 | 44 | initialFilters: GridFilterItem[] = []; 45 | 46 | constructor() { 47 | this.categoryChanged(1); 48 | } 49 | 50 | categoryChanged(columnOrderId: number): void { 51 | let columnOrder = []; 52 | const defaultOrder = ['id', 'first_name', 'last_name', 'email', 'gender']; 53 | 54 | switch (columnOrderId) { 55 | case 1: 56 | columnOrder = JSON.parse(JSON.stringify(defaultOrder)); 57 | break; 58 | case 2: 59 | columnOrder = ['id', 'full_name', 'first_name', 'last_name', 'email']; 60 | break; 61 | } 62 | 63 | const reorderedHeadings: GridHeading[] = []; 64 | columnOrder.forEach((order: string) => { 65 | this.headingsCopy.forEach(heading => { 66 | if (order === heading.fieldName) { 67 | // if (heading.fieldName === sortedField) { 68 | // heading.sort = sortType; 69 | // } 70 | reorderedHeadings.push(heading); 71 | } 72 | }); 73 | }); 74 | 75 | this.headings = reorderedHeadings; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/app/pages/fixed-header/fixed-header.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Fixed Header

3 | 4 |

The grid comes with fixed headers which makes it user-friendly since the user will not have to remember the column 5 | headers when scrolling down. In addition to this the user can also use the arrow buttons to scroll left and right to 6 | quickly scroll horizontally.

7 |
8 | -------------------------------------------------------------------------------- /src/app/pages/fixed-header/fixed-header.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/fixed-header/fixed-header.component.scss -------------------------------------------------------------------------------- /src/app/pages/fixed-header/fixed-header.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FixedHeaderComponent } from './fixed-header.component'; 4 | 5 | describe('FixedHeaderComponent', () => { 6 | let component: FixedHeaderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ FixedHeaderComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(FixedHeaderComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/fixed-header/fixed-header.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-fixed-header', 5 | templateUrl: './fixed-header.component.html', 6 | styleUrls: ['./fixed-header.component.scss'] 7 | }) 8 | export class FixedHeaderComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/pages/image-type/image-type.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Image Type

3 | 4 |

An Image can be displayed on a row if the column's type is image-url. The data for this column should contain 5 | an image url and no additional configurations are required. Each image will be displayed on a 40px by 40px image tag 6 | on the row. A larger preview can be seen when the user hovers over this image which will be 150px by 150px. It is 7 | recommended that the image-url passed should contain a image of 150px by 150px. If larger images are passed the 8 | there will be extra data usage while it does not serve a purpose. If the images passed are lower than this amount the 9 | quality may be lower. 10 |

11 | 12 |

Example of an column which has a data type of image-url.

13 |
14 | 15 |
16 | -------------------------------------------------------------------------------- /src/app/pages/image-type/image-type.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/image-type/image-type.component.scss -------------------------------------------------------------------------------- /src/app/pages/image-type/image-type.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ImageTypeComponent } from './image-type.component'; 4 | 5 | describe('ImageTypeComponent', () => { 6 | let component: ImageTypeComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ImageTypeComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ImageTypeComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/image-type/image-type.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-image-type', 5 | templateUrl: './image-type.component.html', 6 | styleUrls: ['./image-type.component.scss'] 7 | }) 8 | export class ImageTypeComponent { 9 | 10 | ts = ` 11 | headings: GridHeading[] = [ 12 | ... 13 | {fieldName: 'product_image_url', display: 'Image', type: 'image-url', width: '80px', disableSorting: true, textAlign: 'center'}, 14 | ]`; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/pages/installation/installation.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Installation

3 | 4 |

This grid system uses most of the latest features of Angular Material and the CDK project like Drag and Drop 5 | and also CDK Virtual Scrolling. If you intend to use this component make sure you have Angular Material Version and 6 | CDK version of 10.2.7 or higher.

7 | 8 |

1. Install Angular Material

9 |

10 | 11 |

2. Install Angular Material Data Grid

12 |
13 | Note: For Angular 15 please add the legacy theme imports. Refer to this Style file for your reference. 14 |

15 | 16 |

3. Import Modules

17 |
18 | 19 |

4. Usage (Basic)

20 | 21 | 22 |
23 |
24 | 25 |
26 |
27 |
28 |
29 | -------------------------------------------------------------------------------- /src/app/pages/installation/installation.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/installation/installation.component.scss -------------------------------------------------------------------------------- /src/app/pages/installation/installation.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-installation', 5 | templateUrl: './installation.component.html', 6 | styleUrls: ['./installation.component.scss'] 7 | }) 8 | export class InstallationComponent implements OnInit { 9 | 10 | angularMaterial = `ng add @angular/material`; 11 | npmInstall = `// The version you install depends on the verison of Angular Material you are using 12 | 13 | // Between Angular Material verison 10.2.7 and 13.3.9 14 | npm i angular-material-data-grid@0.6.1 15 | // Between Angular Material verison 14.0.0 and 14.2.5 16 | npm i angular-material-data-grid@0.8.0 17 | // Angular Material verison 15.0.0 and above 18 | npm i angular-material-data-grid`; 19 | modules = ` 20 | import { AngularMaterialDataGridModule } from 'angular-material-data-grid'; 21 | 22 | imports: [ 23 | ... 24 | AngularMaterialDataGridModule 25 | ]`; 26 | 27 | usage = { 28 | html: ` 29 | 30 | 31 | 36 | 37 | `, 38 | ts: ` 39 | // import { GridHeading, GridResponse } from 'angular-material-data-grid'; 40 | 41 | url = 'https://angular-grid.onrender.com/getUsers'; // add your POST endpoint here later 42 | /* Try https://angular-grid.onrender.com/getAllUsers for client side pagination */ 43 | 44 | headings: GridHeading[] = [ 45 | {fieldName: 'id', display: 'ID', type: 'number', width: '100px', disableSorting: true, textAlign: 'right'}, 46 | {fieldName: 'first_name', display: 'First Name', type: 'string', width: '120px'}, 47 | {fieldName: 'email', display: 'Email', type: 'string', width: '180px'}, 48 | {fieldName: 'gender', display: 'Gender', type: 'string', width: '100px', 49 | filterType: 'multi-select', 50 | other: { 51 | selectionMode: 'single', 52 | source: 'internal', 53 | optionsObject: [ 54 | {text : 'Female', value: 'FEMALE'}, 55 | {text : 'Male', value: 'MALE'} 56 | ] 57 | } 58 | }, 59 | {fieldName: 'date_of_birth', display: 'Date Of Birth', type: 'date', width: '150px'} 60 | ]; 61 | 62 | responseReceived(response: GridResponse): void { 63 | console.log(response); // If necessary manipulate the data or use data in the parent component 64 | } 65 | `}; 66 | constructor() { } 67 | 68 | ngOnInit(): void { 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/app/pages/introduction/introduction.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Introduction

3 | 4 |

The initial purpose of creating this data grid was to make it easy for developers to easily create highly advanced 5 | data grids with server-side pagination along with multiple filters and sorting with minimum effort and time. 6 | (Client Side Pagination is also present.) 7 | In order to make this possible a tight integration between the back-end data-source and the front-end component 8 | should be agreed upon. This gives the ability to stay focused on advanced functionality and the creation of data 9 | grids with only configurations while staying opinionated. Moreover, the solutions provided by reputed vendors were 10 | expensive which makes open-source software more attractive to many clients. This product is 100% open source.

11 | 12 |

Grid Request

13 |

The grid system should be given a URL which contains a POST endpoint that will accept a request which looks like the 14 | object shown below.
(Go to the demo page and analyze the network tab to understand this better.)

15 |

* entity is an optional attribute which the developer can configure to send additional information to the backend.

16 |

* All other request parameters are automatically handled by the grid system.

17 |
18 | 19 |

Grid Response

20 |

The grid response should contain a boolean value to determine if the request is a success or failure and more 21 | importantly the payload section should contain the requested amount of rows and also the total number of rows 22 | which is present in the database. Note that the total number of rows is not needed for client side paginated grids 23 | but it is essential for server side pagination.

24 |
25 |
26 | 27 | -------------------------------------------------------------------------------- /src/app/pages/introduction/introduction.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/introduction/introduction.component.scss -------------------------------------------------------------------------------- /src/app/pages/introduction/introduction.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-introduction', 5 | templateUrl: './introduction.component.html', 6 | styleUrls: ['./introduction.component.scss'] 7 | }) 8 | export class IntroductionComponent implements OnInit { 9 | 10 | gridRequestObj = `{ 11 | "entity": {}, // any data that can be sent from outside the grid component 12 | "filters": [], // filters array generated by the grid 13 | "page": 1, // page no 14 | "perPage": 100, // page size 15 | "sort": null, // sort -> asc/desc/null 16 | "sortField": null // field name to sort data 17 | }`; 18 | 19 | gridResponseObj = `{ 20 | "payload": { 21 | "gridData": [...], // grid data 22 | "totalCount": 1000, // total count of records in the database for pagination purposes 23 | "other": null // send any other data you wish here in order to use in your application, Refer to @Output() responseEmit: EventEmitter . 24 | }, 25 | "success": true, // if this value is not returned the grid will not populate the data, handle errors if false 26 | "message": "SUCCESS" // show error message if success is false 27 | }`; 28 | 29 | constructor() { } 30 | 31 | ngOnInit(): void { 32 | } 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/app/pages/item-selection/item-selection.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Item Selection

3 | 4 |

Item selection can be done one by one or by using the hold and drag method to choose multiple items 5 | quickly. The user can also toggle the selection of all the items in the page with the checkbox at the top 6 | left. To enable item selection 7 | input should be set to true, by default it is false. The selected items are emitted from the grid 8 | component that can be captured using the selectionEmit 9 | output. 10 |

11 | 15 |
16 | -------------------------------------------------------------------------------- /src/app/pages/item-selection/item-selection.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/item-selection/item-selection.component.scss -------------------------------------------------------------------------------- /src/app/pages/item-selection/item-selection.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ItemSelectionComponent } from './item-selection.component'; 4 | 5 | describe('ItemSelectionComponent', () => { 6 | let component: ItemSelectionComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ItemSelectionComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ItemSelectionComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/item-selection/item-selection.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-item-selection', 5 | templateUrl: './item-selection.component.html', 6 | styleUrls: ['./item-selection.component.scss'] 7 | }) 8 | export class ItemSelectionComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/pages/master-detail-breakdown-grid-example/master-detail-breakdown-grid-example.component.html: -------------------------------------------------------------------------------- 1 |
2 | 11 | 12 | 13 |
14 | Code 15 |
16 | 17 | 18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 | 26 | 27 |
28 |
29 | 30 |
31 |
32 |
33 |
34 | 35 | -------------------------------------------------------------------------------- /src/app/pages/master-detail-breakdown-grid-example/master-detail-breakdown-grid-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/master-detail-breakdown-grid-example/master-detail-breakdown-grid-example.component.scss -------------------------------------------------------------------------------- /src/app/pages/master-detail-breakdown-grid-example/master-detail-breakdown-grid-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MasterDetailBreakdownGridExampleComponent } from './master-detail-breakdown-grid-example.component'; 4 | 5 | describe('MasterDetailBreakdownGridExampleComponent', () => { 6 | let component: MasterDetailBreakdownGridExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ MasterDetailBreakdownGridExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(MasterDetailBreakdownGridExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/master-detail-child-grid-example/master-detail-child-grid-example.component.html: -------------------------------------------------------------------------------- 1 |
2 | 11 | 12 | 13 |
14 | Code 15 |
16 | 17 | 18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 | 26 | 27 |
28 |
29 | 30 |
31 |
32 |
33 |
34 | 35 | -------------------------------------------------------------------------------- /src/app/pages/master-detail-child-grid-example/master-detail-child-grid-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/master-detail-child-grid-example/master-detail-child-grid-example.component.scss -------------------------------------------------------------------------------- /src/app/pages/master-detail-child-grid-example/master-detail-child-grid-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MasterDetailChildGridExampleComponent } from './master-detail-child-grid-example.component'; 4 | 5 | describe('MasterDetailChildGridExampleComponent', () => { 6 | let component: MasterDetailChildGridExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ MasterDetailChildGridExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(MasterDetailChildGridExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/master-detail-example/master-detail-example.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Master Detail Grid (Beta)

3 | 4 |

The grid is capable of making each row expandable to show more details about a particular record. 5 | The developer has the ability to make the expanded row contain a custom HTML template with 6 | the option of adding row variables (using syntax similar to Angular's String interpolation) or 7 | open a child grid with most of the capabilities of the original grid. 8 |

9 | 10 |
11 |
12 | 13 |
14 |

Custom Template

15 |

16 | This example shows how each row can be expanded to show a custom html template which 17 | the developer defines. 18 |

19 |
20 |
21 |
22 | 23 |
24 |

Child Grid

25 |

26 | This shows how each row can be expanded to show a child grid with most of the 27 | capabilities of the original grid. 28 |

29 |
30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 43 |

The documentation will be updated in detail soon.

44 |
45 | -------------------------------------------------------------------------------- /src/app/pages/master-detail-example/master-detail-example.component.scss: -------------------------------------------------------------------------------- 1 | .layout-container { 2 | margin-left: -20px; 3 | margin-right: -20px; 4 | } 5 | 6 | .flex-item { 7 | flex-grow:1; 8 | margin: 15px; 9 | border-radius: 4px; 10 | border: 1px solid rgba(118, 118, 118, 0.26); 11 | cursor: pointer; 12 | 13 | img { 14 | width: 100%; 15 | border-bottom: 1px solid rgba(118, 118, 118, 0.26) ; 16 | border-radius: 4px 4px 0px 0px; 17 | } 18 | } 19 | 20 | .flex-item:hover { 21 | background: rgba(118, 118, 118, 0.1); 22 | } 23 | -------------------------------------------------------------------------------- /src/app/pages/master-detail-example/master-detail-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MasterDetailExampleComponent } from './master-detail-example.component'; 4 | 5 | describe('MasterDetailExampleComponent', () => { 6 | let component: MasterDetailExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ MasterDetailExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(MasterDetailExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/master-detail-example/master-detail-example.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-master-detail-example', 5 | templateUrl: './master-detail-example.component.html', 6 | styleUrls: ['./master-detail-example.component.scss'] 7 | }) 8 | export class MasterDetailExampleComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/pages/master-detail-html-example/master-detail-html-example.component.html: -------------------------------------------------------------------------------- 1 |
2 | 11 | 12 | 13 |
14 | Code 15 |
16 | 17 | 18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 | 26 | 27 |
28 |
29 | 30 |
31 |
32 |
33 |
34 | 35 | -------------------------------------------------------------------------------- /src/app/pages/master-detail-html-example/master-detail-html-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/master-detail-html-example/master-detail-html-example.component.scss -------------------------------------------------------------------------------- /src/app/pages/master-detail-html-example/master-detail-html-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MasterDetailHtmlExampleComponent } from './master-detail-html-example.component'; 4 | 5 | describe('MasterDetailHtmlExampleComponent', () => { 6 | let component: MasterDetailHtmlExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ MasterDetailHtmlExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(MasterDetailHtmlExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/multi-select-filter/multi-select-filter.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Multi Select Filter

3 | 4 |

A multi-select filter type is an advanced filter which can either have one or more filter values given to a 5 | single column. A column with the type of string can contain this Multi Select Filter. To add this filter 6 | to a column it is essential to add filterType as 'multi-select'. 7 | This can be configured to have a single selection or multiple selection of filter values.

8 | 9 |
10 |

interface:

11 |
12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
NameDescription
Multi-select can be configured to have a single selection or multiple selection of filter values.
Multi-select source can either be internal or external. If the source is internal; 26 | url, key and value fields are not needed. However, optionsObject is essential when the source is internal. 27 | IMPORTANT - source can also be used for url builder - if external is given external links can be opened.
This contains the filter values and their display names which is essential when source is internal.
The url of a GET request needed if the source is external which should return an array of objects.
The key is needed if the source is external, this refers to the display name of the filter value.
The value is needed if the source is external, this refers to the actual filter value.
46 |
47 |
48 |

49 | 50 |

Example of an internal and external source multi-select filter configuration.

51 |
52 |

53 |

This is a sample filter object sent through the multi-select filter within the filters array in the grid request. 54 | Notice that when multiple values are sent through this filter, it goes as a comma separated string.

55 | 56 |
57 | -------------------------------------------------------------------------------- /src/app/pages/multi-select-filter/multi-select-filter.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/multi-select-filter/multi-select-filter.component.scss -------------------------------------------------------------------------------- /src/app/pages/multi-select-filter/multi-select-filter.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MultiSelectFilterComponent } from './multi-select-filter.component'; 4 | 5 | describe('MultiSelectFilterComponent', () => { 6 | let component: MultiSelectFilterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ MultiSelectFilterComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(MultiSelectFilterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/multi-select-filter/multi-select-filter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-multi-select-filter', 5 | templateUrl: './multi-select-filter.component.html', 6 | styleUrls: ['./multi-select-filter.component.scss'] 7 | }) 8 | export class MultiSelectFilterComponent implements OnInit { 9 | 10 | ts = ` 11 | headings: GridHeading[] = [ 12 | ... 13 | {fieldName: 'gender', display: 'Gender', type: 'string', width: '100px', 14 | filterType: 'multi-select', 15 | other: { 16 | selectionMode: 'single', 17 | source: 'internal', 18 | optionsObject: [ 19 | {text : 'Female', value: 'FEMALE'}, 20 | {text : 'Male', value: 'MALE'} 21 | ] 22 | } 23 | }, 24 | {fieldName: 'country', display: 'Country', type: 'string', width: '130px', 25 | filterType: 'multi-select', show: true, 26 | other: { 27 | selectionMode: 'multiple', 28 | source: 'external', 29 | url: 'https://angular-grid.onrender.com/countries', 30 | key: 'displayName', 31 | value: 'value' 32 | } 33 | }, 34 | ] 35 | `; 36 | 37 | constructor() { } 38 | 39 | ngOnInit(): void { 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/app/pages/numeric-filter/numeric-filter.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Numeric Filter

3 | 4 |

The numeric filter can be used to enter a search parameter to a certain field and search with different operators. 5 | This filter will be set by default when the column type is number.

6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
OperatorOperator ValueDescription
Is betweenbetweenData in the column should be between the filter parameter. This includes the start value and the end 19 | value given.
Is equal toeqData in the column should exactly match with the filter parameter.
Is not equal toneqData in the column should not be equal with the filter parameter.
Is greater than or equal togreaterorequalData in the column should be greater than or equal to the filter parameter.
Is greater thangreaterthanData in the column should be greater than the filter parameter.
Is less than or equal tolessthanorequalData in the column should be less than or equal to the filter parameter.
Is less thanlessthanData in the column should be less than the filter parameter.
52 |
53 |
54 |
55 |

Example of a numeric filter configuration.

56 |
57 |
58 |

This is a sample filter object sent through the numeric filter within the filters array in the grid request.

59 | 60 |

or

61 | 62 |
63 | -------------------------------------------------------------------------------- /src/app/pages/numeric-filter/numeric-filter.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/numeric-filter/numeric-filter.component.scss -------------------------------------------------------------------------------- /src/app/pages/numeric-filter/numeric-filter.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NumericFilterComponent } from './numeric-filter.component'; 4 | 5 | describe('NumericFilterComponent', () => { 6 | let component: NumericFilterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ NumericFilterComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(NumericFilterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/numeric-filter/numeric-filter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-numeric-filter', 5 | templateUrl: './numeric-filter.component.html', 6 | styleUrls: ['./numeric-filter.component.scss'] 7 | }) 8 | export class NumericFilterComponent implements OnInit { 9 | 10 | ts = ` 11 | headings: GridHeading[] = [ 12 | ... 13 | { fieldName: 'id', display: 'ID', type: 'number' }, 14 | ] 15 | `; 16 | constructor() { } 17 | 18 | ngOnInit(): void { 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/app/pages/open-dialog/grid-within-dialog/grid-within-dialog.component.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /src/app/pages/open-dialog/grid-within-dialog/grid-within-dialog.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/open-dialog/grid-within-dialog/grid-within-dialog.component.scss -------------------------------------------------------------------------------- /src/app/pages/open-dialog/grid-within-dialog/grid-within-dialog.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GridWithinDialogComponent } from './grid-within-dialog.component'; 4 | 5 | describe('GridWithinDialogComponent', () => { 6 | let component: GridWithinDialogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ GridWithinDialogComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(GridWithinDialogComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/open-dialog/grid-within-dialog/grid-within-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject, OnInit } from '@angular/core'; 2 | import { MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA, MatLegacyDialogRef as MatDialogRef } from '@angular/material/legacy-dialog'; 3 | import { GridHeading } from '../../../../../projects/angular-material-data-grid/src/lib/angular-material-data-grid-interfaces'; 4 | 5 | 6 | @Component({ 7 | selector: 'app-grid-within-dialog', 8 | templateUrl: './grid-within-dialog.component.html', 9 | styleUrls: ['./grid-within-dialog.component.scss'] 10 | }) 11 | export class GridWithinDialogComponent implements OnInit { 12 | 13 | /* POST endpoint URL */ 14 | url = 'https://angular-grid.onrender.com/getProductsData'; 15 | 16 | /* Column configuration */ 17 | headings: GridHeading[] = [ 18 | {fieldName: 'product_id', display: 'ID', type: 'string', width: '140px', filterType: 'tag'}, 19 | {fieldName: 'product_image_url', display: 'Image', type: 'image-url', width: '98px', disableSorting: true}, 20 | {fieldName: 'product_name', display: 'Name', type: 'string', width: '280px'}, 21 | {fieldName: 'product_price', display: 'Price', type: 'number', width: '100px'}, 22 | {fieldName: 'product_discounted_price', display: 'Discounted Price', type: 'number', width: '140px'}, 23 | {fieldName: 'currency', display: 'Currency', type: 'string', width: '100px', disableSorting: true, disableFiltering: true }, 24 | ]; 25 | 26 | entity = null; 27 | 28 | constructor(public dialogRef: MatDialogRef, 29 | @Inject(MAT_DIALOG_DATA) public data: any) { } 30 | 31 | ngOnInit(): void { 32 | this.entity = this.data; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/app/pages/open-dialog/open-dialog.component.html: -------------------------------------------------------------------------------- 1 |
2 | 10 | 11 | 12 |
13 | Code 14 |
15 | 16 | 17 | 18 |
19 |
20 | 21 |
22 | 23 |
24 | 25 | 26 |
27 |
28 | 29 |
30 |
31 | 32 |
33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/app/pages/open-dialog/open-dialog.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/open-dialog/open-dialog.component.scss -------------------------------------------------------------------------------- /src/app/pages/open-dialog/open-dialog.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { OpenDialogComponent } from './open-dialog.component'; 4 | 5 | describe('OpenDialogComponent', () => { 6 | let component: OpenDialogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ OpenDialogComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OpenDialogComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/overview/overview.component.scss: -------------------------------------------------------------------------------- 1 | .background-sky { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: center; 5 | align-items: center; 6 | position: absolute; 7 | width: 100%; 8 | min-height: 380px; 9 | height: 40vh; 10 | max-height: 560px; 11 | box-sizing: border-box; 12 | padding: 48px 48px 32px; 13 | overflow: hidden; 14 | transform: skewY(4deg); 15 | transform-origin: 100%; 16 | background: #1976d2 linear-gradient(145deg, #0d47a1, #42a5f5); 17 | color: #fff; 18 | z-index: -1; 19 | } 20 | 21 | .main-logo { 22 | min-width: 100px; 23 | max-width: 350px; 24 | width: 25%; 25 | position: absolute; 26 | left: 20%; 27 | top: 50px; 28 | } 29 | 30 | .main-text-holder { 31 | color: white; 32 | padding-top: 100px; 33 | h1 { 34 | font-size: 30px; 35 | } 36 | p { 37 | font-size: 16px; 38 | opacity: .6; 39 | } 40 | button { 41 | padding: 2px 34px 0; 42 | font-size: 18px; 43 | font-weight: 600; 44 | line-height: 40px; 45 | background-color: #fff; 46 | border-radius: 48px; 47 | box-shadow: 0 2px 5px 0 rgba(0,0,0,.26); 48 | box-sizing: border-box; 49 | cursor: pointer; 50 | color: #1976d2; 51 | border: none; 52 | outline: none; 53 | } 54 | 55 | #buy-me-a-coffee { 56 | position: absolute; 57 | margin-left: 80px; 58 | margin-top: 8px; 59 | } 60 | 61 | .buy-me-a-coffee-container { 62 | margin-top: 20px; 63 | display: none; 64 | } 65 | } 66 | 67 | .youtube { 68 | width: 80px; 69 | position: absolute; 70 | margin-left: auto; 71 | margin-right: auto; 72 | left: 0; 73 | right: 0; 74 | top: 60%; 75 | text-align: center; 76 | cursor: pointer; 77 | } 78 | 79 | .feature { 80 | padding: 16px; 81 | max-width: 800px; 82 | margin: 0 auto; 83 | 84 | img { 85 | max-width: 200px; 86 | margin: 30px; 87 | } 88 | } 89 | 90 | .faq-container { 91 | margin-top: 80px; 92 | text-align: center; 93 | max-width: 80%; 94 | 95 | h1 { 96 | text-decoration: underline; 97 | } 98 | 99 | .faq-header { 100 | min-height: 48px; 101 | height: auto; 102 | padding: 10px 24px !important; 103 | } 104 | 105 | } 106 | 107 | @media screen and (max-width: 768px) { 108 | 109 | .logo-container, #buy-me-a-coffee { 110 | display: none; 111 | } 112 | 113 | .buy-me-a-coffee-container { 114 | display: block !important; 115 | } 116 | 117 | .main-text-holder { 118 | text-align: center; 119 | width: 100%; 120 | } 121 | 122 | .layout-container { 123 | flex-direction: column; 124 | img { 125 | order: 2; 126 | } 127 | } 128 | 129 | .faq-container { 130 | max-width: 96%; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/app/pages/overview/overview.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { OverviewComponent } from './overview.component'; 4 | 5 | describe('OverviewComponent', () => { 6 | let component: OverviewComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ OverviewComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OverviewComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/overview/overview.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-overview', 5 | templateUrl: './overview.component.html', 6 | styleUrls: ['./overview.component.scss'] 7 | }) 8 | export class OverviewComponent { 9 | 10 | playVideo = false; 11 | constructor() { } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/app/pages/preconfigured-filters-example/preconfigured-filters-example.component.html: -------------------------------------------------------------------------------- 1 |
2 | 8 | 9 | 10 |
11 | Code 12 |
13 | 14 | 15 | 16 |
17 |
18 | 19 |
20 | 21 |
22 | 23 | 24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 | 32 | -------------------------------------------------------------------------------- /src/app/pages/preconfigured-filters-example/preconfigured-filters-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/preconfigured-filters-example/preconfigured-filters-example.component.scss -------------------------------------------------------------------------------- /src/app/pages/preconfigured-filters-example/preconfigured-filters-example.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { environment } from '../../../environments/environment'; 3 | import { GridFilterItem, GridHeading } from '../../../../projects/angular-material-data-grid/src/lib/angular-material-data-grid-interfaces'; 4 | 5 | @Component({ 6 | selector: 'app-preconfigured-filters-example', 7 | templateUrl: './preconfigured-filters-example.component.html', 8 | styleUrls: ['./preconfigured-filters-example.component.scss'] 9 | }) 10 | export class PreconfiguredFiltersExampleComponent { 11 | 12 | usage = { 13 | html: ` 14 | 20 | `, 21 | ts: ` 22 | /* POST endpoint URL */ 23 | url = 'https://angular-grid.onrender.com/getUsers'; 24 | 25 | /* Column configuration */ 26 | headings: GridHeading[] = [ 27 | {fieldName: 'id', display: 'ID', type: 'number', width: '100px', disableSorting: true, textAlign: 'right'}, 28 | {fieldName: 'first_name', display: 'First Name', type: 'string', width: '120px', filterType: 'tag'}, 29 | {fieldName: 'last_name', display: 'Last Name', type: 'string', width: '120px', filterType: 'tag'}, 30 | {fieldName: 'email', display: 'Email', type: 'string', width: '180px'}, 31 | {fieldName: 'gender', display: 'Gender', type: 'string', width: '100px', 32 | filterType: 'multi-select', 33 | other: { 34 | selectionMode: 'single', 35 | source: 'internal', 36 | optionsObject: [ 37 | {text : 'Female', value: 'FEMALE'}, 38 | {text : 'Male', value: 'MALE'} 39 | ] 40 | } 41 | } 42 | ]; 43 | 44 | initialFilters: GridFilterItem[] = [ 45 | { 46 | field: 'gender', 47 | operator: 'eq', 48 | value: 'MALE' 49 | }, 50 | { 51 | field: 'id', 52 | operator: 'between', 53 | value: '30-50' 54 | } 55 | ]; 56 | `}; 57 | 58 | /* POST endpoint URL */ 59 | url = `${environment.api}getUsers`; 60 | 61 | /* Original column configuration */ 62 | headings: GridHeading[] = [ 63 | {fieldName: 'id', display: 'ID', type: 'number', width: '100px', disableSorting: true, textAlign: 'right'}, 64 | {fieldName: 'first_name', display: 'First Name', type: 'string', width: '120px', filterType: 'tag'}, 65 | {fieldName: 'last_name', display: 'Last Name', type: 'string', width: '120px', filterType: 'tag'}, 66 | {fieldName: 'email', display: 'Email', type: 'string', width: '180px'}, 67 | {fieldName: 'gender', display: 'Gender', type: 'string', width: '100px', 68 | filterType: 'multi-select', 69 | other: { 70 | selectionMode: 'single', 71 | source: 'internal', 72 | optionsObject: [ 73 | {text : 'Female', value: 'FEMALE'}, 74 | {text : 'Male', value: 'MALE'} 75 | ] 76 | } 77 | } 78 | ]; 79 | 80 | initialFilters: GridFilterItem[] = [ 81 | { 82 | field: 'gender', 83 | operator: 'eq', 84 | value: 'MALE' 85 | }, 86 | { 87 | field: 'id', 88 | operator: 'between', 89 | value: '30-50' 90 | } 91 | ]; 92 | 93 | constructor() { } 94 | 95 | scrollBottom(): void { 96 | window.scrollTo(0, 1000); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/app/pages/properties-and-events/properties-and-events.component.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/app/pages/properties-and-events/properties-and-events.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-properties-and-events', 5 | templateUrl: './properties-and-events.component.html', 6 | styleUrls: ['./properties-and-events.component.scss'] 7 | }) 8 | export class PropertiesAndEventsComponent implements OnInit { 9 | 10 | importLine = `import { AngularMaterialDataGridModule } from 'angular-material-data-grid';`; 11 | 12 | constructor() { } 13 | 14 | ngOnInit(): void { 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/app/pages/reinitialize-grid-example/reinitialize-grid-example.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

This example shows how to reinitialize the grid from parent component

4 | 5 | or 6 | 7 |
8 | 15 | 16 | 17 |
18 | Code 19 |
20 | 21 | 22 | 23 |
24 |
25 | 26 |
27 | 28 |
29 | 30 | 31 |
32 |
33 | 34 |
35 |
36 |
37 |
38 | 39 | -------------------------------------------------------------------------------- /src/app/pages/reinitialize-grid-example/reinitialize-grid-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/reinitialize-grid-example/reinitialize-grid-example.component.scss -------------------------------------------------------------------------------- /src/app/pages/reinitialize-grid-example/reinitialize-grid-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ReinitializeGridExampleComponent } from './reinitialize-grid-example.component'; 4 | 5 | describe('ReinitializeGridExampleComponent', () => { 6 | let component: ReinitializeGridExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ReinitializeGridExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ReinitializeGridExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/server-bind-grid-example/server-bind-grid-example.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | Code 6 |
7 | 8 | 9 | 10 |
11 |
12 | 13 |
14 | 15 | 16 |
17 | 18 | 19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /src/app/pages/server-bind-grid-example/server-bind-grid-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/server-bind-grid-example/server-bind-grid-example.component.scss -------------------------------------------------------------------------------- /src/app/pages/server-bind-grid-example/server-bind-grid-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ServerBindGridExampleComponent } from './server-bind-grid-example.component'; 4 | 5 | describe('ServerBindGridExampleComponent', () => { 6 | let component: ServerBindGridExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ServerBindGridExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ServerBindGridExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/string-filter/string-filter.component.html: -------------------------------------------------------------------------------- 1 |
2 |

String Filter

3 | 4 |

The string filter can be used to enter a search parameter to a certain field and search with different operators.

5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
OperatorOperator ValueDescription
Is equal toeqData in the column should exactly match the filter parameter. (Not case-sensitive)
Is not equal toneqData in the column should not match the filter parameter.
ContainscontainsData in the column should contain the filter parameter somewhere in the value.
Starts withstartswithData in the column should exactly start with the filter parameter. (Not case-sensitive)
Ends withendswithData in the column should exactly end with the filter parameter. (Not case-sensitive)
Is EmptyblankData in the column should be null or empty.
45 |
46 |
47 |

48 |

Example of a string column configuration.

49 |
50 |

51 |

This is a sample filter object sent through the string filter within the filters array in the grid request.

52 | 53 |
54 | -------------------------------------------------------------------------------- /src/app/pages/string-filter/string-filter.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/string-filter/string-filter.component.scss -------------------------------------------------------------------------------- /src/app/pages/string-filter/string-filter.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { StringFilterComponent } from './string-filter.component'; 4 | 5 | describe('StringFilterComponent', () => { 6 | let component: StringFilterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ StringFilterComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(StringFilterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/string-filter/string-filter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-string-filter', 5 | templateUrl: './string-filter.component.html', 6 | styleUrls: ['./string-filter.component.scss'] 7 | }) 8 | export class StringFilterComponent implements OnInit { 9 | ts = ` 10 | headings: GridHeading[] = [ 11 | ... 12 | { fieldName: 'email', display: 'Email', type: 'string' }, 13 | ] 14 | `; 15 | constructor() { } 16 | 17 | ngOnInit(): void { 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/app/pages/tag-filter/tag-filter.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Tag Filter

3 | 4 |

A tag filter is similar to a multi-select filter but is used if there are a very large number of possible 5 | values which cannot be displayed in a multi-filter's list of options. Eg: Social Security Numbers. 6 | A column with the type of 'string' can contain this Tag Filter. Also the data types 'number' and 'currency' 7 | may contain a Tag filter, the only difference is, it only allow numbers to be added. To add this filter to a 8 | column it is essential to add filterType as 'tag'. A user can add 9 | multiple tags by pasting a comma separated string or copying cells from an excel file. 10 |

11 |

Validations for adding tag filters include:

12 |
    13 |
  • A maximum of 5000 tags can be added.
  • 14 |
  • A single tag (string) may only contain a maximum of 30 characters.
  • 15 |
  • A single number tag may only contain a maximum of 9 characters.
  • 16 |
  • Number type tags cannot contain alphanumeric characters.
  • 17 |
  • The same tag cannot be entered again.
  • 18 |
  • If a comma separated string is pasted (multiple tags) the system will automatically remove duplicates and trim 19 | the surrounding spaces, then add the tags.
  • 20 |
21 |
22 |

Example of a tag filter configuration.

23 |
24 |

25 |

This is a sample filter object sent through the tag filter within the filters array in the grid request. 26 | Notice that when multiple values are sent through this filter, it goes as a comma separated string.

27 | 28 |
29 | -------------------------------------------------------------------------------- /src/app/pages/tag-filter/tag-filter.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/tag-filter/tag-filter.component.scss -------------------------------------------------------------------------------- /src/app/pages/tag-filter/tag-filter.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TagFilterComponent } from './tag-filter.component'; 4 | 5 | describe('TagFilterComponent', () => { 6 | let component: TagFilterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ TagFilterComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(TagFilterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/tag-filter/tag-filter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-tag-filter', 5 | templateUrl: './tag-filter.component.html', 6 | styleUrls: ['./tag-filter.component.scss'] 7 | }) 8 | export class TagFilterComponent implements OnInit { 9 | 10 | ts = ` 11 | headings: GridHeading[] = [ 12 | ... 13 | { fieldName: 'first_name', display: 'First Name', type: 'string', filterType: 'tag' }, 14 | ] 15 | `; 16 | 17 | constructor() { } 18 | 19 | ngOnInit(): void { 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/app/pages/theming/theming.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Theming

3 | 4 |

The data grid is a first class material design oriented component, therefore it ships with a light and dark theme 5 | which can be customized further to fit your companies branding and colors.

6 |

Since this grid is made with Angular Material it natively adopts to the theming configuration you provide within 7 | your application. If a new application is generated with the Angular CLI make sure to put custom theme, then you will 8 | be able to change the primary and accent color of your application and observe the grid adopt to these changes.

9 |
10 |

If you wish to add a Dark Theme to your application please be sure to add the class named 'darkMode' to your body 11 | element.

12 |
13 |
14 | -------------------------------------------------------------------------------- /src/app/pages/theming/theming.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/theming/theming.component.scss -------------------------------------------------------------------------------- /src/app/pages/theming/theming.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ThemingComponent } from './theming.component'; 4 | 5 | describe('ThemingComponent', () => { 6 | let component: ThemingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ThemingComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ThemingComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/theming/theming.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-theming', 5 | templateUrl: './theming.component.html', 6 | styleUrls: ['./theming.component.scss'] 7 | }) 8 | export class ThemingComponent implements OnInit { 9 | 10 | ts = ` 11 | import { Renderer2 } from '@angular/core'; 12 | ... 13 | export class SampleComponent { 14 | darkMode = true; 15 | constructor(private renderer: Renderer2) { 16 | if (this.darkMode) { 17 | this.renderer.addClass(document.body, 'darkMode'); // add this 18 | } 19 | } 20 | } 21 | `; 22 | constructor() { } 23 | 24 | ngOnInit(): void { 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/app/pages/top-right-buttons-example/top-right-buttons-example.component.html: -------------------------------------------------------------------------------- 1 |
2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Code 18 |
19 | 20 | 21 | 22 |
23 |
24 | 25 |
26 | 27 |
28 | 29 | 30 |
31 |
32 | 33 |
34 |
35 |
36 |
37 | 38 | -------------------------------------------------------------------------------- /src/app/pages/top-right-buttons-example/top-right-buttons-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/top-right-buttons-example/top-right-buttons-example.component.scss -------------------------------------------------------------------------------- /src/app/pages/top-right-buttons-example/top-right-buttons-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TopRightButtonsExampleComponent } from './top-right-buttons-example.component'; 4 | 5 | describe('TopRightButtonsExampleComponent', () => { 6 | let component: TopRightButtonsExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ TopRightButtonsExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(TopRightButtonsExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/transparency-example/transparency-example.component.html: -------------------------------------------------------------------------------- 1 |
2 | 9 | 10 | 11 |
12 | Code 13 |
14 | 15 | 16 | 17 |
18 |
19 |
20 | 21 |
22 | 23 | 24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /src/app/pages/transparency-example/transparency-example.component.scss: -------------------------------------------------------------------------------- 1 | .position-relative { 2 | background: url("/assets/logo.png") no-repeat right bottom; 3 | background-size: contain, cover; 4 | } 5 | -------------------------------------------------------------------------------- /src/app/pages/transparency-example/transparency-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TransparencyExampleComponent } from './transparency-example.component'; 4 | 5 | describe('TransparencyExampleComponent', () => { 6 | let component: TransparencyExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ TransparencyExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(TransparencyExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/transparency-example/transparency-example.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { environment } from '../../../environments/environment'; 3 | import { GridHeading } from '../../../../projects/angular-material-data-grid/src/lib/angular-material-data-grid-interfaces'; 4 | 5 | @Component({ 6 | selector: 'app-transparency-example', 7 | templateUrl: './transparency-example.component.html', 8 | styleUrls: ['./transparency-example.component.scss'] 9 | }) 10 | export class TransparencyExampleComponent { 11 | 12 | usage = { 13 | html: ` 14 | 15 |
16 | 23 | 24 |
`, 25 | scss: ` 26 | .grid-container { 27 | background: url("/assets/logo.png") no-repeat right bottom; 28 | background-size: contain, cover; 29 | } 30 | ` 31 | }; 32 | 33 | /* POST endpoint URL */ 34 | url = `${environment.api}getUsers`; 35 | 36 | /* Original column configuration */ 37 | headings: GridHeading[] = [ 38 | {fieldName: 'id', display: 'ID', type: 'number', width: '100px', disableSorting: true, textAlign: 'right'}, 39 | {fieldName: 'first_name', display: 'First Name', type: 'string', width: '120px', filterType: 'tag'}, 40 | {fieldName: 'last_name', display: 'Last Name', type: 'string', width: '120px', filterType: 'tag'}, 41 | {fieldName: 'email', display: 'Email', type: 'string', width: '180px'}, 42 | {fieldName: 'gender', display: 'Gender', type: 'string', width: '100px', 43 | filterType: 'multi-select', 44 | other: { 45 | selectionMode: 'single', 46 | source: 'internal', 47 | optionsObject: [ 48 | {text : 'Female', value: 'FEMALE'}, 49 | {text : 'Male', value: 'MALE'} 50 | ] 51 | } 52 | } 53 | ]; 54 | 55 | entity: any = null; 56 | 57 | constructor() { } 58 | 59 | reinitialize(): void { 60 | this.entity = {}; 61 | } 62 | 63 | scrollBottom(): void { 64 | window.scrollTo(0, 1000); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/app/pages/url-builder/url-builder.component.html: -------------------------------------------------------------------------------- 1 |
2 |

URL Builder

3 | 4 |

The grid system makes it really easy to configure dynamic URLs by using URL templates that can be changed 5 | based on the values from each record. It is very easy to configure internal routes within an Angular application 6 | which uses the Router Module or even configure external links.

7 | 8 |
9 |

interface:

10 |
11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 39 | 40 |
NameDescription
This refers to the internal route (url) of the angular application. Eg: '/detail/:id'. 21 | If the character ':' is used within the url provided the word next to it will be treated as a 22 | variable which will be replaced by the data retrieved. For example '/detail/:id' will be replaced 23 | with '/detail/1' or '/detail/2' depending on the id value
The source should be given as internal for internal routes within the angular application which 28 | uses the RouterModule. If external is given external links can be opened. By default internal is given.
This is an optional object that can be provided to build query params. Eg: {{ '{ ' }}userEmail: 'email'{{ ' }' }} 33 | The url may end like this '?userEmail=fzute0@reverbnation.com'
An optional feature which determines if there is an open tab icon next to the url which will open 38 | the url in a separate tab in the browser (if clicked)
41 |
42 |
43 |

44 | 45 |

Example of an internal and external source url type configuration.

46 |
47 |
48 | -------------------------------------------------------------------------------- /src/app/pages/url-builder/url-builder.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/url-builder/url-builder.component.scss -------------------------------------------------------------------------------- /src/app/pages/url-builder/url-builder.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UrlBuilderComponent } from './url-builder.component'; 4 | 5 | describe('UrlBuilderComponent', () => { 6 | let component: UrlBuilderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ UrlBuilderComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(UrlBuilderComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/url-builder/url-builder.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-url-builder', 5 | templateUrl: './url-builder.component.html', 6 | styleUrls: ['./url-builder.component.scss'] 7 | }) 8 | export class UrlBuilderComponent implements OnInit { 9 | 10 | ts = ` 11 | headings: GridHeading[] = [ 12 | ... 13 | { fieldName: 'first_name', display: 'First Name', type: 'string', clickable: 'url', 14 | other: { 15 | openTab: true, 16 | urlTemplate: '/gettingStarted/demo/:id', 17 | queryParams: {userEmail: 'email'} 18 | } 19 | }, 20 | {fieldName: 'url', display: 'URL', type: 'string', width: '120px', clickable: 'url', 21 | other: { 22 | openTab: true, 23 | urlTemplate: 'https://stackoverflow.com', 24 | queryParams: {userEmail: 'email'}, 25 | source: 'external' 26 | } 27 | }, 28 | ]`; 29 | 30 | constructor() { } 31 | 32 | ngOnInit(): void { 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/app/pages/virtual-scrolling/virtual-scrolling.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Virtual Scrolling

3 | 4 |

The user is able to load a large dataset into the data grid and smoothly scroll because of the virtual scrolling 5 | capability of the grid. Under the hood the grid system uses the Angular CDK Virtual Scroll.

6 | 7 |

The cdk-virtual-scroll-viewport 8 | displays large lists of elements performantly by only rendering the items that fit on-screen. 9 | Loading hundreds of elements can be slow in any browser; virtual scrolling enables a performant way to simulate 10 | all items being rendered by making the height of the container element the same as the height of total number of 11 | elements to be rendered, and then only rendering the items in view. Virtual scrolling is different from strategies 12 | like infinite scroll where it renders a set amount of elements and then when you hit the end renders the rest.

13 | 14 | 15 |
16 | -------------------------------------------------------------------------------- /src/app/pages/virtual-scrolling/virtual-scrolling.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/app/pages/virtual-scrolling/virtual-scrolling.component.scss -------------------------------------------------------------------------------- /src/app/pages/virtual-scrolling/virtual-scrolling.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { VirtualScrollingComponent } from './virtual-scrolling.component'; 4 | 5 | describe('VirtualScrollingComponent', () => { 6 | let component: VirtualScrollingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ VirtualScrollingComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(VirtualScrollingComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/virtual-scrolling/virtual-scrolling.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-virtual-scrolling', 5 | templateUrl: './virtual-scrolling.component.html', 6 | styleUrls: ['./virtual-scrolling.component.scss'] 7 | }) 8 | export class VirtualScrollingComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/assets/color-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/color-circle.png -------------------------------------------------------------------------------- /src/assets/column_reordering.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/column_reordering.png -------------------------------------------------------------------------------- /src/assets/favicons/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/android-icon-144x144.png -------------------------------------------------------------------------------- /src/assets/favicons/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/android-icon-192x192.png -------------------------------------------------------------------------------- /src/assets/favicons/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/android-icon-36x36.png -------------------------------------------------------------------------------- /src/assets/favicons/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/android-icon-48x48.png -------------------------------------------------------------------------------- /src/assets/favicons/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/android-icon-72x72.png -------------------------------------------------------------------------------- /src/assets/favicons/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/android-icon-96x96.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon-114x114.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon-120x120.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon-144x144.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon-152x152.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon-180x180.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon-57x57.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon-60x60.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon-72x72.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon-76x76.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon-precomposed.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/apple-icon.png -------------------------------------------------------------------------------- /src/assets/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /src/assets/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /src/assets/favicons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/favicon-96x96.png -------------------------------------------------------------------------------- /src/assets/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/favicon.ico -------------------------------------------------------------------------------- /src/assets/favicons/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/ms-icon-144x144.png -------------------------------------------------------------------------------- /src/assets/favicons/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/ms-icon-150x150.png -------------------------------------------------------------------------------- /src/assets/favicons/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/ms-icon-310x310.png -------------------------------------------------------------------------------- /src/assets/favicons/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/favicons/ms-icon-70x70.png -------------------------------------------------------------------------------- /src/assets/filters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/filters.png -------------------------------------------------------------------------------- /src/assets/game_images/Assassins-Creed-Valhalla.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Assassins-Creed-Valhalla.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/DIRT-5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/DIRT-5.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/F1-2021.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/F1-2021.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Hunting-Simulator-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Hunting-Simulator-2.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Marvels-Avengers.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Marvels-Avengers.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Marvels-Spider.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Marvels-Spider.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Mortal-Kombat-11-Ultimate.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Mortal-Kombat-11-Ultimate.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Outriders-Day-One-Edition.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Outriders-Day-One-Edition.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Ratchet-Clank-Rift-Apart.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Ratchet-Clank-Rift-Apart.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Resident-Evil-Village.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Resident-Evil-Village.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Returnal-PlayStation.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Returnal-PlayStation.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Sniper-Ghost-Warrior-Contracts-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Sniper-Ghost-Warrior-Contracts-2.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Tennis-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Tennis-2.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/Tom-Clancys-Rainbow-Six-Siege-Deluxe-Edition.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/Tom-Clancys-Rainbow-Six-Siege-Deluxe-Edition.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/WRC-9.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/WRC-9.jpeg -------------------------------------------------------------------------------- /src/assets/game_images/hitman-3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/game_images/hitman-3.jpeg -------------------------------------------------------------------------------- /src/assets/grid_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/grid_background.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/master-detail-child-grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/master-detail-child-grid.png -------------------------------------------------------------------------------- /src/assets/master-detail-html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/master-detail-html.png -------------------------------------------------------------------------------- /src/assets/selection.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/selection.mp4 -------------------------------------------------------------------------------- /src/assets/virtual_scrolling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/virtual_scrolling.png -------------------------------------------------------------------------------- /src/assets/youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/assets/youtube.png -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | api: 'https://angular-grid.onrender.com/' 4 | }; 5 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | // api: 'http://localhost:3000/', 8 | api: 'https://angular-grid.onrender.com/' 9 | }; 10 | 11 | /* 12 | * For easier debugging in development mode, you can import the following file 13 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 14 | * 15 | * This import should be commented out in production mode because it will have a negative impact 16 | * on performance if an error is thrown. 17 | */ 18 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 19 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dillyboy/angular_material_data_grid/f94fbe28c93bcd61dd42f175036acf664541afaf/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Advanced Angular Material Data Grid System 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 48 | 49 | 50 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes recent versions of Safari, Chrome (including 12 | * Opera), Edge on the desktop, and iOS and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** 22 | * By default, zone.js will patch all possible macroTask and DomEvents 23 | * user can disable parts of macroTask/DomEvents patch by setting following flags 24 | * because those flags need to be set before `zone.js` being loaded, and webpack 25 | * will put import in the top of bundle, so user need to create a separate file 26 | * in this directory (for example: zone-flags.ts), and put the following flags 27 | * into that file, and then add the following code before importing zone.js. 28 | * import './zone-flags'; 29 | * 30 | * The flags allowed in zone-flags.ts are listed here. 31 | * 32 | * The following flags will work for all browsers. 33 | * 34 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 35 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 36 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 37 | * 38 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 39 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 40 | * 41 | * (window as any).__Zone_enable_cross_context_check = true; 42 | * 43 | */ 44 | 45 | /*************************************************************************************************** 46 | * Zone JS is required by default for Angular itself. 47 | */ 48 | import 'zone.js'; // Included with Angular CLI. 49 | 50 | 51 | /*************************************************************************************************** 52 | * APPLICATION IMPORTS 53 | */ 54 | -------------------------------------------------------------------------------- /src/scss/material-overrides.scss: -------------------------------------------------------------------------------- 1 | .custom-side-nav-header { 2 | .mat-expansion-indicator::after { 3 | color: white !important; 4 | } 5 | } 6 | 7 | 8 | .mat-drawer.mat-drawer-side { 9 | z-index: 1!important; 10 | } 11 | 12 | .mat-drawer-content { 13 | z-index: auto!important; 14 | } 15 | 16 | .mat-drawer-container { 17 | z-index: auto!important; 18 | } 19 | 20 | body { 21 | .hljs { 22 | border: 1px solid #ececec; 23 | } 24 | &.darkMode { 25 | // atom-one-dark theme for highlight js 26 | .hljs { 27 | display: block; 28 | overflow-x: auto; 29 | padding: 0.5em; 30 | color: #abb2bf; 31 | background: #282c34; 32 | border: 1px solid rgba(118, 118, 118, 0.1); 33 | } 34 | 35 | .hljs-comment, 36 | .hljs-quote { 37 | color: #5c6370; 38 | font-style: italic; 39 | } 40 | 41 | .hljs-doctag, 42 | .hljs-keyword, 43 | .hljs-formula { 44 | color: #c678dd; 45 | } 46 | 47 | .hljs-section, 48 | .hljs-name, 49 | .hljs-selector-tag, 50 | .hljs-deletion, 51 | .hljs-subst { 52 | color: #e06c75; 53 | } 54 | 55 | .hljs-literal { 56 | color: #56b6c2; 57 | } 58 | 59 | .hljs-string, 60 | .hljs-regexp, 61 | .hljs-addition, 62 | .hljs-attribute, 63 | .hljs-meta-string { 64 | color: #98c379; 65 | } 66 | 67 | .hljs-built_in, 68 | .hljs-class .hljs-title { 69 | color: #e6c07b; 70 | } 71 | 72 | .hljs-attr, 73 | .hljs-variable, 74 | .hljs-template-variable, 75 | .hljs-type, 76 | .hljs-selector-class, 77 | .hljs-selector-attr, 78 | .hljs-selector-pseudo, 79 | .hljs-number { 80 | color: #d19a66; 81 | } 82 | 83 | .hljs-symbol, 84 | .hljs-bullet, 85 | .hljs-link, 86 | .hljs-meta, 87 | .hljs-selector-id, 88 | .hljs-title { 89 | color: #61aeee; 90 | } 91 | 92 | .hljs-emphasis { 93 | font-style: italic; 94 | } 95 | 96 | .hljs-strong { 97 | font-weight: bold; 98 | } 99 | 100 | .hljs-link { 101 | text-decoration: underline; 102 | } 103 | } 104 | } 105 | 106 | mat-icon { opacity: 0 }; 107 | -------------------------------------------------------------------------------- /src/scss/theme.scss: -------------------------------------------------------------------------------- 1 | @use '@angular/material' as mat; 2 | 3 | // TODO(v15): As of v15 mat.legacy-core no longer includes default typography styles. 4 | // The following line adds: 5 | // 1. Default typography styles for all components 6 | // 2. Styles for typography hierarchy classes (e.g. .mat-headline-1) 7 | // If you specify typography styles for the components you use elsewhere, you should delete this line. 8 | // If you don't need the default component typographies but still want the hierarchy styles, 9 | // you can delete this line and instead use: 10 | // `@include mat.legacy-typography-hierarchy(mat.define-legacy-typography-config());` 11 | @include mat.all-legacy-component-typographies(); 12 | @include mat.legacy-core(); 13 | 14 | $my-primary: mat.define-palette(mat.$blue-palette); 15 | $my-primary-dark: mat.define-palette(mat.$blue-palette, 400); 16 | $my-accent: mat.define-palette(mat.$amber-palette, 800, 700, 900); 17 | $my-warn: mat.define-palette(mat.$red-palette); 18 | 19 | $my-theme: mat.define-light-theme(( 20 | color: ( 21 | primary: $my-primary, 22 | accent: $my-accent, 23 | warn: $my-warn, 24 | ) 25 | )); 26 | 27 | $my-dark-theme: mat.define-dark-theme(( 28 | color: ( 29 | primary: $my-primary-dark, 30 | accent: $my-accent, 31 | warn: $my-warn, 32 | ) 33 | )); 34 | 35 | @include mat.all-legacy-component-themes($my-theme); 36 | 37 | .darkMode { 38 | @include mat.all-legacy-component-themes($my-dark-theme); 39 | } 40 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | // First, initialize the Angular testing environment. 11 | getTestBed().initTestEnvironment( 12 | BrowserDynamicTestingModule, 13 | platformBrowserDynamicTesting(), 14 | ); 15 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "paths": { 6 | "angular-material-data-grid": [ 7 | "dist/angular-material-data-grid/angular-material-data-grid", 8 | "dist/angular-material-data-grid" 9 | ] 10 | }, 11 | "baseUrl": "./", 12 | "outDir": "./dist/out-tsc", 13 | "forceConsistentCasingInFileNames": true, 14 | "strict": true, 15 | "noImplicitOverride": true, 16 | "noPropertyAccessFromIndexSignature": true, 17 | "noImplicitReturns": true, 18 | "noFallthroughCasesInSwitch": true, 19 | "sourceMap": true, 20 | "declaration": false, 21 | "downlevelIteration": true, 22 | "experimentalDecorators": true, 23 | "moduleResolution": "node", 24 | "importHelpers": true, 25 | "target": "ES2022", 26 | "module": "es2020", 27 | "lib": [ 28 | "es2020", 29 | "dom" 30 | ], 31 | "useDefineForClassFields": false 32 | }, 33 | "angularCompilerOptions": { 34 | "enableI18nLegacyMessageIdFormat": false, 35 | "strictInjectionParameters": true, 36 | "strictInputAccessModifiers": true, 37 | "strictTemplates": true 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | --------------------------------------------------------------------------------