mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[ACS-3744] Folder rules styling fixes (#2753)
* Folder rules styling fixes * Fix not showing isInheritable in read only
This commit is contained in:
parent
eee6feca1a
commit
e354ec3891
@ -8,7 +8,7 @@
|
||||
"CREATE": "Create",
|
||||
"CREATE_TITLE": "Create a rule",
|
||||
"UPDATE": "Update",
|
||||
"UPDATE_TITLE": "Update a rule"
|
||||
"UPDATE_TITLE": "Edit a rule"
|
||||
},
|
||||
"RULE_DETAILS": {
|
||||
"LABEL": {
|
||||
@ -38,7 +38,7 @@
|
||||
"IS_ASYNCHRONOUS": "Run rule in the background",
|
||||
"DISABLE_RULE": "Disable rule",
|
||||
"ERROR_SCRIPT": "If errors occur run script",
|
||||
"SELECT_ACTION": "Select action"
|
||||
"NO_SCRIPT": "None"
|
||||
},
|
||||
"COMPARATORS": {
|
||||
"EQUALS": "(=) Equals",
|
||||
|
@ -37,7 +37,7 @@ import { RuleSimpleConditionUiComponent } from './rule-details/conditions/rule-s
|
||||
import { GenericErrorModule, PageLayoutModule } from '@alfresco/aca-shared';
|
||||
import { BreadcrumbModule, DocumentListModule } from '@alfresco/adf-content-services';
|
||||
import { RuleListItemUiComponent } from './rules-list/rule/rule-list-item.ui-component';
|
||||
import { RulesListUiComponent } from './rules-list/rules-list.ui-component';
|
||||
import { RuleListUiComponent } from './rules-list/rule-list.ui-component';
|
||||
import { RuleTriggersUiComponent } from './rule-details/triggers/rule-triggers.ui-component';
|
||||
import { RuleOptionsUiComponent } from './rule-details/options/rule-options.ui-component';
|
||||
import { RuleActionListUiComponent } from './rule-details/actions/rule-action-list.ui-component';
|
||||
@ -70,7 +70,7 @@ const routes: Routes = [
|
||||
RuleCompositeConditionUiComponent,
|
||||
RuleDetailsUiComponent,
|
||||
RuleSimpleConditionUiComponent,
|
||||
RulesListUiComponent,
|
||||
RuleListUiComponent,
|
||||
RuleListItemUiComponent,
|
||||
RuleTriggersUiComponent,
|
||||
RuleOptionsUiComponent
|
||||
|
@ -30,14 +30,22 @@
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<div class="aca-manage-rules__container" *ngIf="(rules$ | async).length > 0 ; else emptyContent">
|
||||
<aca-rules-list [rules]="rules$ | async" (ruleSelected)="onRuleSelected($event)"
|
||||
[selectedRule]="selectedRule" [nodeId]="nodeId"></aca-rules-list>
|
||||
<aca-rule-list [rules]="rules$ | async" (ruleSelected)="onRuleSelected($event)"
|
||||
[selectedRule]="selectedRule" [nodeId]="nodeId"></aca-rule-list>
|
||||
<div class="aca-manage-rules__container__rule-details">
|
||||
<div class="aca-manage-rules__container__preview">
|
||||
<div class="aca-manage-rules__container__preview__toolbar">
|
||||
<span>{{ selectedRule.name }}</span>
|
||||
<div class="aca-manage-rules__container__preview__toolbar__buttons">
|
||||
<button mat-icon-button (click)="onRuleDelete()" id="delete-rule-btn">
|
||||
|
||||
<div class="aca-manage-rules__container__rule-details__header">
|
||||
<div class="aca-manage-rules__container__rule-details__header__title">
|
||||
<div class="aca-manage-rules__container__rule-details__header__title__name">
|
||||
{{ selectedRule.name }}
|
||||
</div>
|
||||
<div class="aca-manage-rules__container__rule-details__header__title__description">
|
||||
{{ selectedRule.description }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="aca-manage-rules__container__rule-details__header__buttons">
|
||||
<button mat-stroked-button (click)="onRuleDelete()" id="delete-rule-btn">
|
||||
<mat-icon>delete_outline</mat-icon>
|
||||
</button>
|
||||
<button mat-stroked-button (click)="onRuleUpdate()" id="edit-rule-btn">
|
||||
@ -45,8 +53,8 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p>{{ selectedRule.description }}</p>
|
||||
</div>
|
||||
|
||||
<div class="aca-manage-rules__container__rule-details__content">
|
||||
<aca-rule-details
|
||||
[actionDefinitions]="actionDefinitions$ | async"
|
||||
[readOnly]="true"
|
||||
@ -55,6 +63,7 @@
|
||||
</aca-rule-details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #emptyContent>
|
||||
<adf-empty-content
|
||||
|
@ -17,40 +17,65 @@
|
||||
|
||||
&__container {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(200px,1fr) 3fr;
|
||||
padding: 32px;
|
||||
overflow: scroll;
|
||||
grid-template-columns: minmax(250px,1fr) 3fr;
|
||||
padding: 20px;
|
||||
gap: 12px;
|
||||
overflow-y: auto;
|
||||
|
||||
&__preview {
|
||||
padding: 0 20px;
|
||||
&__rule-details {
|
||||
border: 1px solid var(--theme-border-color);
|
||||
border-radius: 12px;
|
||||
overflow-y: scroll;
|
||||
|
||||
&__toolbar {
|
||||
&__header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 20px;
|
||||
border-bottom: 1px solid var(--theme-border-color);
|
||||
background-color: var(--theme-background-color);
|
||||
|
||||
span {
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
&__title {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
&__name {
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&__description {
|
||||
font-size: 0.8em;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
&__buttons {
|
||||
display: inline-block;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
gap: 4px;
|
||||
|
||||
button {
|
||||
color: var(--theme-text-color);
|
||||
|
||||
&#delete-rule-btn {
|
||||
padding: 0 8px;
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
p {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
.mat-icon {
|
||||
// Something pops out of this button for some reason so this is necessary
|
||||
overflow: hidden !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__rule-details {
|
||||
overflow-x: scroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ describe('ManageRulesSmartComponent', () => {
|
||||
|
||||
expect(folderRulesService.loadRules).toHaveBeenCalledOnceWith(component.nodeId);
|
||||
|
||||
const rules = debugElement.queryAll(By.css('.aca-rule'));
|
||||
const rules = debugElement.queryAll(By.css('.aca-rule-list-item'));
|
||||
const ruleDetails = debugElement.queryAll(By.css('aca-rule-details'));
|
||||
const deleteRuleBtn = debugElement.query(By.css('#delete-rule-btn'));
|
||||
|
||||
|
@ -41,3 +41,20 @@ export interface Rule {
|
||||
conditions: RuleCompositeCondition;
|
||||
actions: RuleAction[];
|
||||
}
|
||||
|
||||
export interface RuleOptions {
|
||||
isEnabled: boolean;
|
||||
isInheritable: boolean;
|
||||
isAsynchronous: boolean;
|
||||
errorScript: string;
|
||||
}
|
||||
|
||||
export interface RuleForForm {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
triggers: RuleTrigger[];
|
||||
conditions: RuleCompositeCondition;
|
||||
actions: RuleAction[];
|
||||
options: RuleOptions;
|
||||
}
|
||||
|
@ -1,34 +1,36 @@
|
||||
<div class="options-list" [formGroup]="form">
|
||||
<div class="options-list__asynchronous">
|
||||
<ng-container [formGroup]="form">
|
||||
<div class="aca-rule-options__option" *ngIf="!readOnly || isAsynchronousChecked">
|
||||
<mat-checkbox
|
||||
formControlName="isAsynchronous"
|
||||
(change)="toggleScriptSelector()"
|
||||
[attr.data-automation-id]="'rule-option-checkbox-asynchronous'">
|
||||
(change)="toggleErrorScriptDropdown($event)"
|
||||
data-automation-id="rule-option-checkbox-asynchronous">
|
||||
{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.IS_ASYNCHRONOUS' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="select-action" *ngIf="!preview">
|
||||
<span>{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.ERROR_SCRIPT' | translate}}:</span>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select [disabled]="disableSelector" formControlName="errorScript"
|
||||
placeholder="{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.SELECT_ACTION' | translate}}"
|
||||
[attr.data-automation-id]="'rule-option-select-errorScript'">
|
||||
<mat-option>{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.SELECT_ACTION' | translate}}</mat-option>
|
||||
<mat-select
|
||||
formControlName="errorScript"
|
||||
placeholder="{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.ERROR_SCRIPT' | translate}}"
|
||||
data-automation-id="rule-option-select-errorScript">
|
||||
<mat-option value="">{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.NO_SCRIPT' | translate }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="options-list__rest">
|
||||
|
||||
|
||||
<div class="aca-rule-options__option" *ngIf="!readOnly || isInheritableChecked">
|
||||
<mat-checkbox
|
||||
formControlName="isInheritable"
|
||||
[attr.data-automation-id]="'rule-option-checkbox-inheritable'">
|
||||
data-automation-id="rule-option-checkbox-inheritable">
|
||||
{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.IS_INHERITABLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="aca-rule-options__option" *ngIf="!readOnly">
|
||||
<mat-checkbox
|
||||
[attr.data-automation-id]="'rule-option-checkbox-enabled'"
|
||||
[checked]="!form.get('isEnabled').value" *ngIf="!preview"
|
||||
(change)="form.get('isEnabled').setValue(!$event.checked)">
|
||||
formControlName="isDisabled"
|
||||
data-automation-id="rule-option-checkbox-disabled">
|
||||
{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.DISABLE_RULE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
@ -1,20 +1,14 @@
|
||||
.options-list {
|
||||
.aca-rule-options {
|
||||
display: flex;
|
||||
column-gap: 25px;
|
||||
padding: 0.75em 0;
|
||||
flex-direction: row;
|
||||
gap: 24px;
|
||||
|
||||
&__rest {
|
||||
&__option {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
column-gap: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
.select-action {
|
||||
margin-left: 5px;
|
||||
margin-top: 12px;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&.read-only .mat-checkbox-inner-container {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -23,16 +23,16 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed, inject, waitForAsync } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, DebugElement } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule, FormBuilder } from '@angular/forms';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { RuleOptionsUiComponent } from './rule-options.ui-component';
|
||||
import { CoreTestingModule } from '@alfresco/adf-core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
describe('RuleOptionsUiComponent', () => {
|
||||
let component: RuleOptionsUiComponent;
|
||||
let fixture: ComponentFixture<RuleOptionsUiComponent>;
|
||||
let component: RuleOptionsUiComponent;
|
||||
|
||||
const getByDataAutomationId = (dataAutomationId: string): DebugElement =>
|
||||
fixture.debugElement.query(By.css(`[data-automation-id="${dataAutomationId}"]`));
|
||||
@ -41,54 +41,75 @@ describe('RuleOptionsUiComponent', () => {
|
||||
((getByDataAutomationId(dataAutomationId).nativeElement as HTMLElement).children[0] as HTMLElement).click();
|
||||
};
|
||||
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
imports: [FormsModule, ReactiveFormsModule, CoreTestingModule],
|
||||
declarations: [RuleOptionsUiComponent]
|
||||
}).compileComponents();
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
beforeEach(inject([FormBuilder], (fb: FormBuilder) => {
|
||||
fixture = TestBed.createComponent(RuleOptionsUiComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
component.form = fb.group({
|
||||
isAsynchronous: [false],
|
||||
isInheritable: [false],
|
||||
isEnabled: [true],
|
||||
errorScript: ['']
|
||||
component.writeValue({
|
||||
isEnabled: true,
|
||||
isInheritable: false,
|
||||
isAsynchronous: false,
|
||||
errorScript: ''
|
||||
});
|
||||
});
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
it('checkboxes should be falsy by default, selector is disabled', () => {
|
||||
expect(component).toBeTruthy();
|
||||
it('should be able to write to the component', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getByDataAutomationId('rule-option-checkbox-asynchronous').componentInstance.checked).toBeFalsy();
|
||||
expect(getByDataAutomationId('rule-option-checkbox-inheritable').componentInstance.checked).toBeFalsy();
|
||||
expect(getByDataAutomationId('rule-option-checkbox-enabled').componentInstance.checked).toBeFalsy();
|
||||
expect(getByDataAutomationId('rule-option-checkbox-disabled').componentInstance.checked).toBeFalsy();
|
||||
expect(getByDataAutomationId('rule-option-select-errorScript').componentInstance.disabled).toBeTruthy();
|
||||
|
||||
component.writeValue({
|
||||
isEnabled: false,
|
||||
isInheritable: true,
|
||||
isAsynchronous: true,
|
||||
errorScript: ''
|
||||
});
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getByDataAutomationId('rule-option-checkbox-asynchronous').componentInstance.checked).toBeTruthy();
|
||||
expect(getByDataAutomationId('rule-option-checkbox-inheritable').componentInstance.checked).toBeTruthy();
|
||||
expect(getByDataAutomationId('rule-option-checkbox-disabled').componentInstance.checked).toBeTruthy();
|
||||
expect(getByDataAutomationId('rule-option-select-errorScript').componentInstance.disabled).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should enable selector when async checkbox is truthy', () => {
|
||||
toggleMatCheckbox('rule-option-checkbox-asynchronous');
|
||||
|
||||
fixture.detectChanges();
|
||||
toggleMatCheckbox('rule-option-checkbox-asynchronous');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getByDataAutomationId('rule-option-checkbox-asynchronous').componentInstance.checked).toBeTruthy();
|
||||
expect(getByDataAutomationId('rule-option-select-errorScript').componentInstance.disabled).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should hide some fields in preview mode', () => {
|
||||
component.preview = true;
|
||||
it('should hide disabled checkbox and unselected checkboxes in read-only mode', () => {
|
||||
component.readOnly = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getByDataAutomationId('rule-option-checkbox-asynchronous')).toBeFalsy();
|
||||
expect(getByDataAutomationId('rule-option-checkbox-inheritable')).toBeFalsy();
|
||||
expect(getByDataAutomationId('rule-option-checkbox-enabled')).toBeFalsy();
|
||||
expect(getByDataAutomationId('rule-option-select-errorScript')).toBeFalsy();
|
||||
|
||||
component.writeValue({
|
||||
isEnabled: false,
|
||||
isInheritable: true,
|
||||
isAsynchronous: true,
|
||||
errorScript: ''
|
||||
});
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getByDataAutomationId('rule-option-checkbox-asynchronous')).toBeTruthy();
|
||||
expect(getByDataAutomationId('rule-option-checkbox-asynchronous')).toBeTruthy();
|
||||
expect(getByDataAutomationId('rule-option-checkbox-inheritable')).toBeTruthy();
|
||||
expect(getByDataAutomationId('rule-option-checkbox-enabled')).toBeFalsy();
|
||||
expect(getByDataAutomationId('rule-option-select-errorScript')).toBeFalsy();
|
||||
expect(getByDataAutomationId('rule-option-select-errorScript')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -23,20 +23,98 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { Component, forwardRef, HostBinding, OnDestroy, ViewEncapsulation } from '@angular/core';
|
||||
import { AbstractControl, ControlValueAccessor, FormControl, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { MatCheckboxChange } from '@angular/material/checkbox';
|
||||
import { RuleOptions } from '../../model/rule.model';
|
||||
|
||||
@Component({
|
||||
selector: 'aca-rule-options',
|
||||
templateUrl: 'rule-options.ui-component.html',
|
||||
styleUrls: ['rule-options.ui-component.scss']
|
||||
styleUrls: ['rule-options.ui-component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: { class: 'aca-rule-options' },
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
multi: true,
|
||||
useExisting: forwardRef(() => RuleOptionsUiComponent)
|
||||
}
|
||||
]
|
||||
})
|
||||
export class RuleOptionsUiComponent {
|
||||
@Input() form: FormGroup;
|
||||
@Input() preview: boolean;
|
||||
disableSelector = true;
|
||||
export class RuleOptionsUiComponent implements ControlValueAccessor, OnDestroy {
|
||||
form = new FormGroup({
|
||||
isDisabled: new FormControl(),
|
||||
isInheritable: new FormControl(),
|
||||
isAsynchronous: new FormControl(),
|
||||
errorScript: new FormControl()
|
||||
});
|
||||
|
||||
toggleScriptSelector() {
|
||||
this.disableSelector = !this.disableSelector;
|
||||
formSubscription = this.form.valueChanges.subscribe((value: any) => {
|
||||
this.onChange({
|
||||
isEnabled: !value.isDisabled,
|
||||
isInheritable: value.isInheritable,
|
||||
isAsynchronous: value.isAsynchronous,
|
||||
errorScript: value.errorScript ?? ''
|
||||
});
|
||||
this.onTouch();
|
||||
});
|
||||
|
||||
@HostBinding('class.read-only')
|
||||
readOnly = false;
|
||||
|
||||
onChange: (options: RuleOptions) => void = () => undefined;
|
||||
onTouch: () => void = () => undefined;
|
||||
|
||||
get isAsynchronousChecked(): boolean {
|
||||
return this.form.get('isAsynchronous').value;
|
||||
}
|
||||
get isInheritableChecked(): boolean {
|
||||
return this.form.get('isInheritable').value;
|
||||
}
|
||||
|
||||
writeValue(options: RuleOptions) {
|
||||
const isAsynchronousFormControl = this.form.get('isAsynchronous');
|
||||
const errorScriptFormControl = this.form.get('errorScript');
|
||||
this.form.get('isDisabled').setValue(!options.isEnabled);
|
||||
this.form.get('isInheritable').setValue(options.isInheritable);
|
||||
this.form.get('isAsynchronous').setValue(options.isAsynchronous);
|
||||
errorScriptFormControl.setValue(options.errorScript ?? '');
|
||||
if (isAsynchronousFormControl.value) {
|
||||
errorScriptFormControl.enable();
|
||||
} else {
|
||||
errorScriptFormControl.disable();
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: () => void) {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouch = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
if (isDisabled) {
|
||||
this.form.disable();
|
||||
this.readOnly = true;
|
||||
} else {
|
||||
this.form.enable();
|
||||
this.readOnly = false;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.formSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
toggleErrorScriptDropdown(value: MatCheckboxChange) {
|
||||
const formControl: AbstractControl = this.form.get('errorScript');
|
||||
if (value.checked) {
|
||||
formControl.enable();
|
||||
} else {
|
||||
formControl.disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form class="aca-rule-details__form" [formGroup]="form">
|
||||
<form class="aca-rule-details__form" [ngClass]="{ 'read-only': readOnly }" [formGroup]="form">
|
||||
|
||||
<ng-container *ngIf="!preview">
|
||||
<div class="aca-rule-details__form__row">
|
||||
<div class="aca-rule-details__form__row aca-rule-details__form__name">
|
||||
<label for="rule-details-name-input">{{ 'ACA_FOLDER_RULES.RULE_DETAILS.LABEL.NAME' | translate }}</label>
|
||||
<div>
|
||||
<mat-form-field floatLabel='never'>
|
||||
@ -14,7 +14,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="aca-rule-details__form__row">
|
||||
<div class="aca-rule-details__form__row aca-rule-details__form__description">
|
||||
<label for="rule-details-description-textarea">{{ 'ACA_FOLDER_RULES.RULE_DETAILS.LABEL.DESCRIPTION' | translate }}</label>
|
||||
<div>
|
||||
<mat-form-field floatLabel='never'>
|
||||
@ -28,8 +28,6 @@
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="aca-rule-details__form__row aca-rule-details__form__triggers">
|
||||
<div class="label">{{ 'ACA_FOLDER_RULES.RULE_DETAILS.LABEL.WHEN' | translate }}</div>
|
||||
<div>
|
||||
@ -38,12 +36,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="aca-rule-details__form__conditions">
|
||||
<aca-rule-composite-condition formControlName="conditions"></aca-rule-composite-condition>
|
||||
<mat-error class="rule-details-error">{{ getErrorMessage(conditions) | translate }}</mat-error>
|
||||
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<div class="aca-rule-details__form__row aca-rule-details__form__actions">
|
||||
<div class="label">{{ 'ACA_FOLDER_RULES.RULE_DETAILS.LABEL.PERFORM_ACTIONS' | translate }}</div>
|
||||
@ -55,11 +51,9 @@
|
||||
</aca-rule-action-list>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="aca-rule-details__form__row">
|
||||
<div class="aca-rule-details__form__row" *ngIf="showOptionsSection">
|
||||
<div class="label">{{ 'ACA_FOLDER_RULES.RULE_DETAILS.LABEL.OPTIONS' | translate }}</div>
|
||||
<aca-rule-options [form]="form" [preview]="preview" data-automation-id="rule-details-options-component"></aca-rule-options>
|
||||
<aca-rule-options formControlName="options" data-automation-id="rule-details-options-component"></aca-rule-options>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
@ -1,9 +1,31 @@
|
||||
.aca-rule-details {
|
||||
&__form {
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
|
||||
& > div {
|
||||
padding: 8px 20px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow-x: auto;
|
||||
|
||||
&:not(:nth-child(1)) {
|
||||
border-top: 1px solid var(--theme-border-color);
|
||||
}
|
||||
|
||||
&.aca-rule-details__form__name {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
&.aca-rule-details__form__description {
|
||||
padding-top: 0;
|
||||
border: none;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
&__row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
|
||||
& > label, & > .label {
|
||||
@ -11,7 +33,7 @@
|
||||
width: 20%;
|
||||
min-width: 100px;
|
||||
max-width: 150px;
|
||||
padding-top: 0.75em;
|
||||
padding: 0.75em 0;
|
||||
}
|
||||
|
||||
& > div {
|
||||
@ -19,6 +41,7 @@
|
||||
|
||||
mat-form-field {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
font-size: inherit;
|
||||
|
||||
.mat-form-field-infix {
|
||||
@ -28,22 +51,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__triggers {
|
||||
padding: 0.75em 0;
|
||||
&__conditions {
|
||||
width: 100%;
|
||||
|
||||
& > .label {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid var(--theme-border-color);
|
||||
}
|
||||
|
||||
*:disabled, .mat-select-disabled .mat-select-value {
|
||||
& > .rule-details-error {
|
||||
margin-left: 16px;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 4em;
|
||||
@ -54,15 +69,20 @@
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
& > .aca-rule-composite-condition + .rule-details-error {
|
||||
margin-left: 16px;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
.aca-rule-action-list {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.read-only, .mat-form-field-disabled {
|
||||
.mat-form-field-underline, .mat-select-arrow-wrapper {
|
||||
display: none;
|
||||
}
|
||||
|
||||
*:disabled, .mat-select-disabled .mat-select-value {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ import { Rule } from '../model/rule.model';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { RuleCompositeConditionUiComponent } from './conditions/rule-composite-condition.ui-component';
|
||||
import { RuleTriggersUiComponent } from './triggers/rule-triggers.ui-component';
|
||||
import { MatCheckbox } from '@angular/material/checkbox';
|
||||
import { RuleOptionsUiComponent } from './options/rule-options.ui-component';
|
||||
import { RuleActionListUiComponent } from './actions/rule-action-list.ui-component';
|
||||
import { RuleActionUiComponent } from './actions/rule-action.ui-component';
|
||||
@ -46,7 +45,8 @@ describe('RuleDetailsUiComponent', () => {
|
||||
triggers: ['update', 'outbound'],
|
||||
isAsynchronous: true,
|
||||
isInheritable: true,
|
||||
isEnabled: true
|
||||
isEnabled: true,
|
||||
errorScript: ''
|
||||
};
|
||||
|
||||
const getHtmlElement = <T>(dataAutomationId: string) =>
|
||||
@ -79,16 +79,17 @@ describe('RuleDetailsUiComponent', () => {
|
||||
const nameInput = getHtmlElement<HTMLInputElement>('rule-details-name-input');
|
||||
const descriptionTextarea = getHtmlElement<HTMLTextAreaElement>('rule-details-description-textarea');
|
||||
const ruleTriggersComponent = getComponentInstance<RuleTriggersUiComponent>('rule-details-triggers-component');
|
||||
const ruleOptionAsynchronous = getComponentInstance<MatCheckbox>('rule-option-checkbox-asynchronous');
|
||||
const ruleOptionInheritable = getComponentInstance<MatCheckbox>('rule-option-checkbox-inheritable');
|
||||
const ruleOptionDisabled = getComponentInstance<MatCheckbox>('rule-option-checkbox-enabled');
|
||||
const ruleOptionsComponent = getComponentInstance<RuleOptionsUiComponent>('rule-details-options-component');
|
||||
|
||||
expect(nameInput.value).toBe(testValue.name);
|
||||
expect(descriptionTextarea.value).toBe(testValue.description);
|
||||
expect(ruleTriggersComponent.value).toEqual(testValue.triggers);
|
||||
expect(ruleOptionAsynchronous.checked).toBe(testValue.isAsynchronous);
|
||||
expect(ruleOptionInheritable.checked).toBe(testValue.isInheritable);
|
||||
expect(ruleOptionDisabled.checked).toBe(!testValue.isEnabled);
|
||||
expect(ruleOptionsComponent.form.value).toEqual({
|
||||
isDisabled: !testValue.isEnabled,
|
||||
isInheritable: testValue.isInheritable,
|
||||
isAsynchronous: testValue.isAsynchronous,
|
||||
errorScript: testValue.errorScript
|
||||
});
|
||||
});
|
||||
|
||||
it('should modify the form if the value input property is modified', () => {
|
||||
@ -109,38 +110,46 @@ describe('RuleDetailsUiComponent', () => {
|
||||
});
|
||||
|
||||
it('should be editable if not read-only', () => {
|
||||
component.value = testValue;
|
||||
component.readOnly = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
const nameInput = getHtmlElement<HTMLInputElement>('rule-details-name-input');
|
||||
const descriptionTextarea = getHtmlElement<HTMLTextAreaElement>('rule-details-description-textarea');
|
||||
const ruleTriggersComponent = getComponentInstance<RuleTriggersUiComponent>('rule-details-triggers-component');
|
||||
const ruleOptionAsynchronous = getComponentInstance<MatCheckbox>('rule-option-checkbox-asynchronous');
|
||||
const ruleOptionInheritable = getComponentInstance<MatCheckbox>('rule-option-checkbox-inheritable');
|
||||
const ruleOptionDisabled = getComponentInstance<MatCheckbox>('rule-option-checkbox-enabled');
|
||||
const ruleOptionsComponent = getComponentInstance<RuleOptionsUiComponent>('rule-details-options-component');
|
||||
|
||||
expect(nameInput.disabled).toBeFalsy();
|
||||
expect(descriptionTextarea.disabled).toBeFalsy();
|
||||
expect(ruleTriggersComponent.readOnly).toBeFalsy();
|
||||
expect(ruleOptionAsynchronous.disabled).toBeFalsy();
|
||||
expect(ruleOptionInheritable.disabled).toBeFalsy();
|
||||
expect(ruleOptionDisabled.disabled).toBeFalsy();
|
||||
expect(ruleOptionsComponent.readOnly).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should not be editable if read-only', () => {
|
||||
component.value = testValue;
|
||||
component.readOnly = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const nameInput = getHtmlElement<HTMLInputElement>('rule-details-name-input');
|
||||
const descriptionTextarea = getHtmlElement<HTMLTextAreaElement>('rule-details-description-textarea');
|
||||
const ruleTriggersComponent = getComponentInstance<RuleTriggersUiComponent>('rule-details-triggers-component');
|
||||
const ruleOptionAsynchronous = getComponentInstance<MatCheckbox>('rule-option-checkbox-asynchronous');
|
||||
const ruleOptionInheritable = getComponentInstance<MatCheckbox>('rule-option-checkbox-inheritable');
|
||||
const ruleOptionsComponent = getComponentInstance<RuleOptionsUiComponent>('rule-details-options-component');
|
||||
|
||||
expect(nameInput.disabled).toBeTruthy();
|
||||
expect(descriptionTextarea.disabled).toBeTruthy();
|
||||
expect(ruleTriggersComponent.readOnly).toBeTruthy();
|
||||
expect(ruleOptionAsynchronous.disabled).toBeTruthy();
|
||||
expect(ruleOptionInheritable.disabled).toBeTruthy();
|
||||
expect(ruleOptionsComponent.readOnly).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should hide the options section entirely in read-only mode if it has no selected options', () => {
|
||||
component.value = {
|
||||
...testValue,
|
||||
isInheritable: false,
|
||||
isAsynchronous: false
|
||||
};
|
||||
component.readOnly = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getComponentInstance<RuleOptionsUiComponent>('rule-details-options-component')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
@ -27,7 +27,7 @@ import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsul
|
||||
import { AbstractControl, UntypedFormGroup, UntypedFormControl, Validators } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators';
|
||||
import { Rule } from '../model/rule.model';
|
||||
import { Rule, RuleForForm } from '../model/rule.model';
|
||||
import { ruleCompositeConditionValidator } from './validators/rule-composite-condition.validator';
|
||||
import { FolderRulesService } from '../services/folder-rules.service';
|
||||
import { ActionDefinitionTransformed } from '../model/rule-action.model';
|
||||
@ -57,28 +57,38 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
}
|
||||
private _initialValue: Partial<Rule> = FolderRulesService.emptyRule;
|
||||
private _initialValue: RuleForForm = FolderRulesService.emptyRuleForForm;
|
||||
@Input()
|
||||
get value(): Partial<Rule> {
|
||||
return this.form ? this.form.value : this._initialValue;
|
||||
let value = this.form ? this.form.value : this._initialValue;
|
||||
if (value.options) {
|
||||
value = {
|
||||
...value,
|
||||
...(value.options ?? FolderRulesService.emptyRuleOptions)
|
||||
};
|
||||
delete value.options;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
set value(newValue: Partial<Rule>) {
|
||||
newValue = {
|
||||
const newValueForForm: RuleForForm = {
|
||||
id: newValue.id || FolderRulesService.emptyRule.id,
|
||||
name: newValue.name || FolderRulesService.emptyRule.name,
|
||||
description: newValue.description || FolderRulesService.emptyRule.description,
|
||||
triggers: newValue.triggers || FolderRulesService.emptyRule.triggers,
|
||||
conditions: newValue.conditions || FolderRulesService.emptyRule.conditions,
|
||||
isAsynchronous: newValue.isAsynchronous || FolderRulesService.emptyRule.isAsynchronous,
|
||||
errorScript: newValue.errorScript || FolderRulesService.emptyRule.errorScript,
|
||||
isInheritable: newValue.isInheritable || FolderRulesService.emptyRule.isInheritable,
|
||||
actions: newValue.actions || FolderRulesService.emptyRule.actions,
|
||||
options: {
|
||||
isEnabled: typeof newValue.isInheritable == 'boolean' ? newValue.isEnabled : FolderRulesService.emptyRule.isEnabled,
|
||||
actions: newValue.actions || FolderRulesService.emptyRule.actions
|
||||
isInheritable: newValue.isInheritable || FolderRulesService.emptyRule.isInheritable,
|
||||
isAsynchronous: newValue.isAsynchronous || FolderRulesService.emptyRule.isAsynchronous,
|
||||
errorScript: newValue.errorScript || FolderRulesService.emptyRule.errorScript
|
||||
}
|
||||
};
|
||||
if (this.form) {
|
||||
this.form.setValue(newValue);
|
||||
this.form.setValue(newValueForForm);
|
||||
} else {
|
||||
this._initialValue = newValue;
|
||||
this._initialValue = newValueForForm;
|
||||
}
|
||||
}
|
||||
@Input()
|
||||
@ -108,17 +118,9 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
|
||||
get conditions(): UntypedFormControl {
|
||||
return this.form.get('conditions') as UntypedFormControl;
|
||||
}
|
||||
get isAsynchronous(): UntypedFormControl {
|
||||
return this.form.get('isAsynchronous') as UntypedFormControl;
|
||||
}
|
||||
get errorScript(): UntypedFormControl {
|
||||
return this.form.get('errorScript') as UntypedFormControl;
|
||||
}
|
||||
get isInheritable(): UntypedFormControl {
|
||||
return this.form.get('isInheritable') as UntypedFormControl;
|
||||
}
|
||||
get isEnabled(): UntypedFormControl {
|
||||
return this.form.get('isEnabled') as UntypedFormControl;
|
||||
|
||||
get showOptionsSection(): boolean {
|
||||
return !this.readOnly || this.value.isAsynchronous || this.value.isInheritable;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
@ -136,11 +138,13 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
|
||||
},
|
||||
ruleCompositeConditionValidator()
|
||||
),
|
||||
isAsynchronous: new UntypedFormControl(this.value.isAsynchronous),
|
||||
errorScript: new UntypedFormControl(this.value.errorScript),
|
||||
isInheritable: new UntypedFormControl(this.value.isInheritable),
|
||||
isEnabled: new UntypedFormControl(this.value.isEnabled),
|
||||
actions: new UntypedFormControl(this.value.actions, [Validators.required, ruleActionsValidator(this.actionDefinitions)])
|
||||
actions: new UntypedFormControl(this.value.actions, [Validators.required, ruleActionsValidator(this.actionDefinitions)]),
|
||||
options: new UntypedFormControl({
|
||||
isEnabled: this.value.isEnabled,
|
||||
isInheritable: this.value.isInheritable,
|
||||
isAsynchronous: this.value.isAsynchronous,
|
||||
errorScript: this.value.errorScript
|
||||
})
|
||||
});
|
||||
this.readOnly = this._readOnly;
|
||||
|
||||
@ -155,8 +159,8 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
this.formValidationChanged.emit(this.form.valid);
|
||||
|
||||
this.form.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe((newFormValue: any) => {
|
||||
this.formValueChanged.emit(newFormValue);
|
||||
this.form.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
|
||||
this.formValueChanged.emit(this.value);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
<mat-checkbox
|
||||
[attr.data-automation-id]="'rule-trigger-checkbox-' + trigger | lowercase"
|
||||
[checked]="isTriggerChecked(trigger)"
|
||||
[disabled]="readOnly"
|
||||
(change)="onTriggerChange(trigger, $event.checked)">
|
||||
{{ 'ACA_FOLDER_RULES.RULE_DETAILS.TRIGGERS.' + trigger | uppercase | translate }}
|
||||
</mat-checkbox>
|
||||
|
@ -57,7 +57,7 @@ export class RuleTriggersUiComponent implements ControlValueAccessor {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: any) {
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouch = fn;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
<div class="aca-rules-list" >
|
||||
<aca-rule-list-item
|
||||
matRipple matRippleColor="hsla(0,0%,0%,0.05)"
|
||||
*ngFor="let rule of rules"
|
||||
[rule]="rule"
|
||||
[isSelected]="isSelected(rule)"
|
||||
[nodeId]="nodeId"
|
||||
(click)="onRuleClicked(rule)">
|
||||
</aca-rule-list-item>
|
||||
</div>
|
@ -0,0 +1,5 @@
|
||||
.aca-rule-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
@ -24,25 +24,25 @@
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RulesListUiComponent } from './rules-list.ui-component';
|
||||
import { RuleListUiComponent } from './rule-list.ui-component';
|
||||
import { dummyRules } from '../mock/rules.mock';
|
||||
import { DebugElement } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { CoreTestingModule } from '@alfresco/adf-core';
|
||||
import { AcaFolderRulesModule } from '@alfresco/aca-folder-rules';
|
||||
|
||||
describe('RulesListComponent', () => {
|
||||
let component: RulesListUiComponent;
|
||||
let fixture: ComponentFixture<RulesListUiComponent>;
|
||||
describe('RuleListComponent', () => {
|
||||
let component: RuleListUiComponent;
|
||||
let fixture: ComponentFixture<RuleListUiComponent>;
|
||||
let debugElement: DebugElement;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule, AcaFolderRulesModule],
|
||||
declarations: [RulesListUiComponent]
|
||||
declarations: [RuleListUiComponent]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(RulesListUiComponent);
|
||||
fixture = TestBed.createComponent(RuleListUiComponent);
|
||||
component = fixture.componentInstance;
|
||||
debugElement = fixture.debugElement;
|
||||
});
|
||||
@ -54,17 +54,17 @@ describe('RulesListComponent', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const rules = debugElement.queryAll(By.css('.aca-rule'));
|
||||
const rules = debugElement.queryAll(By.css('.aca-rule-list-item'));
|
||||
|
||||
expect(rules).toBeTruthy('Could not find rules');
|
||||
expect(rules.length).toBe(2, 'Unexpected number of rules');
|
||||
|
||||
const rule = debugElement.query(By.css('.aca-rule:first-child'));
|
||||
const title = rule.query(By.css('.rule-info__header__title'));
|
||||
const description = rule.query(By.css('p'));
|
||||
const rule = debugElement.query(By.css('.aca-rule-list-item:first-child'));
|
||||
const name = rule.query(By.css('.aca-rule-list-item__header__name'));
|
||||
const description = rule.query(By.css('.aca-rule-list-item__description'));
|
||||
const toggleBtn = rule.query(By.css('mat-slide-toggle'));
|
||||
|
||||
expect(title.nativeElement.textContent).toBe(dummyRules[0].name);
|
||||
expect(name.nativeElement.textContent).toBe(dummyRules[0].name);
|
||||
expect(toggleBtn).toBeTruthy();
|
||||
expect(description.nativeElement.textContent).toBe(dummyRules[0].description);
|
||||
});
|
@ -23,21 +23,21 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { Rule } from '../model/rule.model';
|
||||
|
||||
@Component({
|
||||
selector: 'aca-rules-list',
|
||||
templateUrl: 'rules-list.ui-component.html',
|
||||
styleUrls: ['rules-list.ui-component.scss']
|
||||
selector: 'aca-rule-list',
|
||||
templateUrl: 'rule-list.ui-component.html',
|
||||
styleUrls: ['rule-list.ui-component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: { class: 'aca-rule-list' }
|
||||
})
|
||||
export class RulesListUiComponent {
|
||||
export class RuleListUiComponent {
|
||||
@Input()
|
||||
rules: Rule[];
|
||||
|
||||
@Input()
|
||||
selectedRule: Rule;
|
||||
|
||||
@Input()
|
||||
nodeId: string;
|
||||
|
@ -1,9 +1,5 @@
|
||||
<div class="aca-rule" [class.selected]="isSelected" >
|
||||
<div class="rule-info">
|
||||
<div class="rule-info__header">
|
||||
<span class="rule-info__header__title">{{rule.name}}</span>
|
||||
<div class="aca-rule-list-item__header">
|
||||
<span class="aca-rule-list-item__header__name">{{ rule.name }}</span>
|
||||
<mat-slide-toggle [(ngModel)]="rule.isEnabled" (click)="onToggleClick(!rule.isEnabled)"></mat-slide-toggle>
|
||||
</div>
|
||||
<p>{{rule.description}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aca-rule-list-item__description">{{ rule.description }}</div>
|
||||
|
@ -1,11 +1,13 @@
|
||||
.aca-rule{
|
||||
.aca-rule-list-item {
|
||||
display: flex;
|
||||
padding: 16px 24px;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
padding: 12px 20px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 8px;
|
||||
cursor: pointer;
|
||||
|
||||
p{
|
||||
p {
|
||||
margin: 6px 0 0 0;
|
||||
color: rgba(33, 35, 40, 0.7);
|
||||
font-style: normal;
|
||||
@ -13,24 +15,24 @@
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.rule-info{
|
||||
width: 100%;
|
||||
|
||||
&__header{
|
||||
&__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
|
||||
&__title{
|
||||
font-weight: 900;
|
||||
font-size: 14px;
|
||||
color: #212121;
|
||||
line-height: 20px;
|
||||
&__name {
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.selected{
|
||||
background: rgba(31, 116, 219, 0.24);
|
||||
&__description {
|
||||
font-size: 0.8em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background: var(--theme-selected-button-bg-color);
|
||||
}
|
||||
}
|
||||
|
@ -23,19 +23,25 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Component, HostBinding, Input, ViewEncapsulation } from '@angular/core';
|
||||
import { Rule } from '../../model/rule.model';
|
||||
import { FolderRulesService } from '../../services/folder-rules.service';
|
||||
|
||||
@Component({
|
||||
selector: 'aca-rule',
|
||||
selector: 'aca-rule-list-item',
|
||||
templateUrl: 'rule-list-item.ui-component.html',
|
||||
styleUrls: ['rule-list-item.ui-component.scss']
|
||||
styleUrls: ['rule-list-item.ui-component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: { class: 'aca-rule-list-item' }
|
||||
})
|
||||
export class RuleListItemUiComponent {
|
||||
@Input() rule: Rule;
|
||||
@Input() isSelected: boolean;
|
||||
@Input() nodeId: string;
|
||||
@Input()
|
||||
rule: Rule;
|
||||
@Input()
|
||||
nodeId: string;
|
||||
@Input()
|
||||
@HostBinding('class.selected')
|
||||
isSelected: boolean;
|
||||
|
||||
constructor(private folderRulesService: FolderRulesService) {}
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
<div class="aca-rules-list" >
|
||||
<aca-rule *ngFor="let rule of rules" [rule]="rule" (click)="onRuleClicked(rule)" [isSelected]="isSelected(rule)"
|
||||
[nodeId]="nodeId"></aca-rule>
|
||||
</div>
|
@ -1,3 +0,0 @@
|
||||
.aca-rules-list {
|
||||
margin-right: 24px;
|
||||
}
|
@ -27,7 +27,7 @@ import { Injectable } from '@angular/core';
|
||||
import { AlfrescoApiService } from '@alfresco/adf-core';
|
||||
import { BehaviorSubject, forkJoin, from, Observable, of } from 'rxjs';
|
||||
import { catchError, finalize, map } from 'rxjs/operators';
|
||||
import { Rule } from '../model/rule.model';
|
||||
import { Rule, RuleForForm, RuleOptions } from '../model/rule.model';
|
||||
import { ContentApiService } from '@alfresco/aca-shared';
|
||||
import { NodeInfo } from '@alfresco/aca-shared/store';
|
||||
import { RuleCompositeCondition } from '../model/rule-composite-condition.model';
|
||||
@ -46,22 +46,39 @@ export class FolderRulesService {
|
||||
};
|
||||
}
|
||||
|
||||
public static get emptyRuleOptions(): RuleOptions {
|
||||
return {
|
||||
isEnabled: true,
|
||||
isInheritable: false,
|
||||
isAsynchronous: false,
|
||||
errorScript: ''
|
||||
};
|
||||
}
|
||||
|
||||
public static get emptyRule(): Rule {
|
||||
return {
|
||||
id: '',
|
||||
name: '',
|
||||
description: '',
|
||||
isEnabled: true,
|
||||
isInheritable: false,
|
||||
isAsynchronous: false,
|
||||
errorScript: '',
|
||||
isShared: false,
|
||||
triggers: ['inbound'],
|
||||
conditions: FolderRulesService.emptyCompositeCondition,
|
||||
actions: []
|
||||
actions: [],
|
||||
...FolderRulesService.emptyRuleOptions
|
||||
};
|
||||
}
|
||||
|
||||
public static get emptyRuleForForm(): RuleForForm {
|
||||
const value = {
|
||||
...FolderRulesService.emptyRule,
|
||||
options: FolderRulesService.emptyRuleOptions
|
||||
};
|
||||
Object.keys(value.options).forEach((key: string) => {
|
||||
delete value[key];
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
private rulesListingSource = new BehaviorSubject<Rule[]>([]);
|
||||
rulesListing$: Observable<Rule[]> = this.rulesListingSource.asObservable();
|
||||
private folderInfoSource = new BehaviorSubject<NodeInfo>(null);
|
||||
|
Loading…
x
Reference in New Issue
Block a user