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.
This commit is contained in:
Emanuel Schütze 2016-11-27 22:57:56 +01:00
parent fb646df1fd
commit e865cfe105
5 changed files with 319 additions and 202 deletions

View File

@ -152,8 +152,8 @@ angular.module('OpenSlidesApp.assignments.site', [
}; };
}, },
// angular-formly fields for assignment form // angular-formly fields for assignment form
getFormFields: function () { getFormFields: function (isCreateForm) {
return [ var formFields = [
{ {
key: 'title', key: 'title',
type: 'input', type: 'input',
@ -193,37 +193,52 @@ angular.module('OpenSlidesApp.assignments.site', [
description: gettextCatalog.getString('If deactivated the election appears as internal item on agenda.') description: gettextCatalog.getString('If deactivated the election appears as internal item on agenda.')
}, },
hide: !operator.hasPerms('assignments.can_manage') 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: '<hr class="smallhr">',
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 // set default value for open posts form field
$scope.model.open_posts = 1; $scope.model.open_posts = 1;
// get all form fields // get all form fields
$scope.formFields = AssignmentForm.getFormFields(); $scope.formFields = AssignmentForm.getFormFields(true);
// save assignment // save assignment
$scope.save = function(assignment) { $scope.save = function(assignment) {
Assignment.create(assignment).then( Assignment.create(assignment).then(

View File

@ -1196,6 +1196,16 @@ img {
padding: 5px; 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 */
.user_details fieldset { .user_details fieldset {
margin-bottom: 10px; margin-bottom: 10px;
@ -1292,16 +1302,42 @@ img {
} }
.ngdialog.ngdialog-theme-default.wide-form .ngdialog-content { .ngdialog.ngdialog-theme-default.wide-form .ngdialog-content {
width: 650px; width: 750px;
line-height: 1em;
} }
.ngdialog h2 { .ngdialog h2 {
margin-top: 5px; 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 */ /* angular-chosen: override default width of select fields in quickmode */
.chosen-container { .chosen-container {
width: 100% !important; 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 */ /* angular-ui-tree style */

View File

@ -412,7 +412,7 @@ angular.module('OpenSlidesApp.motions.site', [
}; };
}, },
// angular-formly fields for motion form // angular-formly fields for motion form
getFormFields: function () { getFormFields: function (isCreateForm) {
var workflows = Workflow.getAll(); var workflows = Workflow.getAll();
var images = Mediafile.getAllImages(); var images = Mediafile.getAllImages();
var formFields = [ var formFields = [
@ -481,107 +481,134 @@ angular.module('OpenSlidesApp.motions.site', [
description: gettextCatalog.getString('If deactivated the motion appears as internal item on agenda.') description: gettextCatalog.getString('If deactivated the motion appears as internal item on agenda.')
}, },
hide: !operator.hasPerms('motions.can_manage') hide: !operator.hasPerms('motions.can_manage')
}, }];
{
key: 'agenda_parent_item_id', // parent item
type: 'select-single', if (isCreateForm) {
templateOptions: { formFields.push({
label: gettextCatalog.getString('Parent item'), key: 'agenda_parent_item_id',
options: AgendaTree.getFlatTree(Agenda.getAll()), type: 'select-single',
ngOptions: 'item.id as item.getListViewTitle() for item in to.options | notself : model.agenda_item_id', templateOptions: {
placeholder: gettextCatalog.getString('Select a parent item ...') 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') {
}] template: '<hr class="smallhr">',
.concat(MotionComment.getFormFields()) hideExpression: '!model.more'
.concat([ }
{ );
key: 'more', // attachments
type: 'checkbox', if (Mediafile.getAll().length > 0) {
templateOptions: { formFields.push({
label: gettextCatalog.getString('Show extended fields') key: 'attachments_id',
}, type: 'select-multiple',
hide: !operator.hasPerms('motions.can_manage') templateOptions: {
}, label: gettextCatalog.getString('Attachment'),
{ options: Mediafile.getAll(),
key: 'attachments_id', ngOptions: 'option.id as option.title_or_filename for option in to.options',
type: 'select-multiple', placeholder: gettextCatalog.getString('Select or search an attachment ...')
templateOptions: { },
label: gettextCatalog.getString('Attachment'), hideExpression: '!model.more'
options: Mediafile.getAll(), });
ngOptions: 'option.id as option.title_or_filename for option in to.options', }
placeholder: gettextCatalog.getString('Select or search an attachment ...') // category
}, if (Category.getAll().length > 0) {
hideExpression: '!model.more' formFields.push({
}, key: 'category_id',
{ type: 'select-single',
key: 'category_id', templateOptions: {
type: 'select-single', label: gettextCatalog.getString('Category'),
templateOptions: { options: Category.getAll(),
label: gettextCatalog.getString('Category'), ngOptions: 'option.id as option.name for option in to.options',
options: Category.getAll(), placeholder: gettextCatalog.getString('Select or search a category ...')
ngOptions: 'option.id as option.name for option in to.options', },
placeholder: gettextCatalog.getString('Select or search a category ...') hideExpression: '!model.more'
}, });
hideExpression: '!model.more' }
}, // motion block
{ if (MotionBlock.getAll().length > 0) {
key: 'motion_block_id', formFields.push({
type: 'select-single', key: 'motion_block_id',
templateOptions: { type: 'select-single',
label: gettextCatalog.getString('Motion block'), templateOptions: {
options: MotionBlock.getAll(), label: gettextCatalog.getString('Motion block'),
ngOptions: 'option.id as option.title for option in to.options', options: MotionBlock.getAll(),
placeholder: gettextCatalog.getString('Select or search a motion block ...') ngOptions: 'option.id as option.title for option in to.options',
}, placeholder: gettextCatalog.getString('Select or search a motion block ...')
hideExpression: '!model.more' },
}, hideExpression: '!model.more'
{ });
}
// origin
formFields.push({
key: 'origin', key: 'origin',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettextCatalog.getString('Origin'), label: gettextCatalog.getString('Origin'),
}, },
hideExpression: '!model.more' hideExpression: '!model.more'
}, });
{ // tags
key: 'tags_id', if (Tag.getAll().length > 0) {
type: 'select-multiple', formFields.push({
templateOptions: { key: 'tags_id',
label: gettextCatalog.getString('Tags'), type: 'select-multiple',
options: Tag.getAll(), templateOptions: {
ngOptions: 'option.id as option.name for option in to.options', label: gettextCatalog.getString('Tags'),
placeholder: gettextCatalog.getString('Select or search a tag ...') options: Tag.getAll(),
}, ngOptions: 'option.id as option.name for option in to.options',
hideExpression: '!model.more' placeholder: gettextCatalog.getString('Select or search a tag ...')
}, },
{ hideExpression: '!model.more'
key: 'supporters_id', });
type: 'select-multiple', }
templateOptions: { // supporters
label: gettextCatalog.getString('Supporters'), if (Config.get('motions_min_supporters') > 0) {
options: User.getAll(), formFields.push({
ngOptions: 'option.id as option.full_name for option in to.options', key: 'supporters_id',
placeholder: gettextCatalog.getString('Select or search a supporter ...') type: 'select-multiple',
}, templateOptions: {
hideExpression: '!model.more' 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) { if (workflows.length > 1) {
formFields = formFields.concat([ formFields.push({
{ key: 'workflow_id',
key: 'workflow_id', type: 'select-single',
type: 'select-single', templateOptions: {
templateOptions: { label: gettextCatalog.getString('Workflow'),
label: gettextCatalog.getString('Workflow'), optionsAttr: 'bs-options',
optionsAttr: 'bs-options', options: workflows,
options: workflows, ngOptions: 'option.id as option.name | translate for option in to.options',
ngOptions: 'option.id as option.name | translate for option in to.options', placeholder: gettextCatalog.getString('Select or search a workflow ...')
placeholder: gettextCatalog.getString('Select or search a workflow ...') },
}, hideExpression: '!model.more',
hideExpression: '!model.more', });
}
]);
} }
return formFields; return formFields;
@ -1323,7 +1350,7 @@ angular.module('OpenSlidesApp.motions.site', [
// ... preselect default workflow // ... preselect default workflow
$scope.model.workflow_id = Config.get('motions_workflow').value; $scope.model.workflow_id = Config.get('motions_workflow').value;
// get all form fields // get all form fields
$scope.formFields = MotionForm.getFormFields(); $scope.formFields = MotionForm.getFormFields(true);
// save motion // save motion
$scope.save = function (motion) { $scope.save = function (motion) {

View File

@ -96,9 +96,9 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics'])
resolve: (resolve) ? resolve : null resolve: (resolve) ? resolve : null
}; };
}, },
getFormFields: function () { getFormFields: function (isCreateForm) {
var images = Mediafile.getAllImages(); var images = Mediafile.getAllImages();
return [ var formFields = [
{ {
key: 'title', key: 'title',
type: 'input', type: 'input',
@ -116,35 +116,45 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics'])
data: { data: {
tinymceOption: Editor.getOptions(images) tinymceOption: Editor.getOptions(images)
} }
}, }];
{ // attachments
key: 'attachments_id', if (Mediafile.getAll().length > 0) {
type: 'select-multiple', formFields.push({
templateOptions: { key: 'attachments_id',
label: gettextCatalog.getString('Attachment'), type: 'select-multiple',
options: Mediafile.getAll(), templateOptions: {
ngOptions: 'option.id as option.title_or_filename for option in to.options', label: gettextCatalog.getString('Attachment'),
placeholder: gettextCatalog.getString('Select or search an 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', key: 'showAsAgendaItem',
type: 'checkbox', type: 'checkbox',
templateOptions: { templateOptions: {
label: gettextCatalog.getString('Show as agenda item'), label: gettextCatalog.getString('Show as agenda item'),
description: gettextCatalog.getString('If deactivated it appears as internal item on agenda.') description: gettextCatalog.getString('If deactivated it appears as internal item on agenda.')
} }
}, });
{
key: 'agenda_parent_item_id', // parent item
type: 'select-single', if (isCreateForm) {
templateOptions: { formFields.push({
label: gettextCatalog.getString('Parent item'), key: 'agenda_parent_item_id',
options: AgendaTree.getFlatTree(Agenda.getAll()), type: 'select-single',
ngOptions: 'item.id as item.getListViewTitle() for item in to.options | notself : model.agenda_item_id', templateOptions: {
placeholder: gettextCatalog.getString('Select a parent item ...') 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 = {};
$scope.model.showAsAgendaItem = true; $scope.model.showAsAgendaItem = true;
// get all form fields // get all form fields
$scope.formFields = TopicForm.getFormFields(); $scope.formFields = TopicForm.getFormFields(true);
// save form // save form
$scope.save = function (topic) { $scope.save = function (topic) {
Topic.create(topic).then( Topic.create(topic).then(

View File

@ -292,6 +292,55 @@ angular.module('OpenSlidesApp.users.site', [
getFormFields: function (hideOnCreateForm) { getFormFields: function (hideOnCreateForm) {
var images = Mediafile.getAllImages(); var images = Mediafile.getAllImages();
return [ 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', key: 'username',
type: 'input', type: 'input',
@ -300,42 +349,6 @@ angular.module('OpenSlidesApp.users.site', [
}, },
hide: hideOnCreateForm 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', key: 'groups_id',
type: 'select-multiple', type: 'select-multiple',
@ -368,19 +381,20 @@ angular.module('OpenSlidesApp.users.site', [
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettextCatalog.getString('Comment'), label: gettextCatalog.getString('Comment'),
description: gettextCatalog.getString('Only for notes.') description: gettextCatalog.getString('Only for internal notes.')
} }
}, },
{ {
key: 'about_me', key: 'more',
type: 'editor', type: 'checkbox',
templateOptions: { templateOptions: {
label: gettextCatalog.getString('About me'), label: gettextCatalog.getString('Show extended fields')
},
data: {
tinymceOption: Editor.getOptions(images)
} }
}, },
{
template: '<hr class="smallhr">',
hideExpression: '!model.more'
},
{ {
key: 'is_present', key: 'is_present',
type: 'checkbox', type: 'checkbox',
@ -388,7 +402,8 @@ angular.module('OpenSlidesApp.users.site', [
label: gettextCatalog.getString('Is present'), label: gettextCatalog.getString('Is present'),
description: gettextCatalog.getString('Designates whether this user is in the room or not.') description: gettextCatalog.getString('Designates whether this user is in the room or not.')
}, },
defaultValue: true defaultValue: true,
hideExpression: '!model.more'
}, },
{ {
key: 'is_active', key: 'is_active',
@ -399,7 +414,8 @@ angular.module('OpenSlidesApp.users.site', [
'Designates whether this user should be treated as ' + 'Designates whether this user should be treated as ' +
'active. Unselect this instead of deleting the account.') 'active. Unselect this instead of deleting the account.')
}, },
defaultValue: true defaultValue: true,
hideExpression: '!model.more'
}, },
{ {
key: 'is_committee', key: 'is_committee',
@ -409,8 +425,21 @@ angular.module('OpenSlidesApp.users.site', [
description: gettextCatalog.getString( description: gettextCatalog.getString(
'Designates whether this user should be treated as a committee.') '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'
}
];
} }
}; };
} }