Compare commits
2 Commits
main
..
79d474f9f5
| Author | SHA1 | Date | |
|---|---|---|---|
|
79d474f9f5
|
|||
|
8becaa7653
|
@@ -1,12 +0,0 @@
|
|||||||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
|
||||||
# For additional information regarding the format and rule options, please see:
|
|
||||||
# https://github.com/browserslist/browserslist#queries
|
|
||||||
|
|
||||||
# You can see what browsers were selected by your queries by running:
|
|
||||||
# npx browserslist
|
|
||||||
|
|
||||||
> 0.5%
|
|
||||||
last 2 versions
|
|
||||||
Firefox ESR
|
|
||||||
not dead
|
|
||||||
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
|
||||||
+10
-15
@@ -1,21 +1,18 @@
|
|||||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
|
||||||
|
|
||||||
# compiled output
|
# Compiled output
|
||||||
/dist
|
/dist
|
||||||
/tmp
|
/tmp
|
||||||
/out-tsc
|
/out-tsc
|
||||||
# Only exists if Bazel was run
|
|
||||||
/bazel-out
|
/bazel-out
|
||||||
|
|
||||||
# dependencies
|
# Node
|
||||||
/node_modules
|
/node_modules
|
||||||
|
npm-debug.log
|
||||||
# profiling files
|
yarn-error.log
|
||||||
chrome-profiler-events*.json
|
|
||||||
speed-measure-plugin*.json
|
|
||||||
|
|
||||||
# IDEs and editors
|
# IDEs and editors
|
||||||
/.idea
|
.idea/
|
||||||
.project
|
.project
|
||||||
.classpath
|
.classpath
|
||||||
.c9/
|
.c9/
|
||||||
@@ -23,7 +20,7 @@ speed-measure-plugin*.json
|
|||||||
.settings/
|
.settings/
|
||||||
*.sublime-workspace
|
*.sublime-workspace
|
||||||
|
|
||||||
# IDE - VSCode
|
# Visual Studio Code
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/settings.json
|
!.vscode/settings.json
|
||||||
!.vscode/tasks.json
|
!.vscode/tasks.json
|
||||||
@@ -31,17 +28,15 @@ speed-measure-plugin*.json
|
|||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
.history/*
|
.history/*
|
||||||
|
|
||||||
# misc
|
# Miscellaneous
|
||||||
/.angular/cache
|
/.angular/cache
|
||||||
/.sass-cache
|
.sass-cache/
|
||||||
/connect.lock
|
/connect.lock
|
||||||
/coverage
|
/coverage
|
||||||
/libpeerconnection.log
|
/libpeerconnection.log
|
||||||
npm-debug.log
|
|
||||||
yarn-error.log
|
|
||||||
testem.log
|
testem.log
|
||||||
/typings
|
/typings
|
||||||
|
|
||||||
# System Files
|
# System files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
|
||||||
|
"recommendations": ["angular.ng-template"]
|
||||||
|
}
|
||||||
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "ng serve",
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "npm: start",
|
||||||
|
"url": "http://localhost:4200/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ng test",
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "npm: test",
|
||||||
|
"url": "http://localhost:9876/debug.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+42
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "start",
|
||||||
|
"isBackground": true,
|
||||||
|
"problemMatcher": {
|
||||||
|
"owner": "typescript",
|
||||||
|
"pattern": "$tsc",
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": {
|
||||||
|
"regexp": "(.*?)"
|
||||||
|
},
|
||||||
|
"endsPattern": {
|
||||||
|
"regexp": "bundle generation complete"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "test",
|
||||||
|
"isBackground": true,
|
||||||
|
"problemMatcher": {
|
||||||
|
"owner": "typescript",
|
||||||
|
"pattern": "$tsc",
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": {
|
||||||
|
"regexp": "(.*?)"
|
||||||
|
},
|
||||||
|
"endsPattern": {
|
||||||
|
"regexp": "bundle generation complete"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2023 Powered Software Inc.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,5 +1,27 @@
|
|||||||
> This project was originally initiated by [Powered Software Inc.](https://poweredsoft.com/) and was forked from the [ngx-ui](https://github.com/PoweredSoft/ngx-ui) Repository
|
# NgxDataUi
|
||||||
|
|
||||||
## License
|
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.0.7.
|
||||||
|
|
||||||
This project is licensed under the [MIT License](LICENSE).
|
## Development server
|
||||||
|
|
||||||
|
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
|
||||||
|
|
||||||
|
## Code scaffolding
|
||||||
|
|
||||||
|
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||||
|
|
||||||
|
## Running end-to-end tests
|
||||||
|
|
||||||
|
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
|
||||||
|
|
||||||
|
## Further help
|
||||||
|
|
||||||
|
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
||||||
|
|||||||
+108
-162
@@ -3,214 +3,160 @@
|
|||||||
"version": 1,
|
"version": 1,
|
||||||
"newProjectRoot": "projects",
|
"newProjectRoot": "projects",
|
||||||
"projects": {
|
"projects": {
|
||||||
"demo": {
|
"core": {
|
||||||
"projectType": "application",
|
"projectType": "library",
|
||||||
"schematics": {
|
"root": "projects/core",
|
||||||
"@schematics/angular:component": {
|
"sourceRoot": "projects/core/src",
|
||||||
"style": "scss"
|
"prefix": "dui",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||||
|
"options": {
|
||||||
|
"project": "projects/core/ng-package.json"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"tsConfig": "projects/core/tsconfig.lib.prod.json"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"tsConfig": "projects/core/tsconfig.lib.json"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "production"
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": "projects/core/tsconfig.spec.json",
|
||||||
|
"polyfills": [
|
||||||
|
"zone.js",
|
||||||
|
"zone.js/testing"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"root": "",
|
},
|
||||||
"sourceRoot": "src",
|
"md-ui": {
|
||||||
"prefix": "ps",
|
"projectType": "library",
|
||||||
|
"root": "projects/md-ui",
|
||||||
|
"sourceRoot": "projects/md-ui/src",
|
||||||
|
"prefix": "mdx",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||||
|
"options": {
|
||||||
|
"project": "projects/md-ui/ng-package.json"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"tsConfig": "projects/md-ui/tsconfig.lib.prod.json"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"tsConfig": "projects/md-ui/tsconfig.lib.json"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "production"
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": "projects/md-ui/tsconfig.spec.json",
|
||||||
|
"polyfills": [
|
||||||
|
"zone.js",
|
||||||
|
"zone.js/testing"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"md-demo": {
|
||||||
|
"projectType": "application",
|
||||||
|
"schematics": {},
|
||||||
|
"root": "projects/material-design-demo-app",
|
||||||
|
"sourceRoot": "projects/material-design-demo-app/src",
|
||||||
|
"prefix": "app",
|
||||||
"architect": {
|
"architect": {
|
||||||
"build": {
|
"build": {
|
||||||
"builder": "@angular-devkit/build-angular:application",
|
"builder": "@angular-devkit/build-angular:application",
|
||||||
"options": {
|
"options": {
|
||||||
"outputPath": {
|
"outputPath": "dist/material-design-demo-app",
|
||||||
"base": "dist/ngx-cdk-ui"
|
"index": "projects/material-design-demo-app/src/index.html",
|
||||||
},
|
"browser": "projects/material-design-demo-app/src/main.ts",
|
||||||
"index": "src/index.html",
|
|
||||||
"polyfills": [
|
"polyfills": [
|
||||||
"src/polyfills.ts"
|
"zone.js"
|
||||||
],
|
],
|
||||||
"tsConfig": "tsconfig.app.json",
|
"tsConfig": "projects/material-design-demo-app/tsconfig.app.json",
|
||||||
"assets": [
|
"assets": [
|
||||||
"src/favicon.ico",
|
{
|
||||||
"src/assets"
|
"glob": "**/*",
|
||||||
|
"input": "projects/material-design-demo-app/public"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
"@angular/material/prebuilt-themes/azure-blue.css",
|
||||||
"src/styles.scss"
|
"projects/material-design-demo-app/src/styles.css"
|
||||||
],
|
],
|
||||||
"scripts": [],
|
"scripts": []
|
||||||
"extractLicenses": false,
|
|
||||||
"sourceMap": true,
|
|
||||||
"optimization": false,
|
|
||||||
"namedChunks": true,
|
|
||||||
"browser": "src/main.ts"
|
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "src/environments/environment.ts",
|
|
||||||
"with": "src/environments/environment.prod.ts"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"optimization": true,
|
|
||||||
"outputHashing": "all",
|
|
||||||
"sourceMap": false,
|
|
||||||
"namedChunks": false,
|
|
||||||
"extractLicenses": true,
|
|
||||||
"budgets": [
|
"budgets": [
|
||||||
{
|
{
|
||||||
"type": "initial",
|
"type": "initial",
|
||||||
"maximumWarning": "2mb",
|
"maximumWarning": "500kB",
|
||||||
"maximumError": "5mb"
|
"maximumError": "1MB"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "anyComponentStyle",
|
"type": "anyComponentStyle",
|
||||||
"maximumWarning": "6kb",
|
"maximumWarning": "2kB",
|
||||||
"maximumError": "10kb"
|
"maximumError": "4kB"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"outputHashing": "all"
|
||||||
},
|
},
|
||||||
"development": {}
|
"development": {
|
||||||
|
"optimization": false,
|
||||||
|
"extractLicenses": false,
|
||||||
|
"sourceMap": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"defaultConfiguration": "production"
|
"defaultConfiguration": "production"
|
||||||
},
|
},
|
||||||
"serve": {
|
"serve": {
|
||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
"options": {
|
|
||||||
},
|
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
"buildTarget": "ngx-cdk-ui:build:production"
|
"buildTarget": "material-design-demo-app:build:production"
|
||||||
},
|
},
|
||||||
"development": {
|
"development": {
|
||||||
"buildTarget": "ngx-cdk-ui:build:development"
|
"buildTarget": "material-design-demo-app:build:development"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultConfiguration": "development"
|
"defaultConfiguration": "development"
|
||||||
},
|
},
|
||||||
"extract-i18n": {
|
"extract-i18n": {
|
||||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
"builder": "@angular-devkit/build-angular:extract-i18n"
|
||||||
"options": {
|
|
||||||
"buildTarget": "ngx-cdk-ui:build"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"builder": "@angular-devkit/build-angular:karma",
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
"options": {
|
"options": {
|
||||||
"main": "src/test.ts",
|
"polyfills": [
|
||||||
"polyfills": "src/polyfills.ts",
|
"zone.js",
|
||||||
"tsConfig": "tsconfig.spec.json",
|
"zone.js/testing"
|
||||||
"karmaConfig": "karma.conf.js",
|
],
|
||||||
|
"tsConfig": "projects/material-design-demo-app/tsconfig.spec.json",
|
||||||
"assets": [
|
"assets": [
|
||||||
"src/favicon.ico",
|
{
|
||||||
"src/assets"
|
"glob": "**/*",
|
||||||
|
"input": "projects/material-design-demo-app/public"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.scss"
|
"@angular/material/prebuilt-themes/azure-blue.css",
|
||||||
|
"projects/material-design-demo-app/src/styles.css"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"e2e": {
|
|
||||||
"builder": "@angular-devkit/build-angular:protractor",
|
|
||||||
"options": {
|
|
||||||
"protractorConfig": "e2e/protractor.conf.js"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"devServerTarget": "ngx-cdk-ui:serve:production"
|
|
||||||
},
|
|
||||||
"development": {
|
|
||||||
"devServerTarget": "ngx-cdk-ui:serve:development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultConfiguration": "development"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ngx-data-cdk-ui": {
|
|
||||||
"projectType": "library",
|
|
||||||
"root": "projects/openharbor/ngx-data-cdk-ui",
|
|
||||||
"sourceRoot": "projects/openharbor/ngx-data-cdk-ui/src",
|
|
||||||
"prefix": "cdk",
|
|
||||||
"architect": {
|
|
||||||
"build": {
|
|
||||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": "projects/openharbor/ngx-data-cdk-ui/tsconfig.lib.json",
|
|
||||||
"project": "projects/openharbor/ngx-data-cdk-ui/ng-package.json"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"tsConfig": "projects/openharbor/ngx-data-cdk-ui/tsconfig.lib.prod.json"
|
|
||||||
},
|
|
||||||
"development": {}
|
|
||||||
},
|
|
||||||
"defaultConfiguration": "production"
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"builder": "@angular-devkit/build-angular:karma",
|
|
||||||
"options": {
|
|
||||||
"main": "projects/openharbor/ngx-data-cdk-ui/src/test.ts",
|
|
||||||
"tsConfig": "projects/openharbor/ngx-data-cdk-ui/tsconfig.spec.json",
|
|
||||||
"karmaConfig": "projects/openharbor/ngx-data-cdk-ui/karma.conf.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ngx-data-bootstrap-ui": {
|
|
||||||
"projectType": "library",
|
|
||||||
"root": "projects/openharbor/ngx-data-bootstrap-ui",
|
|
||||||
"sourceRoot": "projects/openharbor/ngx-data-bootstrap-ui/src",
|
|
||||||
"prefix": "bsx",
|
|
||||||
"architect": {
|
|
||||||
"build": {
|
|
||||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": "projects/openharbor/ngx-data-bootstrap-ui/tsconfig.lib.json",
|
|
||||||
"project": "projects/openharbor/ngx-data-bootstrap-ui/ng-package.json"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"tsConfig": "projects/openharbor/ngx-data-bootstrap-ui/tsconfig.lib.prod.json"
|
|
||||||
},
|
|
||||||
"development": {}
|
|
||||||
},
|
|
||||||
"defaultConfiguration": "production"
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"builder": "@angular-devkit/build-angular:karma",
|
|
||||||
"options": {
|
|
||||||
"main": "projects/openharbor/ngx-data-bootstrap-ui/src/test.ts",
|
|
||||||
"tsConfig": "projects/openharbor/ngx-data-bootstrap-ui/tsconfig.spec.json",
|
|
||||||
"karmaConfig": "projects/openharbor/ngx-data-bootstrap-ui/karma.conf.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ngx-data-ng-select-ui": {
|
|
||||||
"projectType": "library",
|
|
||||||
"root": "projects/openharbor/ngx-data-ng-select-ui",
|
|
||||||
"sourceRoot": "projects/openharbor/ngx-data-ng-select-ui/src",
|
|
||||||
"prefix": "ps-ng",
|
|
||||||
"architect": {
|
|
||||||
"build": {
|
|
||||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": "projects/openharbor/ngx-data-ng-select-ui/tsconfig.lib.json",
|
|
||||||
"project": "projects/openharbor/ngx-data-ng-select-ui/ng-package.json"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"tsConfig": "projects/openharbor/ngx-data-ng-select-ui/tsconfig.lib.prod.json"
|
|
||||||
},
|
|
||||||
"development": {}
|
|
||||||
},
|
|
||||||
"defaultConfiguration": "production"
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"builder": "@angular-devkit/build-angular:karma",
|
|
||||||
"options": {
|
|
||||||
"main": "projects/openharbor/ngx-data-ng-select-ui/src/test.ts",
|
|
||||||
"tsConfig": "projects/openharbor/ngx-data-ng-select-ui/tsconfig.spec.json",
|
|
||||||
"karmaConfig": "projects/openharbor/ngx-data-ng-select-ui/karma.conf.js"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
// @ts-check
|
|
||||||
// Protractor configuration file, see link for more information
|
|
||||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
|
||||||
|
|
||||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type { import("protractor").Config }
|
|
||||||
*/
|
|
||||||
exports.config = {
|
|
||||||
allScriptsTimeout: 11000,
|
|
||||||
specs: [
|
|
||||||
'./src/**/*.e2e-spec.ts'
|
|
||||||
],
|
|
||||||
capabilities: {
|
|
||||||
browserName: 'chrome'
|
|
||||||
},
|
|
||||||
directConnect: true,
|
|
||||||
baseUrl: 'http://localhost:4200/',
|
|
||||||
framework: 'jasmine',
|
|
||||||
jasmineNodeOpts: {
|
|
||||||
showColors: true,
|
|
||||||
defaultTimeoutInterval: 30000,
|
|
||||||
print: function() {}
|
|
||||||
},
|
|
||||||
onPrepare() {
|
|
||||||
require('ts-node').register({
|
|
||||||
project: require('path').join(__dirname, './tsconfig.json')
|
|
||||||
});
|
|
||||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { AppPage } from './app.po';
|
|
||||||
import { browser, logging } from 'protractor';
|
|
||||||
|
|
||||||
describe('workspace-project App', () => {
|
|
||||||
let page: AppPage;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
page = new AppPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display welcome message', () => {
|
|
||||||
page.navigateTo();
|
|
||||||
expect(page.getTitleText()).toEqual('ngx-cdk-ui app is running!');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(async () => {
|
|
||||||
// Assert that there are no errors emitted from the browser
|
|
||||||
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
|
|
||||||
expect(logs).not.toContain(jasmine.objectContaining({
|
|
||||||
level: logging.Level.SEVERE,
|
|
||||||
} as logging.Entry));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { browser, by, element } from 'protractor';
|
|
||||||
|
|
||||||
export class AppPage {
|
|
||||||
navigateTo(): Promise<unknown> {
|
|
||||||
return browser.get(browser.baseUrl) as Promise<unknown>;
|
|
||||||
}
|
|
||||||
|
|
||||||
getTitleText(): Promise<string> {
|
|
||||||
return element(by.css('app-root .content span')).getText() as Promise<string>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../out-tsc/e2e",
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "es2018",
|
|
||||||
"types": [
|
|
||||||
"jasmine",
|
|
||||||
"jasminewd2",
|
|
||||||
"node"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
// Karma configuration file, see link for more information
|
|
||||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
|
||||||
|
|
||||||
module.exports = function (config) {
|
|
||||||
config.set({
|
|
||||||
basePath: '',
|
|
||||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
|
||||||
plugins: [
|
|
||||||
require('karma-jasmine'),
|
|
||||||
require('karma-chrome-launcher'),
|
|
||||||
require('karma-jasmine-html-reporter'),
|
|
||||||
require('karma-coverage-istanbul-reporter'),
|
|
||||||
require('@angular-devkit/build-angular/plugins/karma')
|
|
||||||
],
|
|
||||||
client: {
|
|
||||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
|
||||||
},
|
|
||||||
coverageIstanbulReporter: {
|
|
||||||
dir: require('path').join(__dirname, './coverage/ngx-cdk-ui'),
|
|
||||||
reports: ['html', 'lcovonly', 'text-summary'],
|
|
||||||
fixWebpackSourcePaths: true
|
|
||||||
},
|
|
||||||
reporters: ['progress', 'kjhtml'],
|
|
||||||
port: 9876,
|
|
||||||
colors: true,
|
|
||||||
logLevel: config.LOG_INFO,
|
|
||||||
autoWatch: true,
|
|
||||||
browsers: ['Chrome'],
|
|
||||||
singleRun: false,
|
|
||||||
restartOnFileChange: true
|
|
||||||
});
|
|
||||||
};
|
|
||||||
+30
-68
@@ -1,79 +1,41 @@
|
|||||||
{
|
{
|
||||||
"name": "demo",
|
"name": "ngx-data-ui",
|
||||||
"version": "0.0.0",
|
"version": "0.1.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"up-md": "ng serve md-demo",
|
||||||
"start": "ng serve",
|
"build-md": "ng build md-ui --configuration production",
|
||||||
"build": "ng build",
|
"publish-md": "npm publish md-ui --access-public"
|
||||||
"test": "ng test",
|
|
||||||
"lint": "ng lint",
|
|
||||||
"e2e": "ng e2e",
|
|
||||||
"clean": "rimraf dist",
|
|
||||||
|
|
||||||
"build-bootstrap": "ng build ngx-data-bootstrap-ui --configuration production",
|
|
||||||
"publish-bootstrap": "npm publish dist/openharbor/ngx-data-bootstrap-ui --access public",
|
|
||||||
|
|
||||||
"build-cdk": "ng build ngx-data-cdk-ui --configuration production",
|
|
||||||
"publish-cdk": "npm publish dist/openharbor/ngx-data-cdk-ui --access public",
|
|
||||||
|
|
||||||
"build-ng-select": "ng build ngx-data-ng-select-ui --configuration production",
|
|
||||||
"publish-ng-select": "npm publish dist/openharbor/ngx-data-ng-select-ui --access public",
|
|
||||||
|
|
||||||
"start:app": "wait-on dist/openharbor/ngx-cdk-ui/fesm5 && dist/poweredsoft/ngx-bootstrap/fesm5 && ng serve --poll 2000",
|
|
||||||
"watch:lib": "ng build @poweredsoft/ngx-cdk-ui --watch && ng build @poweredsoft/ngx-bootstrap --watch",
|
|
||||||
"watch:all": "npm run clean && run-p watch:lib start:app"
|
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^18.2.1",
|
"@angular/animations": "^18.0.0",
|
||||||
"@angular/common": "^18.2.1",
|
"@angular/cdk": "18.2.2",
|
||||||
"@angular/compiler": "^18.2.1",
|
"@angular/common": "^18.0.0",
|
||||||
"@angular/core": "^18.2.1",
|
"@angular/compiler": "^18.0.0",
|
||||||
"@angular/forms": "^18.2.1",
|
"@angular/core": "^18.0.0",
|
||||||
"@angular/platform-browser": "^18.2.1",
|
"@angular/forms": "^18.0.0",
|
||||||
"@angular/platform-browser-dynamic": "^18.2.1",
|
"@angular/material": "18.2.2",
|
||||||
"@angular/router": "^18.2.1",
|
"@angular/platform-browser": "^18.0.0",
|
||||||
"@ng-select/ng-select": "^13.0.0",
|
"@angular/platform-browser-dynamic": "^18.0.0",
|
||||||
"@openharbor/ngx-data": "^18.0.0-alpha.3",
|
"@angular/router": "^18.0.0",
|
||||||
"@poweredsoft/data": "^0.0.36",
|
"@openharbor/data": "^1.0.0-alpha.1",
|
||||||
"@poweredsoft/ngx-data-apollo": "0.0.10",
|
"rxjs": "~7.8.0",
|
||||||
"apollo-angular": "^1.8.0",
|
"tslib": "^2.3.0",
|
||||||
"apollo-angular-link-http": "^1.9.0",
|
"zone.js": "~0.14.3"
|
||||||
"apollo-cache-inmemory": "^1.6.0",
|
|
||||||
"apollo-client": "^2.6.0",
|
|
||||||
"apollo-link": "^1.2.11",
|
|
||||||
"bootstrap": "^4.5.0",
|
|
||||||
"graphql": "^14.5.0",
|
|
||||||
"graphql-tag": "^2.10.0",
|
|
||||||
"ngx-bootstrap": "^18.0.0",
|
|
||||||
"rxjs": "~6.5.4",
|
|
||||||
"tslib": "^2.0.0",
|
|
||||||
"zone.js": "~0.14.10"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^18.2.1",
|
"@angular-devkit/build-angular": "^18.2.1",
|
||||||
"@angular/cli": "^18.2.1",
|
"@angular/cli": "^18.0.7",
|
||||||
"@angular/compiler-cli": "^18.2.1",
|
"@angular/compiler-cli": "^18.0.0",
|
||||||
"@angular/language-service": "^18.2.1",
|
"@types/jasmine": "~5.1.0",
|
||||||
"@types/jasmine": "~3.6.0",
|
"jasmine-core": "~5.1.0",
|
||||||
"@types/jasminewd2": "~2.0.3",
|
"karma": "~6.4.0",
|
||||||
"@types/node": "^12.11.1",
|
"karma-chrome-launcher": "~3.2.0",
|
||||||
"codelyzer": "^6.0.0",
|
"karma-coverage": "~2.2.0",
|
||||||
"jasmine-core": "~3.6.0",
|
"karma-jasmine": "~5.1.0",
|
||||||
"jasmine-spec-reporter": "~5.0.0",
|
"karma-jasmine-html-reporter": "~2.1.0",
|
||||||
"karma": "~6.4.4",
|
"ng-packagr": "^18.2.0",
|
||||||
"karma-chrome-launcher": "~3.1.0",
|
"typescript": "~5.4.2"
|
||||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
|
||||||
"karma-jasmine": "~4.0.0",
|
|
||||||
"karma-jasmine-html-reporter": "^1.5.0",
|
|
||||||
"ng-packagr": "^18.2.1",
|
|
||||||
"npm-run-all": "^4.1.5",
|
|
||||||
"protractor": "~7.0.0",
|
|
||||||
"rimraf": "^3.0.2",
|
|
||||||
"ts-node": "~8.3.0",
|
|
||||||
"tslint": "~6.1.0",
|
|
||||||
"typescript": "~5.5.4",
|
|
||||||
"wait-on": "^5.0.1"
|
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
|
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||||
|
"dest": "../../dist/core",
|
||||||
|
"lib": {
|
||||||
|
"entryFile": "src/public-api.ts"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "@openharbor/ngx-data-ui-core",
|
||||||
|
"version": "18.0.0-alpha.1",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": "^18.2.0",
|
||||||
|
"@angular/core": "^18.2.0",
|
||||||
|
"@openharbor/data": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"sideEffects": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import {Observable} from "rxjs";
|
||||||
|
|
||||||
|
export interface IConfirmOptions {
|
||||||
|
title: string;
|
||||||
|
message: string;
|
||||||
|
confirmText?: string;
|
||||||
|
cancelText?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class ICommandDirectiveService<TConfirmOptions extends IConfirmOptions = IConfirmOptions> {
|
||||||
|
abstract confirm(options: TConfirmOptions): Observable<boolean>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import {Directive, EventEmitter, HostListener, Inject, Input, Optional, Output} from '@angular/core';
|
||||||
|
import {IDataSource} from '@poweredsoft/data';
|
||||||
|
import {finalize} from "rxjs";
|
||||||
|
import {ICommandDirectiveService, IConfirmOptions} from "../abstractions/command-directive-service.abstraction";
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[duiCommand]',
|
||||||
|
standalone: true
|
||||||
|
})
|
||||||
|
export class CommandDirective<TModel extends {}, TConfirmOptions extends IConfirmOptions> {
|
||||||
|
|
||||||
|
@Input() confirm: boolean = false;
|
||||||
|
@Input() confirmOptions?: TConfirmOptions;
|
||||||
|
@Input() refreshOnSuccess: boolean = false;
|
||||||
|
@Input() params: any;
|
||||||
|
|
||||||
|
@Input() dataSource!: IDataSource<TModel>;
|
||||||
|
@Input() command!: string;
|
||||||
|
@Input() model!: TModel;
|
||||||
|
|
||||||
|
@Output() success: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
@Output() failure: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
@Output() loading: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
constructor(@Optional() private service?: ICommandDirectiveService<TConfirmOptions>) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostListener('click')
|
||||||
|
handleClick() {
|
||||||
|
if (this.confirm) {
|
||||||
|
if (!this.service) {
|
||||||
|
const error = new Error(`NullInjectorError: No implementation provider for CommandDirectiveService Abstraction!`);
|
||||||
|
error.name = 'NullInjectorError';
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.service.confirm(this.confirmOptions)
|
||||||
|
.subscribe(result => {
|
||||||
|
if (result)
|
||||||
|
this.executeCommand();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.executeCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
private executeCommand() {
|
||||||
|
this.dataSource.resolveCommandModelByName<TModel>({
|
||||||
|
command: this.command,
|
||||||
|
model: this.model,
|
||||||
|
params: this.params
|
||||||
|
})
|
||||||
|
.subscribe({ next: commandModel => {
|
||||||
|
this.loading.emit(true);
|
||||||
|
this.dataSource.executeCommandByName(this.command, commandModel)
|
||||||
|
.pipe(
|
||||||
|
finalize(() => this.loading.emit(false))
|
||||||
|
)
|
||||||
|
.subscribe({
|
||||||
|
next: commandResult =>
|
||||||
|
{
|
||||||
|
if (this.refreshOnSuccess)
|
||||||
|
this.dataSource.refresh();
|
||||||
|
|
||||||
|
this.success.emit(commandResult);
|
||||||
|
},
|
||||||
|
error: commandError => {
|
||||||
|
this.failure.emit(commandError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: resolveCommandError => {
|
||||||
|
this.failure.emit(resolveCommandError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/*
|
||||||
|
* Public API Surface of core
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './lib/command/directives/command.directive';
|
||||||
|
export * from './lib/command/abstractions/command-directive-service.abstraction';
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../out-tsc/lib",
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"inlineSources": true,
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.lib.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"declarationMap": false
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"compilationMode": "partial"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,336 @@
|
|||||||
|
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * * The content below * * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * Delete the template below * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * to get started with your project! * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
--bright-blue: oklch(51.01% 0.274 263.83);
|
||||||
|
--electric-violet: oklch(53.18% 0.28 296.97);
|
||||||
|
--french-violet: oklch(47.66% 0.246 305.88);
|
||||||
|
--vivid-pink: oklch(69.02% 0.277 332.77);
|
||||||
|
--hot-red: oklch(61.42% 0.238 15.34);
|
||||||
|
--orange-red: oklch(63.32% 0.24 31.68);
|
||||||
|
|
||||||
|
--gray-900: oklch(19.37% 0.006 300.98);
|
||||||
|
--gray-700: oklch(36.98% 0.014 302.71);
|
||||||
|
--gray-400: oklch(70.9% 0.015 304.04);
|
||||||
|
|
||||||
|
--red-to-pink-to-purple-vertical-gradient: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
var(--orange-red) 0%,
|
||||||
|
var(--vivid-pink) 50%,
|
||||||
|
var(--electric-violet) 100%
|
||||||
|
);
|
||||||
|
|
||||||
|
--red-to-pink-to-purple-horizontal-gradient: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
var(--orange-red) 0%,
|
||||||
|
var(--vivid-pink) 50%,
|
||||||
|
var(--electric-violet) 100%
|
||||||
|
);
|
||||||
|
|
||||||
|
--pill-accent: var(--bright-blue);
|
||||||
|
|
||||||
|
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||||
|
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
||||||
|
"Segoe UI Symbol";
|
||||||
|
box-sizing: border-box;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 3.125rem;
|
||||||
|
color: var(--gray-900);
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 100%;
|
||||||
|
letter-spacing: -0.125rem;
|
||||||
|
margin: 0;
|
||||||
|
font-family: "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||||
|
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
||||||
|
"Segoe UI Symbol";
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--gray-700);
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem;
|
||||||
|
box-sizing: inherit;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-logo {
|
||||||
|
max-width: 9.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 700px;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content h1 {
|
||||||
|
margin-top: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content p {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
width: 1px;
|
||||||
|
background: var(--red-to-pink-to-purple-vertical-gradient);
|
||||||
|
margin-inline: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pill-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: start;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pill {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
--pill-accent: var(--bright-blue);
|
||||||
|
background: color-mix(in srgb, var(--pill-accent) 5%, transparent);
|
||||||
|
color: var(--pill-accent);
|
||||||
|
padding-inline: 0.75rem;
|
||||||
|
padding-block: 0.375rem;
|
||||||
|
border-radius: 2.75rem;
|
||||||
|
border: 0;
|
||||||
|
transition: background 0.3s ease;
|
||||||
|
font-family: var(--inter-font);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.4rem;
|
||||||
|
letter-spacing: -0.00875rem;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pill:hover {
|
||||||
|
background: color-mix(in srgb, var(--pill-accent) 15%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pill-group .pill:nth-child(6n + 1) {
|
||||||
|
--pill-accent: var(--bright-blue);
|
||||||
|
}
|
||||||
|
.pill-group .pill:nth-child(6n + 2) {
|
||||||
|
--pill-accent: var(--french-violet);
|
||||||
|
}
|
||||||
|
.pill-group .pill:nth-child(6n + 3),
|
||||||
|
.pill-group .pill:nth-child(6n + 4),
|
||||||
|
.pill-group .pill:nth-child(6n + 5) {
|
||||||
|
--pill-accent: var(--hot-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pill-group svg {
|
||||||
|
margin-inline-start: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-links {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.73rem;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-links path {
|
||||||
|
transition: fill 0.3s ease;
|
||||||
|
fill: var(--gray-400);
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-links a:hover svg path {
|
||||||
|
fill: var(--gray-900);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 650px) {
|
||||||
|
.content {
|
||||||
|
flex-direction: column;
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
background: var(--red-to-pink-to-purple-horizontal-gradient);
|
||||||
|
margin-block: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<main class="main">
|
||||||
|
<div class="content">
|
||||||
|
<div class="left-side">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 982 239"
|
||||||
|
fill="none"
|
||||||
|
class="angular-logo"
|
||||||
|
>
|
||||||
|
<g clip-path="url(#a)">
|
||||||
|
<path
|
||||||
|
fill="url(#b)"
|
||||||
|
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.602 64.311h-44.431Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.039-7.037 7.037 0 12.846 1.145 17.347 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.745 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.618 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.009 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.092 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.814 58.814 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="url(#c)"
|
||||||
|
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.602 64.311h-44.431Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.039-7.037 7.037 0 12.846 1.145 17.347 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.745 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.618 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.009 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.092 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.814 58.814 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<radialGradient
|
||||||
|
id="c"
|
||||||
|
cx="0"
|
||||||
|
cy="0"
|
||||||
|
r="1"
|
||||||
|
gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
>
|
||||||
|
<stop stop-color="#FF41F8" />
|
||||||
|
<stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
|
||||||
|
<stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="b"
|
||||||
|
x1="0"
|
||||||
|
x2="982"
|
||||||
|
y1="192"
|
||||||
|
y2="192"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
>
|
||||||
|
<stop stop-color="#F0060B" />
|
||||||
|
<stop offset="0" stop-color="#F0070C" />
|
||||||
|
<stop offset=".526" stop-color="#CC26D5" />
|
||||||
|
<stop offset="1" stop-color="#7702FF" />
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<h1>Hello, {{ title }}</h1>
|
||||||
|
<p>Congratulations! Your app is running. 🎉</p>
|
||||||
|
</div>
|
||||||
|
<div class="divider" role="separator" aria-label="Divider"></div>
|
||||||
|
<div class="right-side">
|
||||||
|
<div class="pill-group">
|
||||||
|
@for (item of [
|
||||||
|
{ title: 'Explore the Docs', link: 'https://angular.dev' },
|
||||||
|
{ title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' },
|
||||||
|
{ title: 'CLI Docs', link: 'https://angular.dev/tools/cli' },
|
||||||
|
{ title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' },
|
||||||
|
{ title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' },
|
||||||
|
]; track item.title) {
|
||||||
|
<a
|
||||||
|
class="pill"
|
||||||
|
[href]="item.link"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
<span>{{ item.title }}</span>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
height="14"
|
||||||
|
viewBox="0 -960 960 960"
|
||||||
|
width="14"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="social-links">
|
||||||
|
<a
|
||||||
|
href="https://github.com/angular/angular"
|
||||||
|
aria-label="Github"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="25"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 25 24"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
alt="Github"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M12.3047 0C5.50634 0 0 5.50942 0 12.3047C0 17.7423 3.52529 22.3535 8.41332 23.9787C9.02856 24.0946 9.25414 23.7142 9.25414 23.3871C9.25414 23.0949 9.24389 22.3207 9.23876 21.2953C5.81601 22.0377 5.09414 19.6444 5.09414 19.6444C4.53427 18.2243 3.72524 17.8449 3.72524 17.8449C2.61064 17.082 3.81137 17.0973 3.81137 17.0973C5.04697 17.1835 5.69604 18.3647 5.69604 18.3647C6.79321 20.2463 8.57636 19.7029 9.27978 19.3881C9.39052 18.5924 9.70736 18.0499 10.0591 17.7423C7.32641 17.4347 4.45429 16.3765 4.45429 11.6618C4.45429 10.3185 4.9311 9.22133 5.72065 8.36C5.58222 8.04931 5.16694 6.79833 5.82831 5.10337C5.82831 5.10337 6.85883 4.77319 9.2121 6.36459C10.1965 6.09082 11.2424 5.95546 12.2883 5.94931C13.3342 5.95546 14.3801 6.09082 15.3644 6.36459C17.7023 4.77319 18.7328 5.10337 18.7328 5.10337C19.3942 6.79833 18.9789 8.04931 18.8559 8.36C19.6403 9.22133 20.1171 10.3185 20.1171 11.6618C20.1171 16.3888 17.2409 17.4296 14.5031 17.7321C14.9338 18.1012 15.3337 18.8559 15.3337 20.0084C15.3337 21.6552 15.3183 22.978 15.3183 23.3779C15.3183 23.7009 15.5336 24.0854 16.1642 23.9623C21.0871 22.3484 24.6094 17.7341 24.6094 12.3047C24.6094 5.50942 19.0999 0 12.3047 0Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://twitter.com/angular"
|
||||||
|
aria-label="Twitter"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
alt="Twitter"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://www.youtube.com/channel/UCbn1OgGei-DV7aSRo_HaAiw"
|
||||||
|
aria-label="Youtube"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="29"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 29 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
alt="Youtube"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M27.4896 1.52422C27.9301 1.96749 28.2463 2.51866 28.4068 3.12258C29.0004 5.35161 29.0004 10 29.0004 10C29.0004 10 29.0004 14.6484 28.4068 16.8774C28.2463 17.4813 27.9301 18.0325 27.4896 18.4758C27.0492 18.9191 26.5 19.2389 25.8972 19.4032C23.6778 20 14.8068 20 14.8068 20C14.8068 20 5.93586 20 3.71651 19.4032C3.11363 19.2389 2.56449 18.9191 2.12405 18.4758C1.68361 18.0325 1.36732 17.4813 1.20683 16.8774C0.613281 14.6484 0.613281 10 0.613281 10C0.613281 10 0.613281 5.35161 1.20683 3.12258C1.36732 2.51866 1.68361 1.96749 2.12405 1.52422C2.56449 1.08095 3.11363 0.76113 3.71651 0.596774C5.93586 0 14.8068 0 14.8068 0C14.8068 0 23.6778 0 25.8972 0.596774C26.5 0.76113 27.0492 1.08095 27.4896 1.52422ZM19.3229 10L11.9036 5.77905V14.221L19.3229 10Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * * The content above * * * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * End of Placeholder * * * * * * * * * * * * -->
|
||||||
|
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||||
|
|
||||||
|
|
||||||
|
<router-outlet />
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
describe('AppComponent', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [AppComponent],
|
||||||
|
}).compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create the app', () => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.componentInstance;
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should have the 'material-design-demo-app' title`, () => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.componentInstance;
|
||||||
|
expect(app.title).toEqual('material-design-demo-app');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render title', () => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
fixture.detectChanges();
|
||||||
|
const compiled = fixture.nativeElement as HTMLElement;
|
||||||
|
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, material-design-demo-app');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { RouterOutlet } from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
standalone: true,
|
||||||
|
imports: [RouterOutlet],
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrl: './app.component.css'
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
title = 'material-design-demo-app';
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||||
|
import { provideRouter } from '@angular/router';
|
||||||
|
|
||||||
|
import { routes } from './app.routes';
|
||||||
|
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
||||||
|
|
||||||
|
export const appConfig: ApplicationConfig = {
|
||||||
|
providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideAnimationsAsync()]
|
||||||
|
};
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { Routes } from '@angular/router';
|
||||||
|
|
||||||
|
export const routes: Routes = [];
|
||||||
@@ -2,10 +2,12 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>NgxCdkUi</title>
|
<title>MaterialDesignDemoApp</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import { bootstrapApplication } from '@angular/platform-browser';
|
||||||
|
import { appConfig } from './app/app.config';
|
||||||
|
import { AppComponent } from './app/app.component';
|
||||||
|
|
||||||
|
bootstrapApplication(AppComponent, appConfig)
|
||||||
|
.catch((err) => console.error(err));
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
|
||||||
|
html, body { height: 100%; }
|
||||||
|
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../out-tsc/app",
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/main.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
],
|
||||||
|
"path": {
|
||||||
|
"@openharbor/ngx-data-material-design-ui" : [
|
||||||
|
"../ngx-data-material-design-ui/src/public-api"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.spec.ts",
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
### Angular X Data Material Design Extension UI
|
||||||
|
|
||||||
|
pkg name: @openharbor/ngx-data-md-ui
|
||||||
|
prefix: mdx
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||||
|
"dest": "../../dist/md-ui",
|
||||||
|
"lib": {
|
||||||
|
"entryFile": "src/public-api.ts"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "@openharbor/ngx-data-ui-md",
|
||||||
|
"version": "18.0.0-alpha.1",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": "^18.0.0",
|
||||||
|
"@angular/core": "^18.0.0",
|
||||||
|
"@angular/material": "^18.0.0",
|
||||||
|
"@openharbor/ngx-data-ui-core": "^18.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"sideEffects": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import {inject, Injectable} from '@angular/core';
|
||||||
|
import {ICommandDirectiveService, IConfirmOptions} from "@openharbor/ngx-data-ui-core";
|
||||||
|
import {Observable} from 'rxjs';
|
||||||
|
import {MatDialog, MatDialogConfig} from "@angular/material/dialog";
|
||||||
|
import {
|
||||||
|
ConfirmDialogDefaultComponent,
|
||||||
|
IConfirmDialogDefaultOptions
|
||||||
|
} from "../../confirm-dialog/confirm-dialog-default/confirm-dialog-default.component";
|
||||||
|
|
||||||
|
export interface IMDCommandDirectiveServiceOptions extends IConfirmOptions {
|
||||||
|
dialogOptions?: Omit<MatDialogConfig, 'data'>;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
useExisting: ICommandDirectiveService
|
||||||
|
})
|
||||||
|
export class CommandDirectiveService extends ICommandDirectiveService<IMDCommandDirectiveServiceOptions> {
|
||||||
|
readonly dialog = inject(MatDialog);
|
||||||
|
|
||||||
|
confirm(options: IMDCommandDirectiveServiceOptions): Observable<boolean> {
|
||||||
|
const defaultOptions: Partial<IConfirmOptions> = {
|
||||||
|
confirmText: 'Confirm',
|
||||||
|
cancelText: 'Cancel'
|
||||||
|
};
|
||||||
|
|
||||||
|
const finalOptions: IMDCommandDirectiveServiceOptions = { ...defaultOptions, ...options };
|
||||||
|
|
||||||
|
return new Observable<boolean>(subscriber => {
|
||||||
|
const dialogOptions : MatDialogConfig<IConfirmDialogDefaultOptions> = {
|
||||||
|
...{
|
||||||
|
autoFocus: 'dialog'
|
||||||
|
},
|
||||||
|
...finalOptions.dialogOptions,
|
||||||
|
...{
|
||||||
|
data: {
|
||||||
|
title: finalOptions.title,
|
||||||
|
message: finalOptions.message,
|
||||||
|
confirmText: finalOptions.confirmText,
|
||||||
|
cancelText: finalOptions.cancelText,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dialog.open<ConfirmDialogDefaultComponent, IConfirmDialogDefaultOptions>(ConfirmDialogDefaultComponent, dialogOptions);
|
||||||
|
|
||||||
|
subscriber.next(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<h2 mat-dialog-title>{{ title }}</h2>
|
||||||
|
<mat-dialog-content>
|
||||||
|
{{ message }}
|
||||||
|
</mat-dialog-content>
|
||||||
|
<mat-dialog-actions>
|
||||||
|
<button mat-button mat-dialog-close>{{ cancelText ?? 'Cancel' }}</button>
|
||||||
|
<button mat-button mat-dialog-close cdkFocusInitial>{{ confirmText ?? 'Confirm' }}</button>
|
||||||
|
</mat-dialog-actions>
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
import {Component, inject, Input} from '@angular/core';
|
||||||
|
import {
|
||||||
|
MAT_DIALOG_DATA,
|
||||||
|
MatDialogActions,
|
||||||
|
MatDialogClose,
|
||||||
|
MatDialogContent,
|
||||||
|
MatDialogTitle
|
||||||
|
} from "@angular/material/dialog";
|
||||||
|
import {MatButton} from "@angular/material/button";
|
||||||
|
|
||||||
|
export interface IConfirmDialogDefaultOptions {
|
||||||
|
title: string;
|
||||||
|
message: string;
|
||||||
|
confirmText?: string;
|
||||||
|
cancelText?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mdx-confirm-dialog-default',
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
MatDialogContent,
|
||||||
|
MatDialogActions,
|
||||||
|
MatButton,
|
||||||
|
MatDialogClose,
|
||||||
|
MatDialogTitle
|
||||||
|
],
|
||||||
|
templateUrl: './confirm-dialog-default.component.html',
|
||||||
|
styleUrl: './confirm-dialog-default.component.css'
|
||||||
|
})
|
||||||
|
export class ConfirmDialogDefaultComponent {
|
||||||
|
readonly data = inject<IConfirmDialogDefaultOptions>(MAT_DIALOG_DATA)
|
||||||
|
|
||||||
|
readonly title: string = this.data.title;
|
||||||
|
readonly message: string = this.data.message;
|
||||||
|
readonly confirmText?: string = this.data.confirmText;
|
||||||
|
readonly cancelText?: string = this.data.cancelText;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/*
|
||||||
|
* Public API Surface of md-ui
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './lib/command/services/command-directive.service';
|
||||||
|
export * from './lib/confirm-dialog/confirm-dialog-default/confirm-dialog-default.component';
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../out-tsc/lib",
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"inlineSources": true,
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"**/*.spec.ts"
|
||||||
|
],
|
||||||
|
/*"paths": {
|
||||||
|
"@openharbor/ngx-data-ui-core": [
|
||||||
|
"../core/src/public-api",
|
||||||
|
]
|
||||||
|
}*/
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.lib.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"declarationMap": false
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"compilationMode": "partial"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
> This project was originally initiated by [Powered Software Inc.](https://poweredsoft.com/) and was forked from the [ngx-ui](https://github.com/PoweredSoft/ngx-ui) Repository
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is licensed under the [MIT License](LICENSE).
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
// Karma configuration file, see link for more information
|
|
||||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
|
||||||
|
|
||||||
module.exports = function (config) {
|
|
||||||
config.set({
|
|
||||||
basePath: '',
|
|
||||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
|
||||||
plugins: [
|
|
||||||
require('karma-jasmine'),
|
|
||||||
require('karma-chrome-launcher'),
|
|
||||||
require('karma-jasmine-html-reporter'),
|
|
||||||
require('karma-coverage-istanbul-reporter'),
|
|
||||||
require('@angular-devkit/build-angular/plugins/karma')
|
|
||||||
],
|
|
||||||
client: {
|
|
||||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
|
||||||
},
|
|
||||||
coverageIstanbulReporter: {
|
|
||||||
dir: require('path').join(__dirname, '../../../coverage/poweredsoft/ngx-bootstrap'),
|
|
||||||
reports: ['html', 'lcovonly', 'text-summary'],
|
|
||||||
fixWebpackSourcePaths: true
|
|
||||||
},
|
|
||||||
reporters: ['progress', 'kjhtml'],
|
|
||||||
port: 9876,
|
|
||||||
colors: true,
|
|
||||||
logLevel: config.LOG_INFO,
|
|
||||||
autoWatch: true,
|
|
||||||
browsers: ['Chrome'],
|
|
||||||
singleRun: false,
|
|
||||||
restartOnFileChange: true
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
|
|
||||||
"dest": "../../../dist/openharbor/ngx-data-bootstrap-ui",
|
|
||||||
"lib": {
|
|
||||||
"entryFile": "src/public-api.ts"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@openharbor/ngx-data-bootstrap-ui",
|
|
||||||
"version": "18.0.0-alpha.2",
|
|
||||||
"repository": "https://git.openharbor.io/Open-Harbor/ngx-data-ui",
|
|
||||||
"description": "an internal use library for handling data sources grid filtering sorting, add commands etc",
|
|
||||||
"keywords": [
|
|
||||||
"angular",
|
|
||||||
"ngx-bootstrap"
|
|
||||||
],
|
|
||||||
"peerDependencies": {
|
|
||||||
"@poweredsoft/data": "^0.0.36",
|
|
||||||
"@angular/common": "^18.0.0",
|
|
||||||
"@angular/core": "^18.0.0",
|
|
||||||
"ngx-bootstrap": "^18.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
import {NgModule} from '@angular/core';
|
|
||||||
import {CommonModule} from '@angular/common';
|
|
||||||
import {ModalModule} from 'ngx-bootstrap/modal';
|
|
||||||
import {CommandModalDirective} from './directives/command-modal.directive';
|
|
||||||
import {CommandModalComponent} from './command-modal/command-modal.component';
|
|
||||||
import {FormsModule} from '@angular/forms';
|
|
||||||
import {CommandModalService} from './command-modal.service';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
ModalModule.forRoot(),
|
|
||||||
FormsModule
|
|
||||||
],
|
|
||||||
providers: [CommandModalService],
|
|
||||||
declarations: [CommandModalDirective, CommandModalComponent],
|
|
||||||
exports: [CommandModalDirective]
|
|
||||||
})
|
|
||||||
export class CommandModalModule { }
|
|
||||||
-60
@@ -1,60 +0,0 @@
|
|||||||
import {CommandModalComponent} from './command-modal/command-modal.component';
|
|
||||||
import {EventEmitter, Injectable, TemplateRef} from '@angular/core';
|
|
||||||
import {IDataSource} from '@poweredsoft/data';
|
|
||||||
import {BsModalService} from 'ngx-bootstrap/modal';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class CommandModalService {
|
|
||||||
constructor(private modalService: BsModalService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
spawn<TModel>(options: {
|
|
||||||
dataSource: IDataSource<TModel>
|
|
||||||
command: string,
|
|
||||||
model: TModel,
|
|
||||||
template: TemplateRef<any>,
|
|
||||||
commandTitle?: string,
|
|
||||||
refreshOnSuccess?: boolean,
|
|
||||||
commandText?: string,
|
|
||||||
cancelText?: string,
|
|
||||||
animated?: boolean,
|
|
||||||
btnClass?: string,
|
|
||||||
modalSize?: string,
|
|
||||||
disableValidationSummary?: boolean,
|
|
||||||
backdrop?: boolean,
|
|
||||||
ignoreBackdropClick?: boolean,
|
|
||||||
params?: any,
|
|
||||||
success?: EventEmitter<any>
|
|
||||||
}) {
|
|
||||||
options.dataSource.resolveCommandModelByName({
|
|
||||||
command: options.command,
|
|
||||||
model: options.model,
|
|
||||||
params: options.params
|
|
||||||
}).subscribe(commandModel => {
|
|
||||||
const initialState = {
|
|
||||||
dataSource: options.dataSource,
|
|
||||||
command: options.command,
|
|
||||||
commandModel,
|
|
||||||
template: options.template,
|
|
||||||
title: options.commandTitle,
|
|
||||||
disableValidationSummary: options.disableValidationSummary === undefined ? false : options.disableValidationSummary,
|
|
||||||
refreshOnSuccess: options.refreshOnSuccess === undefined ? true : options.refreshOnSuccess,
|
|
||||||
commandText: options.commandText || 'OK',
|
|
||||||
cancelText: options.cancelText || 'Cancel',
|
|
||||||
successEmitter: options.success,
|
|
||||||
btnClass: options.btnClass || 'primary'
|
|
||||||
};
|
|
||||||
this.modalService.show(CommandModalComponent, {
|
|
||||||
animated: options.animated === undefined ? true : options.animated,
|
|
||||||
class: options.modalSize,
|
|
||||||
initialState,
|
|
||||||
backdrop: options.backdrop === undefined ? true : options.backdrop,
|
|
||||||
ignoreBackdropClick: options.ignoreBackdropClick === undefined ? false : options.ignoreBackdropClick
|
|
||||||
});
|
|
||||||
}, error => {
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
<div class="modal-header">
|
|
||||||
<h4 class="modal-title pull-left">{{ title }}</h4>
|
|
||||||
<button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<ng-container [ngTemplateOutlet]="template"
|
|
||||||
[ngTemplateOutletContext]="{ $implicit: commandModel, loading: loading, dataSource: dataSource }"></ng-container>
|
|
||||||
<div *ngIf="hasError && !disableValidationSummary" class="alert alert-danger mt-2" style="white-space: pre-wrap">{{validationMessage}}</div>
|
|
||||||
<div *ngIf="hasErrorMessage" class="alert alert-danger mt-2" style="white-space: pre-wrap">{{errorMessage}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-light" (click)="modalRef.hide()"
|
|
||||||
[disabled]="loading">{{ cancelText }}</button>
|
|
||||||
<button type="button" class="btn btn-{{btnClass}}" [disabled]="loading" (click)="onSubmit()">{{ commandText }}</button>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<div class="progress" style="width: 100%" *ngIf="loading">
|
|
||||||
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="100"
|
|
||||||
aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
.field-error{
|
|
||||||
border: 1px solid red;
|
|
||||||
}
|
|
||||||
-82
@@ -1,82 +0,0 @@
|
|||||||
import {Component, EventEmitter, OnDestroy, OnInit, TemplateRef} from '@angular/core';
|
|
||||||
import {IDataSource} from '@poweredsoft/data';
|
|
||||||
import {BsModalRef} from 'ngx-bootstrap/modal';
|
|
||||||
import {finalize} from 'rxjs/operators';
|
|
||||||
import {Subscription} from 'rxjs';
|
|
||||||
import {NgForm} from '@angular/forms';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'bsx-command-modal',
|
|
||||||
templateUrl: './command-modal.component.html',
|
|
||||||
styleUrls: ['./command-modal.component.scss']
|
|
||||||
})
|
|
||||||
export class CommandModalComponent implements OnInit, OnDestroy {
|
|
||||||
title: string;
|
|
||||||
template: TemplateRef<any>;
|
|
||||||
command: string;
|
|
||||||
commandModel: any;
|
|
||||||
dataSource: IDataSource<any>;
|
|
||||||
refreshOnSuccess: boolean;
|
|
||||||
loading: boolean;
|
|
||||||
commandText: string;
|
|
||||||
cancelText: string;
|
|
||||||
form:NgForm;
|
|
||||||
validationMessage:string ;
|
|
||||||
disableValidationSummary: boolean;
|
|
||||||
btnClass:string;
|
|
||||||
successEmitter: EventEmitter<any>;
|
|
||||||
hasError: boolean;
|
|
||||||
errorMessage: string = '';
|
|
||||||
|
|
||||||
private _notifyMessage: Subscription;
|
|
||||||
private _validationError: Subscription;
|
|
||||||
|
|
||||||
constructor(public modalRef: BsModalRef) { }
|
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
this._notifyMessage.unsubscribe();
|
|
||||||
this._validationError.unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasErrorMessage() {
|
|
||||||
return this.errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this._notifyMessage = this.dataSource.notifyMessage$.subscribe(message => {
|
|
||||||
if (message.type !== 'info' && message.type !== 'success')
|
|
||||||
this.errorMessage = message.message;
|
|
||||||
});
|
|
||||||
|
|
||||||
this._validationError = this.dataSource.validationError$.subscribe(validatorErrors => {
|
|
||||||
let validationSummary = '';
|
|
||||||
Object.getOwnPropertyNames(validatorErrors.errors).forEach(property => {
|
|
||||||
const errors = validatorErrors.errors[property].join('\n');
|
|
||||||
validationSummary += errors + '\n';
|
|
||||||
});
|
|
||||||
this.validationMessage = validationSummary.trim();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit(){
|
|
||||||
this.loading = true;
|
|
||||||
this.validationMessage = null;
|
|
||||||
|
|
||||||
this.dataSource.executeCommandByName(this.command, this.commandModel)
|
|
||||||
.pipe(
|
|
||||||
finalize(() => {
|
|
||||||
this.loading = false;
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.subscribe(commandResult => {
|
|
||||||
if (this.refreshOnSuccess)
|
|
||||||
this.dataSource.refresh();
|
|
||||||
this.hasError = false;
|
|
||||||
this.modalRef.hide();
|
|
||||||
this.successEmitter.emit(commandResult);
|
|
||||||
}, fail => {
|
|
||||||
this.hasError = true;
|
|
||||||
// you do not want to close on failure.. so just ignore..
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-61
@@ -1,61 +0,0 @@
|
|||||||
import { Directive, HostListener, Input, TemplateRef, Output, EventEmitter } from '@angular/core';
|
|
||||||
import { IDataSource } from '@poweredsoft/data';
|
|
||||||
import { BsModalService } from 'ngx-bootstrap/modal';
|
|
||||||
import { CommandModalComponent } from '../command-modal/command-modal.component';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[bsxCommandModal]'
|
|
||||||
})
|
|
||||||
export class CommandModalDirective {
|
|
||||||
constructor(private modalService: BsModalService) { }
|
|
||||||
|
|
||||||
@Input() dataSource: IDataSource<any>;
|
|
||||||
@Input() command: string;
|
|
||||||
@Input() model: any;
|
|
||||||
@Input() template: TemplateRef<any>;
|
|
||||||
@Input() commandTitle: string;
|
|
||||||
@Input() refreshOnSuccess: boolean;
|
|
||||||
@Input() commandText: string;
|
|
||||||
@Input() cancelText: string;
|
|
||||||
@Input() animated: boolean;
|
|
||||||
@Input() btnClass: string;
|
|
||||||
@Input() modalSize: string;
|
|
||||||
@Input() disableValidationSummary: boolean;
|
|
||||||
@Input() backdrop: boolean;
|
|
||||||
@Input() ignoreBackdropClick: boolean;
|
|
||||||
@Input() params: any;
|
|
||||||
|
|
||||||
@Output() success: EventEmitter<any> = new EventEmitter<any>();
|
|
||||||
|
|
||||||
@HostListener('click')
|
|
||||||
wasClicked() {
|
|
||||||
this.dataSource.resolveCommandModelByName({
|
|
||||||
command: this.command,
|
|
||||||
model: this.model,
|
|
||||||
params: this.params
|
|
||||||
}).subscribe(commandModel => {
|
|
||||||
const initialState = {
|
|
||||||
dataSource: this.dataSource,
|
|
||||||
command: this.command,
|
|
||||||
commandModel,
|
|
||||||
template: this.template,
|
|
||||||
title: this.commandTitle,
|
|
||||||
disableValidationSummary: this.disableValidationSummary === undefined ? false : this.disableValidationSummary,
|
|
||||||
refreshOnSuccess: this.refreshOnSuccess === undefined ? true : this.refreshOnSuccess,
|
|
||||||
commandText: this.commandText || 'OK',
|
|
||||||
cancelText: this.cancelText || 'Cancel',
|
|
||||||
successEmitter: this.success,
|
|
||||||
btnClass: this.btnClass || 'primary'
|
|
||||||
};
|
|
||||||
this.modalService.show(CommandModalComponent, {
|
|
||||||
animated: this.animated === undefined ? true : this.animated,
|
|
||||||
class: this.modalSize,
|
|
||||||
initialState,
|
|
||||||
backdrop: this.backdrop === undefined ? true : this.backdrop,
|
|
||||||
ignoreBackdropClick: this.ignoreBackdropClick === undefined ? false : this.ignoreBackdropClick
|
|
||||||
});
|
|
||||||
}, error => {
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-76
@@ -1,76 +0,0 @@
|
|||||||
import {Directive, EventEmitter, HostListener, Input, Output} from '@angular/core';
|
|
||||||
import {IDataSource} from '@poweredsoft/data';
|
|
||||||
import {finalize} from 'rxjs/operators';
|
|
||||||
import {ConfirmModalService} from '../../confirm-modal/confirm-modal.service';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[bsxCommand]',
|
|
||||||
standalone: true
|
|
||||||
})
|
|
||||||
export class CommandDirective {
|
|
||||||
constructor(private confirmModalService: ConfirmModalService) { }
|
|
||||||
|
|
||||||
@Input() dataSource: IDataSource<any>;
|
|
||||||
@Input() command: string;
|
|
||||||
@Input() model: any;
|
|
||||||
@Input() refreshOnSuccess: boolean;
|
|
||||||
@Input() animated: boolean;
|
|
||||||
@Input() params: any;
|
|
||||||
|
|
||||||
@Input() confirm: boolean;
|
|
||||||
@Input() confirmMessage: string;
|
|
||||||
@Input() yesText: string;
|
|
||||||
@Input() noText: string;
|
|
||||||
@Input() yesClass: string;
|
|
||||||
@Input() noClass: string;
|
|
||||||
|
|
||||||
@Output() success: EventEmitter<any> = new EventEmitter<any>();
|
|
||||||
@Output() failure: EventEmitter<any> = new EventEmitter<any>();
|
|
||||||
@Output() loading: EventEmitter<boolean> = new EventEmitter<boolean>();
|
|
||||||
|
|
||||||
private doCommand() {
|
|
||||||
this.dataSource.resolveCommandModelByName({
|
|
||||||
command: this.command,
|
|
||||||
model: this.model,
|
|
||||||
params: this.params
|
|
||||||
}).subscribe(commandModel => {
|
|
||||||
this.loading.emit(true);
|
|
||||||
this.dataSource.executeCommandByName(this.command, commandModel)
|
|
||||||
.pipe(
|
|
||||||
finalize(() => this.loading.emit(false))
|
|
||||||
)
|
|
||||||
.subscribe(
|
|
||||||
commandResult => {
|
|
||||||
if (this.refreshOnSuccess !== false)
|
|
||||||
this.dataSource.refresh();
|
|
||||||
|
|
||||||
this.success.emit(commandResult);
|
|
||||||
},
|
|
||||||
commandError => {
|
|
||||||
this.failure.emit(commandError);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}, resolveCommandError => {
|
|
||||||
this.failure.emit(resolveCommandError);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@HostListener('click')
|
|
||||||
wasClicked() {
|
|
||||||
if (this.confirm) {
|
|
||||||
this.confirmModalService.confirm({
|
|
||||||
message: this.confirmMessage,
|
|
||||||
yesText: this.yesText || 'yes',
|
|
||||||
yesClass: this.yesClass || 'danger',
|
|
||||||
noText: this.noText || 'no',
|
|
||||||
noClass: this.noClass || 'light',
|
|
||||||
}).subscribe(result => {
|
|
||||||
if (result)
|
|
||||||
this.doCommand();
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.doCommand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-6
@@ -1,6 +0,0 @@
|
|||||||
<div class="modal-body text-center">
|
|
||||||
<p>{{ message }}</p>
|
|
||||||
<button type="button" [ngClass]="yesButtonClass" (click)="confirm()">{{ yesText }}</button>
|
|
||||||
|
|
||||||
<button type="button" [ngClass]="noButtonClass" (click)="decline()">{{ noText }}</button>
|
|
||||||
</div>
|
|
||||||
-44
@@ -1,44 +0,0 @@
|
|||||||
import {Component, Inject} from '@angular/core';
|
|
||||||
import {BsModalRef} from 'ngx-bootstrap/modal';
|
|
||||||
import {Observer} from 'rxjs';
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'bsx-confirm-modal',
|
|
||||||
templateUrl: './confirm-modal.component.html',
|
|
||||||
styleUrls: ['./confirm-modal.component.scss'],
|
|
||||||
standalone: true,
|
|
||||||
imports: [
|
|
||||||
CommonModule
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class ConfirmModalComponent {
|
|
||||||
@Inject(BsModalRef) modelRef!: BsModalRef;
|
|
||||||
yesText: string;
|
|
||||||
noText: string;
|
|
||||||
message: string;
|
|
||||||
yesClass: string;
|
|
||||||
noClass: string;
|
|
||||||
observer: Observer<boolean>;
|
|
||||||
|
|
||||||
get yesButtonClass() {
|
|
||||||
return `btn btn-${this.yesClass}`
|
|
||||||
}
|
|
||||||
|
|
||||||
get noButtonClass() {
|
|
||||||
return `btn btn-${this.noClass}`
|
|
||||||
}
|
|
||||||
|
|
||||||
confirm(): void {
|
|
||||||
this.modelRef.hide();
|
|
||||||
this.observer.next(true);
|
|
||||||
this.observer.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
decline(): void {
|
|
||||||
this.modelRef.hide();
|
|
||||||
this.observer.next(false);
|
|
||||||
this.observer.complete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { BsModalService } from 'ngx-bootstrap/modal';
|
|
||||||
import { ConfirmModalComponent } from './confirm-modal-components/confirm-modal/confirm-modal.component';
|
|
||||||
import { Observable, Observer } from 'rxjs';
|
|
||||||
|
|
||||||
export interface IConfirmModalOptions
|
|
||||||
{
|
|
||||||
yesClass?: string;
|
|
||||||
noClass?: string;
|
|
||||||
message: string;
|
|
||||||
yesText?: string;
|
|
||||||
noText?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class ConfirmModalService {
|
|
||||||
constructor(private modalService: BsModalService) { }
|
|
||||||
|
|
||||||
confirm(options: IConfirmModalOptions) : Observable<boolean> {
|
|
||||||
return new Observable<boolean>((o: Observer<boolean>) => {
|
|
||||||
const initialState = {
|
|
||||||
message: options.message,
|
|
||||||
yesText: options.yesText || 'yes',
|
|
||||||
noText: options.noText || 'no',
|
|
||||||
yesClass: options.yesClass || 'primary',
|
|
||||||
noClass: options.noClass || 'light',
|
|
||||||
observer: o
|
|
||||||
};
|
|
||||||
|
|
||||||
this.modalService.show(ConfirmModalComponent, {
|
|
||||||
initialState: initialState,
|
|
||||||
animated: true,
|
|
||||||
keyboard: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-117
@@ -1,117 +0,0 @@
|
|||||||
<ng-template #popTemplate>
|
|
||||||
<form (ngSubmit)="applyFilter()" novalidate>
|
|
||||||
<div class="container" >
|
|
||||||
<div class="row">
|
|
||||||
<select class="custom-select" title="Choose one of the following..." [(ngModel)]="filterType" [ngModelOptions]="{standalone: true}">
|
|
||||||
<option *ngFor="let filter of filterTypes" [value]="filter.value">{{filter.key}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="row mt-1 mb-1">
|
|
||||||
<input *ngIf="!isRangeFilter"
|
|
||||||
type="text"
|
|
||||||
placeholder="Datepicker"
|
|
||||||
class="form-control"
|
|
||||||
bsDatepicker [(ngModel)]="filterValue" [ngModelOptions]="{standalone: true}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mt-1 mb-1">
|
|
||||||
<input *ngIf="isRangeFilter" type="text"
|
|
||||||
placeholder="Daterangepicker"
|
|
||||||
class="form-control"
|
|
||||||
bsDaterangepicker [(ngModel)]="filterValue" [ngModelOptions]="{standalone: true}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mt-2">
|
|
||||||
<button class="btn btn-primary mr-1" type="submit" >Filter</button>
|
|
||||||
<button type="button" class="btn btn-warning" *ngIf="!isFiltering" (click)="pop.hide()">Hide</button>
|
|
||||||
<button type="button" class="btn btn-dark" *ngIf="isFiltering" (click)="clearFilter()">Clear</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<!-- <button [popover]="popTemplate" class="btn btn-default" [(isOpen)]="filterPopUpOpened" [outsideClick]="true" #pop="bs-popover">
|
|
||||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 477.875 477.875" style="enable-background:new 0 0 477.875 477.875;" xml:space="preserve" fill-opacity="0.5" [tooltip]="showTooltip()" [tooltipEnable]="!filterPopUpOpened" width="13px" height="13px" [ngStyle]="{'fill': isFiltering ? 'red': 'black', 'fill-opacity': isFiltering ? '1': '0.5'}">
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path d="M460.804,0H17.071C7.645,0,0.004,7.641,0.004,17.067V102.4c-0.004,4.842,2.05,9.458,5.649,12.698l165.018,148.514V460.8
|
|
||||||
c-0.004,9.426,7.633,17.07,17.059,17.075c2.651,0.001,5.266-0.615,7.637-1.8l102.4-51.2c5.786-2.891,9.441-8.806,9.438-15.275
|
|
||||||
V263.612l165.018-148.48c3.608-3.247,5.662-7.878,5.649-12.732V17.067C477.871,7.641,470.23,0,460.804,0z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button> -->
|
|
||||||
|
|
||||||
<svg id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
|
||||||
viewBox="0 0 477.875 477.875" fill-opacity="0.5" [tooltip]="showTooltip()" [isDisabled]="filterPopUpOpened" width="13px" height="13px" [ngStyle]="{'fill': isFiltering ? 'red': 'black', 'fill-opacity': isFiltering ? '1': '0.5'}" [popover]="popTemplate" [isOpen]="filterPopUpOpened" [outsideClick]="true" #pop="bs-popover">
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path d="M460.804,0H17.071C7.645,0,0.004,7.641,0.004,17.067V102.4c-0.004,4.842,2.05,9.458,5.649,12.698l165.018,148.514V460.8
|
|
||||||
c-0.004,9.426,7.633,17.07,17.059,17.075c2.651,0.001,5.266-0.615,7.637-1.8l102.4-51.2c5.786-2.891,9.441-8.806,9.438-15.275
|
|
||||||
V263.612l165.018-148.48c3.608-3.247,5.662-7.878,5.649-12.732V17.067C477.871,7.641,470.23,0,460.804,0z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
-158
@@ -1,158 +0,0 @@
|
|||||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
|
||||||
import {FilterType, ICompositeFilter, IDataSource, ISimpleFilter} from '@poweredsoft/data';
|
|
||||||
import {FormsModule} from "@angular/forms";
|
|
||||||
import {BsDatepickerModule} from "ngx-bootstrap/datepicker";
|
|
||||||
import {TooltipModule} from "ngx-bootstrap/tooltip";
|
|
||||||
import {PopoverModule} from "ngx-bootstrap/popover";
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'bsx-ds-datetime-filter',
|
|
||||||
templateUrl: './data-source-datetime-filter.component.html',
|
|
||||||
styleUrls: ['./data-source-datetime-filter.component.scss'],
|
|
||||||
standalone: true,
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
BsDatepickerModule,
|
|
||||||
TooltipModule,
|
|
||||||
PopoverModule
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class DataSourceDatetimeFilterComponent implements OnInit {
|
|
||||||
@Input() path: string;
|
|
||||||
@Input() dataSource : IDataSource<any>;
|
|
||||||
@Input() filterType: string;
|
|
||||||
@Output() filterTypeChanged: EventEmitter<string> = new EventEmitter<string>();
|
|
||||||
|
|
||||||
filterPopUpOpened: boolean = false;
|
|
||||||
isFiltering: boolean;
|
|
||||||
filterValue: Date = null;
|
|
||||||
filterTypes = [
|
|
||||||
{key:'Equal', value: 'Equal'},
|
|
||||||
{key:'Greater Than', value: 'GreaterThan'},
|
|
||||||
{key:'Less Than', value: 'LessThan'},
|
|
||||||
{key:'Greater Than Equal', value: 'GreaterThanOrEqual'},
|
|
||||||
{key:'Less Than Equal', value: 'LessThanOrEqual'},
|
|
||||||
{key:'Range', value: FilterType.COMPOSITE }
|
|
||||||
];
|
|
||||||
|
|
||||||
bsInlineValue = new Date();
|
|
||||||
bsInlineRangeValue: Date[];
|
|
||||||
maxDate = new Date();
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.maxDate.setDate(this.maxDate.getDate() + 7);
|
|
||||||
this.bsInlineRangeValue = [this.bsInlineValue, this.maxDate];
|
|
||||||
}
|
|
||||||
|
|
||||||
get isRangeFilter() {
|
|
||||||
return this.filterType == FilterType.COMPOSITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
if (!this.filterType)
|
|
||||||
this.filterType = 'Equal';
|
|
||||||
}
|
|
||||||
|
|
||||||
showTooltip(){
|
|
||||||
return "Filter by "+ this.path;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearFilter() {
|
|
||||||
this.filterValue = null;
|
|
||||||
this.isFiltering = false;
|
|
||||||
const existingFilter = this.dataSource.filters.find(t => (t as ISimpleFilter).path == this.path) as ISimpleFilter;
|
|
||||||
if (existingFilter) {
|
|
||||||
this.dataSource.query({
|
|
||||||
page: 1,
|
|
||||||
filters: this.dataSource.filters.filter(t => t != existingFilter)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isRangeFilter) {
|
|
||||||
let existingFilter2 = this.dataSource.filters.find(t=> t.type == 'Composite');
|
|
||||||
this.dataSource.query({
|
|
||||||
page: 1,
|
|
||||||
filters: this.dataSource.filters.filter(t => t != existingFilter2)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
applyFilter(){
|
|
||||||
|
|
||||||
this.isFiltering = true;
|
|
||||||
const filters = this.dataSource.filters;
|
|
||||||
let compositeF: any = null;
|
|
||||||
let freshFilter: ISimpleFilter = null;
|
|
||||||
let startDate: Date;
|
|
||||||
let endDate: Date;
|
|
||||||
|
|
||||||
// TODO create filter here.
|
|
||||||
if(Array.isArray(this.filterValue)){ //check if it's a dateRange value
|
|
||||||
startDate = this.filterValue[0];
|
|
||||||
endDate = this.filterValue[1];
|
|
||||||
|
|
||||||
compositeF = {
|
|
||||||
type: FilterType.COMPOSITE,
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
path: this.path,
|
|
||||||
type: 'GREATERTHANOREQUAL',
|
|
||||||
value: startDate,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
and: true,
|
|
||||||
path: this.path,
|
|
||||||
type: 'LESSTHANOREQUAL',
|
|
||||||
value: endDate,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
freshFilter = {
|
|
||||||
type: this.filterType,
|
|
||||||
and: true,
|
|
||||||
path: this.path,
|
|
||||||
value: this.filterValue
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO???
|
|
||||||
// set this for gql better handling of variant.
|
|
||||||
//(freshFilter as IGraphQLFilter).__gqlVariantType = 'DATETIME';
|
|
||||||
|
|
||||||
const existingFilterIndex = filters.findIndex(t => {
|
|
||||||
if (t.type == 'COMPOSITE') {
|
|
||||||
const compositeFilter = t as ICompositeFilter;
|
|
||||||
return compositeFilter.filters && compositeFilter.filters.length
|
|
||||||
&& compositeFilter[0].path == this.path;
|
|
||||||
} else {
|
|
||||||
return (t as ISimpleFilter).path == this.path;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (existingFilterIndex == -1) {
|
|
||||||
// create it.
|
|
||||||
if(compositeF) {
|
|
||||||
filters.push(compositeF);
|
|
||||||
} else {
|
|
||||||
filters.push(freshFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// replace it.
|
|
||||||
if (compositeF) {
|
|
||||||
filters[existingFilterIndex] = compositeF;
|
|
||||||
} else {
|
|
||||||
filters[existingFilterIndex] = freshFilter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dataSource.query({
|
|
||||||
filters: filters,
|
|
||||||
page: 1
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-62
@@ -1,62 +0,0 @@
|
|||||||
<ng-template #popTemplate>
|
|
||||||
<form (ngSubmit)="applyFilter()" novalidate>
|
|
||||||
<div class="container" >
|
|
||||||
<div class="row">
|
|
||||||
<select class="custom-select" title="Choose one of the following..." [(ngModel)]="filterType" [ngModelOptions]="{standalone: true}">
|
|
||||||
<option *ngFor="let filter of filterTypes" [value]="filter.value">{{filter.key}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mt-1 mb-1">
|
|
||||||
<input type="number" class="form-control" placeholder="Value" aria-label="number"
|
|
||||||
aria-describedby="basic-addon1" [(ngModel)]="filterValue" [ngModelOptions]="{standalone: true}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button class="btn btn-primary mr-1">Filter</button>
|
|
||||||
<button type="button" class="btn btn-warning" *ngIf="!isFiltering" (click)="pop.hide()">Hide</button>
|
|
||||||
<button type="button" class="btn btn-dark" *ngIf="isFiltering" (click)="clearFilter()">Clear</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<svg id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
|
||||||
viewBox="0 0 477.875 477.875" fill-opacity="0.5" [tooltip]="showTooltip()" [isDisabled]="filterIsOpened" width="13px" height="13px" [ngStyle]="{'fill': isFiltering ? 'red': 'black', 'fill-opacity': isFiltering ? '1': '0.5'}" [popover]="popTemplate" [isOpen]="filterIsOpened" [outsideClick]="true" #pop="bs-popover">
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path d="M460.804,0H17.071C7.645,0,0.004,7.641,0.004,17.067V102.4c-0.004,4.842,2.05,9.458,5.649,12.698l165.018,148.514V460.8
|
|
||||||
c-0.004,9.426,7.633,17.07,17.059,17.075c2.651,0.001,5.266-0.615,7.637-1.8l102.4-51.2c5.786-2.891,9.441-8.806,9.438-15.275
|
|
||||||
V263.612l165.018-148.48c3.608-3.247,5.662-7.878,5.649-12.732V17.067C477.871,7.641,470.23,0,460.804,0z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
-74
@@ -1,74 +0,0 @@
|
|||||||
import {Component, Input} from '@angular/core';
|
|
||||||
import {IDataSource, ISimpleFilter} from '@poweredsoft/data';
|
|
||||||
import {FormsModule} from "@angular/forms";
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
import {TooltipModule} from "ngx-bootstrap/tooltip";
|
|
||||||
import {PopoverModule} from "ngx-bootstrap/popover";
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'bsx-ds-number-filter',
|
|
||||||
templateUrl: './data-source-number-filter.component.html',
|
|
||||||
styleUrls: ['./data-source-number-filter.component.scss'],
|
|
||||||
standalone: true,
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
TooltipModule,
|
|
||||||
PopoverModule
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class DataSourceNumberFilterComponent {
|
|
||||||
@Input() dataSource : IDataSource<any>;
|
|
||||||
@Input() path: string;
|
|
||||||
|
|
||||||
filterType: string = 'Equal';
|
|
||||||
filterValue: number = 0;
|
|
||||||
isFiltering: boolean;
|
|
||||||
filterIsOpened: boolean = false;
|
|
||||||
filterTypes = [
|
|
||||||
{key:'Equals', value: 'Equal'},
|
|
||||||
{key:'Greater Than', value: 'GreaterThan'},
|
|
||||||
{key:'Less Than', value: 'LessThan'},
|
|
||||||
{key:'Greater Than Equal', value: 'GreaterThanOrEqual'},
|
|
||||||
{key:'Less Than Equal', value: 'LessThanOrEqual'},
|
|
||||||
];
|
|
||||||
|
|
||||||
clearFilter() {
|
|
||||||
this.filterValue = 0;
|
|
||||||
this.isFiltering = false;
|
|
||||||
const existingFilter = this.dataSource.filters.find(t => (t as ISimpleFilter).path == this.path) as ISimpleFilter;
|
|
||||||
if (existingFilter) {
|
|
||||||
this.dataSource.query({
|
|
||||||
page: 1,
|
|
||||||
filters: this.dataSource.filters.filter(t => t != existingFilter)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
applyFilter(){
|
|
||||||
this.isFiltering = true;
|
|
||||||
const filters = this.dataSource.filters;
|
|
||||||
const existingFilter = filters.find(t => (t as ISimpleFilter).path == this.path) as ISimpleFilter;
|
|
||||||
if (existingFilter) {
|
|
||||||
existingFilter.type = this.filterType;
|
|
||||||
existingFilter.value =this.filterValue.toString();
|
|
||||||
} else {
|
|
||||||
filters.push(<ISimpleFilter>{
|
|
||||||
and: true,
|
|
||||||
type: this.filterType,
|
|
||||||
path: this.path,
|
|
||||||
value: this.filterValue.toString()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dataSource.query({
|
|
||||||
filters: filters,
|
|
||||||
page: 1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
showTooltip(){
|
|
||||||
return "Filter by "+ this.path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
<ng-template #popTemplate>
|
|
||||||
<form (ngSubmit)="applyFilter(pop)" novalidate>
|
|
||||||
|
|
||||||
<div class="container" >
|
|
||||||
<div class="row">
|
|
||||||
<select class="custom-select" title="Choose one of the following..." [(ngModel)]="filterType" [ngModelOptions]="{standalone: true}">
|
|
||||||
<option *ngFor="let filter of filterTypes" [value]="filter.value">{{filter.key}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mt-1 mb-1">
|
|
||||||
<input type="text" class="form-control" placeholder="Value" aria-label="Username"
|
|
||||||
aria-describedby="basic-addon1" [(ngModel)]="filterValue" [ngModelOptions]="{standalone: true}" >
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button class="btn btn-primary mr-1" type="submit">Filter</button>
|
|
||||||
<button type="button" class="btn btn-warning" *ngIf="!isFiltering" (click)="pop.hide()">Hide</button>
|
|
||||||
<button type="button" class="btn btn-dark" *ngIf="isFiltering" (click)="clearFilter()">Clear</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<!-- <button [popover]="popTemplate" class="btn btn-default" [(isOpen)]="filterIsOpenned" [outsideClick]="true" #pop="bs-popover">
|
|
||||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 477.875 477.875" style="enable-background:new 0 0 477.875 477.875;" xml:space="preserve" fill-opacity="0.5" [tooltip]="showTooltip()" [tooltipEnable]="!filterIsOpenned" width="13px" height="13px" [ngStyle]="{'fill': isFiltering ? 'red': 'black', 'fill-opacity': isFiltering ? '1': '0.5'}">
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path d="M460.804,0H17.071C7.645,0,0.004,7.641,0.004,17.067V102.4c-0.004,4.842,2.05,9.458,5.649,12.698l165.018,148.514V460.8
|
|
||||||
c-0.004,9.426,7.633,17.07,17.059,17.075c2.651,0.001,5.266-0.615,7.637-1.8l102.4-51.2c5.786-2.891,9.441-8.806,9.438-15.275
|
|
||||||
V263.612l165.018-148.48c3.608-3.247,5.662-7.878,5.649-12.732V17.067C477.871,7.641,470.23,0,460.804,0z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button> -->
|
|
||||||
|
|
||||||
<svg id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 477.875 477.875" fill-opacity="0.5" [tooltip]="showTooltip()" [isDisabled]="filterIsOpened" width="13px" height="13px" [ngStyle]="{'fill': isFiltering ? 'red': 'black', 'fill-opacity': isFiltering ? '1': '0.5'}" [popover]="popTemplate" [isOpen]="filterIsOpened" [outsideClick]="true" #pop="bs-popover">
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path d="M460.804,0H17.071C7.645,0,0.004,7.641,0.004,17.067V102.4c-0.004,4.842,2.05,9.458,5.649,12.698l165.018,148.514V460.8
|
|
||||||
c-0.004,9.426,7.633,17.07,17.059,17.075c2.651,0.001,5.266-0.615,7.637-1.8l102.4-51.2c5.786-2.891,9.441-8.806,9.438-15.275
|
|
||||||
V263.612l165.018-148.48c3.608-3.247,5.662-7.878,5.649-12.732V17.067C477.871,7.641,470.23,0,460.804,0z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
-76
@@ -1,76 +0,0 @@
|
|||||||
import {Component, Input} from '@angular/core';
|
|
||||||
import {IDataSource, ISimpleFilter} from '@poweredsoft/data';
|
|
||||||
import {PopoverDirective, PopoverModule} from 'ngx-bootstrap/popover';
|
|
||||||
import {FormsModule} from "@angular/forms";
|
|
||||||
import {TooltipModule} from "ngx-bootstrap/tooltip";
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'bsx-ds-text-filter',
|
|
||||||
templateUrl: './data-source-text-filter.component.html',
|
|
||||||
styleUrls: ['./data-source-text-filter.component.scss'],
|
|
||||||
standalone: true,
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
TooltipModule,
|
|
||||||
PopoverModule,
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class DataSourceTextFilterComponent {
|
|
||||||
@Input() dataSource : IDataSource<any>;
|
|
||||||
@Input() path: string;
|
|
||||||
|
|
||||||
filterType: string = 'Contains';
|
|
||||||
filterValue: string = null;
|
|
||||||
isFiltering: boolean;
|
|
||||||
filterIsOpened: boolean = false;
|
|
||||||
|
|
||||||
filterTypes = [
|
|
||||||
{key:'Contains', value: 'Contains'},
|
|
||||||
{key:'Equals', value: 'Equal'},
|
|
||||||
{key:'Starts With', value: 'startsWith'},
|
|
||||||
{key:'Ends With', value: 'endsWith'}
|
|
||||||
];
|
|
||||||
|
|
||||||
clearFilter() {
|
|
||||||
this.filterValue = '';
|
|
||||||
this.isFiltering = false;
|
|
||||||
const existingFilter = this.dataSource.filters.find(t => (t as ISimpleFilter).path == this.path) as ISimpleFilter;
|
|
||||||
if (existingFilter) {
|
|
||||||
this.dataSource.query({
|
|
||||||
page: 1,
|
|
||||||
filters: this.dataSource.filters.filter(t => t != existingFilter)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
applyFilter(pop: PopoverDirective = null){
|
|
||||||
this.isFiltering = true;
|
|
||||||
const filters = this.dataSource.filters;
|
|
||||||
const existingFilter = filters.find(t => (t as ISimpleFilter).path == this.path) as ISimpleFilter;
|
|
||||||
if (existingFilter) {
|
|
||||||
existingFilter.type = this.filterType;
|
|
||||||
existingFilter.value = this.filterValue;
|
|
||||||
} else {
|
|
||||||
filters.push(<ISimpleFilter>{
|
|
||||||
and: true,
|
|
||||||
type: this.filterType,
|
|
||||||
path: this.path,
|
|
||||||
value: this.filterValue
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dataSource.query({
|
|
||||||
filters: filters,
|
|
||||||
page: 1
|
|
||||||
})
|
|
||||||
|
|
||||||
if (pop)
|
|
||||||
pop.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
showTooltip(){
|
|
||||||
return "Filter by "+ this.path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
<span>
|
|
||||||
<span class="caret dropdown-toggle" [class.text-primary]="isSorting" [class.not-sorting-state]="!isSorting" [class.sort-desc]="isAscending" (click)="sorting()"></span>
|
|
||||||
</span>
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
:host span.dropdown-toggle.sort-desc{
|
|
||||||
transform: rotate(180deg);
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host span{
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host .not-sorting-state{
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host .not-sorting-state:hover{
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
import {Component, Input} from '@angular/core';
|
|
||||||
import {IDataSource} from '@poweredsoft/data';
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'bsx-ds-sorting',
|
|
||||||
templateUrl: './data-source-sorting.component.html',
|
|
||||||
styleUrls: ['./data-source-sorting.component.scss'],
|
|
||||||
standalone: true,
|
|
||||||
imports: [CommonModule]
|
|
||||||
})
|
|
||||||
export class DataSourceSortingComponent {
|
|
||||||
@Input() dataSource : IDataSource<any>;
|
|
||||||
@Input() path: string;
|
|
||||||
|
|
||||||
get sort() {
|
|
||||||
return this.dataSource.sorts.find(t => t.path == this.path);
|
|
||||||
}
|
|
||||||
|
|
||||||
get isSorting() {
|
|
||||||
return this.sort ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
get isAscending() {
|
|
||||||
return !this.isSorting ? true : this.sort.ascending;
|
|
||||||
}
|
|
||||||
|
|
||||||
sorting(){
|
|
||||||
if (!this.isSorting) {
|
|
||||||
this.dataSource.sorts.push({
|
|
||||||
path: this.path,
|
|
||||||
ascending: true
|
|
||||||
});
|
|
||||||
} else if(this.isSorting && this.isAscending) {
|
|
||||||
this.sort.ascending = false;
|
|
||||||
} else {
|
|
||||||
this.dataSource.sorts = this.dataSource.sorts.filter(t => t.path != this.path);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dataSource.query({
|
|
||||||
sorts: this.dataSource.sorts,
|
|
||||||
page: 1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-84
@@ -1,84 +0,0 @@
|
|||||||
import {Directive, EventEmitter, HostListener, Inject, Input, Output, TemplateRef} from '@angular/core';
|
|
||||||
import {IDataSource} from '@poweredsoft/data';
|
|
||||||
import {BsModalService} from 'ngx-bootstrap/modal';
|
|
||||||
import {FormGroupCommandModalComponent} from '../form-group-command-modal/form-group-command-modal.component';
|
|
||||||
import {UntypedFormGroup} from '@angular/forms';
|
|
||||||
|
|
||||||
export interface IModelFormCreateEvent
|
|
||||||
{
|
|
||||||
shouldSetCommandModel: boolean;
|
|
||||||
viewModel: any;
|
|
||||||
commandName: string;
|
|
||||||
commandModel: any;
|
|
||||||
formGroup?: UntypedFormGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[bsxFormGroupCommandModal]',
|
|
||||||
standalone: true
|
|
||||||
})
|
|
||||||
export class FormGroupCommandModalDirective {
|
|
||||||
@Inject(BsModalService) private modalService!: BsModalService;
|
|
||||||
|
|
||||||
@Input() dataSource: IDataSource<any>;
|
|
||||||
@Input() command: string;
|
|
||||||
@Input() model: any;
|
|
||||||
@Input() template: TemplateRef<any>;
|
|
||||||
@Input() commandTitle: string;
|
|
||||||
@Input() animated: boolean;
|
|
||||||
@Input() refreshOnSuccess: boolean;
|
|
||||||
@Input() commandText: string;
|
|
||||||
@Input() cancelText: string;
|
|
||||||
@Input() backdrop: boolean;
|
|
||||||
@Input() ignoreBackdropClick: boolean;
|
|
||||||
@Input() params: any;
|
|
||||||
|
|
||||||
@Output() formCreate: EventEmitter<IModelFormCreateEvent> = new EventEmitter<IModelFormCreateEvent>();
|
|
||||||
@Output() success: EventEmitter<any> = new EventEmitter<any>();
|
|
||||||
|
|
||||||
@HostListener('click')
|
|
||||||
wasClicked() {
|
|
||||||
this.dataSource.resolveCommandModelByName({
|
|
||||||
command: this.command,
|
|
||||||
model: this.model,
|
|
||||||
params: this.params,
|
|
||||||
}).subscribe(commandModel => {
|
|
||||||
const event = <IModelFormCreateEvent>{
|
|
||||||
commandName: this.command,
|
|
||||||
viewModel: this.model,
|
|
||||||
commandModel: commandModel,
|
|
||||||
shouldSetCommandModel: true
|
|
||||||
}
|
|
||||||
|
|
||||||
this.formCreate.emit(event);
|
|
||||||
if (event.formGroup == null)
|
|
||||||
throw new Error('form group should be set, after form createEvent');
|
|
||||||
|
|
||||||
if (event.shouldSetCommandModel)
|
|
||||||
event.formGroup.patchValue(commandModel);
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
dataSource: this.dataSource,
|
|
||||||
command: this.command,
|
|
||||||
template: this.template,
|
|
||||||
title: this.commandTitle,
|
|
||||||
refreshOnSuccess: this.refreshOnSuccess === undefined ? true : this.refreshOnSuccess,
|
|
||||||
commandText: this.commandText || 'OK',
|
|
||||||
cancelText: this.cancelText || 'Cancel',
|
|
||||||
modelForm: event.formGroup,
|
|
||||||
commandModel:commandModel,
|
|
||||||
successEmitter: this.success
|
|
||||||
};
|
|
||||||
|
|
||||||
this.modalService.show(FormGroupCommandModalComponent, {
|
|
||||||
animated: this.animated === undefined ? true : this.animated,
|
|
||||||
initialState,
|
|
||||||
backdrop: this.backdrop === undefined ? true : this.backdrop,
|
|
||||||
ignoreBackdropClick: this.ignoreBackdropClick === undefined ? false : this.ignoreBackdropClick
|
|
||||||
});
|
|
||||||
|
|
||||||
}, error => {
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-25
@@ -1,25 +0,0 @@
|
|||||||
<div class="modal-header">
|
|
||||||
<h4 class="modal-title pull-left">{{ title }}</h4>
|
|
||||||
<button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="model-body">
|
|
||||||
<ng-container [ngTemplateOutlet]="template" [ngTemplateOutletContext]="{ $implicit: modelForm, loading: loading }">
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<div *ngIf="errorMessage" class="alert alert-danger mt-2" style="white-space: pre-wrap">{{ errorMessage }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-light" (click)="modalRef.hide()"
|
|
||||||
[disabled]="loading">{{ cancelText }}</button>
|
|
||||||
<button type="button" class="btn btn-primary" (click)="attemptSave()" [disabled]="loading">{{commandText}}</button>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<div class="progress" style="width: 100%" *ngIf="loading">
|
|
||||||
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="100"
|
|
||||||
aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
-86
@@ -1,86 +0,0 @@
|
|||||||
import {Component, EventEmitter, Inject, OnDestroy, OnInit, TemplateRef} from '@angular/core';
|
|
||||||
import {BsModalRef} from 'ngx-bootstrap/modal';
|
|
||||||
import {IDataSource} from '@poweredsoft/data';
|
|
||||||
import {finalize} from 'rxjs/operators';
|
|
||||||
import {Subscription} from 'rxjs'
|
|
||||||
import {UntypedFormGroup} from '@angular/forms';
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'bsx-form-group-command-modal',
|
|
||||||
templateUrl: './form-group-command-modal.component.html',
|
|
||||||
styleUrls: ['./form-group-command-modal.component.scss'],
|
|
||||||
standalone: true,
|
|
||||||
imports: [CommonModule]
|
|
||||||
})
|
|
||||||
export class FormGroupCommandModalComponent implements OnInit, OnDestroy {
|
|
||||||
@Inject(BsModalRef) public modalRef!: BsModalRef;
|
|
||||||
|
|
||||||
modelForm: UntypedFormGroup;
|
|
||||||
title: string;
|
|
||||||
template: TemplateRef<any>;
|
|
||||||
command: string;
|
|
||||||
dataSource: IDataSource<any>;
|
|
||||||
refreshOnSuccess: boolean;
|
|
||||||
loading: boolean;
|
|
||||||
commandText: string;
|
|
||||||
cancelText: string;
|
|
||||||
errorMessage: string;
|
|
||||||
commandModel: any;
|
|
||||||
successEmitter: EventEmitter<any>;
|
|
||||||
|
|
||||||
private _notifyMessage: Subscription;
|
|
||||||
private _validationError: Subscription;
|
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
this._notifyMessage.unsubscribe();
|
|
||||||
this._validationError.unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.errorMessage = null;
|
|
||||||
this._notifyMessage = this.dataSource.notifyMessage$.subscribe(message => {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
this._validationError = this.dataSource.validationError$.subscribe(validatorErrors => {
|
|
||||||
let validationSummary = '';
|
|
||||||
Object.getOwnPropertyNames(validatorErrors.errors).forEach(property => {
|
|
||||||
const errors = validatorErrors.errors[property].join('\n');
|
|
||||||
validationSummary += errors + '\n';
|
|
||||||
});
|
|
||||||
this.errorMessage = validationSummary.trim();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
attemptSave() {
|
|
||||||
// this.errorMessage = null;
|
|
||||||
// if (!this.modelForm.valid)
|
|
||||||
// {
|
|
||||||
// this.errorMessage = 'Form is not valid, please enter all required fields';
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
const finalModel = this.modelForm.value;
|
|
||||||
if(this.commandModel.id)
|
|
||||||
{
|
|
||||||
finalModel.id = this.commandModel.id;
|
|
||||||
}
|
|
||||||
this.loading = true;
|
|
||||||
this.dataSource.executeCommandByName(this.command, finalModel)
|
|
||||||
.pipe(
|
|
||||||
finalize(() => {
|
|
||||||
this.loading = false;
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.subscribe(commandResult => {
|
|
||||||
if (this.refreshOnSuccess)
|
|
||||||
this.dataSource.refresh();
|
|
||||||
|
|
||||||
this.modalRef.hide();
|
|
||||||
this.successEmitter.emit(commandResult);
|
|
||||||
}, fail => {
|
|
||||||
// you do not want to close on failure.. so just ignore..
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-2
@@ -1,2 +0,0 @@
|
|||||||
<pagination [totalItems]="numberOfItems" [itemsPerPage]="pageSize" [(ngModel)]="dataSource.page" [maxSize]="10"
|
|
||||||
[boundaryLinks]='true' previousText="‹" nextText="›" firstText="«" lastText="»"></pagination>
|
|
||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
import {ChangeDetectorRef, Component, Inject, Input, OnDestroy, OnInit} from '@angular/core';
|
|
||||||
import {IDataSource} from '@poweredsoft/data';
|
|
||||||
import {Subscription} from 'rxjs';
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
import {PaginationModule} from "ngx-bootstrap/pagination";
|
|
||||||
import {FormsModule} from "@angular/forms";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'bsx-ds-pagination',
|
|
||||||
templateUrl: './data-source-pagination.component.html',
|
|
||||||
styleUrls: ['./data-source-pagination.component.scss'],
|
|
||||||
standalone: true,
|
|
||||||
imports: [CommonModule, PaginationModule, FormsModule]
|
|
||||||
})
|
|
||||||
export class DataSourcePaginationComponent implements OnInit, OnDestroy {
|
|
||||||
@Inject(ChangeDetectorRef) private cdf!: ChangeDetectorRef;
|
|
||||||
|
|
||||||
@Input() dataSource: IDataSource<any>
|
|
||||||
|
|
||||||
numberOfItems: number = 0;
|
|
||||||
private dataSubscription: Subscription;
|
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
this.dataSubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
get pageSize() {
|
|
||||||
return this.dataSource.pageSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.dataSubscription = this.dataSource.data$.subscribe(latest => {
|
|
||||||
if (latest)
|
|
||||||
this.numberOfItems = latest.totalRecords;
|
|
||||||
else
|
|
||||||
this.numberOfItems = 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
<div class="center">
|
|
||||||
<div class="spinner-grow text-primary" role="status">
|
|
||||||
</div>
|
|
||||||
<div class="spinner-grow text-secondary" role="status">
|
|
||||||
</div>
|
|
||||||
<div class="spinner-grow text-primary" role="status">
|
|
||||||
</div>
|
|
||||||
<div class="spinner-grow text-secondary" role="status">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
-6
@@ -1,6 +0,0 @@
|
|||||||
.center {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
import {Component} from '@angular/core';
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'bsx-spinner',
|
|
||||||
templateUrl: './spinner.component.html',
|
|
||||||
styleUrls: ['./spinner.component.scss'],
|
|
||||||
standalone: true,
|
|
||||||
imports: [CommonModule]
|
|
||||||
})
|
|
||||||
export class SpinnerComponent {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
* Public API Surface of ngx-bootstrap
|
|
||||||
*/
|
|
||||||
|
|
||||||
export * from './lib/command-modal/command-modal.module';
|
|
||||||
export * from './lib/command-modal/command-modal.service';
|
|
||||||
export * from './lib/command-modal/directives/command-modal.directive';
|
|
||||||
export * from './lib/form-group-command-modal/directives/form-group-command-modal.directive';
|
|
||||||
export * from './lib/pagination/data-source-pagination/data-source-pagination.component';
|
|
||||||
export * from './lib/confirm-modal/confirm-modal.service';
|
|
||||||
export * from './lib/spinner/spinner/spinner.component';
|
|
||||||
export * from './lib/data-source-filter/text-filter/data-source-text-filter.component';
|
|
||||||
export * from './lib/data-source-filter/number-filter/data-source-number-filter.component';
|
|
||||||
export * from './lib/data-source-filter/datetime-filter/data-source-datetime-filter.component';
|
|
||||||
export * from './lib/data-source-sorting/ds-sorting/data-source-sorting.component';
|
|
||||||
export * from './lib/command/directives/command.directive';
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
|
||||||
|
|
||||||
import 'zone.js';
|
|
||||||
import 'zone.js/testing';
|
|
||||||
import { getTestBed } from '@angular/core/testing';
|
|
||||||
import {
|
|
||||||
BrowserDynamicTestingModule,
|
|
||||||
platformBrowserDynamicTesting
|
|
||||||
} from '@angular/platform-browser-dynamic/testing';
|
|
||||||
|
|
||||||
// First, initialize the Angular testing environment.
|
|
||||||
getTestBed().initTestEnvironment(
|
|
||||||
BrowserDynamicTestingModule,
|
|
||||||
platformBrowserDynamicTesting(), {
|
|
||||||
teardown: { destroyAfterEach: false }
|
|
||||||
}
|
|
||||||
);
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../../../out-tsc/lib",
|
|
||||||
"declarationMap": true,
|
|
||||||
"declaration": true,
|
|
||||||
"inlineSources": true,
|
|
||||||
"types": [],
|
|
||||||
"lib": [
|
|
||||||
"dom",
|
|
||||||
"es2018"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"angularCompilerOptions": {
|
|
||||||
"skipTemplateCodegen": true,
|
|
||||||
"strictMetadataEmit": true,
|
|
||||||
"enableResourceInlining": true
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"src/test.ts",
|
|
||||||
"**/*.spec.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "./tsconfig.lib.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"declarationMap": false
|
|
||||||
},
|
|
||||||
"angularCompilerOptions": {
|
|
||||||
"compilationMode": "partial"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../../../out-tsc/spec",
|
|
||||||
"types": [
|
|
||||||
"jasmine",
|
|
||||||
"node"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"src/test.ts"
|
|
||||||
],
|
|
||||||
"include": [
|
|
||||||
"**/*.spec.ts",
|
|
||||||
"**/*.d.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
> This project was originally initiated by [Powered Software Inc.](https://poweredsoft.com/) and was forked from the [ngx-ui](https://github.com/PoweredSoft/ngx-ui) Repository
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is licensed under the [MIT License](LICENSE).
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
// Karma configuration file, see link for more information
|
|
||||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
|
||||||
|
|
||||||
module.exports = function (config) {
|
|
||||||
config.set({
|
|
||||||
basePath: '',
|
|
||||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
|
||||||
plugins: [
|
|
||||||
require('karma-jasmine'),
|
|
||||||
require('karma-chrome-launcher'),
|
|
||||||
require('karma-jasmine-html-reporter'),
|
|
||||||
require('karma-coverage-istanbul-reporter'),
|
|
||||||
require('@angular-devkit/build-angular/plugins/karma')
|
|
||||||
],
|
|
||||||
client: {
|
|
||||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
|
||||||
},
|
|
||||||
coverageIstanbulReporter: {
|
|
||||||
dir: require('path').join(__dirname, '../../../coverage/poweredsoft/ngx-cdk-ui'),
|
|
||||||
reports: ['html', 'lcovonly', 'text-summary'],
|
|
||||||
fixWebpackSourcePaths: true
|
|
||||||
},
|
|
||||||
reporters: ['progress', 'kjhtml'],
|
|
||||||
port: 9876,
|
|
||||||
colors: true,
|
|
||||||
logLevel: config.LOG_INFO,
|
|
||||||
autoWatch: true,
|
|
||||||
browsers: ['Chrome'],
|
|
||||||
singleRun: false,
|
|
||||||
restartOnFileChange: true
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
|
|
||||||
"dest": "../../../dist/openharbor/ngx-data-cdk-ui",
|
|
||||||
"lib": {
|
|
||||||
"entryFile": "src/public-api.ts"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@openharbor/ngx-data-cdk-ui",
|
|
||||||
"version": "18.0.0-alpha.2",
|
|
||||||
"repository": "https://git.openharbor.io/Open-Harbor/ngx-data-ui",
|
|
||||||
"peerDependencies": {
|
|
||||||
"@angular/common": "^18.0.0",
|
|
||||||
"@angular/core": "^18.0.0",
|
|
||||||
"@poweredsoft/data": "^0.0.36"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import {NgModule} from '@angular/core';
|
|
||||||
import {CommonModule} from '@angular/common';
|
|
||||||
import {DataGridComponent} from './data-grid/data-grid.component';
|
|
||||||
import {DataGridColDirective} from './directives/data-grid-col.directive';
|
|
||||||
import {DataGridColHeaderDirective} from './directives/data-grid-col-header.directive';
|
|
||||||
import {DataGridCellDirective} from './directives/data-grid-cell.directive';
|
|
||||||
import {DataGridFooterDirective} from './directives/data-grid-footer.directive';
|
|
||||||
import {DataGridHeaderDirective} from './directives/data-grid-header.directive';
|
|
||||||
import {DataGridLoaderDirective} from './directives/data-grid-loader.directive';
|
|
||||||
import {DataGridCellFilterDirective} from './directives/data-grid-cell-filter.directive';
|
|
||||||
import {DataGridColSortDirective} from './directives/data-grid-col-sort.directive';
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [
|
|
||||||
DataGridComponent,DataGridColDirective,DataGridColHeaderDirective,
|
|
||||||
DataGridCellDirective, DataGridFooterDirective, DataGridHeaderDirective,
|
|
||||||
DataGridLoaderDirective, DataGridCellFilterDirective, DataGridColSortDirective,
|
|
||||||
|
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
CommonModule
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
DataGridComponent,DataGridColDirective,DataGridColHeaderDirective,
|
|
||||||
DataGridCellDirective,DataGridFooterDirective, DataGridHeaderDirective,
|
|
||||||
DataGridLoaderDirective,DataGridCellFilterDirective,DataGridColSortDirective]
|
|
||||||
})
|
|
||||||
export class DataGridModule { }
|
|
||||||
-75
@@ -1,75 +0,0 @@
|
|||||||
<ng-container *ngIf="loading" [ngTemplateOutlet]="loadingTemplate"></ng-container>
|
|
||||||
|
|
||||||
<table [ngClass]="tableClasses">
|
|
||||||
<thead [ngClass]="headerClasses">
|
|
||||||
<tr *ngFor="let header of gridHeaders" >
|
|
||||||
<th [attr.colspan]="columns.length">
|
|
||||||
<ng-container [ngTemplateOutlet]="header.template"></ng-container>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th *ngFor="let column of columns">
|
|
||||||
<div class="flex-container">
|
|
||||||
<div class="flex-item">
|
|
||||||
<ng-container *ngIf="hasHeaderTemplate(column)" >
|
|
||||||
<ng-container
|
|
||||||
[ngTemplateOutlet]="getColumnHeaderTemplate(column)"
|
|
||||||
></ng-container>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex-item">
|
|
||||||
<ng-container *ngIf="hasSortingTemplate(column)">
|
|
||||||
<ng-container [ngTemplateOutlet]="getSortingTemplate(column)"></ng-container>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container *ngIf="hasFilterTemplate(column)">
|
|
||||||
<ng-container [ngTemplateOutlet]="getFilterTemplate(column)"></ng-container>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody *ngIf="!noData else noResultTemplate">
|
|
||||||
<tr *ngFor="let rowModel of latestResult.data; let i = index; let first = first; let last = last; let odd = odd">
|
|
||||||
<td *ngFor="let column of columns">
|
|
||||||
<ng-container *ngIf="hasCellTemplate(column)">
|
|
||||||
<ng-container
|
|
||||||
[ngTemplateOutlet]="getColumnCellTemplate(column)"
|
|
||||||
[ngTemplateOutletContext]="{
|
|
||||||
$implicit: rowModel,
|
|
||||||
column: column,
|
|
||||||
rowIndex: i,
|
|
||||||
first: first,
|
|
||||||
last: last,
|
|
||||||
odd: odd
|
|
||||||
}"
|
|
||||||
></ng-container>
|
|
||||||
</ng-container>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<td *ngFor="let footer of gridFooters" [attr.colspan]="columns.length">
|
|
||||||
<ng-container [ngTemplateOutlet]="footer.template"></ng-container>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<ng-template #loadingTemplate>
|
|
||||||
<ng-container *ngFor="let loader of loaders">
|
|
||||||
<ng-container [ngTemplateOutlet]="loader.template"></ng-container>
|
|
||||||
</ng-container>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template #noResultTemplate>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td [attr.colspan]="columns.length">
|
|
||||||
<p style="text-align: center;">{{ noRecordsDisplayText }}</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</ng-template>
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
:host {
|
|
||||||
.flex-container{
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-item{
|
|
||||||
margin-right: 1px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-139
@@ -1,139 +0,0 @@
|
|||||||
import {
|
|
||||||
ChangeDetectorRef,
|
|
||||||
Component,
|
|
||||||
ContentChildren,
|
|
||||||
EventEmitter, Inject,
|
|
||||||
Input,
|
|
||||||
OnDestroy,
|
|
||||||
OnInit,
|
|
||||||
Output,
|
|
||||||
QueryList
|
|
||||||
} from '@angular/core';
|
|
||||||
import {IDataSource, IQueryExecutionGroupResult, IQueryExecutionResult} from '@poweredsoft/data';
|
|
||||||
import {DataGridColDirective} from '../directives/data-grid-col.directive';
|
|
||||||
import {DataGridHeaderDirective} from '../directives/data-grid-header.directive';
|
|
||||||
import {DataGridFooterDirective} from '../directives/data-grid-footer.directive';
|
|
||||||
import {DataGridLoaderDirective} from '../directives/data-grid-loader.directive';
|
|
||||||
import {Subscription} from 'rxjs';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'cdk-data-grid',
|
|
||||||
templateUrl: './data-grid.component.html',
|
|
||||||
styleUrls: ['./data-grid.component.scss']
|
|
||||||
})
|
|
||||||
export class DataGridComponent implements OnInit, OnDestroy {
|
|
||||||
@Inject(ChangeDetectorRef) private cdr!: ChangeDetectorRef;
|
|
||||||
|
|
||||||
@ContentChildren(DataGridColDirective) columnDefinitions: QueryList<DataGridColDirective>;
|
|
||||||
@ContentChildren(DataGridHeaderDirective) gridHeaders: QueryList<DataGridHeaderDirective>;
|
|
||||||
@ContentChildren(DataGridFooterDirective) gridFooters: QueryList<DataGridFooterDirective>;
|
|
||||||
@ContentChildren(DataGridLoaderDirective) loaders: QueryList<DataGridLoaderDirective>;
|
|
||||||
|
|
||||||
latestResult: IQueryExecutionResult<any> & IQueryExecutionGroupResult<any>;
|
|
||||||
loading: boolean = false;
|
|
||||||
|
|
||||||
@Input() dataSource: IDataSource<any>;
|
|
||||||
@Input() tableClasses: any;
|
|
||||||
@Input() headerClasses: any;
|
|
||||||
@Input() noRecordsText: string;
|
|
||||||
|
|
||||||
private _columns: string[];
|
|
||||||
private _dataSubscription: Subscription;
|
|
||||||
private _loadingSubscription: Subscription;
|
|
||||||
|
|
||||||
@Input() set columns(value: string[]) {
|
|
||||||
this._columns = value;
|
|
||||||
this.columnsChange.emit(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
get columns() {
|
|
||||||
return this._columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Output() columnsChange: EventEmitter<string []> = new EventEmitter<string []>();
|
|
||||||
|
|
||||||
get noData() {
|
|
||||||
return !this.latestResult || this.latestResult.totalRecords == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
get noRecordsDisplayText() {
|
|
||||||
return this.noRecordsText || 'No records';
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
this._dataSubscription.unsubscribe();
|
|
||||||
this._loadingSubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this._dataSubscription = this.dataSource.data$.subscribe(newData => {
|
|
||||||
this.latestResult = newData;
|
|
||||||
});
|
|
||||||
|
|
||||||
this._loadingSubscription = this.dataSource.loading$.subscribe(isLoading => {
|
|
||||||
this.loading = isLoading;
|
|
||||||
this.cdr.detectChanges();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getSortingTemplate(columnName: string){
|
|
||||||
const ret = this.getColumn(columnName);
|
|
||||||
if (ret && ret.sortTemplate)
|
|
||||||
return ret.sortTemplate.template;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
getFilterTemplate(columnName: string){
|
|
||||||
const ret = this.getColumn(columnName);
|
|
||||||
if (ret && ret.filterTemplate)
|
|
||||||
return ret.filterTemplate.template;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
getColumn(columnName: string) {
|
|
||||||
if (!this.columnDefinitions)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
const ret = this.columnDefinitions.find(t =>
|
|
||||||
{
|
|
||||||
return t.columnName == columnName;
|
|
||||||
});
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
getColumnHeaderTemplate(columnName: string) {
|
|
||||||
const ret = this.getColumn(columnName);
|
|
||||||
if (ret && ret.headerTemplate)
|
|
||||||
return ret.headerTemplate.template;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
getColumnCellTemplate(columnName: string) {
|
|
||||||
const ret = this.getColumn(columnName);
|
|
||||||
if (ret && ret.cellTemplate)
|
|
||||||
return ret.cellTemplate.template;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasHeaderTemplate(columnName: string) {
|
|
||||||
return this.getColumnHeaderTemplate(columnName) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasCellTemplate(columnName: string) {
|
|
||||||
return this.getColumnCellTemplate(columnName) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasFilterTemplate(columnName: string) {
|
|
||||||
return this.getFilterTemplate(columnName) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasSortingTemplate(columnName: string) {
|
|
||||||
return this.getSortingTemplate(columnName) ? true : false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
import {Directive, TemplateRef} from '@angular/core';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[cdkDataGridCellFilter]'
|
|
||||||
})
|
|
||||||
export class DataGridCellFilterDirective {
|
|
||||||
constructor(public template: TemplateRef<any>) { }
|
|
||||||
}
|
|
||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
import {Directive, TemplateRef} from '@angular/core';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[cdkDataGridCell]'
|
|
||||||
})
|
|
||||||
export class DataGridCellDirective {
|
|
||||||
constructor(public template: TemplateRef<any>) { }
|
|
||||||
}
|
|
||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
import {Directive, TemplateRef} from '@angular/core';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[cdkDataGridColHeader]'
|
|
||||||
})
|
|
||||||
export class DataGridColHeaderDirective {
|
|
||||||
constructor(public template: TemplateRef<any>) { }
|
|
||||||
}
|
|
||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
import {Directive, TemplateRef} from '@angular/core';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[cdkDataGridColSort]'
|
|
||||||
})
|
|
||||||
export class DataGridColSortDirective {
|
|
||||||
constructor(public template: TemplateRef<any>) { }
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
import {ContentChild, Directive, Input} from '@angular/core';
|
|
||||||
import {DataGridColHeaderDirective} from './data-grid-col-header.directive';
|
|
||||||
import {DataGridCellDirective} from './data-grid-cell.directive';
|
|
||||||
import {DataGridCellFilterDirective} from './data-grid-cell-filter.directive';
|
|
||||||
import {DataGridColSortDirective} from './data-grid-col-sort.directive';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[cdkDataGridCol]'
|
|
||||||
})
|
|
||||||
export class DataGridColDirective {
|
|
||||||
@Input('psDataGridCol') columnName: string;
|
|
||||||
|
|
||||||
@ContentChild(DataGridColHeaderDirective) headerTemplate: DataGridColHeaderDirective;
|
|
||||||
@ContentChild(DataGridCellDirective) cellTemplate: DataGridCellDirective;
|
|
||||||
@ContentChild(DataGridCellFilterDirective) filterTemplate: DataGridCellFilterDirective;
|
|
||||||
@ContentChild(DataGridColSortDirective) sortTemplate: DataGridColSortDirective;
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
}
|
|
||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
import {Directive, TemplateRef} from '@angular/core';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[cdkDataGridFooter]'
|
|
||||||
})
|
|
||||||
export class DataGridFooterDirective {
|
|
||||||
constructor(public template: TemplateRef<any>) { }
|
|
||||||
}
|
|
||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
import {Directive, TemplateRef} from '@angular/core';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[cdkDataGridHeader]'
|
|
||||||
})
|
|
||||||
export class DataGridHeaderDirective {
|
|
||||||
constructor(public template: TemplateRef<any>) { }
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user