diff --git a/projects/aca-folder-rules/assets/i18n/en.json b/projects/aca-folder-rules/assets/i18n/en.json
index af73a207f..287676ae1 100644
--- a/projects/aca-folder-rules/assets/i18n/en.json
+++ b/projects/aca-folder-rules/assets/i18n/en.json
@@ -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",
diff --git a/projects/aca-folder-rules/src/lib/folder-rules.module.ts b/projects/aca-folder-rules/src/lib/folder-rules.module.ts
index fab75c403..f519b98f8 100644
--- a/projects/aca-folder-rules/src/lib/folder-rules.module.ts
+++ b/projects/aca-folder-rules/src/lib/folder-rules.module.ts
@@ -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
diff --git a/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.html b/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.html
index e8baf52f7..1ca8e1d07 100644
--- a/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.html
+++ b/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.html
@@ -30,29 +30,38 @@
0 ; else emptyContent">
-
+
-
-
diff --git a/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.scss b/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.scss
index a8e4850f2..add9b93cf 100644
--- a/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.scss
+++ b/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.scss
@@ -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;
+ }
+
+ .mat-icon {
+ // Something pops out of this button for some reason so this is necessary
+ overflow: hidden !important;
+ }
+ }
}
}
-
- p {
- font-style: normal;
- font-weight: 400;
- font-size: 12px;
- line-height: 16px;
- }
- }
-
- &__rule-details {
- overflow-x: scroll;
}
}
}
diff --git a/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.spec.ts b/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.spec.ts
index 7869ee11a..7a9a52cf3 100644
--- a/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.spec.ts
+++ b/projects/aca-folder-rules/src/lib/manage-rules/manage-rules.smart-component.spec.ts
@@ -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'));
diff --git a/projects/aca-folder-rules/src/lib/model/rule.model.ts b/projects/aca-folder-rules/src/lib/model/rule.model.ts
index 872f54585..466989b0d 100644
--- a/projects/aca-folder-rules/src/lib/model/rule.model.ts
+++ b/projects/aca-folder-rules/src/lib/model/rule.model.ts
@@ -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;
+}
diff --git a/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.html b/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.html
index 582d3b1b6..10d961170 100644
--- a/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.html
+++ b/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.html
@@ -1,34 +1,36 @@
-
-
+
+
+ (change)="toggleErrorScriptDropdown($event)"
+ data-automation-id="rule-option-checkbox-asynchronous">
{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.IS_ASYNCHRONOUS' | translate }}
-
- {{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.ERROR_SCRIPT' | translate}}:
-
-
- {{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.SELECT_ACTION' | translate}}
-
-
-
+
+
+
+ {{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.NO_SCRIPT' | translate }}
+
+
-
+
+
+
+ data-automation-id="rule-option-checkbox-inheritable">
{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.IS_INHERITABLE' | translate }}
+
+
+
+ formControlName="isDisabled"
+ data-automation-id="rule-option-checkbox-disabled">
{{ 'ACA_FOLDER_RULES.RULE_DETAILS.OPTIONS.DISABLE_RULE' | translate }}
-
-
+
diff --git a/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.scss b/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.scss
index 11783d8b3..34a18c083 100644
--- a/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.scss
+++ b/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.scss
@@ -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;
}
}
diff --git a/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.spec.ts b/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.spec.ts
index 4990e1157..51c4caa6a 100644
--- a/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.spec.ts
+++ b/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.spec.ts
@@ -23,16 +23,16 @@
* along with Alfresco. If not, see
.
*/
-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
;
+ 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(() => {
- TestBed.configureTestingModule({
- schemas: [CUSTOM_ELEMENTS_SCHEMA],
- imports: [FormsModule, ReactiveFormsModule, CoreTestingModule],
- declarations: [RuleOptionsUiComponent]
- }).compileComponents();
- })
- );
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
+ imports: [FormsModule, ReactiveFormsModule, CoreTestingModule],
+ declarations: [RuleOptionsUiComponent]
+ });
- 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();
});
});
diff --git a/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.ts b/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.ts
index de7a28683..8376acb3f 100644
--- a/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.ts
+++ b/projects/aca-folder-rules/src/lib/rule-details/options/rule-options.ui-component.ts
@@ -23,20 +23,98 @@
* along with Alfresco. If not, see .
*/
-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();
+ }
}
}
diff --git a/projects/aca-folder-rules/src/lib/rule-details/rule-details.ui-component.html b/projects/aca-folder-rules/src/lib/rule-details/rule-details.ui-component.html
index b0e4c9c00..2b105e991 100644
--- a/projects/aca-folder-rules/src/lib/rule-details/rule-details.ui-component.html
+++ b/projects/aca-folder-rules/src/lib/rule-details/rule-details.ui-component.html
@@ -1,7 +1,7 @@
-