diff --git a/.github/workflows/ci_release.yml b/.github/workflows/ci_release.yml index ecc4ab1e..560c4af7 100644 --- a/.github/workflows/ci_release.yml +++ b/.github/workflows/ci_release.yml @@ -13,6 +13,7 @@ on: - layout - list-loader - message-box + - message-box-dialog - numeric-stepper - overlay - search-container diff --git a/.github/workflows/ci_test_core.yml b/.github/workflows/ci_test_core.yml index 2166d9f4..be9af5af 100644 --- a/.github/workflows/ci_test_core.yml +++ b/.github/workflows/ci_test_core.yml @@ -31,7 +31,11 @@ jobs: # needs: ci_test_core # uses: ./.github/workflows/ci_test_layout.yml - ci_test_numeric_stepper: + ci_test_message-box-dialog: + needs: ci_test_core + uses: ./.github/workflows/ci_test_message-box-dialog.yml + + ci_test_numeric-stepper: needs: ci_test_core uses: ./.github/workflows/ci_test_numeric-stepper.yml diff --git a/.github/workflows/ci_test_message-box-dialog.yml b/.github/workflows/ci_test_message-box-dialog.yml new file mode 100644 index 00000000..e515f615 --- /dev/null +++ b/.github/workflows/ci_test_message-box-dialog.yml @@ -0,0 +1,26 @@ +name: Test message-box-dialog + +on: + workflow_dispatch: + workflow_call: + push: + branches: + - '**' + tags-ignore: + - '**' + paths: + - '.github/workflows/ci_test_message-box-dialog.yml' + - 'projects/message-box-dialog/**' + +concurrency: + group: ci-test-message-box-dialog-group-${{ github.ref }} + cancel-in-progress: true + +jobs: + ci_test_message-box-dialog: + if: "${{ !contains(github.event.head_commit.message, 'chore(release): publish') }}" + uses: dsi-hug/action/.github/workflows/action.yml@v1 + with: + working-directory: projects/message-box-dialog + runs-on: '["ubuntu-latest", "macos-latest", "windows-latest"]' + node-versions: '[18, 20]' diff --git a/README.md b/README.md index 2750ef1f..df390003 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Package | Version | Downloads | Tests [@hug/ngx-layout](/projects/layout) | [![npm version][npm-logo-layout]][npm-layout] | [![npm downloads][npm-dl-logo-layout]][npm-dl-layout] | [![build status][tests-logo-layout]][tests-layout] [@hug/ngx-list-loader](/projects/list-loader) | [![npm version][npm-logo-list-loader]][npm-list-loader] | [![npm downloads][npm-dl-logo-list-loader]][npm-dl-list-loader] | [![build status][tests-logo-list-loader]][tests-list-loader] [@hug/ngx-message-box](/projects/message-box) | [![npm version][npm-logo-message-box]][npm-message-box] | [![npm downloads][npm-dl-logo-message-box]][npm-dl-message-box] | [![build status][tests-logo-message-box]][tests-message-box] +[@hug/ngx-message-box-dialog](/projects/message-box-dialog) | [![npm version][npm-logo-message-box-dialog]][npm-message-box-dialog] | [![npm downloads][npm-dl-logo-message-box-dialog]][npm-dl-message-box-dialog] | [![build status][tests-logo-message-box-dialog]][tests-message-box-dialog] [@hug/ngx-numeric-stepper](/projects/numeric-stepper) | [![npm version][npm-logo-numeric-stepper]][npm-numeric-stepper] | [![npm downloads][npm-dl-logo-numeric-stepper]][npm-dl-numeric-stepper] | [![build status][tests-logo-numeric-stepper]][tests-numeric-stepper] [@hug/ngx-overlay](/projects/overlay) | [![npm version][npm-logo-overlay]][npm-overlay] | [![npm downloads][npm-dl-logo-overlay]][npm-dl-overlay] | [![build status][tests-logo-overlay]][tests-overlay] [@hug/ngx-search-container](/projects/search-container) | [![npm version][npm-logo-search-container]][npm-search-container] | [![npm downloads][npm-dl-logo-search-container]][npm-dl-search-container] | [![build status][tests-logo-search-container]][tests-search-container] @@ -107,6 +108,13 @@ Copyright (C) 2024 [HUG - Hôpitaux Universitaires Genève][dsi-hug] [tests-message-box]: https://github.com/dsi-hug/ngx-components/actions/workflows/ci_test_message-box.yml [tests-logo-message-box]: https://github.com/dsi-hug/ngx-components/actions/workflows/ci_test_message-box.yml/badge.svg +[npm-message-box-dialog]: https://www.npmjs.com/package/@hug/ngx-message-box-dialog +[npm-logo-message-box-dialog]: https://img.shields.io/npm/v/@hug/ngx-message-box-dialog.svg?color=blue&logo=npm +[npm-dl-message-box-dialog]: https://npmcharts.com/compare/@hug/ngx-message-box-dialog?minimal=true +[npm-dl-logo-message-box-dialog]: https://img.shields.io/npm/dw/@hug/ngx-message-box-dialog.svg?color=7986CB&logo=npm&label=npm +[tests-message-box-dialog]: https://github.com/dsi-hug/ngx-components/actions/workflows/ci_test_message-box-dialog.yml +[tests-logo-message-box-dialog]: https://github.com/dsi-hug/ngx-components/actions/workflows/ci_test_message-box-dialog.yml/badge.svg + [npm-numeric-stepper]: https://www.npmjs.com/package/@hug/ngx-numeric-stepper [npm-logo-numeric-stepper]: https://img.shields.io/npm/v/@hug/ngx-numeric-stepper.svg?color=blue&logo=npm [npm-dl-numeric-stepper]: https://npmcharts.com/compare/@hug/ngx-numeric-stepper?minimal=true diff --git a/angular.json b/angular.json index 135eb169..900be523 100644 --- a/angular.json +++ b/angular.json @@ -569,6 +569,37 @@ } } } + }, + "message-box-dialog": { + "projectType": "library", + "root": "projects/message-box-dialog", + "sourceRoot": "projects/message-box-dialog/src", + "prefix": "lib", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:ng-packagr", + "options": { + "project": "projects/message-box-dialog/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "projects/message-box-dialog/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "projects/message-box-dialog/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "projects/message-box-dialog/src/test.ts", + "tsConfig": "projects/message-box-dialog/tsconfig.spec.json", + "karmaConfig": "projects/message-box-dialog/karma.conf.js" + } + } + } } } } diff --git a/package-lock.json b/package-lock.json index c7ae6350..e7c94944 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "ngx-components", + "name": "@hug/ngx-components", "lockfileVersion": 3, "requires": true, "packages": { @@ -10,6 +10,7 @@ "projects/layout", "projects/list-loader", "projects/message-box", + "projects/message-box-dialog", "projects/numeric-stepper", "projects/overlay", "projects/search-container", @@ -4434,6 +4435,10 @@ "resolved": "projects/message-box", "link": true }, + "node_modules/@hug/ngx-message-box-dialog": { + "resolved": "projects/message-box-dialog", + "link": true + }, "node_modules/@hug/ngx-numeric-stepper": { "resolved": "projects/numeric-stepper", "link": true @@ -22792,6 +22797,20 @@ "@angular/material": ">= 14" } }, + "projects/message-box-dialog": { + "version": "1.0.0", + "license": "GPL-3.0-only", + "dependencies": { + "tslib": "^2.6.3" + }, + "peerDependencies": { + "@angular/common": ">= 14", + "@angular/core": ">= 14", + "@angular/material": ">= 14", + "@hug/ngx-core": "1.1.5", + "rxjs": ">= 7.0.0" + } + }, "projects/numeric-stepper": { "name": "@hug/ngx-numeric-stepper", "version": "1.1.2", diff --git a/package.json b/package.json index 8fcabc00..6c35ea57 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "projects/layout", "projects/list-loader", "projects/message-box", + "projects/message-box-dialog", "projects/numeric-stepper", "projects/overlay", "projects/search-container", diff --git a/projects/message-box-dialog/README.md b/projects/message-box-dialog/README.md new file mode 100644 index 00000000..27e991f6 --- /dev/null +++ b/projects/message-box-dialog/README.md @@ -0,0 +1,6 @@ +@hug/message-box-dialog +======= + +The sources for this package are in the main [DSI-HUG/ngx-components](https://github.com/dsi-hug/ngx-components) repo. Please file issues and pull requests against that repo. + +License: GPL-3.0-only diff --git a/projects/message-box-dialog/karma.conf.js b/projects/message-box-dialog/karma.conf.js new file mode 100644 index 00000000..e07d1298 --- /dev/null +++ b/projects/message-box-dialog/karma.conf.js @@ -0,0 +1,45 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = 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'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with `random: false` + // or set a specific seed with `seed: 4321` + }, + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true // removes the duplicated traces + }, + coverageReporter: { + dir: require('path').join(__dirname, '../../coverage/message-box-dialog'), + subdir: '.', + reporters: [ + { type: 'html' }, + { type: 'text-summary' } + ] + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + failOnEmptyTestSuite: false, + restartOnFileChange: true + }); +}; diff --git a/projects/message-box-dialog/ng-package.json b/projects/message-box-dialog/ng-package.json new file mode 100644 index 00000000..b9ab2f73 --- /dev/null +++ b/projects/message-box-dialog/ng-package.json @@ -0,0 +1,15 @@ +{ + "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../dist/message-box-dialog", + "assets": [ + "CHANGELOG.md", + { + "input": "src/", + "glob": "_message-box-dialog-theme.scss", + "output": "." + } + ], + "lib": { + "entryFile": "src/index.ts" + } +} diff --git a/projects/message-box-dialog/package.json b/projects/message-box-dialog/package.json new file mode 100644 index 00000000..5d1f6136 --- /dev/null +++ b/projects/message-box-dialog/package.json @@ -0,0 +1,45 @@ +{ + "name": "@hug/ngx-message-box-dialog", + "version": "1.0.0", + "description": "HUG Angular - message-box-dialog component", + "homepage": "https://github.com/dsi-hug/ngx-components", + "license": "GPL-3.0-only", + "author": "HUG - Hôpitaux Universitaires Genève", + "contributors": [ + "badisi (https://github.com/badisi)", + "vapkse (https://github.com/vapkse)" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/dsi-hug/ngx-components.git" + }, + "keywords": [ + "angular", + "material", + "material design", + "components" + ], + "sideEffects": false, + "scripts": { + "lint": "eslint . --fix", + "test": "ng test message-box-dialog", + "test:ci": "ng test message-box-dialog --watch=false --browsers=ChromeHeadless", + "build:ng": "ng build message-box-dialog -c=production", + "build": "nx build:ng @hug/ngx-message-box-dialog --verbose", + "release": "nx release -p=@hug/ngx-message-box-dialog --yes --verbose", + "release:dry-run": "nx release -p=@hug/ngx-message-box-dialog --verbose --dry-run" + }, + "peerDependencies": { + "@angular/common": ">= 14", + "@angular/core": ">= 14", + "@angular/material": ">= 14", + "rxjs": ">= 7.0.0", + "@hug/ngx-core": "1.1.5" + }, + "dependencies": { + "tslib": "^2.6.3" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/projects/message-box-dialog/src/_message-box-dialog-theme.scss b/projects/message-box-dialog/src/_message-box-dialog-theme.scss new file mode 100644 index 00000000..3fa92f43 --- /dev/null +++ b/projects/message-box-dialog/src/_message-box-dialog-theme.scss @@ -0,0 +1,33 @@ +@use '@angular/material' as mat; + +@mixin message-box-dialog-theme($theme) { + $warn: map-get($theme, warn); + + .cdk-overlay-container { + .cdk-overlay-pane { + &.warning { + app-message-box-dialog { + .mat-toolbar { + background-color: mat.get-color-from-palette(mat.$orange-palette, 500); + } + + button.mat-primary { + color: mat.get-color-from-palette(mat.$orange-palette, 500); + } + } + } + + &.error { + app-message-box-dialog { + .mat-toolbar { + background-color: mat.get-color-from-palette($warn); + } + + button.mat-primary { + color: mat.get-color-from-palette($warn); + } + } + } + } + } +} diff --git a/projects/message-box-dialog/src/index.ts b/projects/message-box-dialog/src/index.ts new file mode 100644 index 00000000..11998d78 --- /dev/null +++ b/projects/message-box-dialog/src/index.ts @@ -0,0 +1,4 @@ +export * from './message-box-dialog.component'; +export * from './message-box-dialog.service'; +export * from './message-box-dialog.model'; +export * from './message-box-dialog.module'; diff --git a/projects/message-box-dialog/src/message-box-dialog.component.html b/projects/message-box-dialog/src/message-box-dialog.component.html new file mode 100644 index 00000000..1f52b870 --- /dev/null +++ b/projects/message-box-dialog/src/message-box-dialog.component.html @@ -0,0 +1,18 @@ + + {{ dialogParams.title }} + close + + +
+
+
+ +
+ + + + + + + +
diff --git a/projects/message-box-dialog/src/message-box-dialog.component.scss b/projects/message-box-dialog/src/message-box-dialog.component.scss new file mode 100644 index 00000000..85faca5d --- /dev/null +++ b/projects/message-box-dialog/src/message-box-dialog.component.scss @@ -0,0 +1,10 @@ +app-message-box-dialog { + padding-top: 1rem; + + .dialog-container { + display: flex; + flex-direction: column; + margin: 1rem 1rem 0.5rem 1rem; + max-height: 80vh; + } +} diff --git a/projects/message-box-dialog/src/message-box-dialog.component.ts b/projects/message-box-dialog/src/message-box-dialog.component.ts new file mode 100644 index 00000000..0f929da9 --- /dev/null +++ b/projects/message-box-dialog/src/message-box-dialog.component.ts @@ -0,0 +1,22 @@ +import { ChangeDetectionStrategy, Component, Inject, ViewEncapsulation } from '@angular/core'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; + +import { MessageBoxDialogButtons, MessageBoxDialogData } from './message-box-dialog.model'; + +@Component({ + selector: 'app-message-box-dialog', + templateUrl: './message-box-dialog.component.html', + styleUrls: ['./message-box-dialog.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None +}) +export class MessageBoxDialogComponent { + public constructor( + @Inject(MAT_DIALOG_DATA) protected dialogParams: MessageBoxDialogData + ) { } + + protected hasControl(key: 'OK' | 'CANCEL' | 'IGNORE' | 'RETRY' | 'YES' | 'NO' | 'CONTINUE'): boolean { + // eslint-disable-next-line no-bitwise + return !!this.dialogParams.buttons && (this.dialogParams.buttons & MessageBoxDialogButtons[key]) !== 0; + } +} diff --git a/projects/message-box-dialog/src/message-box-dialog.model.ts b/projects/message-box-dialog/src/message-box-dialog.model.ts new file mode 100644 index 00000000..436c1115 --- /dev/null +++ b/projects/message-box-dialog/src/message-box-dialog.model.ts @@ -0,0 +1,17 @@ +export type MessageBoxDialogResponse = 'ok' | 'cancel' | 'ignore' | 'retry' | 'yes' | 'no' | 'continue'; + +export enum MessageBoxDialogButtons { + OK = 0x1, + CANCEL = 0x2, + IGNORE = 0x4, + RETRY = 0x8, + YES = 0x10, + NO = 0x20, + CONTINUE = 0x40 +} + +export interface MessageBoxDialogData { + title: string; + text: string; + buttons?: MessageBoxDialogButtons; +} diff --git a/projects/message-box-dialog/src/message-box-dialog.module.ts b/projects/message-box-dialog/src/message-box-dialog.module.ts new file mode 100644 index 00000000..bd45b5e2 --- /dev/null +++ b/projects/message-box-dialog/src/message-box-dialog.module.ts @@ -0,0 +1,26 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { AbstractLazyModule } from '@hug/ngx-core'; + +import { MessageBoxDialogComponent } from './message-box-dialog.component'; + +@NgModule({ + declarations: [MessageBoxDialogComponent], + exports: [MessageBoxDialogComponent], + imports: [ + CommonModule, + MatButtonModule, + MatDialogModule, + MatIconModule, + MatToolbarModule + ] +}) +export class MessageBoxDialogModule extends AbstractLazyModule { + public constructor() { + super(MessageBoxDialogComponent); + } +} diff --git a/projects/message-box-dialog/src/message-box-dialog.service.ts b/projects/message-box-dialog/src/message-box-dialog.service.ts new file mode 100644 index 00000000..0de572ad --- /dev/null +++ b/projects/message-box-dialog/src/message-box-dialog.service.ts @@ -0,0 +1,50 @@ +import { Injectable, Type } from '@angular/core'; +import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { AbstractLazyModule, DialogService, LazyLoaderService } from '@hug/ngx-core'; +import { Observable, take } from 'rxjs'; + +import { MessageBoxDialogButtons, MessageBoxDialogData, MessageBoxDialogResponse } from './message-box-dialog.model'; + +@Injectable({ + providedIn: 'root' +}) +export class MessageBoxDialogService extends DialogService { + public constructor( + lazyLoaderService: LazyLoaderService, + dialog: MatDialog + ) { + super(lazyLoaderService, dialog, { + panelClass: 'no-padding-dialog' + } as MatDialogConfig); + } + + public override openDialog$(dialogData: string | MessageBoxDialogData, dialogConfig?: MatDialogConfig): Observable { + let messageBoxDialogData: MessageBoxDialogData; + if (typeof dialogData === 'string') { + messageBoxDialogData = { + text: dialogData, + buttons: MessageBoxDialogButtons.OK + } as MessageBoxDialogData; + } else { + messageBoxDialogData = dialogData; + } + messageBoxDialogData.title = messageBoxDialogData.title || 'Confirmation'; // Translate + + return super.openDialog$(messageBoxDialogData, dialogConfig); + } + + public openConfirmation$(message: string): Observable { + const dialogData = { + text: message, + buttons: MessageBoxDialogButtons.OK + MessageBoxDialogButtons.CANCEL + } as MessageBoxDialogData; + + return this.openDialog$(dialogData).pipe( + take(1) + ); + } + + protected getModule(): Promise>> { + return import('./message-box-dialog.module').then(m => m.MessageBoxDialogModule); + } +} diff --git a/projects/message-box-dialog/src/test.ts b/projects/message-box-dialog/src/test.ts new file mode 100644 index 00000000..390c9374 --- /dev/null +++ b/projects/message-box-dialog/src/test.ts @@ -0,0 +1,28 @@ +// 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'; + +declare const require: { + context: (path: string, deep?: boolean, filter?: RegExp) => { + (id: string): T; + keys: () => string[]; + }; +}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); + +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().forEach(context); diff --git a/projects/message-box-dialog/tsconfig.lib.json b/projects/message-box-dialog/tsconfig.lib.json new file mode 100644 index 00000000..599bb9f4 --- /dev/null +++ b/projects/message-box-dialog/tsconfig.lib.json @@ -0,0 +1,15 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "../../out-tsc/lib", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": [ + "src/test.ts", + "**/*.spec.ts" + ] +} diff --git a/projects/message-box-dialog/tsconfig.lib.prod.json b/projects/message-box-dialog/tsconfig.lib.prod.json new file mode 100644 index 00000000..560c2391 --- /dev/null +++ b/projects/message-box-dialog/tsconfig.lib.prod.json @@ -0,0 +1,10 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declarationMap": false + }, + "angularCompilerOptions": { + "compilationMode": "partial" + } +} diff --git a/projects/message-box-dialog/tsconfig.spec.json b/projects/message-box-dialog/tsconfig.spec.json new file mode 100644 index 00000000..3823c756 --- /dev/null +++ b/projects/message-box-dialog/tsconfig.spec.json @@ -0,0 +1,17 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "files": [ + "src/test.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 1d4e2cb8..76e1abd9 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -34,6 +34,9 @@ "@hug/ngx-message-box": [ "dist/message-box" ], + "@hug/ngx-message-box-dialog": [ + "dist/message-box-dialog" + ], "@hug/ngx-numeric-stepper": [ "dist/numeric-stepper" ], diff --git a/tsconfig.json b/tsconfig.json index 7cb0a8a3..7cdf4b7d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,6 +14,9 @@ "@hug/ngx-message-box": [ "projects/message-box/src" ], + "@hug/ngx-message-box-dialog": [ + "projects/message-box-dialog/src" + ], "@hug/ngx-numeric-stepper": [ "projects/numeric-stepper/src" ],