Merge pull request #4944 from opf/fix/23896/enter-in-edit-mode

[23896] Submit and close edit mode on enter for most edit fields
pull/4963/merge
ulferts 8 years ago committed by GitHub
commit 2387901eff
  1. 4
      frontend/app/components/routing/main/work-packages.new.html
  2. 9
      frontend/app/components/routing/wp-list/wp.list.new.html
  3. 2
      frontend/app/components/work-packages/work-package-comment/work-package-comment.directive.html
  4. 2
      frontend/app/components/work-packages/work-package-comment/work-package-comment.directive.ts
  5. 15
      frontend/app/components/wp-create/wp-create.controller.ts
  6. 2
      frontend/app/components/wp-edit/field-types/wp-edit-boolean-field.directive.html
  7. 5
      frontend/app/components/wp-edit/field-types/wp-edit-date-field.directive.html
  8. 1
      frontend/app/components/wp-edit/field-types/wp-edit-duration-field.directive.html
  9. 1
      frontend/app/components/wp-edit/field-types/wp-edit-float-field.directive.html
  10. 1
      frontend/app/components/wp-edit/field-types/wp-edit-integer-field.directive.html
  11. 2
      frontend/app/components/wp-edit/field-types/wp-edit-select-field.directive.html
  12. 1
      frontend/app/components/wp-edit/field-types/wp-edit-text-field.directive.html
  13. 2
      frontend/app/components/wp-edit/field-types/wp-edit-wiki-textarea-field.directive.html
  14. 3
      frontend/app/components/wp-edit/wp-edit-field/wp-edit-field.directive.html
  15. 29
      frontend/app/components/wp-edit/wp-edit-field/wp-edit-field.directive.ts
  16. 12
      frontend/app/components/wp-edit/wp-edit-form.directive.ts
  17. 11
      frontend/app/components/wp-edit/wp-edit-mode-state.service.ts
  18. 12
      spec/features/work_packages/edit_work_package_spec.rb
  19. 14
      spec/features/work_packages/new_work_package_spec.rb

@ -3,12 +3,12 @@
ng-if="$ctrl.newWorkPackage"
has-edit-mode="true"
wp-edit-form="$ctrl.newWorkPackage"
>
wp-edit-form-on-save="$ctrl.refreshAfterSave(workPackage, 'work-packages.show')">
<h2>{{ $ctrl.header }}</h2>
<wp-subject work-package="$ctrl.newWorkPackage"></wp-subject>
<wp-single-view work-package="$ctrl.newWorkPackage"></wp-single-view>
<edit-actions-bar
on-save="$ctrl.saveWorkPackage('work-packages.show')"
on-save="$ctrl.saveWorkPackage()"
on-cancel="$ctrl.cancelAndBackToList()"
></edit-actions-bar>
</div>

@ -4,10 +4,9 @@
>
<div class="work-packages--details-content -create-mode">
<span class="hidden-for-sighted" tabindex="-1" focus ng-bind="focusAnchorLabel"></span>
<div
has-edit-mode="true"
wp-edit-form="$ctrl.newWorkPackage"
>
<div has-edit-mode="true"
wp-edit-form="$ctrl.newWorkPackage"
wp-edit-form-on-save="$ctrl.refreshAfterSave(workPackage, 'work-packages.list.details.overview')">
<h2>{{ $ctrl.header }}</h2>
<wp-subject work-package="$ctrl.newWorkPackage"></wp-subject>
<wp-single-view work-package="$ctrl.newWorkPackage"></wp-single-view>
@ -16,7 +15,7 @@
<div class="bottom-toolbar">
<edit-actions-bar
on-save="$ctrl.saveWorkPackage('work-packages.list.details.overview')"
on-save="$ctrl.saveWorkPackage()"
on-cancel="$ctrl.cancelAndBackToList()"
></edit-actions-bar>
</div>

@ -9,7 +9,7 @@
<form ng-switch-when="true"
name="wp-edit-form-coment"
ng-submit="vm.submit()"
ng-submit="vm.handleUserSubmit()"
role="form"
tabindex="-1">

