mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-19 17:14:57 +00:00
[ACS-7570] [ADF] Create generic dialog component (#9678)
This commit is contained in:
parent
b916fd5ef9
commit
0d2d08aab3
@ -342,6 +342,7 @@ for more information about installing and using the source code.
|
||||
|
||||
| Name | Description | Source link |
|
||||
| ---- | ----------- | ----------- |
|
||||
| [Dialog component](content-services/dialogs/dialog.md) | Dialog styled wrapper. | [Source](../lib/content-services/src/lib/dialogs/dialog/dialog.component.ts) |
|
||||
| [Confirm dialog component](content-services/dialogs/confirm.dialog.md) | Requests a yes/no choice from the user. | [Source](../lib/content-services/src/lib/dialogs/confirm.dialog.ts) |
|
||||
| [Library dialog component](content-services/dialogs/library.dialog.md) | Creates a new Content Services document library/site. | [Source](../lib/content-services/src/lib/dialogs/library/library.dialog.ts) |
|
||||
|
||||
|
86
docs/content-services/dialogs/dialog.md
Normal file
86
docs/content-services/dialogs/dialog.md
Normal file
@ -0,0 +1,86 @@
|
||||
---
|
||||
Title: Dialog component
|
||||
Added: v6.9.0
|
||||
Status: Active
|
||||
Last reviewed: 2024-05-17
|
||||
---
|
||||
|
||||
# [Dialog component](../../../lib/content-services/src/lib/dialogs/dialog/ "Defined in dialog.component.ts")
|
||||
|
||||
Dialog wrapper styled according to a consistent design system.
|
||||
|
||||
## Dialog views
|
||||
|
||||
### Large size and Medium
|
||||
|
||||
Looks the same but have different sizes.
|
||||
Max-width for Large dialog is `1075px`;
|
||||
Max-width for Medium dialog is `778px`;
|
||||
|
||||

|
||||
|
||||
### Alert dialogs
|
||||
|
||||
Standard:
|
||||
|
||||

|
||||
|
||||
With icon:
|
||||
|
||||

|
||||
|
||||
### Dialog with additional buttons
|
||||
|
||||

|
||||
|
||||
## Basic Usage
|
||||
|
||||
```html
|
||||
|
||||
<ng-template #contentDialogTemplate>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Similique nihil, natus corrupti asperiores voluptas, incidunt veritatis.
|
||||
</ng-template>
|
||||
|
||||
<ng-template #actionsDialogTemplate>
|
||||
<button mat-button>
|
||||
Reset
|
||||
</button>
|
||||
|
||||
<button mat-button>
|
||||
Clean
|
||||
</button>
|
||||
</ng-template>
|
||||
```
|
||||
|
||||
```ts
|
||||
@ViewChild('contentDialogTemplate') contentDialogTemplate: TemplateRef<any>;
|
||||
@ViewChild('actionsDialogTemplate') actionsDialogTemplate: TemplateRef<any>;
|
||||
|
||||
constructor(private dialog: MatDialog) {}
|
||||
|
||||
//...
|
||||
|
||||
function openDialog() {
|
||||
const data: DialogData = {
|
||||
title: 'Dialog title',
|
||||
dialogSize: DialogSize.Alert,
|
||||
isConfirmButtonDisabled$: of(true),
|
||||
contentTemplate: this.contentDialogTemplate,
|
||||
actionsTemplate: this.actionsDialogTemplate
|
||||
};
|
||||
|
||||
this.dialog.open(DialogComponent, { data });
|
||||
}
|
||||
```
|
||||
|
||||
## Details
|
||||
|
||||
This component lets the user reuse styled dialog wrapper. Use the
|
||||
Angular [`MatDialog`](https://material.angular.io/components/dialog/overview)
|
||||
service to open the dialog, as shown in the example, and pass a `data` object
|
||||
with properties.
|
||||
|
||||
## See also
|
||||
|
||||
- [Dialog Data Interface](../interfaces/dialog.interface.md)
|
||||
- [Dialog Model](../models/dialog.model.md)
|
51
docs/content-services/interfaces/dialog.interface.md
Normal file
51
docs/content-services/interfaces/dialog.interface.md
Normal file
@ -0,0 +1,51 @@
|
||||
---
|
||||
Title: Dialog Data Interface
|
||||
Added: v6.9.0
|
||||
Status: Active
|
||||
Last reviewed: 2024-05-17
|
||||
---
|
||||
|
||||
# [Dialog Data Interface](../../../lib/content-services/src/lib/dialogs/dialog/dialog-data.interface.ts "Defined in dialog-data.interface.ts")
|
||||
|
||||
Specifies interface for [Dialog Component](../dialogs/dialog.md).
|
||||
|
||||
## Basic usage
|
||||
|
||||
```ts
|
||||
interface DialogData {
|
||||
title: string;
|
||||
description?: string;
|
||||
confirmButtonTitle?: string;
|
||||
cancelButtonTitle?: string;
|
||||
isConfirmButtonDisabled$?: Subject<boolean>;
|
||||
isCloseButtonHidden?: boolean;
|
||||
isCancelButtonHidden?: boolean;
|
||||
dialogSize?: DialogSizes;
|
||||
contentTemplate?: TemplateRef<any>;
|
||||
actionsTemplate?: TemplateRef<any>;
|
||||
descriptionTemplate?: TemplateRef<any>;
|
||||
headerIcon?: string;
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Name | Type | Default value | Description |
|
||||
| ---- | ---- | ------------- | ----------- |
|
||||
| title | `string` | | It will be placed in the dialog title section. |
|
||||
| headerIcon | `string` | | It will be placed in header section. Should be used with Alert dialogs. (optional) |
|
||||
| description | `string` | | It will be placed first in the dialog content section. (optional) |
|
||||
| confirmButtonTitle | `string` | `COMMON.APPLY` | Confirmation action. After this, the dialog is closed and the `isConfirmButtonDisabled$` is set to `true`. (optional) |
|
||||
| cancelButtonTitle | `string` | `COMMON.CANCEL` | Cancellation action. After this, the dialog is closed |
|
||||
| isCancelButtonHidden | `boolean` | `false` | Toggles cancel button visibility. (optional) |
|
||||
| isCloseButtonHidden | `boolean` | `false` | Toggles close button visibility. (optional) |
|
||||
| isConfirmButtonDisabled$ | `Subject<boolean>` | `false` | Toggles confirm button disability. (optional) |
|
||||
| dialogSize | `DialogSize` | `Medium` | Set dialog size. Can be `Large`, `Medium`, `Alert`. (optional) |
|
||||
| contentTemplate | `TemplateRef<any>` | | Inserts a content template. (optional) |
|
||||
| actionsTemplate | `TemplateRef<any>` | | Inserts a template styled on the left. Should be used for additional `mat-button` style buttons. (optional) |
|
||||
| descriptionTemplate | `TemplateRef<any>` | | Inserts a description template. (optional) |
|
||||
|
||||
## See also
|
||||
|
||||
- [Dialog Component](../dialogs/dialog.md)
|
||||
- [Dialog Model](../models/dialog.model.md)
|
52
docs/content-services/models/dialog.model.md
Normal file
52
docs/content-services/models/dialog.model.md
Normal file
@ -0,0 +1,52 @@
|
||||
---
|
||||
Title: Dialog Size Model
|
||||
Added: v6.9.0
|
||||
Status: Active
|
||||
Last reviewed: 2024-05-17
|
||||
---
|
||||
|
||||
# [Dialog Size model](../../../lib/content-services/src/lib/dialogs/dialog/dialog.model.ts "Defined in dialog.model.ts")
|
||||
|
||||
Sets a specific CSS class to [Dialog Component](../dialogs/dialog.md).
|
||||
|
||||
## Basic usage
|
||||
|
||||
```ts
|
||||
const DialogSize = {
|
||||
Large: 'adf-large',
|
||||
Medium: 'adf-medium',
|
||||
Alert: 'adf-alert'
|
||||
} as const;
|
||||
|
||||
type DialogSizes = typeof DialogSize[keyof typeof DialogSize];
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Name | Type | Default value | Description |
|
||||
| ---- | ---- | ------------- | ----------- |
|
||||
| Large | `string` | `adf-large` | Add `afd-large` class to Dialog container |
|
||||
| Medium | `string` | `adf-medium` | Add `afd-medium` class to Dialog container |
|
||||
| Alert | `string` | `adf-alert` | Add `afd-alert` class to Dialog container |
|
||||
|
||||
### Examples
|
||||
|
||||
```ts
|
||||
constructor(private dialog: MatDialog) {}
|
||||
|
||||
...
|
||||
|
||||
function openDialog() {
|
||||
const data: DialogData = {
|
||||
title: 'Dialog title',
|
||||
dialogSize: DialogSize.Large,
|
||||
};
|
||||
|
||||
this.dialog.open(DialogComponent, { data });
|
||||
}
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [Dialog Component](../dialogs/dialog.md)
|
||||
- [Dialog Data Interface](../interfaces/dialog.interface.md)
|
BIN
docs/docassets/images/adf-dialog-alert-standart.png
Normal file
BIN
docs/docassets/images/adf-dialog-alert-standart.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
BIN
docs/docassets/images/adf-dialog-alert-with-icon.png
Normal file
BIN
docs/docassets/images/adf-dialog-alert-with-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
docs/docassets/images/adf-dialog-with-additional-buttons.png
Normal file
BIN
docs/docassets/images/adf-dialog-with-additional-buttons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
BIN
docs/docassets/images/adf-dialog.png
Normal file
BIN
docs/docassets/images/adf-dialog.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 194 KiB |
@ -0,0 +1,35 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TemplateRef } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { DialogSizes } from './dialog.model';
|
||||
|
||||
export interface DialogData {
|
||||
title: string;
|
||||
description?: string;
|
||||
confirmButtonTitle?: string;
|
||||
cancelButtonTitle?: string;
|
||||
isConfirmButtonDisabled$?: Subject<boolean>;
|
||||
isCloseButtonHidden?: boolean;
|
||||
isCancelButtonHidden?: boolean;
|
||||
dialogSize?: DialogSizes;
|
||||
contentTemplate?: TemplateRef<any>;
|
||||
actionsTemplate?: TemplateRef<any>;
|
||||
descriptionTemplate?: TemplateRef<any>;
|
||||
headerIcon?: string;
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
<div
|
||||
data-automation-id="adf-dialog-container"
|
||||
class="adf-dialog-container {{dialogSize}}"
|
||||
>
|
||||
<div
|
||||
mat-dialog-title
|
||||
data-automation-id="adf-dialog-header"
|
||||
class="adf-dialog-header"
|
||||
[ngClass]="{'adf-centered-header': data.headerIcon}"
|
||||
>
|
||||
<div class="adf-dialog-title-container" [ngClass]="{ 'adf-centered-title': data.headerIcon }">
|
||||
<mat-icon
|
||||
*ngIf="data.headerIcon"
|
||||
color="primary"
|
||||
class="adf-dialog-header-icon"
|
||||
>
|
||||
{{data.headerIcon}}
|
||||
</mat-icon>
|
||||
<h2 class="adf-dialog-title">{{data.title}}</h2>
|
||||
</div>
|
||||
<button
|
||||
*ngIf="!isCloseButtonHidden"
|
||||
mat-icon-button
|
||||
mat-dialog-close
|
||||
data-automation-id="adf-dialog-close-button"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
[ngTemplateOutlet]="data.descriptionTemplate"
|
||||
[ngClass]="{ 'adf-description': data.description || data.descriptionTemplate }"
|
||||
>
|
||||
<ng-container>{{data.description}}</ng-container>
|
||||
</div>
|
||||
|
||||
<mat-dialog-content class="adf-dialog-content">
|
||||
<ng-container [ngTemplateOutlet]="data.contentTemplate"></ng-container>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions class="adf-dialog-actions" [ngClass]="{ 'adf-additional-actions': data.actionsTemplate }">
|
||||
<div>
|
||||
<ng-container [ngTemplateOutlet]="data.actionsTemplate"></ng-container>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
*ngIf="!isCancelButtonHidden"
|
||||
mat-button
|
||||
mat-dialog-close
|
||||
adf-auto-focus
|
||||
data-automation-id="adf-dialog-actions-cancel"
|
||||
>
|
||||
{{cancelButtonTitle | translate}}
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
data-automation-id="adf-dialog-actions-confirm"
|
||||
[disabled]="isConfirmButtonDisabled$ | async"
|
||||
(click)="onConfirm()"
|
||||
>
|
||||
{{confirmButtonTitle | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</mat-dialog-actions>
|
||||
</div>
|
@ -0,0 +1,226 @@
|
||||
$dialog-large-l-width: 1075px;
|
||||
$dialog-large-l-height: 907px;
|
||||
|
||||
$dialog-medium-l-width: 691px;
|
||||
$dialog-medium-l-height: 778px;
|
||||
|
||||
$dialog-small-l-width: 461px;
|
||||
$dialog-small-s-width: 346px;
|
||||
$dialog-small-l-height: 432px;
|
||||
$dialog-small-s-height: 360px;
|
||||
|
||||
$l-screen: 1920px;
|
||||
$m-screen: 1680px;
|
||||
$s-screen: 1440px;
|
||||
$xs-screen: 375px;
|
||||
|
||||
$breakpoint-alert-with-additional-buttons-centered: 1469px;
|
||||
$breakpoint-medium-with-additional-buttons-centered: 1469px;
|
||||
$breakpoint-large-with-additional-buttons-centered: 642px;
|
||||
|
||||
$dialog-padding: 24px;
|
||||
|
||||
.adf-dialog-container {
|
||||
min-width: calc(269px - $dialog-padding * 2);
|
||||
min-height: calc(300px - $dialog-padding * 2);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: calc(84vh - $dialog-padding * 2);
|
||||
|
||||
.adf-dialog-header,
|
||||
.adf-dialog-content,
|
||||
.adf-dialog-actions {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.adf-dialog-header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: $dialog-padding;
|
||||
|
||||
&.adf-centered-header {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.adf-dialog-title {
|
||||
font-size: large;
|
||||
font-weight: 200;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.adf-dialog-header-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
font-size: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.adf-description {
|
||||
padding-top: $dialog-padding;
|
||||
}
|
||||
|
||||
.adf-dialog-content {
|
||||
margin: $dialog-padding 0;
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
max-height: none;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.adf-dialog-header,
|
||||
.adf-dialog-actions {
|
||||
&::after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
left: -$dialog-padding;
|
||||
display: block;
|
||||
height: 0;
|
||||
border-bottom: 1px solid var(--adf-theme-foreground-divider-color);
|
||||
width: calc(100% + $dialog-padding * 2);
|
||||
}
|
||||
}
|
||||
|
||||
.adf-dialog-actions::after {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.adf-dialog-header::after {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.adf-dialog-actions {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-top: $dialog-padding;
|
||||
text-transform: capitalize;
|
||||
min-height: auto;
|
||||
|
||||
// TODO: Update after migration to Angular 15
|
||||
/* stylelint-disable-next-line selector-class-pattern */
|
||||
.mat-button.mat-button-base + .mat-button-base {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
// TODO: Update after migration to Angular 15
|
||||
/* stylelint-disable-next-line selector-class-pattern */
|
||||
.mat-button {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Update after migration to Angular 15
|
||||
/* stylelint-disable-next-line selector-class-pattern */
|
||||
.mat-dialog-container {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
&.adf-large {
|
||||
max-width: calc(56vw - $dialog-padding * 2);
|
||||
max-height: calc(84vh - $dialog-padding * 2);
|
||||
|
||||
@media screen and (min-width: $l-screen) {
|
||||
max-width: calc($dialog-large-l-width - $dialog-padding * 2);
|
||||
}
|
||||
|
||||
@media screen and (min-height: $dialog-large-l-width) {
|
||||
max-height: calc($dialog-large-l-height - $dialog-padding * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: $xs-screen) {
|
||||
max-width: calc(100vw - $dialog-padding * 2);
|
||||
max-height: calc(100vh - $dialog-padding * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: $breakpoint-large-with-additional-buttons-centered) {
|
||||
.adf-additional-actions {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.adf-medium {
|
||||
max-width: calc(36vw - $dialog-padding * 2);
|
||||
max-height: calc(72vh - $dialog-padding * 2);
|
||||
|
||||
@media screen and (min-width: $l-screen) {
|
||||
max-width: calc($dialog-medium-l-width - $dialog-padding * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: $xs-screen) {
|
||||
max-width: calc(100vw - $dialog-padding * 2);
|
||||
max-height: calc(100vh - $dialog-padding * 2);
|
||||
}
|
||||
|
||||
@media screen and (min-height: $dialog-large-l-width) {
|
||||
max-height: calc($dialog-medium-l-height - $dialog-padding * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: $breakpoint-medium-with-additional-buttons-centered) {
|
||||
.adf-additional-actions {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.adf-alert {
|
||||
.adf-centered-title {
|
||||
padding-left: 40px;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.adf-dialog-content {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.adf-dialog-header {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.adf-dialog-header,
|
||||
.adf-dialog-actions {
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
max-width: calc(24vw - $dialog-padding * 2);
|
||||
max-height: calc(40vh - $dialog-padding * 2);
|
||||
|
||||
@media screen and (min-width: $m-screen) {
|
||||
max-width: calc($dialog-small-l-width - $dialog-padding * 2);
|
||||
max-height: calc($dialog-small-l-height - $dialog-padding * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: $s-screen) {
|
||||
max-width: calc($dialog-small-s-width - $dialog-padding * 2);
|
||||
max-height: calc($dialog-small-s-height - $dialog-padding * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: $xs-screen) {
|
||||
max-width: calc(84vw - $dialog-padding * 2);
|
||||
max-height: calc(41vh - $dialog-padding * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-height: $dialog-small-l-height) {
|
||||
max-height: calc(84vh - $dialog-padding * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: $breakpoint-alert-with-additional-buttons-centered) {
|
||||
.adf-additional-actions {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $xs-screen) {
|
||||
.adf-additional-actions {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,259 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ContentTestingModule } from '../../testing/content.testing.module';
|
||||
import { DialogComponent } from './dialog.component';
|
||||
import { DialogData } from './dialog-data.interface';
|
||||
import { DialogSize } from './dialog.model';
|
||||
|
||||
describe('DialogComponent', () => {
|
||||
let component: DialogComponent;
|
||||
let fixture: ComponentFixture<DialogComponent>;
|
||||
let closeButton: HTMLButtonElement;
|
||||
let cancelButton: HTMLButtonElement;
|
||||
let confirmButton: HTMLButtonElement;
|
||||
let dialogContainer: HTMLElement;
|
||||
|
||||
const data: DialogData = {
|
||||
title: 'Title',
|
||||
description: 'Description that can be longer or shorter'
|
||||
};
|
||||
|
||||
const dialogRef = {
|
||||
close: jasmine.createSpy('close')
|
||||
};
|
||||
|
||||
const setupBeforeEach = (dialogOptions: DialogData = data) => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ContentTestingModule],
|
||||
providers: [
|
||||
{ provide: MAT_DIALOG_DATA, useValue: dialogOptions },
|
||||
{ provide: MatDialogRef, useValue: dialogRef }
|
||||
]
|
||||
}).compileComponents();
|
||||
dialogRef.close.calls.reset();
|
||||
fixture = TestBed.createComponent(DialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
||||
confirmButton = fixture.nativeElement.querySelector('[data-automation-id="adf-dialog-actions-confirm"]');
|
||||
closeButton = fixture.nativeElement.querySelector('[data-automation-id="adf-dialog-close-button"]');
|
||||
cancelButton = fixture.nativeElement.querySelector(
|
||||
'[data-automation-id="adf-dialog-actions-cancel"]');
|
||||
dialogContainer = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-dialog-container"]');
|
||||
};
|
||||
|
||||
describe('when init with default data', () => {
|
||||
beforeEach(() => {
|
||||
setupBeforeEach();
|
||||
});
|
||||
|
||||
it('should have default template elements', () => {
|
||||
expect(dialogContainer).toBeDefined();
|
||||
expect(fixture.nativeElement.querySelector('.adf-dialog-header')).toBeDefined();
|
||||
expect(fixture.nativeElement.querySelector('.adf-dialog-content')).toBeDefined();
|
||||
expect(fixture.nativeElement.querySelector('.adf-dialog-actions')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have default values for the dialog', () => {
|
||||
expect(closeButton).toBeDefined();
|
||||
|
||||
expect(dialogContainer.classList).toContain('adf-medium');
|
||||
|
||||
expect(confirmButton.innerText).toBe('COMMON.APPLY');
|
||||
|
||||
expect(cancelButton.innerText).toBe('COMMON.CANCEL');
|
||||
});
|
||||
});
|
||||
|
||||
describe('confirm action', () => {
|
||||
const mockButtonTitle = 'mockTitle';
|
||||
beforeEach(() => {
|
||||
setupBeforeEach({ ...data, confirmButtonTitle: mockButtonTitle});
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should disable confirm button after confirm button was clicked', (done) => {
|
||||
expect(confirmButton.getAttribute('disabled')).toBeFalsy();
|
||||
|
||||
confirmButton.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(confirmButton.getAttribute('disabled')).toBeTruthy();
|
||||
component.isConfirmButtonDisabled$.subscribe((value) => {
|
||||
expect(value).toBeTrue();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should disable confirm button with updated confirmButtonDisabled$', () => {
|
||||
component.isConfirmButtonDisabled$.next(false);
|
||||
|
||||
expect(confirmButton.getAttribute('disabled')).toBeFalsy();
|
||||
|
||||
component.isConfirmButtonDisabled$.next(true);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(confirmButton.getAttribute('disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should close dialog', () => {
|
||||
component.onConfirm();
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set correct button title', () => {
|
||||
expect(component.confirmButtonTitle).toEqual(mockButtonTitle);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cancel action', () => {
|
||||
beforeEach(() => {
|
||||
setupBeforeEach();
|
||||
});
|
||||
|
||||
it('should close dialog when cancel button was clicked', () => {
|
||||
cancelButton.click();
|
||||
fixture.detectChanges();
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should close dialog when close button was clicked', () => {
|
||||
closeButton.click();
|
||||
fixture.detectChanges();
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when isCloseButtonHidden and isCancelButtonHidden set to true', () => {
|
||||
beforeEach(() => {
|
||||
setupBeforeEach({
|
||||
...data,
|
||||
isCloseButtonHidden: true,
|
||||
isCancelButtonHidden: true
|
||||
});
|
||||
});
|
||||
|
||||
it ('should hide close button', () => {
|
||||
expect(closeButton).toBeNull();
|
||||
});
|
||||
|
||||
|
||||
it ('should hide close button', () => {
|
||||
expect(cancelButton).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when dialog has large size', () => {
|
||||
beforeEach(() => {
|
||||
setupBeforeEach({ ...data, dialogSize: DialogSize.Large});
|
||||
});
|
||||
|
||||
it('should have correct dialogSize value', () => {
|
||||
expect(component.dialogSize).toEqual(DialogSize.Large);
|
||||
});
|
||||
|
||||
it(`should contain ${DialogSize.Large} class`, () => {
|
||||
expect(dialogContainer.classList).toContain(DialogSize.Large);
|
||||
});
|
||||
|
||||
it('should not have header and actions border', () => {
|
||||
const headerBorder = fixture.nativeElement.querySelector('.adf-alert .adf-dialog-header::after');
|
||||
const actionsBorder = fixture.nativeElement.querySelector('.adf-alert .adf-dialog-actions::after');
|
||||
|
||||
expect(headerBorder).toBeDefined();
|
||||
expect(actionsBorder).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when dialog has medium size', () => {
|
||||
beforeEach(() => {
|
||||
setupBeforeEach({ ...data, dialogSize: DialogSize.Medium});
|
||||
});
|
||||
|
||||
it('should have correct dialogSize value', () => {
|
||||
expect(component.dialogSize).toEqual(DialogSize.Medium);
|
||||
});
|
||||
|
||||
it(`should contain ${DialogSize.Medium} class`, () => {
|
||||
expect(dialogContainer.classList).toContain(DialogSize.Medium);
|
||||
});
|
||||
|
||||
it('should not have header and actions border', () => {
|
||||
const headerBorder = fixture.nativeElement.querySelector('.adf-alert .adf-dialog-header::after');
|
||||
const actionsBorder = fixture.nativeElement.querySelector('.adf-alert .adf-dialog-actions::after');
|
||||
|
||||
expect(headerBorder).toBeDefined();
|
||||
expect(actionsBorder).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when dialog has alert size', () => {
|
||||
describe('when dialog has not an ican', () => {
|
||||
beforeEach(() => {
|
||||
setupBeforeEach({ ...data, dialogSize: DialogSize.Alert});
|
||||
});
|
||||
|
||||
it('should have correct dialogSize value', () => {
|
||||
expect(component.dialogSize).toEqual(DialogSize.Alert);
|
||||
});
|
||||
|
||||
it(`should contain ${DialogSize.Alert} class`, () => {
|
||||
expect(dialogContainer.classList).toContain(DialogSize.Alert);
|
||||
});
|
||||
|
||||
it('should not have header and actions border', () => {
|
||||
const headerBorder = fixture.nativeElement.querySelector('.adf-alert .adf-dialog-header::after');
|
||||
const actionsBorder = fixture.nativeElement.querySelector('.adf-alert .adf-dialog-actions::after');
|
||||
|
||||
expect(headerBorder).toBeNull();
|
||||
expect(actionsBorder).toBeNull();
|
||||
});
|
||||
|
||||
it('should not center header content', () => {
|
||||
const header = fixture.nativeElement.querySelector('.adf-centered-header');
|
||||
|
||||
expect(header).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when header contains icon', () => {
|
||||
beforeEach(() => {
|
||||
setupBeforeEach({
|
||||
...data,
|
||||
dialogSize: DialogSize.Alert,
|
||||
headerIcon: 'access_time'
|
||||
});
|
||||
});
|
||||
|
||||
it('should have icon element', () => {
|
||||
const headerIcon = fixture.nativeElement.querySelector('.adf-dialog-header-icon');
|
||||
|
||||
expect(headerIcon).toBeDefined();
|
||||
});
|
||||
|
||||
|
||||
it('should center header content', () => {
|
||||
const header = fixture.nativeElement.querySelector('.adf-centered-header');
|
||||
|
||||
expect(header).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,74 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Inject, OnDestroy, ViewEncapsulation } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { DialogData } from './dialog-data.interface';
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
import { DialogSize, DialogSizes } from './dialog.model';
|
||||
import { MaterialModule } from '../../material.module';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'adf-dialog',
|
||||
templateUrl: './dialog.component.html',
|
||||
styleUrls: ['./dialog.component.scss'],
|
||||
imports: [CommonModule, MaterialModule, TranslateModule],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class DialogComponent implements OnDestroy {
|
||||
isConfirmButtonDisabled$ = new BehaviorSubject<boolean>(false);
|
||||
isCloseButtonHidden: boolean;
|
||||
isCancelButtonHidden: boolean;
|
||||
dialogSize: DialogSizes;
|
||||
confirmButtonTitle: string;
|
||||
cancelButtonTitle: string;
|
||||
disableSubmitButton = false;
|
||||
|
||||
private onDestroy$ = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
public data: DialogData,
|
||||
public dialogRef: MatDialogRef<DialogComponent>
|
||||
) {
|
||||
if (data) {
|
||||
this.isCancelButtonHidden = data.isCancelButtonHidden || false;
|
||||
this.isCloseButtonHidden = data.isCloseButtonHidden || false;
|
||||
this.dialogSize = data.dialogSize || DialogSize.Medium;
|
||||
this.confirmButtonTitle = data.confirmButtonTitle || 'COMMON.APPLY';
|
||||
this.cancelButtonTitle = data.cancelButtonTitle || 'COMMON.CANCEL';
|
||||
|
||||
if (data.isConfirmButtonDisabled$) {
|
||||
data.isConfirmButtonDisabled$.pipe(takeUntil(this.onDestroy$)).subscribe((value) => this.isConfirmButtonDisabled$.next(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onConfirm() {
|
||||
this.isConfirmButtonDisabled$.next(true);
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next();
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
24
lib/content-services/src/lib/dialogs/dialog/dialog.model.ts
Normal file
24
lib/content-services/src/lib/dialogs/dialog/dialog.model.ts
Normal file
@ -0,0 +1,24 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export const DialogSize = {
|
||||
Large: 'adf-large',
|
||||
Medium: 'adf-medium',
|
||||
Alert: 'adf-alert'
|
||||
} as const;
|
||||
|
||||
export type DialogSizes = typeof DialogSize[keyof typeof DialogSize];
|
20
lib/content-services/src/lib/dialogs/dialog/index.ts
Normal file
20
lib/content-services/src/lib/dialogs/dialog/index.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './dialog-data.interface';
|
||||
export * from './dialog.model';
|
||||
export * from './dialog.component';
|
@ -22,9 +22,9 @@ export * from './category-selector.dialog';
|
||||
|
||||
export * from './dialog.module';
|
||||
export * from './library/library.dialog';
|
||||
export * from './dialog';
|
||||
|
||||
export * from './download-zip/download-zip.dialog';
|
||||
export * from './download-zip/download-zip.dialog.module';
|
||||
|
||||
|
||||
export * from './folder-name.validators';
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "تطبيق",
|
||||
"CANCEL": "إلغاء"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "استعادة",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Použít",
|
||||
"CANCEL": "Zrušit"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Obnovit",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Anvend",
|
||||
"CANCEL": "Annuller"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Gendan",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Anwenden",
|
||||
"CANCEL": "Abbrechen"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Wiederherstellen",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Apply",
|
||||
"CANCEL": "Cancel"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Restore",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Aplicar",
|
||||
"CANCEL": "Cancelar"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Restaurar",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Käytä",
|
||||
"CANCEL": "Peruuta"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Palauta",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Appliquer",
|
||||
"CANCEL": "Annuler"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Restaurer",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Applica",
|
||||
"CANCEL": "Annulla"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Ripristina",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "適用",
|
||||
"CANCEL": "キャンセル"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "復元",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Bruk",
|
||||
"CANCEL": "Avbryt"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Gjenopprett",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Toepassen",
|
||||
"CANCEL": "Annuleren"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Herstellen",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Zastosuj",
|
||||
"CANCEL": "Anuluj"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Przywróć",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Aplicar",
|
||||
"CANCEL": "Cancelar"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Restaurar",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Применить",
|
||||
"CANCEL": "Отмена"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Восстановить",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "Tillämpa",
|
||||
"CANCEL": "Avbryt"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "Återställ",
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"COMMON": {
|
||||
"APPLY": "应用",
|
||||
"CANCEL": "取消"
|
||||
},
|
||||
"ADF_VERSION_LIST": {
|
||||
"ACTIONS": {
|
||||
"RESTORE": "恢复",
|
||||
|
Loading…
x
Reference in New Issue
Block a user