diff --git a/cspell.json b/cspell.json
index 366073da1e..f12c11bd22 100644
--- a/cspell.json
+++ b/cspell.json
@@ -131,7 +131,8 @@
"processstring",
"typeahed",
"minmax",
- "jsons"
+ "jsons",
+ "Inplace"
],
"dictionaries": [
"html",
diff --git a/lib/core/form/components/inplace-form-input/inplace-form-input.component.html b/lib/core/form/components/inplace-form-input/inplace-form-input.component.html
new file mode 100644
index 0000000000..ede1f948d7
--- /dev/null
+++ b/lib/core/form/components/inplace-form-input/inplace-form-input.component.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/lib/core/form/components/inplace-form-input/inplace-form-input.component.scss b/lib/core/form/components/inplace-form-input/inplace-form-input.component.scss
new file mode 100644
index 0000000000..dce4f72dee
--- /dev/null
+++ b/lib/core/form/components/inplace-form-input/inplace-form-input.component.scss
@@ -0,0 +1,35 @@
+.adf-inplace-input-container {
+ .mat-form-field-underline {
+ display: none;
+ }
+
+ .mat-form-field-infix {
+ display: flex;
+ border-top: 0;
+ }
+
+ &-error {
+ input {
+ border: 1px solid var(--theme-warn-color) !important;
+ }
+ }
+
+ .adf-inplace-input-mat-form-field {
+ width: 100%;
+ }
+
+ .adf-inplace-input {
+ padding: 7px;
+ border: 1px solid transparent;
+ border-radius: 4px;
+
+ &:focus {
+ border: 1px solid var(--theme-primary-color);
+ }
+
+ &:hover:not(:focus) {
+ border: 1px solid var(--theme-bg-hover-color);
+ background-color: var(--theme-bg-hover-color);
+ }
+ }
+}
diff --git a/lib/core/form/components/inplace-form-input/inplace-form-input.component.spec.ts b/lib/core/form/components/inplace-form-input/inplace-form-input.component.spec.ts
new file mode 100644
index 0000000000..7d293c734c
--- /dev/null
+++ b/lib/core/form/components/inplace-form-input/inplace-form-input.component.spec.ts
@@ -0,0 +1,72 @@
+/*!
+ * @license
+ * Copyright 2019 Alfresco Software, Ltd.
+ *
+ * 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 { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormControl } from '@angular/forms';
+import { TranslateModule } from '@ngx-translate/core';
+import { ContentTestingModule } from 'content-services/src/lib/testing/content.testing.module';
+import { InplaceFormInputComponent } from './inplace-form-input.component';
+
+describe('InplaceFormInputComponent', () => {
+ let component: InplaceFormInputComponent;
+ let fixture: ComponentFixture;
+ let formControl: FormControl;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [
+ TranslateModule.forRoot(),
+ ContentTestingModule
+ ],
+ declarations: [InplaceFormInputComponent]
+ }).compileComponents();
+ });
+
+ beforeEach(() => {
+ formControl = new FormControl('');
+ fixture = TestBed.createComponent(InplaceFormInputComponent);
+
+ component = fixture.componentInstance;
+ component.control = formControl;
+ });
+
+ it('should update form value', () => {
+ formControl.setValue('New Value');
+ fixture.detectChanges();
+
+ const input = fixture.nativeElement.querySelector(
+ '[data-automation-id="adf-inplace-input"]'
+ );
+
+ expect(input.value).toBe('New Value');
+ });
+
+ it('should show error', () => {
+ formControl.setValidators(() => ({ error: 'error' }));
+ formControl.setValue('value');
+ formControl.markAsTouched();
+ formControl.updateValueAndValidity();
+
+ fixture.detectChanges();
+
+ const error = fixture.nativeElement.querySelector(
+ '[data-automation-id="adf-inplace-input-error"]'
+ );
+
+ expect(error).toBeTruthy();
+ });
+});
diff --git a/lib/core/form/components/inplace-form-input/inplace-form-input.component.ts b/lib/core/form/components/inplace-form-input/inplace-form-input.component.ts
new file mode 100644
index 0000000000..f249dd8f39
--- /dev/null
+++ b/lib/core/form/components/inplace-form-input/inplace-form-input.component.ts
@@ -0,0 +1,34 @@
+/*!
+ * @license
+ * Copyright 2019 Alfresco Software, Ltd.
+ *
+ * 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,
+ Input,
+ ViewEncapsulation
+} from '@angular/core';
+import { FormControl } from '@angular/forms';
+
+@Component({
+ selector: 'adf-inplace-form-input',
+ templateUrl: './inplace-form-input.component.html',
+ styleUrls: ['./inplace-form-input.component.scss'],
+ encapsulation: ViewEncapsulation.None
+})
+export class InplaceFormInputComponent {
+ @Input()
+ control: FormControl;
+}
diff --git a/lib/core/form/form-base.module.ts b/lib/core/form/form-base.module.ts
index 83f7225ca0..61f7f94f26 100644
--- a/lib/core/form/form-base.module.ts
+++ b/lib/core/form/form-base.module.ts
@@ -40,6 +40,7 @@ import { EditJsonDialogModule } from '../dialogs/edit-json/edit-json.dialog.modu
import { A11yModule } from '@angular/cdk/a11y';
import { FlexLayoutModule } from '@angular/flex-layout';
import { ViewerModule } from '../viewer/viewer.module';
+import { InplaceFormInputComponent } from './components/inplace-form-input/inplace-form-input.component';
@NgModule({
imports: [
@@ -67,7 +68,8 @@ import { ViewerModule } from '../viewer/viewer.module';
StartFormCustomButtonDirective,
...WIDGET_DIRECTIVES,
...MASK_DIRECTIVE,
- WidgetComponent
+ WidgetComponent,
+ InplaceFormInputComponent
],
exports: [
ContentWidgetComponent,
@@ -75,6 +77,7 @@ import { ViewerModule } from '../viewer/viewer.module';
FormListComponent,
FormRendererComponent,
StartFormCustomButtonDirective,
+ InplaceFormInputComponent,
...WIDGET_DIRECTIVES
]
})
diff --git a/lib/core/form/public-api.ts b/lib/core/form/public-api.ts
index e911256624..39fd7dadb1 100644
--- a/lib/core/form/public-api.ts
+++ b/lib/core/form/public-api.ts
@@ -18,6 +18,7 @@
export * from './components/form-field/form-field.component';
export * from './components/form-base.component';
export * from './components/form-list.component';
+export * from './components/inplace-form-input/inplace-form-input.component';
export * from './components/widgets/content/content.widget';
export * from './components/form-custom-button.directive';
export * from './components/form-renderer.component';
diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html
index 807ce1deae..6559913882 100755
--- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html
+++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html
@@ -1,6 +1,8 @@
-
- {{'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.FORM.TITLE' | translate}}
+
+ {{'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.FORM.TITLE' | translate}}
@@ -9,8 +11,13 @@
-
@@ -34,22 +41,17 @@
-
- {{ 'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.FORM.LABEL.NAME' | translate }}
-
-
+
+
{{ 'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.ERROR.PROCESS_NAME_REQUIRED' | translate }}
-
-
+
+
{{ 'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.ERROR.MAXIMUM_LENGTH' | translate : { characters : maxNameLength } }}
-
-
+
+
{{ 'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.ERROR.SPACE_VALIDATOR' | translate }}
-
-
+
+
diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.scss b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.scss
index 41d24c524d..6d7e141d3b 100755
--- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.scss
+++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.scss
@@ -1,9 +1,5 @@
.adf {
&-start-process {
- mat-form-field {
- width: 100%;
- }
-
.mat-form-field-label {
color: var(--theme-colors-mat-grey-dark);
}
@@ -17,14 +13,17 @@
}
}
+ &-select-process-form {
+ display: flex;
+ flex-direction: column;
+ }
+
&-title {
padding-bottom: 1.25em;
}
&-process-input-container {
- mat-form-field {
- width: 100%;
- }
+ margin: 0 7px;
}
&-process-input-autocomplete {
@@ -37,7 +36,7 @@
}
}
- &-start-form-container {
+ &-form-container {
.mat-card {
box-shadow: none !important;
padding: 0 !important;
diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts
index fa1c822dea..db6f932d22 100755
--- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts
+++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts
@@ -165,7 +165,7 @@ describe('StartProcessCloudComponent', () => {
component.ngOnChanges({ appName: change });
fixture.detectChanges();
tick();
- typeValueInto('#processName', 'OLE');
+ typeValueInto('[data-automation-id="adf-inplace-input"]', 'OLE');
typeValueInto('#processDefinitionName', 'processwithoutform2');
fixture.detectChanges();
tick(550);
@@ -242,7 +242,7 @@ describe('StartProcessCloudComponent', () => {
component.ngOnChanges({ appName: change });
fixture.detectChanges();
tick();
- typeValueInto('#processName', 'My new process with form');
+ typeValueInto('[data-automation-id="adf-inplace-input"]', 'My new process with form');
typeValueInto('#processDefinitionName', 'processwithform');
fixture.detectChanges();
tick(550);
@@ -269,7 +269,7 @@ describe('StartProcessCloudComponent', () => {
fixture.detectChanges();
tick();
- typeValueInto('#processName', 'My new process with form');
+ typeValueInto('[data-automation-id="adf-inplace-input"]', 'My new process with form');
typeValueInto('#processDefinitionName', 'processwithform');
fixture.detectChanges();
tick(550);
@@ -297,7 +297,7 @@ describe('StartProcessCloudComponent', () => {
fixture.detectChanges();
tick();
- typeValueInto('#processName', 'My new process with form');
+ typeValueInto('[data-automation-id="adf-inplace-input"]', 'My new process with form');
typeValueInto('#processDefinitionName', 'processwithform');
fixture.detectChanges();
tick(550);
@@ -327,7 +327,7 @@ describe('StartProcessCloudComponent', () => {
fixture.detectChanges();
tick();
- typeValueInto('#processName', 'My new process with form');
+ typeValueInto('[data-automation-id="adf-inplace-input"]', 'My new process with form');
typeValueInto('#processDefinitionName', 'processwithform');
fixture.detectChanges();
tick(4500);
@@ -582,18 +582,6 @@ describe('StartProcessCloudComponent', () => {
fixture.detectChanges();
});
- it('should have labels for process name and type', async () => {
- component.appName = 'myApp';
- component.processDefinitionName = 'NewProcess 2';
- component.ngOnChanges({ appName: firstChange });
-
- fixture.detectChanges();
- await fixture.whenStable();
-
- const inputLabelsNodes = document.querySelectorAll('.adf-start-process .adf-process-input-container mat-label');
- expect(inputLabelsNodes.length).toBe(2);
- });
-
it('should have floating labels for process name and type', async () => {
component.appName = 'myApp';
component.processDefinitionName = 'NewProcess 2';
@@ -862,5 +850,39 @@ describe('StartProcessCloudComponent', () => {
expect(escapeKeyboardEvent.cancelBubble).toBe(true);
});
+
+ it('should hide title', () => {
+ component.showTitle = false;
+ fixture.detectChanges();
+
+ const title = fixture.debugElement.query(By.css('.adf-title'));
+
+ expect(title).toBeFalsy();
+ });
+
+ it('should show title', () => {
+ const title = fixture.debugElement.query(By.css('.adf-title'));
+
+ expect(title).toBeTruthy();
+ });
+
+ it('should show process definition dropdown', () => {
+ component.processDefinitionList = fakeProcessDefinitions;
+ fixture.detectChanges();
+
+ const processDropdown = fixture.debugElement.query(By.css('[data-automation-id="adf-select-cloud-process-dropdown"]'));
+
+ expect(processDropdown).toBeTruthy();
+ });
+
+ it('should hide process definition dropdown', () => {
+ component.processDefinitionList = fakeProcessDefinitions;
+ component.showSelectProcessDropdown = false;
+ fixture.detectChanges();
+
+ const processDropdown = fixture.debugElement.query(By.css('#processDefinitionName'));
+
+ expect(processDropdown).toBeFalsy();
+ });
});
});
diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts
index daf4398449..ab9e61caf5 100755
--- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts
+++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts
@@ -74,6 +74,10 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy
@Input()
showSelectProcessDropdown: boolean = true;
+ /** Show/hide title. */
+ @Input()
+ showTitle: boolean = true;
+
/** Emitted when the process is successfully started. */
@Output()
success = new EventEmitter();
@@ -369,8 +373,8 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy
return !!process.name ? process.name : process.key;
}
- get processInstanceName(): AbstractControl {
- return this.processForm.get('processInstanceName');
+ get processInstanceName(): FormControl {
+ return this.processForm.get('processInstanceName') as FormControl;
}
get processDefinition(): AbstractControl {
diff --git a/lib/testing/src/lib/protractor/process-services-cloud/pages/start-process-cloud-component.page.ts b/lib/testing/src/lib/protractor/process-services-cloud/pages/start-process-cloud-component.page.ts
index 37cc9b2680..d612a1615d 100644
--- a/lib/testing/src/lib/protractor/process-services-cloud/pages/start-process-cloud-component.page.ts
+++ b/lib/testing/src/lib/protractor/process-services-cloud/pages/start-process-cloud-component.page.ts
@@ -23,7 +23,7 @@ import { FormFields } from '../../core/pages/form/form-fields';
export class StartProcessCloudPage {
defaultProcessName = $('input[id="processName"]');
- processNameInput = $('#processName');
+ processNameInput = $('[data-automation-id="adf-inplace-input"]');
selectProcessDropdownArrow = $('button[id="adf-select-process-dropdown"]');
cancelProcessButton = $('#cancel_process');
formStartProcessButton = $('button[data-automation-id="adf-form-start process"]');
@@ -89,6 +89,8 @@ export class StartProcessCloudPage {
async isStartProcessButtonEnabled(): Promise {
await BrowserVisibility.waitUntilElementIsNotVisible(this.startProcessButtonDisabled);
await BrowserVisibility.waitUntilElementIsVisible(this.startProcessButton);
+ await BrowserVisibility.waitUntilElementIsClickable(this.startProcessButton);
+
return this.startProcessButton.isEnabled();
}