@mosa-ng/material 17.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +31 -0
- package/README.md +24 -0
- package/ng-package.json +10 -0
- package/package.json +12 -0
- package/src/lib/components/alert-widget/alert-widget.module.ts +17 -0
- package/src/lib/components/alert-widget/alert.widget.html +7 -0
- package/src/lib/components/alert-widget/alert.widget.scss +50 -0
- package/src/lib/components/alert-widget/alert.widget.ts +61 -0
- package/src/lib/components/base/base.module.ts +14 -0
- package/src/lib/components/base/cell-editor.base.component.ts +79 -0
- package/src/lib/components/cell-editor/cell-editor.component.html +6 -0
- package/src/lib/components/cell-editor/cell-editor.component.scss +53 -0
- package/src/lib/components/cell-editor/cell-editor.component.ts +115 -0
- package/src/lib/components/cell-editor/cell-editor.module.ts +15 -0
- package/src/lib/components/confirm-dialog/confirm-dialog.module.ts +19 -0
- package/src/lib/components/confirm-dialog/confirm.dialog.html +15 -0
- package/src/lib/components/confirm-dialog/confirm.dialog.scss +3 -0
- package/src/lib/components/confirm-dialog/confirm.dialog.ts +60 -0
- package/src/lib/components/loading-button/loading-button.component.html +42 -0
- package/src/lib/components/loading-button/loading-button.component.scss +40 -0
- package/src/lib/components/loading-button/loading-button.component.ts +42 -0
- package/src/lib/components/loading-button/loading-button.module.ts +21 -0
- package/src/lib/components/logger/README.md +83 -0
- package/src/lib/components/logger/logger.component.html +32 -0
- package/src/lib/components/logger/logger.component.scss +120 -0
- package/src/lib/components/logger/logger.component.ts +116 -0
- package/src/lib/components/logger/logger.module.ts +23 -0
- package/src/lib/components/skeleton-loader/base.skeleton-loader.ts +14 -0
- package/src/lib/components/skeleton-loader/list-skeleton-loader/list-skeleton-loader.module.ts +17 -0
- package/src/lib/components/skeleton-loader/list-skeleton-loader/list.skeleton-loader.html +5 -0
- package/src/lib/components/skeleton-loader/list-skeleton-loader/list.skeleton-loader.scss +0 -0
- package/src/lib/components/skeleton-loader/list-skeleton-loader/list.skeleton-loader.ts +26 -0
- package/src/lib/components/skeleton-loader/skeleton/skeleton.component.html +0 -0
- package/src/lib/components/skeleton-loader/skeleton/skeleton.component.scss +15 -0
- package/src/lib/components/skeleton-loader/skeleton/skeleton.component.ts +64 -0
- package/src/lib/components/skeleton-loader/skeleton-loader.module.ts +17 -0
- package/src/lib/components/skeleton-loader/table-skeleton-loader/table-skeleton-loader.module.ts +19 -0
- package/src/lib/components/skeleton-loader/table-skeleton-loader/table.skeleton-loader.html +12 -0
- package/src/lib/components/skeleton-loader/table-skeleton-loader/table.skeleton-loader.scss +3 -0
- package/src/lib/components/skeleton-loader/table-skeleton-loader/table.skeleton-loader.ts +44 -0
- package/src/lib/components/update-dialog/mat-update-dialog/mat-update.dialog.html +17 -0
- package/src/lib/components/update-dialog/mat-update-dialog/mat-update.dialog.scss +3 -0
- package/src/lib/components/update-dialog/mat-update-dialog/mat-update.dialog.ts +28 -0
- package/src/lib/components/update-dialog/update-dialog.module.ts +22 -0
- package/src/lib/components/update-dialog/update.dialog.ts +124 -0
- package/src/lib/directives/cell-editor/cell-editor.directive.module.ts +15 -0
- package/src/lib/directives/cell-editor/cell-editor.directive.ts +163 -0
- package/src/lib/directives/click-outside/click-outside.directive.module.ts +15 -0
- package/src/lib/directives/click-outside/click-outside.directive.ts +48 -0
- package/src/lib/models/confirm-dialog.model.ts +33 -0
- package/src/lib/models/skeleton.model.ts +19 -0
- package/src/lib/models/states/cell-editor-base-state.model.ts +3 -0
- package/src/lib/models/states/logger-state.model.ts +5 -0
- package/src/lib/models/table-item.model.ts +6 -0
- package/src/lib/models/update-config.model.ts +20 -0
- package/src/lib/mosa-material.module.ts +26 -0
- package/src/lib/services/cell-editor.service.ts +46 -0
- package/src/lib/services/facades/logger.facade.ts +37 -0
- package/src/lib/services/logger.service.ts +49 -0
- package/src/lib/styles/_vars.scss +71 -0
- package/src/public-api.ts +1 -0
- package/tsconfig.lib.json +14 -0
- package/tsconfig.lib.prod.json +10 -0
- package/tsconfig.spec.json +14 -0
package/.eslintrc.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../.eslintrc.json",
|
|
3
|
+
"parserOptions": {
|
|
4
|
+
"project": "**/tsconfig.json"
|
|
5
|
+
},
|
|
6
|
+
"overrides": [
|
|
7
|
+
{
|
|
8
|
+
"files": [
|
|
9
|
+
"*.ts"
|
|
10
|
+
],
|
|
11
|
+
"rules": {
|
|
12
|
+
"@angular-eslint/component-selector": [
|
|
13
|
+
"error",
|
|
14
|
+
{
|
|
15
|
+
"type": "element",
|
|
16
|
+
"prefix": "mosa",
|
|
17
|
+
"style": "kebab-case"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"@angular-eslint/directive-selector": [
|
|
21
|
+
"error",
|
|
22
|
+
{
|
|
23
|
+
"type": "attribute",
|
|
24
|
+
"prefix": "mosa",
|
|
25
|
+
"style": "camelCase"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# material
|
|
2
|
+
|
|
3
|
+
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.3.0.
|
|
4
|
+
|
|
5
|
+
## Code scaffolding
|
|
6
|
+
|
|
7
|
+
Run `ng generate component component-name --project material` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project material`.
|
|
8
|
+
> Note: Don't forget to add `--project material` or else it will be added to the default project in your `angular.json` file.
|
|
9
|
+
|
|
10
|
+
## Build
|
|
11
|
+
|
|
12
|
+
Run `ng build material` to build the project. The build artifacts will be stored in the `dist/` directory.
|
|
13
|
+
|
|
14
|
+
## Publishing
|
|
15
|
+
|
|
16
|
+
After building your library with `ng build material`, go to the dist folder `cd dist/material` and run `npm publish`.
|
|
17
|
+
|
|
18
|
+
## Running unit tests
|
|
19
|
+
|
|
20
|
+
Run `ng test material` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
21
|
+
|
|
22
|
+
## Further help
|
|
23
|
+
|
|
24
|
+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
package/ng-package.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { NgModule } from '@angular/core';
|
|
3
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
4
|
+
import { AlertWidget } from './alert.widget';
|
|
5
|
+
|
|
6
|
+
@NgModule({
|
|
7
|
+
declarations: [ AlertWidget ],
|
|
8
|
+
exports: [
|
|
9
|
+
AlertWidget,
|
|
10
|
+
],
|
|
11
|
+
imports: [
|
|
12
|
+
CommonModule,
|
|
13
|
+
MatIconModule,
|
|
14
|
+
],
|
|
15
|
+
})
|
|
16
|
+
export class AlertWidgetModule {
|
|
17
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
@import "../../styles/vars";
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.alert {
|
|
8
|
+
position: relative;
|
|
9
|
+
padding: 15px;
|
|
10
|
+
border-radius: 4px;
|
|
11
|
+
width: 100%;
|
|
12
|
+
display: table;
|
|
13
|
+
color: #222222;
|
|
14
|
+
border: 1px solid #222222;
|
|
15
|
+
border-left-width: 5px;
|
|
16
|
+
|
|
17
|
+
.icon {
|
|
18
|
+
@include flex(false, false, true);
|
|
19
|
+
margin-bottom: 10px;
|
|
20
|
+
|
|
21
|
+
mat-icon {
|
|
22
|
+
margin-right: 10px;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&-danger {
|
|
27
|
+
background: rgba($danger, .1);
|
|
28
|
+
border-color: $danger;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&-warning {
|
|
32
|
+
background: rgba($warning, .1);
|
|
33
|
+
border-color: $warning;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&-info {
|
|
37
|
+
background: rgba($info, .1);
|
|
38
|
+
border-color: $info;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&-primary {
|
|
42
|
+
background: rgba($primary, .1);
|
|
43
|
+
border-color: $primary;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&-success {
|
|
47
|
+
background: rgba($success, .1);
|
|
48
|
+
border-color: $success;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
selector: 'mosa-alert-widget',
|
|
5
|
+
templateUrl: './alert.widget.html',
|
|
6
|
+
styleUrls: [ './alert.widget.scss' ],
|
|
7
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
8
|
+
})
|
|
9
|
+
export class AlertWidget implements OnInit, OnChanges {
|
|
10
|
+
|
|
11
|
+
@Input()
|
|
12
|
+
public icon: string;
|
|
13
|
+
|
|
14
|
+
@Input()
|
|
15
|
+
public title: string;
|
|
16
|
+
|
|
17
|
+
@Input()
|
|
18
|
+
public message: string;
|
|
19
|
+
|
|
20
|
+
@Input()
|
|
21
|
+
public type: 'warning' | 'error' | 'info' | 'success';
|
|
22
|
+
|
|
23
|
+
constructor() {
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public ngOnInit(): void {
|
|
27
|
+
this.updateData();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public ngOnChanges(_changes: SimpleChanges): void {
|
|
31
|
+
this.updateData();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private updateData(): void {
|
|
35
|
+
if (!this.title || !this.icon) {
|
|
36
|
+
switch (this.type) {
|
|
37
|
+
case 'error':
|
|
38
|
+
this.icon ||= 'alert-circle-outline';
|
|
39
|
+
this.title ||= 'Error';
|
|
40
|
+
break;
|
|
41
|
+
case 'info':
|
|
42
|
+
this.icon ||= 'information-outline';
|
|
43
|
+
this.title ||= 'Information';
|
|
44
|
+
break;
|
|
45
|
+
case 'success':
|
|
46
|
+
this.icon ||= 'check';
|
|
47
|
+
this.title ||= 'Success';
|
|
48
|
+
break;
|
|
49
|
+
case 'warning':
|
|
50
|
+
this.icon ||= 'alert-outline';
|
|
51
|
+
this.title ||= 'Warning';
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
this.icon ||= 'information-outline';
|
|
55
|
+
this.title ||= 'Alert';
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { NgModule } from '@angular/core';
|
|
3
|
+
import { CellEditorBaseComponent } from './cell-editor.base.component';
|
|
4
|
+
|
|
5
|
+
@NgModule({
|
|
6
|
+
declarations: [
|
|
7
|
+
CellEditorBaseComponent,
|
|
8
|
+
],
|
|
9
|
+
imports: [
|
|
10
|
+
CommonModule,
|
|
11
|
+
],
|
|
12
|
+
})
|
|
13
|
+
export class BaseModule {
|
|
14
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, OnInit, Optional } from '@angular/core';
|
|
2
|
+
import { MatDialog } from '@angular/material/dialog';
|
|
3
|
+
import { MatTableDataSource } from '@angular/material/table';
|
|
4
|
+
import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot, UrlTree } from '@angular/router';
|
|
5
|
+
import { PromiseReject, PromiseResolve } from '@mosa-ng/core';
|
|
6
|
+
import { Observable } from 'rxjs';
|
|
7
|
+
import { ConfirmDialogData, ConfirmDialogResult } from '../../models/confirm-dialog.model';
|
|
8
|
+
import { TableItem } from '../../models/table-item.model';
|
|
9
|
+
import { ConfirmDialog } from '../confirm-dialog/confirm.dialog';
|
|
10
|
+
|
|
11
|
+
@Component({
|
|
12
|
+
selector: 'mosa-cell-editor-base',
|
|
13
|
+
template: '',
|
|
14
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
15
|
+
})
|
|
16
|
+
export class CellEditorBaseComponent<Model> implements OnInit, CanDeactivate<CellEditorBaseComponent<Model>> {
|
|
17
|
+
|
|
18
|
+
public dataSource: MatTableDataSource<TableItem<Model>>;
|
|
19
|
+
public displayedColumns: (keyof Model | string)[] = [];
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
@Optional()
|
|
23
|
+
protected readonly myMatDialog: MatDialog,
|
|
24
|
+
) {
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public ngOnInit(): void {
|
|
28
|
+
this.dataSource = new MatTableDataSource<TableItem<Model>>();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public get changedRows(): TableItem<Model>[] {
|
|
32
|
+
return this.dataSource?.data?.filter((c: TableItem<Model>): boolean => c.changedRowKeys?.length > 0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Remove table item data
|
|
37
|
+
* @param data
|
|
38
|
+
*/
|
|
39
|
+
public serializeData(data: TableItem<Model>[]): Model[] {
|
|
40
|
+
return data.map((val: TableItem<Model>): Model => {
|
|
41
|
+
delete val.changedRowKeys;
|
|
42
|
+
delete val.rowOriginalData;
|
|
43
|
+
return val;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public toTableItems(data: Model[]): TableItem<Model>[] {
|
|
48
|
+
return data.map((val: Model): TableItem<Model> => ({
|
|
49
|
+
...val,
|
|
50
|
+
rowOriginalData: val,
|
|
51
|
+
changedRowKeys: [],
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public canDeactivate(_component: CellEditorBaseComponent<Model>, _currentRoute: ActivatedRouteSnapshot, _currentState: RouterStateSnapshot,
|
|
56
|
+
_nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
|
57
|
+
if (!this.changedRows.length) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return new Promise((resolve: PromiseResolve<boolean>, _reject: PromiseReject): void => {
|
|
62
|
+
this.myMatDialog
|
|
63
|
+
.open(ConfirmDialog, {
|
|
64
|
+
width: '600px',
|
|
65
|
+
data: new ConfirmDialogData('mosa.components.cellEditorBase.discardChanges.label',
|
|
66
|
+
'mosa.components.cellEditorBase.discardChanges.message'),
|
|
67
|
+
})
|
|
68
|
+
.afterClosed()
|
|
69
|
+
.subscribe((result: ConfirmDialogResult): void => {
|
|
70
|
+
if (result === ConfirmDialogResult.confirmed) {
|
|
71
|
+
resolve(true);
|
|
72
|
+
} else {
|
|
73
|
+
resolve(false);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
@import "../../styles/vars";
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
position: absolute;
|
|
7
|
+
width: 100%;
|
|
8
|
+
height: 100%;
|
|
9
|
+
top: 0;
|
|
10
|
+
left: 0;
|
|
11
|
+
z-index: 1;
|
|
12
|
+
|
|
13
|
+
&.focused .input-wrapper {
|
|
14
|
+
height: calc(100% - 6px);
|
|
15
|
+
width: 100%;
|
|
16
|
+
box-shadow: 0 0 0 3px rgba(#1387DF, .8);
|
|
17
|
+
outline: 0;
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&.edited {
|
|
23
|
+
color: #1387DF;
|
|
24
|
+
font-weight: 500;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
::ng-deep .editable-cell {
|
|
29
|
+
position: relative;
|
|
30
|
+
|
|
31
|
+
&:first-child mosa-cell-editor:not(.focused) {
|
|
32
|
+
padding-left: 24px;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
::ng-deep .cell-input {
|
|
37
|
+
padding: 10px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
::ng-deep .cell-output {
|
|
41
|
+
text-overflow: ellipsis;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
white-space: nowrap;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
::ng-deep input.cell-input {
|
|
47
|
+
font-size: 14px;
|
|
48
|
+
font-family: $fontRoboto;
|
|
49
|
+
background: none;
|
|
50
|
+
flex-grow: 1;
|
|
51
|
+
outline: 0;
|
|
52
|
+
border: none;
|
|
53
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChangeDetectionStrategy,
|
|
3
|
+
ChangeDetectorRef,
|
|
4
|
+
Component,
|
|
5
|
+
ContentChild,
|
|
6
|
+
ElementRef,
|
|
7
|
+
EventEmitter,
|
|
8
|
+
Input,
|
|
9
|
+
OnInit,
|
|
10
|
+
Output,
|
|
11
|
+
} from '@angular/core';
|
|
12
|
+
import { MatSelect } from '@angular/material/select';
|
|
13
|
+
import { TableItem } from '../../models/table-item.model';
|
|
14
|
+
import { BaseComponent } from '../base/base.component';
|
|
15
|
+
|
|
16
|
+
@Component({
|
|
17
|
+
selector: 'mosa-cell-editor',
|
|
18
|
+
templateUrl: './cell-editor.component.html',
|
|
19
|
+
styleUrls: [ './cell-editor.component.scss' ],
|
|
20
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
21
|
+
})
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
+
export class CellEditorComponent<T = any> extends BaseComponent implements OnInit {
|
|
24
|
+
|
|
25
|
+
@Input()
|
|
26
|
+
public key: string;
|
|
27
|
+
|
|
28
|
+
@Input()
|
|
29
|
+
public rowItem: TableItem<T>;
|
|
30
|
+
|
|
31
|
+
@Input()
|
|
32
|
+
public value: T;
|
|
33
|
+
|
|
34
|
+
@Output()
|
|
35
|
+
public valueChange: EventEmitter<T> = new EventEmitter<T>();
|
|
36
|
+
|
|
37
|
+
@Output()
|
|
38
|
+
public cellClick: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
|
39
|
+
|
|
40
|
+
@Output()
|
|
41
|
+
private readonly cellChange: EventEmitter<void> = new EventEmitter<void>();
|
|
42
|
+
|
|
43
|
+
@Output()
|
|
44
|
+
private readonly cellCancel: EventEmitter<void> = new EventEmitter<void>();
|
|
45
|
+
|
|
46
|
+
@ContentChild(MatSelect)
|
|
47
|
+
private readonly select: MatSelect;
|
|
48
|
+
|
|
49
|
+
public mode: 'input' | 'output' = 'output';
|
|
50
|
+
|
|
51
|
+
private oldValue: T;
|
|
52
|
+
|
|
53
|
+
constructor(
|
|
54
|
+
private readonly myChangeDetectorRef: ChangeDetectorRef,
|
|
55
|
+
private readonly myElementRef: ElementRef<HTMLElement>,
|
|
56
|
+
) {
|
|
57
|
+
super();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public get element(): HTMLElement {
|
|
61
|
+
return this.myElementRef.nativeElement;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public override ngOnInit(): void {
|
|
65
|
+
this.oldValue = this.value;
|
|
66
|
+
this.rowItem.rowOriginalData = this.rowItem;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public toOutput(save?: boolean): void {
|
|
70
|
+
if (this.mode !== 'output') {
|
|
71
|
+
this.mode = 'output';
|
|
72
|
+
this.myChangeDetectorRef.markForCheck();
|
|
73
|
+
this.element.classList.remove('focused');
|
|
74
|
+
|
|
75
|
+
if (save) {
|
|
76
|
+
if (!this.rowItem.changedRowKeys) {
|
|
77
|
+
this.rowItem.changedRowKeys = [];
|
|
78
|
+
}
|
|
79
|
+
const index: number = this.rowItem.changedRowKeys.indexOf(this.key);
|
|
80
|
+
if (this.value !== this.oldValue) {
|
|
81
|
+
if (index === -1) {
|
|
82
|
+
this.rowItem.changedRowKeys.push(this.key);
|
|
83
|
+
this.element.classList.add('edited');
|
|
84
|
+
}
|
|
85
|
+
this.cellChange.emit();
|
|
86
|
+
} else {
|
|
87
|
+
if (index !== -1) {
|
|
88
|
+
this.rowItem.changedRowKeys.splice(index, 1);
|
|
89
|
+
this.element.classList.remove('edited');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
this.value = this.oldValue;
|
|
94
|
+
this.cellCancel.emit();
|
|
95
|
+
}
|
|
96
|
+
this.valueChange.next(this.value);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public toInput(): void {
|
|
101
|
+
this.mode = 'input';
|
|
102
|
+
this.myChangeDetectorRef.markForCheck();
|
|
103
|
+
this.element.classList.add('focused');
|
|
104
|
+
setTimeout((): void => {
|
|
105
|
+
const comp: HTMLElement = this.element.querySelector('.cell-input');
|
|
106
|
+
|
|
107
|
+
if (comp instanceof HTMLInputElement) {
|
|
108
|
+
comp.focus();
|
|
109
|
+
} else if (this.select) {
|
|
110
|
+
this.select.open();
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { NgModule } from '@angular/core';
|
|
3
|
+
import { CellEditorComponent } from './cell-editor.component';
|
|
4
|
+
|
|
5
|
+
@NgModule({
|
|
6
|
+
declarations: [ CellEditorComponent ],
|
|
7
|
+
imports: [
|
|
8
|
+
CommonModule,
|
|
9
|
+
],
|
|
10
|
+
exports: [
|
|
11
|
+
CellEditorComponent,
|
|
12
|
+
],
|
|
13
|
+
})
|
|
14
|
+
export class CellEditorModule {
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { NgModule } from '@angular/core';
|
|
3
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
4
|
+
import { MatDialogModule } from '@angular/material/dialog';
|
|
5
|
+
import { TranslateModule } from '@ngx-translate/core';
|
|
6
|
+
import { ConfirmDialog } from './confirm.dialog';
|
|
7
|
+
|
|
8
|
+
@NgModule({
|
|
9
|
+
declarations: [ ConfirmDialog ],
|
|
10
|
+
imports: [
|
|
11
|
+
CommonModule,
|
|
12
|
+
MatDialogModule,
|
|
13
|
+
MatButtonModule,
|
|
14
|
+
TranslateModule,
|
|
15
|
+
],
|
|
16
|
+
exports: [ ConfirmDialog ],
|
|
17
|
+
})
|
|
18
|
+
export class ConfirmDialogModule {
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<h1 class="active" mat-dialog-title>{{ dialogData.title | translate }}</h1>
|
|
2
|
+
<div mat-dialog-content>
|
|
3
|
+
{{ dialogData.message | translate }}
|
|
4
|
+
</div>
|
|
5
|
+
<div mat-dialog-actions>
|
|
6
|
+
<button (click)="confirm(result.cancelled)" *ngIf="dialogData.cancel" color="primary" mat-stroked-button>
|
|
7
|
+
{{ 'mosa.commons.buttons.cancel' | translate | uppercase }}
|
|
8
|
+
</button>
|
|
9
|
+
<button (click)="confirm(result.denied)" *ngIf="dialogData.deny.visible" color="primary" mat-stroked-button>
|
|
10
|
+
{{ dialogData.deny.label | translate | uppercase }}
|
|
11
|
+
</button>
|
|
12
|
+
<button (click)="confirm(result.confirmed)" *ngIf="dialogData.confirm.visible" color="primary" mat-flat-button>
|
|
13
|
+
{{ dialogData.confirm.label | translate | uppercase }}
|
|
14
|
+
</button>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core';
|
|
2
|
+
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
|
3
|
+
import { ConfirmDialogAction, ConfirmDialogData, ConfirmDialogResult } from '../../models/confirm-dialog.model';
|
|
4
|
+
import { BaseComponent } from '../base/base.component';
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: 'mosa-confirm-dialog',
|
|
8
|
+
templateUrl: './confirm.dialog.html',
|
|
9
|
+
styleUrls: [ './confirm.dialog.scss' ],
|
|
10
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
11
|
+
})
|
|
12
|
+
export class ConfirmDialog extends BaseComponent implements OnInit {
|
|
13
|
+
|
|
14
|
+
public dialogData: ConfirmDialogData;
|
|
15
|
+
public result: typeof ConfirmDialogResult = ConfirmDialogResult;
|
|
16
|
+
|
|
17
|
+
constructor(
|
|
18
|
+
@Inject(MAT_DIALOG_DATA)
|
|
19
|
+
private readonly myConfirmDialogData: ConfirmDialogData,
|
|
20
|
+
private readonly myMatDialogRef: MatDialogRef<ConfirmDialog>,
|
|
21
|
+
) {
|
|
22
|
+
super();
|
|
23
|
+
const cancel: ConfirmDialogAction = new ConfirmDialogAction('mosa.commons.buttons.cancel', true);
|
|
24
|
+
const deny: ConfirmDialogAction = new ConfirmDialogAction('mosa.commons.buttons.deny');
|
|
25
|
+
const confirm: ConfirmDialogAction = new ConfirmDialogAction('mosa.commons.buttons.confirm', true);
|
|
26
|
+
const title: string = 'mosa.components.confirmDialog.title';
|
|
27
|
+
const message: string = 'mosa.components.confirmDialog.message';
|
|
28
|
+
|
|
29
|
+
this.dialogData = myConfirmDialogData || new ConfirmDialogData(title, message, cancel, confirm, deny);
|
|
30
|
+
|
|
31
|
+
if (!this.dialogData.title) {
|
|
32
|
+
this.dialogData.title = title;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!this.dialogData.message) {
|
|
36
|
+
this.dialogData.message = message;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!this.dialogData.cancel) {
|
|
40
|
+
this.dialogData.cancel = cancel;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!this.dialogData.confirm) {
|
|
44
|
+
this.dialogData.confirm = confirm;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!this.dialogData.deny) {
|
|
48
|
+
this.dialogData.deny = deny;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public override ngOnInit(): void {
|
|
53
|
+
super.ngOnInit();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public confirm(result: ConfirmDialogResult): void {
|
|
57
|
+
this.myMatDialogRef.close(result);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<ng-container [ngSwitch]="buttonType">
|
|
2
|
+
<button (click)="onClick($event)" *ngSwitchDefault [class]="mode" [color]="color"
|
|
3
|
+
[disabled]="loading || disabled" mat-button>
|
|
4
|
+
<ng-container [ngTemplateOutlet]="buttonContent"></ng-container>
|
|
5
|
+
</button>
|
|
6
|
+
<button (click)="onClick($event)" *ngSwitchCase="'raised'" [class]="mode" [color]="color"
|
|
7
|
+
[disabled]="loading || disabled" mat-raised-button>
|
|
8
|
+
<ng-container [ngTemplateOutlet]="buttonContent"></ng-container>
|
|
9
|
+
</button>
|
|
10
|
+
<button (click)="onClick($event)" *ngSwitchCase="'stroked'" [class]="mode" [color]="color"
|
|
11
|
+
[disabled]="loading || disabled" mat-stroked-button>
|
|
12
|
+
<ng-container [ngTemplateOutlet]="buttonContent"></ng-container>
|
|
13
|
+
</button>
|
|
14
|
+
<button (click)="onClick($event)" *ngSwitchCase="'flat'" [class]="mode" [color]="color"
|
|
15
|
+
[disabled]="loading || disabled" mat-flat-button>
|
|
16
|
+
<ng-container [ngTemplateOutlet]="buttonContent"></ng-container>
|
|
17
|
+
</button>
|
|
18
|
+
<button (click)="onClick($event)" *ngSwitchCase="'icon'" [class]="mode" [color]="color"
|
|
19
|
+
[disabled]="loading || disabled" mat-icon-button>
|
|
20
|
+
<mat-spinner *ngIf="loading" class="icon-spinner" [color]="color" [diameter]="40" [strokeWidth]="2"></mat-spinner>
|
|
21
|
+
<mat-icon *ngIf="icon">{{ icon }}</mat-icon>
|
|
22
|
+
<ng-content select=".icon"></ng-content>
|
|
23
|
+
</button>
|
|
24
|
+
</ng-container>
|
|
25
|
+
|
|
26
|
+
<ng-template #buttonContent>
|
|
27
|
+
<mat-icon *ngIf="icon">{{ icon }}</mat-icon>
|
|
28
|
+
<ng-container [ngSwitch]="mode">
|
|
29
|
+
<ng-container *ngSwitchCase="'spinner'">
|
|
30
|
+
<div class="spinner-inner">
|
|
31
|
+
<mat-spinner *ngIf="loading" [color]="color" [diameter]="20"></mat-spinner>
|
|
32
|
+
<span [class.loading]="loading" class="label">
|
|
33
|
+
<ng-content select=".spinner-label"></ng-content>
|
|
34
|
+
</span>
|
|
35
|
+
</div>
|
|
36
|
+
</ng-container>
|
|
37
|
+
<ng-container *ngSwitchCase="'progress-bar'">
|
|
38
|
+
<ng-content select=".progress-bar-label"></ng-content>
|
|
39
|
+
<mat-progress-bar *ngIf="loading" [color]="color" mode="indeterminate"></mat-progress-bar>
|
|
40
|
+
</ng-container>
|
|
41
|
+
</ng-container>
|
|
42
|
+
</ng-template>
|