@ -98,7 +98,7 @@ export class CommentFieldDirectiveController {
return this.editing = true;
}
public submit() {
public handleUserSubmit() {
if (this.field.isEmpty()) {
return;
}

@ -92,19 +92,12 @@ export class WorkPackageCreateController {
this.$state.go('work-packages.list', this.$state.params);
}
public saveWorkPackage(successState:string):ng.IPromise<WorkPackageResource> {
if (this.wpEditModeState.active) {
return this.wpEditModeState.save().then(wp => {
this.newWorkPackage = null;
this.refreshAfterSave(wp, successState);
return wp;
});
}
return this.$q.reject();
public saveWorkPackage():ng.IPromise<WorkPackageResource> {
return this.wpEditModeState.save();
}
private refreshAfterSave(wp, successState) {
public refreshAfterSave(wp, successState) {
this.wpEditModeState.onSaved();
this.loadingIndicator.mainPage = this.$state.go(successState, {workPackageId: wp.id})
.then(() => {
this.$rootScope.$emit('workPackagesRefreshInBackground');

@ -3,7 +3,7 @@
wp-edit-field-requirements="vm.field.schema"
ng-model="vm.workPackage[vm.fieldName]"
ng-false-value="false"
ng-change="vm.submit()"
ng-change="vm.handleUserSubmit()"
ng-focus="vm.handleUserFocus()"
ng-blur="vm.handleUserBlur()"
ng-disabled="vm.workPackage.inFlight"

@ -1,7 +1,7 @@
<op-date-picker
tabindex="-1"
on-change="vm.submit()"
on-close="vm.submit()"
on-change="vm.handleUserSubmit()"
on-change="vm.handleUserSubmit()"
ng-model="vm.workPackage[vm.fieldName]">
<input ng-model="vm.workPackage[vm.fieldName]"
@ -9,6 +9,7 @@
class="wp-inline-edit--field"
transform-date-value
ng-blur="vm.onlyInAccessibilityMode(vm.handleUserBlur)"
ng-keydown="vm.handleUserSubmitOnEnter($event)"
ng-required="vm.field.required"
ng-disabled="vm.workPackage.inFlight"
focus="vm.shouldFocus()"

@ -6,6 +6,7 @@
ng-required="vm.field.required"
ng-focus="vm.handleUserFocus()"
ng-blur="vm.handleUserBlur()"
ng-keydown="vm.handleUserSubmitOnEnter($event)"
ng-disabled="vm.workPackage.inFlight"
focus="vm.shouldFocus()"
focus-priority="vm.shouldFocus()"

@ -5,6 +5,7 @@
ng-required="vm.field.required"
ng-focus="vm.handleUserFocus()"
ng-blur="vm.handleUserBlur()"
ng-keydown="vm.handleUserSubmitOnEnter($event)"
transform-float-value
ng-disabled="vm.workPackage.inFlight"
focus="vm.shouldFocus()"

@ -5,6 +5,7 @@
ng-required="vm.field.required"
ng-focus="vm.handleUserFocus()"
ng-blur="vm.handleUserBlur()"
ng-keydown="vm.handleUserSubmitOnEnter($event)"
ng-disabled="vm.workPackage.inFlight"
focus="vm.shouldFocus()"
focus-priority="vm.shouldFocus()"

@ -2,7 +2,7 @@
class="wp-inline-edit--field form--select"
wp-edit-field-requirements="vm.field.schema"
ng-options="value as (value.name || value.value) for value in vm.field.options track by value.href"
ng-change="vm.submit()"
ng-change="vm.handleUserSubmit()"
ng-required="vm.field.required"
ng-focus="vm.handleUserFocus()"
ng-blur="vm.handleUserBlur()"

@ -6,6 +6,7 @@
ng-focus="vm.handleUserFocus()"
ng-blur="vm.handleUserBlur()"
ng-disabled="vm.workPackage.inFlight"
ng-keydown="vm.handleUserSubmitOnEnter($event)"
focus="vm.shouldFocus()"
focus-priority="vm.shouldFocus()"
ng-attr-id="{{vm.htmlId}}" />

@ -19,7 +19,7 @@
</div>
<wp-edit-field-controls ng-show="!vm.inEditMode"
field-controller="vm"
on-save="vm.submit()"
on-save="vm.handleUserSubmit()"
on-cancel="vm.handleUserCancel()"
save-title="{{ vm.field.text.saveTitle }}"
cancel-title="{{ vm.field.text.cancelTitle }}">

@ -13,7 +13,8 @@
ng-click="vm.haltUserFormClick($event)"
ng-dblclick="vm.haltUserFormClick($event)"
name="vm.fieldForm"
ng-submit="vm.submit()"
ng-submit="vm.handleUserSubmit()"
ng-keydown="vm.handleUserKey($event)"
role="form"
tabindex="-1">

@ -65,6 +65,7 @@ export class WorkPackageEditFieldController {
protected NotificationsService,
protected ConfigurationService,
protected wpCacheService: WorkPackageCacheService,
protected ENTER_KEY,
protected I18n) {
}
@ -81,11 +82,7 @@ export class WorkPackageEditFieldController {
}
public submit() {
if (this.inEditMode) {
return this.formCtrl.updateForm();
}
this.formCtrl.updateWorkPackage()
this.formCtrl.onFieldSubmit()
.finally(() => {
this.deactivate();
this._forceFocus = true;
@ -235,6 +232,26 @@ export class WorkPackageEditFieldController {
});
}
public handleUserSubmit() {
if (this.inEditMode) {
return this.formCtrl.updateForm();
}
return this.submit();
}
/**
* Handle users pressing enter inside an edit mode.
* Outside an edit mode, the regular save event is captured by handleUserSubmit (submit event).
* In an edit mode, we can't derive from a submit event wheteher the user pressed enter
* (and on what field he did that).
*/
public handleUserSubmitOnEnter(event) {
if (this.inEditMode && event.which === this.ENTER_KEY) {
return this.submit();
}
}
public handleUserFocus() {
this._hasFocus = true;
}
@ -253,7 +270,7 @@ export class WorkPackageEditFieldController {
}
this.deactivate();
this.submit();
this.handleUserSubmit();
}
public handleUserCancel() {

@ -120,6 +120,18 @@ export class WorkPackageEditFormController {
});
}
/**
* Handle submission event of a single work package field that may or
* may not be involved inside an active edit mode.
*/
public onFieldSubmit() {
if (this.wpEditModeState.active) {
return this.wpEditModeState.save();
}
return this.updateWorkPackage();
}
public updateWorkPackage() {
if (!(this.workPackage.dirty || this.workPackage.isNew)) {
return this.$q.when(this.workPackage);

@ -80,13 +80,16 @@ export class WorkPackageEditModeStateService {
return this._active = false;
}
public onSaved() {
// Doesn't use cancel() since that resets all values
this.form.closeAllFields();
this._active = false;
}
public save() {
if (this.active) {
return this.form.updateWorkPackage().then(wp => {
// Doesn't use cancel() since that resets all values
this.form.closeAllFields();
this._active = false;
this.onSaved();
return wp;
});
}

@ -227,4 +227,16 @@ describe 'edit work package', js: true do
wp_page.expect_notification message: 'Subject is too long (maximum is 255 characters)',
type: 'error'
end
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.set_value 'My new subject!'
subject_field.input_element.send_keys(:return)
wp_page.expect_notification(message: 'Successful update')
subject_field.expect_inactive!
subject_field.expect_state_text 'My new subject!'
end
end

@ -96,6 +96,20 @@ describe 'new work package', js: true do
selected: 'Bug')
end
it 'saves the work package with enter' do
subject_field = wp_page.subject_field
subject_field.set(subject)
subject_field.send_keys(:return)
# safegurards
wp_page.dismiss_notification!
wp_page.expect_no_notification(
message: 'Successful creation. Click here to open this work package in fullscreen view.'
)
wp_page.expect_subject
end
context 'with missing values' do
it 'shows an error when subject is missing' do
wp_page.description_field.set(description)

Loading…
Cancel
Save