pull/5753/head
Oliver Günther 7 years ago
parent 56b67e9f9e
commit 3cb9408faf
No known key found for this signature in database
GPG Key ID: 88872239EB414F99
  1. 28
      frontend/app/components/wp-edit-form/single-view-edit-context.ts
  2. 2
      frontend/app/components/wp-edit-form/work-package-edit-context.ts
  3. 4
      frontend/app/components/wp-edit-form/work-package-edit-form.ts
  4. 3
      frontend/app/components/wp-edit-form/wp-edit-form.template.html
  5. 12
      frontend/app/components/wp-edit/wp-edit-field/wp-edit-field-group.directive.ts
  6. 11
      spec/features/work_packages/edit_work_package_spec.rb
  7. 6
      spec/features/work_packages/table/switch_types_spec.rb
  8. 1
      spec/support/rspec_retry.rb
  9. 18
      spec/support/work_packages/work_package_field.rb

@ -62,8 +62,8 @@ export class SingleViewEditContext implements WorkPackageEditContext {
'FocusHelper', '$q', '$timeout', 'templateRenderer'); 'FocusHelper', '$q', '$timeout', 'templateRenderer');
} }
public activateField(form:WorkPackageEditForm, field:EditField, errors:string[]):ng.IPromise<WorkPackageEditFieldHandler> { public async activateField(form:WorkPackageEditForm, field:EditField, errors:string[]):Promise<WorkPackageEditFieldHandler> {
const ctrl = this.fieldCtrl(field.name); const ctrl = await this.fieldCtrl(field.name);
const container = ctrl.editContainer; const container = ctrl.editContainer;
// Create a field handler for the newly active field // Create a field handler for the newly active field
@ -89,17 +89,21 @@ export class SingleViewEditContext implements WorkPackageEditContext {
} }
); );
return promise.then(() => { return new Promise<WorkPackageEditFieldHandler>((resolve, reject) => {
// Assure the element is visible promise
return this.$timeout(() => { .then(() => {
ctrl.editContainer.show(); // Assure the element is visible
return fieldHandler; this.$timeout(() => {
}); ctrl.editContainer.show();
resolve(fieldHandler);
});
})
.catch(reject);
}); });
} }
public reset(workPackage:WorkPackageResourceInterface, fieldName:string, focus:boolean = false) { public async reset(workPackage:WorkPackageResourceInterface, fieldName:string, focus:boolean = false) {
const ctrl = this.fieldCtrl(fieldName); const ctrl = await this.fieldCtrl(fieldName);
ctrl.reset(workPackage); ctrl.reset(workPackage);
ctrl.deactivate(focus); ctrl.deactivate(focus);
} }
@ -113,8 +117,8 @@ export class SingleViewEditContext implements WorkPackageEditContext {
return 'subject'; return 'subject';
} }
public fieldCtrl(name:string) { private async fieldCtrl(name:string):Promise<WorkPackageEditFieldController> {
return this.fieldGroup.fields[name] as WorkPackageEditFieldController; return this.fieldGroup.waitForField(name);
} }
public onSaved(workPackage:WorkPackageResource) { public onSaved(workPackage:WorkPackageResource) {

@ -35,7 +35,7 @@ export interface WorkPackageEditContext {
/** /**
* Activate the field, returning the element and associated field handler * Activate the field, returning the element and associated field handler
*/ */
activateField(form:WorkPackageEditForm, field:EditField, errors:string[]):ng.IPromise<WorkPackageEditFieldHandler>; activateField(form:WorkPackageEditForm, field:EditField, errors:string[]):Promise<WorkPackageEditFieldHandler>;
/** /**
* Show this required field. E.g., add the necessary column * Show this required field. E.g., add the necessary column

@ -82,7 +82,7 @@ export class WorkPackageEditForm {
* Active the edit field upon user's request. * Active the edit field upon user's request.
* @param fieldName * @param fieldName
*/ */
public activate(fieldName:string, noWarnings:boolean = false):ng.IPromise<WorkPackageEditFieldHandler> { public activate(fieldName:string, noWarnings:boolean = false):Promise<WorkPackageEditFieldHandler> {
return this.workPackage.loadFormSchema().then((schema:SchemaResource) => { return this.workPackage.loadFormSchema().then((schema:SchemaResource) => {
const field = this.wpEditField.getField( const field = this.wpEditField.getField(
this.workPackage, this.workPackage,
@ -237,7 +237,7 @@ export class WorkPackageEditForm {
} }
} }
private buildField(fieldName:string, field:EditField):ng.IPromise<WorkPackageEditFieldHandler> { private buildField(fieldName:string, field:EditField):Promise<WorkPackageEditFieldHandler> {
const promise = this.editContext.activateField(this, const promise = this.editContext.activateField(this,
field, field,
this.errorsPerAttribute[fieldName] || []); this.errorsPerAttribute[fieldName] || []);

@ -1,4 +1,5 @@
<div class="wp-inline-edit--active-field wp-edit-field inplace-edit {{ ::vm.field.name }}"> <div class="wp-inline-edit--active-field wp-edit-field inplace-edit {{ ::vm.field.name }}"
ng-class="{'-error': vm.isErrorenous }">
<form ng-click="vm.stopPropagation($event)" <form ng-click="vm.stopPropagation($event)"
ng-dblclick="vm.stopPropagation($event)" ng-dblclick="vm.stopPropagation($event)"
ng-submit="vm.handleUserSubmit()" ng-submit="vm.handleUserSubmit()"

@ -32,11 +32,13 @@ import {opWorkPackagesModule} from '../../../angular-modules';
import {WorkPackageEditingService} from '../../wp-edit-form/work-package-editing-service'; import {WorkPackageEditingService} from '../../wp-edit-form/work-package-editing-service';
import {WorkPackageEditForm} from '../../wp-edit-form/work-package-edit-form'; import {WorkPackageEditForm} from '../../wp-edit-form/work-package-edit-form';
import {SingleViewEditContext} from '../../wp-edit-form/single-view-edit-context'; import {SingleViewEditContext} from '../../wp-edit-form/single-view-edit-context';
import {input} from 'reactivestates';
export class WorkPackageEditFieldGroupController { export class WorkPackageEditFieldGroupController {
public workPackageId:string; public workPackageId:string;
public inEditMode:boolean; public inEditMode:boolean;
public fields:{ [attribute:string]:WorkPackageEditFieldController } = {}; public fields:{ [attribute:string]:WorkPackageEditFieldController } = {};
private registeredFields = input<string[]>();
constructor(protected $scope:ng.IScope, constructor(protected $scope:ng.IScope,
protected states:States, protected states:States,
@ -75,6 +77,7 @@ export class WorkPackageEditFieldGroupController {
public register(field:WorkPackageEditFieldController) { public register(field:WorkPackageEditFieldController) {
this.fields[field.fieldName] = field; this.fields[field.fieldName] = field;
this.registeredFields.putValue(_.keys(this.fields));
const form = this.editingForm; const form = this.editingForm;
if (form && form.editMode) { if (form && form.editMode) {
@ -82,6 +85,15 @@ export class WorkPackageEditFieldGroupController {
} }
} }
public waitForField(name:string):Promise<WorkPackageEditFieldController> {
return this.registeredFields
.values$()
.filter(keys => keys.indexOf(name) >= 0)
.take(1)
.map(() => this.fields[name])
.toPromise();
}
public start() { public start() {
const form = this.wpEditing.startEditing(this.workPackageId, this.editContext, true); const form = this.wpEditing.startEditing(this.workPackageId, this.editContext, true);
_.each(this.fields, ctrl => form.activate(ctrl.fieldName)); _.each(this.fields, ctrl => form.activate(ctrl.fieldName));

@ -173,17 +173,18 @@ describe 'edit work package', js: true do
let!(:type2) { FactoryGirl.create(:type, custom_fields: [custom_field]) } let!(:type2) { FactoryGirl.create(:type, custom_fields: [custom_field]) }
it 'shows the required field when switching' do it 'shows the required field when switching' do
page.click_button(I18n.t('js.button_edit'))
type_field = wp_page.edit_field(:type) type_field = wp_page.edit_field(:type)
type_field.activate!
type_field.set_value type2.name type_field.set_value type2.name
expect(type_field.input_element).to have_selector('option:checked', text: type2.name)
wp_page.expect_notification message: "Custom Field Nr. #{custom_field.id} can't be blank.",
type: 'error'
cf_field = wp_page.edit_field("customField#{custom_field.id}") cf_field = wp_page.edit_field("customField#{custom_field.id}")
cf_field.expect_active! cf_field.expect_active!
cf_field.expect_value('') cf_field.expect_value('')
find('#work-packages--edit-actions-cancel').click
end end
end end
@ -229,9 +230,9 @@ describe 'edit work package', js: true do
end end
it 'submits the edit mode when pressing enter' do it 'submits the edit mode when pressing enter' do
page.click_button(I18n.t('js.button_edit'))
subject_field = wp_page.edit_field(:subject) subject_field = wp_page.edit_field(:subject)
subject_field.activate!
subject_field.set_value 'My new subject!' subject_field.set_value 'My new subject!'
subject_field.input_element.send_keys(:return) subject_field.input_element.send_keys(:return)

@ -94,7 +94,7 @@ describe 'Switching types in work package table', js: true do
) )
# Old text field should disappear # Old text field should disappear
text_field.expect_state_text '' expect { text_field.display_element }.to raise_error(Capybara::ElementNotFound)
# Required CF requires activation # Required CF requires activation
req_text_field.activate! req_text_field.activate!
@ -124,7 +124,7 @@ describe 'Switching types in work package table', js: true do
message: 'Successful update. Click here to open this work package in fullscreen view.' message: 'Successful update. Click here to open this work package in fullscreen view.'
) )
req_text_field.expect_state_text '' expect { req_text_field.display_element }.to raise_error(Capybara::ElementNotFound)
end end
end end
@ -193,7 +193,7 @@ describe 'Switching types in work package table', js: true do
type_field = wp_page.edit_field :type type_field = wp_page.edit_field :type
type_field.set_value type_with_cf.name type_field.set_value type_with_cf.name
cf_edit_field.element.find('.wp-inline-edit--toggle-multiselect').click cf_edit_field.field_container.find('.wp-inline-edit--toggle-multiselect').click
sel = cf_edit_field.input_element sel = cf_edit_field.input_element
sel.select "pineapple" sel.select "pineapple"
sel.select "mushrooms" sel.select "mushrooms"

@ -31,6 +31,7 @@ end
Retriable.configure do |c| Retriable.configure do |c|
# Three tries in that block # Three tries in that block
c.tries = 3 c.tries = 3
c.base_interval = 1
end end
## ##

@ -22,12 +22,16 @@ class WorkPackageField
@context.find @selector @context.find @selector
end end
def display_selector
'.wp-edit-field--display-field'
end
def display_element def display_element
field_container.find '.wp-edit-field--display-field' @context.find "#{@selector} #{display_selector}"
end end
def input_element def input_element
field_container.find input_selector @context.find "#{@selector} #{input_selector}"
end end
def expect_state_text(text) def expect_state_text(text)
@ -63,20 +67,18 @@ class WorkPackageField
end end
def active? def active?
input_element.present? @context.has_selector? "#{@selector} #{input_selector}", wait: 1
rescue Capybara::ElementNotFound
false
end end
alias :editing? :active? alias :editing? :active?
def expect_active! def expect_active!
expect(element) expect(field_container)
.to have_selector(field_type, wait: 10), .to have_selector(field_type, wait: 10),
"Expected WP field input type '#{field_type}' for attribute '#{property_name}'." "Expected WP field input type '#{field_type}' for attribute '#{property_name}'."
end end
def expect_inactive! def expect_inactive!
expect(page).to have_no_selector("#{@selector} #{field_type}", wait: 10) expect(page).to have_no_selector("#{@selector} #{field_type}")
end end
def expect_invalid def expect_invalid
@ -127,7 +129,7 @@ class WorkPackageField
end end
def editable? def editable?
@context.find("#{@selector}.-editable") field_container.find "#{display_selector}.-editable"
true true
rescue Capybara::ElementNotFound rescue Capybara::ElementNotFound
false false

Loading…
Cancel
Save