From e865cfe1050aeb316ec82ea353775ee90ac40bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emanuel=20Sch=C3=BCtze?= Date: Sun, 27 Nov 2016 22:57:56 +0100 Subject: [PATCH] Improved forms in ng-dialogs. - users: use form field in grid layout and add more option to reduce scrolling of long dialog. - agenda/motions/assignment: show parent agenda item field for create dialog only (to prevent corrupt agenda by action 'set my child item as my new parent item') - refactor ng dialog and formly code. --- .../assignments/static/js/assignments/site.js | 81 ++++--- openslides/core/static/css/app.css | 38 ++- openslides/motions/static/js/motions/site.js | 217 ++++++++++-------- openslides/topics/static/js/topics/site.js | 62 ++--- openslides/users/static/js/users/site.js | 123 ++++++---- 5 files changed, 319 insertions(+), 202 deletions(-) diff --git a/openslides/assignments/static/js/assignments/site.js b/openslides/assignments/static/js/assignments/site.js index cef4bf1f5..c00783f72 100644 --- a/openslides/assignments/static/js/assignments/site.js +++ b/openslides/assignments/static/js/assignments/site.js @@ -152,8 +152,8 @@ angular.module('OpenSlidesApp.assignments.site', [ }; }, // angular-formly fields for assignment form - getFormFields: function () { - return [ + getFormFields: function (isCreateForm) { + var formFields = [ { key: 'title', type: 'input', @@ -193,37 +193,52 @@ angular.module('OpenSlidesApp.assignments.site', [ description: gettextCatalog.getString('If deactivated the election appears as internal item on agenda.') }, hide: !operator.hasPerms('assignments.can_manage') - }, - { - key: 'agenda_parent_item_id', - type: 'select-single', - templateOptions: { - label: gettextCatalog.getString('Parent item'), - options: AgendaTree.getFlatTree(Agenda.getAll()), - ngOptions: 'item.id as item.getListViewTitle() for item in to.options | notself : model.agenda_item_id', - placeholder: gettextCatalog.getString('Select a parent item ...') - }, - hide: !operator.hasPerms('agenda.can_manage') - }, - { - key: 'more', - type: 'checkbox', - templateOptions: { - label: gettextCatalog.getString('Show extended fields') - }, - hide: !operator.hasPerms('assignments.can_manage') - }, - { - key: 'tags_id', - type: 'select-multiple', - templateOptions: { - label: gettextCatalog.getString('Tags'), - options: Tag.getAll(), - ngOptions: 'option.id as option.name for option in to.options', - placeholder: gettextCatalog.getString('Select or search a tag ...') - }, - hideExpression: '!model.more' }]; + + // parent item + if (isCreateForm) { + formFields.push({ + key: 'agenda_parent_item_id', + type: 'select-single', + templateOptions: { + label: gettextCatalog.getString('Parent item'), + options: AgendaTree.getFlatTree(Agenda.getAll()), + ngOptions: 'item.id as item.getListViewTitle() for item in to.options | notself : model.agenda_item_id', + placeholder: gettextCatalog.getString('Select a parent item ...') + }, + hide: !operator.hasPerms('agenda.can_manage') + }); + } + // more (with tags field) + if (Tag.getAll().length > 0) { + formFields.push( + { + key: 'more', + type: 'checkbox', + templateOptions: { + label: gettextCatalog.getString('Show extended fields') + }, + hide: !operator.hasPerms('assignments.can_manage') + }, + { + template: '
', + hideExpression: '!model.more' + }, + { + key: 'tags_id', + type: 'select-multiple', + templateOptions: { + label: gettextCatalog.getString('Tags'), + options: Tag.getAll(), + ngOptions: 'option.id as option.name for option in to.options', + placeholder: gettextCatalog.getString('Select or search a tag ...') + }, + hideExpression: '!model.more' + } + ); + } + + return formFields; } }; } @@ -588,7 +603,7 @@ angular.module('OpenSlidesApp.assignments.site', [ // set default value for open posts form field $scope.model.open_posts = 1; // get all form fields - $scope.formFields = AssignmentForm.getFormFields(); + $scope.formFields = AssignmentForm.getFormFields(true); // save assignment $scope.save = function(assignment) { Assignment.create(assignment).then( diff --git a/openslides/core/static/css/app.css b/openslides/core/static/css/app.css index a8e30f1b4..5c6bfbef3 100644 --- a/openslides/core/static/css/app.css +++ b/openslides/core/static/css/app.css @@ -1196,6 +1196,16 @@ img { padding: 5px; } +.no-padding { + padding: 0 !important; +} +.no-padding-left { + padding-left: 0 !important; +} +.no-padding-right { + padding-right: 0 !important; +} + /* user details */ .user_details fieldset { margin-bottom: 10px; @@ -1292,16 +1302,42 @@ img { } .ngdialog.ngdialog-theme-default.wide-form .ngdialog-content { - width: 650px; + width: 750px; + line-height: 1em; } .ngdialog h2 { margin-top: 5px; } +.ngdialog .row:after, .ngdialog .row:before { + display: table-cell !important; +} + +.help-block { + font-size: 85%; + margin-top: 2px; + margin-left: 2px; +} + /* angular-chosen: override default width of select fields in quickmode */ .chosen-container { width: 100% !important; + font-size: 14px; +} +.chosen-container .chosen-choices { + border: 1px solid #ccc; + border-radius: 4px; +} +.chosen-container-active .chosen-choices { + border-color: rgba(82,168,236,.8); + box-shadow: 0 0 8px rgba(82,168,236,.6); +} +.chosen-container .chosen-choices li.search-choice { + margin: 6px 5px 0 0 !important; +} +.chosen-container input { + margin: 4px 0 !important; } /* angular-ui-tree style */ diff --git a/openslides/motions/static/js/motions/site.js b/openslides/motions/static/js/motions/site.js index 6dcf4d15f..2c24ce4e2 100644 --- a/openslides/motions/static/js/motions/site.js +++ b/openslides/motions/static/js/motions/site.js @@ -412,7 +412,7 @@ angular.module('OpenSlidesApp.motions.site', [ }; }, // angular-formly fields for motion form - getFormFields: function () { + getFormFields: function (isCreateForm) { var workflows = Workflow.getAll(); var images = Mediafile.getAllImages(); var formFields = [ @@ -481,107 +481,134 @@ angular.module('OpenSlidesApp.motions.site', [ description: gettextCatalog.getString('If deactivated the motion appears as internal item on agenda.') }, hide: !operator.hasPerms('motions.can_manage') - }, - { - key: 'agenda_parent_item_id', - type: 'select-single', - templateOptions: { - label: gettextCatalog.getString('Parent item'), - options: AgendaTree.getFlatTree(Agenda.getAll()), - ngOptions: 'item.id as item.getListViewTitle() for item in to.options | notself : model.agenda_item_id', - placeholder: gettextCatalog.getString('Select a parent item ...') + }]; + + // parent item + if (isCreateForm) { + formFields.push({ + key: 'agenda_parent_item_id', + type: 'select-single', + templateOptions: { + label: gettextCatalog.getString('Parent item'), + options: AgendaTree.getFlatTree(Agenda.getAll()), + ngOptions: 'item.id as item.getListViewTitle() for item in to.options | notself : model.agenda_item_id', + placeholder: gettextCatalog.getString('Select a parent item ...') + }, + hide: !operator.hasPerms('agenda.can_manage') + }); + } + + // motion comments + formFields = formFields.concat(MotionComment.getFormFields()); + + // more + formFields.push( + { + key: 'more', + type: 'checkbox', + templateOptions: { + label: gettextCatalog.getString('Show extended fields') + }, + hide: !operator.hasPerms('motions.can_manage') }, - hide: !operator.hasPerms('agenda.can_manage') - }] - .concat(MotionComment.getFormFields()) - .concat([ - { - key: 'more', - type: 'checkbox', - templateOptions: { - label: gettextCatalog.getString('Show extended fields') - }, - hide: !operator.hasPerms('motions.can_manage') - }, - { - key: 'attachments_id', - type: 'select-multiple', - templateOptions: { - label: gettextCatalog.getString('Attachment'), - options: Mediafile.getAll(), - ngOptions: 'option.id as option.title_or_filename for option in to.options', - placeholder: gettextCatalog.getString('Select or search an attachment ...') - }, - hideExpression: '!model.more' - }, - { - key: 'category_id', - type: 'select-single', - templateOptions: { - label: gettextCatalog.getString('Category'), - options: Category.getAll(), - ngOptions: 'option.id as option.name for option in to.options', - placeholder: gettextCatalog.getString('Select or search a category ...') - }, - hideExpression: '!model.more' - }, - { - key: 'motion_block_id', - type: 'select-single', - templateOptions: { - label: gettextCatalog.getString('Motion block'), - options: MotionBlock.getAll(), - ngOptions: 'option.id as option.title for option in to.options', - placeholder: gettextCatalog.getString('Select or search a motion block ...') - }, - hideExpression: '!model.more' - }, - { + { + template: '
', + hideExpression: '!model.more' + } + ); + // attachments + if (Mediafile.getAll().length > 0) { + formFields.push({ + key: 'attachments_id', + type: 'select-multiple', + templateOptions: { + label: gettextCatalog.getString('Attachment'), + options: Mediafile.getAll(), + ngOptions: 'option.id as option.title_or_filename for option in to.options', + placeholder: gettextCatalog.getString('Select or search an attachment ...') + }, + hideExpression: '!model.more' + }); + } + // category + if (Category.getAll().length > 0) { + formFields.push({ + key: 'category_id', + type: 'select-single', + templateOptions: { + label: gettextCatalog.getString('Category'), + options: Category.getAll(), + ngOptions: 'option.id as option.name for option in to.options', + placeholder: gettextCatalog.getString('Select or search a category ...') + }, + hideExpression: '!model.more' + }); + } + // motion block + if (MotionBlock.getAll().length > 0) { + formFields.push({ + key: 'motion_block_id', + type: 'select-single', + templateOptions: { + label: gettextCatalog.getString('Motion block'), + options: MotionBlock.getAll(), + ngOptions: 'option.id as option.title for option in to.options', + placeholder: gettextCatalog.getString('Select or search a motion block ...') + }, + hideExpression: '!model.more' + }); + } + // origin + formFields.push({ key: 'origin', type: 'input', templateOptions: { label: gettextCatalog.getString('Origin'), }, hideExpression: '!model.more' - }, - { - key: 'tags_id', - type: 'select-multiple', - templateOptions: { - label: gettextCatalog.getString('Tags'), - options: Tag.getAll(), - ngOptions: 'option.id as option.name for option in to.options', - placeholder: gettextCatalog.getString('Select or search a tag ...') - }, - hideExpression: '!model.more' - }, - { - key: 'supporters_id', - type: 'select-multiple', - templateOptions: { - label: gettextCatalog.getString('Supporters'), - options: User.getAll(), - ngOptions: 'option.id as option.full_name for option in to.options', - placeholder: gettextCatalog.getString('Select or search a supporter ...') - }, - hideExpression: '!model.more' - }]); - + }); + // tags + if (Tag.getAll().length > 0) { + formFields.push({ + key: 'tags_id', + type: 'select-multiple', + templateOptions: { + label: gettextCatalog.getString('Tags'), + options: Tag.getAll(), + ngOptions: 'option.id as option.name for option in to.options', + placeholder: gettextCatalog.getString('Select or search a tag ...') + }, + hideExpression: '!model.more' + }); + } + // supporters + if (Config.get('motions_min_supporters') > 0) { + formFields.push({ + key: 'supporters_id', + type: 'select-multiple', + templateOptions: { + label: gettextCatalog.getString('Supporters'), + options: User.getAll(), + ngOptions: 'option.id as option.full_name for option in to.options', + placeholder: gettextCatalog.getString('Select or search a supporter ...') + }, + hideExpression: '!model.more' + }); + } + // workflows if (workflows.length > 1) { - formFields = formFields.concat([ - { - key: 'workflow_id', - type: 'select-single', - templateOptions: { - label: gettextCatalog.getString('Workflow'), - optionsAttr: 'bs-options', - options: workflows, - ngOptions: 'option.id as option.name | translate for option in to.options', - placeholder: gettextCatalog.getString('Select or search a workflow ...') - }, - hideExpression: '!model.more', - } - ]); + formFields.push({ + key: 'workflow_id', + type: 'select-single', + templateOptions: { + label: gettextCatalog.getString('Workflow'), + optionsAttr: 'bs-options', + options: workflows, + ngOptions: 'option.id as option.name | translate for option in to.options', + placeholder: gettextCatalog.getString('Select or search a workflow ...') + }, + hideExpression: '!model.more', + }); } return formFields; @@ -1323,7 +1350,7 @@ angular.module('OpenSlidesApp.motions.site', [ // ... preselect default workflow $scope.model.workflow_id = Config.get('motions_workflow').value; // get all form fields - $scope.formFields = MotionForm.getFormFields(); + $scope.formFields = MotionForm.getFormFields(true); // save motion $scope.save = function (motion) { diff --git a/openslides/topics/static/js/topics/site.js b/openslides/topics/static/js/topics/site.js index cb389942c..efdf1cd76 100644 --- a/openslides/topics/static/js/topics/site.js +++ b/openslides/topics/static/js/topics/site.js @@ -96,9 +96,9 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics']) resolve: (resolve) ? resolve : null }; }, - getFormFields: function () { + getFormFields: function (isCreateForm) { var images = Mediafile.getAllImages(); - return [ + var formFields = [ { key: 'title', type: 'input', @@ -116,35 +116,45 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics']) data: { tinymceOption: Editor.getOptions(images) } - }, - { - key: 'attachments_id', - type: 'select-multiple', - templateOptions: { - label: gettextCatalog.getString('Attachment'), - options: Mediafile.getAll(), - ngOptions: 'option.id as option.title_or_filename for option in to.options', - placeholder: gettextCatalog.getString('Select or search an attachment ...') - } - }, - { + }]; + // attachments + if (Mediafile.getAll().length > 0) { + formFields.push({ + key: 'attachments_id', + type: 'select-multiple', + templateOptions: { + label: gettextCatalog.getString('Attachment'), + options: Mediafile.getAll(), + ngOptions: 'option.id as option.title_or_filename for option in to.options', + placeholder: gettextCatalog.getString('Select or search an attachment ...') + } + }); + } + // show as agenda item + formFields.push({ key: 'showAsAgendaItem', type: 'checkbox', templateOptions: { label: gettextCatalog.getString('Show as agenda item'), description: gettextCatalog.getString('If deactivated it appears as internal item on agenda.') } - }, - { - key: 'agenda_parent_item_id', - type: 'select-single', - templateOptions: { - label: gettextCatalog.getString('Parent item'), - options: AgendaTree.getFlatTree(Agenda.getAll()), - ngOptions: 'item.id as item.getListViewTitle() for item in to.options | notself : model.agenda_item_id', - placeholder: gettextCatalog.getString('Select a parent item ...') - } - }]; + }); + + // parent item + if (isCreateForm) { + formFields.push({ + key: 'agenda_parent_item_id', + type: 'select-single', + templateOptions: { + label: gettextCatalog.getString('Parent item'), + options: AgendaTree.getFlatTree(Agenda.getAll()), + ngOptions: 'item.id as item.getListViewTitle() for item in to.options | notself : model.agenda_item_id', + placeholder: gettextCatalog.getString('Select a parent item ...') + } + }); + } + + return formFields; } }; } @@ -187,7 +197,7 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics']) $scope.model = {}; $scope.model.showAsAgendaItem = true; // get all form fields - $scope.formFields = TopicForm.getFormFields(); + $scope.formFields = TopicForm.getFormFields(true); // save form $scope.save = function (topic) { Topic.create(topic).then( diff --git a/openslides/users/static/js/users/site.js b/openslides/users/static/js/users/site.js index 2b867cf5f..47540f7d4 100644 --- a/openslides/users/static/js/users/site.js +++ b/openslides/users/static/js/users/site.js @@ -292,6 +292,55 @@ angular.module('OpenSlidesApp.users.site', [ getFormFields: function (hideOnCreateForm) { var images = Mediafile.getAllImages(); return [ + { + className: "row", + fieldGroup: [ + { + key: 'title', + type: 'input', + className: "col-xs-2 no-padding-left", + templateOptions: { + label: gettextCatalog.getString('Title') + } + }, + { + key: 'first_name', + type: 'input', + className: "col-xs-5 no-padding", + templateOptions: { + label: gettextCatalog.getString('First name') + } + }, + { + key: 'last_name', + type: 'input', + className: "col-xs-5 no-padding-right", + templateOptions: { + label: gettextCatalog.getString('Last name') + } + } + ] + }, + { + className: "row", + fieldGroup: [ + { + key: 'structure_level', + type: 'input', + className: "col-xs-9 no-padding-left", + templateOptions: { + label: gettextCatalog.getString('Structure level'), + } + }, + { key: 'number', + type: 'input', + className: "col-xs-3 no-padding-left no-padding-right", + templateOptions: { + label:gettextCatalog.getString('Participant number') + } + } + ] + }, { key: 'username', type: 'input', @@ -300,42 +349,6 @@ angular.module('OpenSlidesApp.users.site', [ }, hide: hideOnCreateForm }, - { - key: 'title', - type: 'input', - templateOptions: { - label: gettextCatalog.getString('Title'), - description: gettextCatalog.getString('Will be shown before the name.') - } - }, - { - key: 'first_name', - type: 'input', - templateOptions: { - label: gettextCatalog.getString('First name') - } - }, - { - key: 'last_name', - type: 'input', - templateOptions: { - label: gettextCatalog.getString('Last name') - } - }, - { - key: 'structure_level', - type: 'input', - templateOptions: { - label: gettextCatalog.getString('Structure level'), - description: gettextCatalog.getString('Will be shown after the name.') - } - }, - { key: 'number', - type: 'input', - templateOptions: { - label:gettextCatalog.getString('Participant number') - } - }, { key: 'groups_id', type: 'select-multiple', @@ -368,19 +381,20 @@ angular.module('OpenSlidesApp.users.site', [ type: 'input', templateOptions: { label: gettextCatalog.getString('Comment'), - description: gettextCatalog.getString('Only for notes.') + description: gettextCatalog.getString('Only for internal notes.') } }, { - key: 'about_me', - type: 'editor', + key: 'more', + type: 'checkbox', templateOptions: { - label: gettextCatalog.getString('About me'), - }, - data: { - tinymceOption: Editor.getOptions(images) + label: gettextCatalog.getString('Show extended fields') } }, + { + template: '
', + hideExpression: '!model.more' + }, { key: 'is_present', type: 'checkbox', @@ -388,7 +402,8 @@ angular.module('OpenSlidesApp.users.site', [ label: gettextCatalog.getString('Is present'), description: gettextCatalog.getString('Designates whether this user is in the room or not.') }, - defaultValue: true + defaultValue: true, + hideExpression: '!model.more' }, { key: 'is_active', @@ -399,7 +414,8 @@ angular.module('OpenSlidesApp.users.site', [ 'Designates whether this user should be treated as ' + 'active. Unselect this instead of deleting the account.') }, - defaultValue: true + defaultValue: true, + hideExpression: '!model.more' }, { key: 'is_committee', @@ -409,8 +425,21 @@ angular.module('OpenSlidesApp.users.site', [ description: gettextCatalog.getString( 'Designates whether this user should be treated as a committee.') }, - defaultValue: false - }]; + defaultValue: false, + hideExpression: '!model.more' + }, + { + key: 'about_me', + type: 'editor', + templateOptions: { + label: gettextCatalog.getString('About me'), + }, + data: { + tinymceOption: Editor.getOptions(images) + }, + hideExpression: '!model.more' + } + ]; } }; }