From 7acfbf2e30440d4a04ad6ea6d1c9958272c2785b Mon Sep 17 00:00:00 2001 From: Robbie Mackay Date: Thu, 18 Jun 2015 22:07:50 +1200 Subject: [PATCH] Post type editor Summary: What works: - View a list of all post types - add/edit/delete post types - Add/edit/delete form attributes - Add/edit/delete form stages - Attribute re-ordering - Stage re-ordering Still missing - Visible To/Editable By permissions - missing on the backend - Field instructions - also missing on the backend Test Plan: Edit a form, add stages and fields save and check they're reflected elsewhere. Same with a new form. Reviewers: aMoniker, vladimir, lkamau Subscribers: rjmackay, vladimir, lkamau, aMoniker Maniphest Tasks: T1139 Differential Revision: https://phabricator.ushahidi.com/D777 --- app/common/common-module.js | 1 + app/common/locales/en.json | 52 +++- .../services/endpoints/form-attributes.js | 6 + app/common/services/endpoints/form-stages.js | 31 +++ app/common/services/endpoints/form.js | 7 +- app/common/services/notify.js | 9 +- .../controllers/post-detail-controller.js | 2 +- app/post/controllers/post-edit-controller.js | 2 +- app/post/directives/post-preview-directive.js | 2 +- .../controllers/setting-forms-controller.js | 37 ++- .../setting-forms-create-controller.js | 35 +++ ...etting-forms-create-template-controller.js | 11 + .../setting-forms-edit-controller.js | 28 ++ .../setting-forms-edit-stage-controller.js | 28 ++ .../setting-form-editor-directive.js | 133 +++++++++ .../setting-form-stage-editor-directive.js | 258 ++++++++++++++++++ app/setting/setting-module.js | 2 + app/setting/setting-routes.js | 18 +- .../www/templates/partials/form-editor.html | 71 +++++ .../templates/partials/form-stage-editor.html | 154 +++++++++++ server/www/templates/partials/main-menu.html | 4 +- .../settings/forms-create-template.html | 13 + .../www/templates/settings/forms-create.html | 30 ++ .../templates/settings/forms-edit-stage.html | 11 + server/www/templates/settings/forms-edit.html | 10 + server/www/templates/settings/forms.html | 52 ++++ 26 files changed, 988 insertions(+), 19 deletions(-) create mode 100644 app/common/services/endpoints/form-stages.js create mode 100644 app/setting/controllers/setting-forms-create-controller.js create mode 100644 app/setting/controllers/setting-forms-create-template-controller.js create mode 100644 app/setting/controllers/setting-forms-edit-controller.js create mode 100644 app/setting/controllers/setting-forms-edit-stage-controller.js create mode 100644 app/setting/directives/setting-form-editor-directive.js create mode 100644 app/setting/directives/setting-form-stage-editor-directive.js create mode 100644 server/www/templates/partials/form-editor.html create mode 100644 server/www/templates/partials/form-stage-editor.html create mode 100644 server/www/templates/settings/forms-create-template.html create mode 100644 server/www/templates/settings/forms-create.html create mode 100644 server/www/templates/settings/forms-edit-stage.html create mode 100644 server/www/templates/settings/forms-edit.html create mode 100644 server/www/templates/settings/forms.html diff --git a/app/common/common-module.js b/app/common/common-module.js index 7341f95835..9c29448783 100644 --- a/app/common/common-module.js +++ b/app/common/common-module.js @@ -11,6 +11,7 @@ angular.module('ushahidi.common', [ .service('UserEndpoint', require('./services/endpoints/user-endpoint.js')) .service('FormEndpoint', require('./services/endpoints/form.js')) .service('FormAttributeEndpoint', require('./services/endpoints/form-attributes.js')) +.service('FormStageEndpoint', require('./services/endpoints/form-stages.js')) .service('TagEndpoint', require('./services/endpoints/tag.js')) .service('RoleHelper', require('./services/role-helper.js')) .service('Config', require('./services/config.js')) diff --git a/app/common/locales/en.json b/app/common/locales/en.json index d731cd0550..9315973fc3 100644 --- a/app/common/locales/en.json +++ b/app/common/locales/en.json @@ -6,10 +6,46 @@ "forbidden": "Sorry, you're not allowed to do that." }, "form": { - "add_field" : "Add Field", - "edit_field" : "Edit Field", + "add_field" : "Add New Field", + "add_field_instructions": "Add instructions to this field", + "add_field_instructions_info": "These instructions will be presented as a tooltip to a user when filling in this field.", + "add_field_instructions_placeholder": "Instructions for field", + "add_new_step": "Add New Step", + "currently_disabled": "This post type is currently disabled.", + "custom_structure": "Custom Structure", + "default_date_placeholder": "Default date", + "default_default_placeholder": "Default value", + "default_location_placeholder": "Nairobi, Kenya", + "delete_post_type": "Delete this post type", + "editable_by": "Editable By", + "edit_post_step": "Edit Step: {{step}}", + "edit_post_type": "Edit Post Type: {{form}}", + "field_add_option": "Add", + "field_default": "Field Default", + "field_key": "Field Key", + "field_input": "Field Input", + "field_type": "Field Storage", + "field_name": "Field Name", + "field_options": "Field Options", + "field_key_placeholder": "field-key", + "field_name_placeholder": "Title", + "field_option_placeholder": "Option 1", + "field_required": "This field is required", + "form_name": "Post Type Name", + "form_description": "Post Type Description", "forms" : "Forms", - "type" : "type" + "permission_public": "Public", + "permission_admin": "Admin", + "permission_self": "Only Me", + "post_type_settings": "Post Type Settings", + "post_step_settings": "Post Step Settings", + "save_and_close": "Save & Close", + "save_post_type": "Save Post Type", + "save_post_step": "Save Post Step", + "step_name": "Step Name", + "step_required": "This step is required", + "type" : "type", + "visible_to": "Visible To" }, "globalFilter": { "filter" : "Filter", @@ -99,7 +135,7 @@ "please_wait_loading" : "Please wait. Loading...", "plugins" : "Plugins", "posts" : "Posts", - "posts_and_entities" : "Posts & Entites", + "posts_and_entities" : "Post Types", "profile": "My Profile", "role" : "Role", "roles" : "Roles", @@ -372,13 +408,19 @@ "destroy_error" : "Unable to delete user, please try again", "bulk_destroy_confirm" : "Are you sure you want to delete {{count}} users?", "bulk_role_change_confirm": "Are you sure you want to change the role of {{count}} users to {{role}}?" + }, + "form" : { + "delete_form_confirm" : "Are you sure you want to delete this form?", + "delete_stage_confirm" : "Are you sure you want to delete this step?", + "delete_attribute_confirm" : "Are you sure you want to delete this field?" } }, "empty": { "default" : "No records found.", "post" : "No posts found.", "user" : "No users found.", - "category" : "No categories found." + "category" : "No categories found.", + "form": "No forms found." }, "location": { "search": "Search", diff --git a/app/common/services/endpoints/form-attributes.js b/app/common/services/endpoints/form-attributes.js index c69d0cac86..d571aadbb4 100644 --- a/app/common/services/endpoints/form-attributes.js +++ b/app/common/services/endpoints/form-attributes.js @@ -18,6 +18,12 @@ function ( transformResponse: function (data /*, header*/) { return Util.transformResponse(data).results; } + }, + update: { + method: 'PUT' + }, + delete: { + method: 'DELETE' } }); diff --git a/app/common/services/endpoints/form-stages.js b/app/common/services/endpoints/form-stages.js new file mode 100644 index 0000000000..ee692e4595 --- /dev/null +++ b/app/common/services/endpoints/form-stages.js @@ -0,0 +1,31 @@ +module.exports = [ + '$resource', + 'Util', +function ( + $resource, + Util +) { + + var FormStageEndpoint = $resource(Util.apiUrl('/forms/:formId/stages/:id'), { + formId: '@formId', + id: '@id', + order: 'asc', + orderby: 'priority' + }, { + query: { + method: 'GET', + isArray: true, + transformResponse: function (data /*, header*/) { + return Util.transformResponse(data).results; + } + }, + update: { + method: 'PUT' + }, + delete: { + method: 'DELETE' + } + }); + + return FormStageEndpoint; +}]; diff --git a/app/common/services/endpoints/form.js b/app/common/services/endpoints/form.js index 63fa43dc15..6fccd8ea11 100644 --- a/app/common/services/endpoints/form.js +++ b/app/common/services/endpoints/form.js @@ -6,8 +6,8 @@ function ( Util ) { - var FormEndpoint = $resource(Util.apiUrl('/forms/:formId'), { - formId: '@formId' + var FormEndpoint = $resource(Util.apiUrl('/forms/:id'), { + id: '@id' }, { query: { method: 'GET', @@ -15,6 +15,9 @@ function ( transformResponse: function (data /*, header*/) { return Util.transformResponse(data).results; } + }, + update: { + method: 'PUT' } }); diff --git a/app/common/services/notify.js b/app/common/services/notify.js index 8f0f00ed0b..c6bf9edf73 100644 --- a/app/common/services/notify.js +++ b/app/common/services/notify.js @@ -12,9 +12,16 @@ module.exports = ['$window', function ($window) { alertMessages.forEach(showSingleAlert); }; + var showConfirm = function (confirmMessage) { + // TODO: find a better solution for that + var confirm = $window.confirm(confirmMessage); + return confirm; + }; + return { showSingleAlert: showSingleAlert, - showAlerts: showAlerts + showAlerts: showAlerts, + showConfirm: showConfirm }; }]; diff --git a/app/post/controllers/post-detail-controller.js b/app/post/controllers/post-detail-controller.js index 804392a17d..7734891763 100644 --- a/app/post/controllers/post-detail-controller.js +++ b/app/post/controllers/post-detail-controller.js @@ -58,7 +58,7 @@ function ( if ($scope.post.form && $scope.post.form.id) { $scope.form_attributes = []; - FormEndpoint.get({formId: $scope.post.form.id}, function (form) { + FormEndpoint.get({id: $scope.post.form.id}, function (form) { $scope.form_name = form.name; // Set page title to '{form.name} Details' if a post title isn't provided. diff --git a/app/post/controllers/post-edit-controller.js b/app/post/controllers/post-edit-controller.js index f7f9425dd2..a3919b747f 100644 --- a/app/post/controllers/post-edit-controller.js +++ b/app/post/controllers/post-edit-controller.js @@ -35,7 +35,7 @@ function ( post.tags = tags; $scope.post = post; - $scope.active_form = FormEndpoint.get({ formId: post.form.id }, function (form) { + $scope.active_form = FormEndpoint.get({ id: post.form.id }, function (form) { // Set page title to post title, if there is one available. if (post.title && post.title.length) { $translate('post.modify.edit_type', { type: form.name, title: post.title }).then(function (title) { diff --git a/app/post/directives/post-preview-directive.js b/app/post/directives/post-preview-directive.js index 00af6db2e2..0ae3f7d300 100644 --- a/app/post/directives/post-preview-directive.js +++ b/app/post/directives/post-preview-directive.js @@ -23,7 +23,7 @@ function ( }); if (scope.post.form) { - FormEndpoint.get({formId: scope.post.form.id}, function (form) { + FormEndpoint.get({id: scope.post.form.id}, function (form) { scope.form_name = form.name; }); } else { diff --git a/app/setting/controllers/setting-forms-controller.js b/app/setting/controllers/setting-forms-controller.js index 1e7df19e21..398b15fd7a 100644 --- a/app/setting/controllers/setting-forms-controller.js +++ b/app/setting/controllers/setting-forms-controller.js @@ -1,14 +1,41 @@ module.exports = [ '$scope', '$translate', + '$location', + 'FormEndpoint', function ( $scope, - $translate + $translate, + $location, + FormEndpoint ) { - $translate('tool.manage_forms').then(function (title) { - $scope.title = title; - $scope.$emit('setPageTitle', title); - }); + $translate('nav.posts_and_entities').then(function (title) { + $scope.title = title; + $scope.$emit('setPageTitle', title); + }); + + // Get all the forms for display + FormEndpoint.get().$promise.then(function (response) { + $scope.forms = response.results; + }); + + // Manage new form settings + $scope.isNewFormOpen = false; + $scope.openNewForm = function () { + $scope.newForm = {}; + $scope.isNewFormOpen = !$scope.isNewFormOpen; + }; + $scope.saveNewForm = function (form) { + FormEndpoint + .save(form) + .$promise + .then(function (form) { + $scope.isNewFormOpen = false; + $scope.newForm = {}; + $location.url('/settings/forms/' + form.id); + }); + }; + // End new form }]; diff --git a/app/setting/controllers/setting-forms-create-controller.js b/app/setting/controllers/setting-forms-create-controller.js new file mode 100644 index 0000000000..9d65715e57 --- /dev/null +++ b/app/setting/controllers/setting-forms-create-controller.js @@ -0,0 +1,35 @@ +module.exports = [ + '$scope', + '$q', + 'FormEndpoint', + 'FormAttributeEndpoint', + '_', +function ( + $scope, + $q, + FormEndpoint, + FormAttributeEndpoint, + _ +) { + + // Get all the forms for display + FormEndpoint.get().$promise.then(function (response) { + var forms = response.results; + + // Get all form attributes for each form + var attribute_promises = []; + _.each(forms, function (form) { + attribute_promises.push( + FormAttributeEndpoint.query({ formId: form.id }).$promise + ); + }); + + $q.all(attribute_promises).then(function (data) { + _.each(data, function (datum, idx) { + forms[idx].attributes = [].concat(data[idx]); + }); + $scope.forms = forms; + }); + }); + +}]; diff --git a/app/setting/controllers/setting-forms-create-template-controller.js b/app/setting/controllers/setting-forms-create-template-controller.js new file mode 100644 index 0000000000..58a3a68491 --- /dev/null +++ b/app/setting/controllers/setting-forms-create-template-controller.js @@ -0,0 +1,11 @@ +module.exports = [ + '$scope', + '$routeParams', +function ( + $scope, + $routeParams +) { + + $scope.form_template = $routeParams.id; + +}]; diff --git a/app/setting/controllers/setting-forms-edit-controller.js b/app/setting/controllers/setting-forms-edit-controller.js new file mode 100644 index 0000000000..372755d363 --- /dev/null +++ b/app/setting/controllers/setting-forms-edit-controller.js @@ -0,0 +1,28 @@ +module.exports = [ + '$scope', + '$routeParams', + '$q', + 'FormEndpoint', + 'FormStageEndpoint', +function ( + $scope, + $routeParams, + $q, + FormEndpoint, + FormStageEndpoint +) { + + $scope.formId = $routeParams.id; + + // If we're editing an existing form, + // load the form info and all the fields. + $q.all([ + FormEndpoint.get({ id: $scope.formId }).$promise, + FormStageEndpoint.query({ formId: $scope.formId }).$promise + ]).then(function (results) { + var form = results[0]; + form.stages = results[1]; + $scope.form = form; + }); + +}]; diff --git a/app/setting/controllers/setting-forms-edit-stage-controller.js b/app/setting/controllers/setting-forms-edit-stage-controller.js new file mode 100644 index 0000000000..2cb495b0b6 --- /dev/null +++ b/app/setting/controllers/setting-forms-edit-stage-controller.js @@ -0,0 +1,28 @@ +module.exports = [ + '$scope', + '$routeParams', + '$q', + 'FormEndpoint', + 'FormStageEndpoint', +function ( + $scope, + $routeParams, + $q, + FormEndpoint, + FormStageEndpoint +) { + + $scope.formId = $routeParams.formId; + $scope.stageId = $routeParams.id; + + // If we're editing an existing form, + // load the form info and all the fields. + $q.all([ + FormEndpoint.get({ id: $scope.formId }).$promise, + FormStageEndpoint.get({ formId: $scope.formId, id: $scope.stageId }).$promise + ]).then(function (results) { + $scope.form = results[0]; + $scope.stage = results[1]; + }); + +}]; diff --git a/app/setting/directives/setting-form-editor-directive.js b/app/setting/directives/setting-form-editor-directive.js new file mode 100644 index 0000000000..4a6de43915 --- /dev/null +++ b/app/setting/directives/setting-form-editor-directive.js @@ -0,0 +1,133 @@ +module.exports = [ + '$q', + '$location', + '$translate', + 'FormEndpoint', + 'FormStageEndpoint', + 'FormAttributeEndpoint', + '_', + 'Notify', +function ( + $q, + $location, + $translate, + FormEndpoint, + FormStageEndpoint, + FormAttributeEndpoint, + _, + Notify +) { + return { + restrict: 'E', + replace: true, + scope: { + formId: '@', + formTemplate: '@' + }, + templateUrl: 'templates/partials/form-editor.html', + link: function ($scope, $element, $attrs) { + // If we're editing an existing form, + // load the form info and all the fields. + $q.all([ + FormEndpoint.get({ id: $attrs.formId }).$promise, + FormStageEndpoint.query({ formId: $attrs.formId }).$promise + ]).then(function (results) { + var form = results[0]; + form.stages = _.sortBy(results[1], 'priority'); + $scope.form = form; + }); + + $scope.isSettingsOpen = false; + $scope.openSettings = function () { + $scope.isSettingsOpen = !$scope.isSettingsOpen; + }; + + $scope.saveFormSettings = function (form) { + FormEndpoint + .update(form) + .$promise + .then(function () { + $scope.isSettingsOpen = false; + }); + }; + + $scope.deleteForm = function (stage) { + $translate('notify.form.delete_form_confirm') + .then(function (message) { + if (Notify.showConfirm(message)) { + FormEndpoint.delete({ + id: $scope.form.id + }).$promise.then(function () { + $location.url('/settings/forms'); + }); + } + }); + }; + + $scope.deleteStage = function (stage, $index) { + $translate('notify.form.delete_stage_confirm') + .then(function (message) { + if (Notify.showConfirm(message)) { + FormStageEndpoint.delete({ + formId: $scope.form.id, + id: stage.id + }).$promise.then(function () { + // Remove stage from scope, binding should take care of the rest + delete $scope.form.stages[$index]; + }); + } + }); + }; + + $scope.changePriority = function (stage, increment) { + var stages = $scope.form.stages, + // Find our current stage + index = _.indexOf(stages, stage), + // Grab prev/next stage + next = stages[index + increment]; + + // Check we're not at the end of the list + if (_.isUndefined(next)) { + return; + } + + // Swap priorities + next.priority = stage.priority; + stage.priority = stage.priority + increment; + + // Save stage + FormStageEndpoint.update(_.extend(stage, { + formId: $scope.form.id + })); + + // Save adjacent stage + FormStageEndpoint.update(_.extend(next, { + formId: $scope.form.id + })); + + // Resort stage list + $scope.form.stages = _.sortBy(stages, 'priority'); + }; + + // Manage stage settings + $scope.isNewStageOpen = false; + $scope.openNewStage = function () { + $scope.newStage = {}; + $scope.isNewStageOpen = !$scope.isNewStageOpen; + }; + $scope.saveNewStage = function (stage) { + FormStageEndpoint + .save(_.extend(stage, { + formId: $scope.form.id + })) + .$promise + .then(function (stage) { + $scope.isNewStageOpen = false; + $scope.newStage = {}; + $location.url('/settings/forms/' + $scope.form.id + '/stages/' + stage.id); + }); + }; + // End manage stage + } + }; +}]; diff --git a/app/setting/directives/setting-form-stage-editor-directive.js b/app/setting/directives/setting-form-stage-editor-directive.js new file mode 100644 index 0000000000..1744aab84b --- /dev/null +++ b/app/setting/directives/setting-form-stage-editor-directive.js @@ -0,0 +1,258 @@ +module.exports = [ + '$q', + '$location', + '$translate', + 'FormEndpoint', + 'FormStageEndpoint', + 'FormAttributeEndpoint', + '_', + 'Notify', +function ( + $q, + $location, + $translate, + FormEndpoint, + FormStageEndpoint, + FormAttributeEndpoint, + _, + Notify +) { + return { + restrict: 'E', + replace: true, + scope: { + formId: '@', + formTemplate: '@', + stageId: '@' + }, + templateUrl: 'templates/partials/form-stage-editor.html', + link: function ($scope, $element, $attrs) { + var stageId = $attrs.stageId; + + $scope.editIsOpen = {}; + + // If we're editing an existing form, + // load the form info and all the fields. + $q.all([ + FormEndpoint.get({ id: $attrs.formId }).$promise, + FormStageEndpoint.query({ formId: $attrs.formId }).$promise, + FormAttributeEndpoint.query({ formId: $attrs.formId }).$promise + ]).then(function (results) { + var form = results[0], + firstStage = results[1][0].id, + currentStageId = parseInt(stageId ? stageId : firstStage); + + form.stages = _.indexBy(results[1], 'id'); + form.attributes = _.chain(results[2]) + .where({ form_stage_id : currentStageId }) + .sortBy('priority') + .value(); + + $scope.form = form; + $scope.currentStageId = currentStageId; + }); + + // Manage stage settings + $scope.isSettingsOpen = false; + $scope.openSettings = function () { + $scope.isSettingsOpen = !$scope.isSettingsOpen; + }; + $scope.saveStageSettings = function (stage) { + FormStageEndpoint + .update(_.extend(stage, { + formId: $scope.form.id + })) + .$promise + .then(function () { + $scope.isSettingsOpen = false; + }); + }; + // End manage stage + + // Manage stage settings + $scope.isNewStageOpen = false; + $scope.openNewStage = function () { + $scope.newStage = {}; + $scope.isNewStageOpen = !$scope.isNewStageOpen; + }; + $scope.saveNewStage = function (stage) { + FormStageEndpoint + .save(_.extend(stage, { + formId: $scope.form.id + })) + .$promise + .then(function (stage) { + $scope.isNewStageOpen = false; + $scope.newStage = {}; + $location.url('/settings/forms/' + $scope.form.id + '/stages/' + stage.id); + }); + }; + // End manage stage + + // Add new attribute + $scope.availableAttrTypes = [ + { + label: 'Short text', + type: 'varchar', + input: 'text' + }, + { + label: 'Long text', + type: 'text', + input: 'textarea' + }, + { + label: 'Number (Decimal)', + type: 'decimal', + input: 'number' + }, + { + label: 'Number (Integer)', + type: 'int', + input: 'number' + }, + { + label: 'Location', + type: 'point', + input: 'location' + }, + // { + // label: 'Geometry', + // type: 'geometry', + // input: 'text' + // }, + { + label: 'Date', + type: 'date', + input: 'date' + }, + { + label: 'Date & time', + type: 'datetime', + input: 'datetime' + }, + // { + // label: 'Time', + // type: 'datetime', + // input: 'time' + // }, + { + label: 'Select', + type: 'varchar', + input: 'select' + }, + { + label: 'Radio', + type: 'varchar', + input: 'radio' + }, + { + label: 'Checkbox', + type: 'varchar', + input: 'checkbox' + } + ]; + $scope.isNewAttributeOpen = false; + var newAttrCount = 0; + $scope.openNewAttribute = function () { + $scope.isNewAttributeOpen = true; + }; + $scope.addNewAttribute = function (type, input) { + newAttrCount++; + $scope.isNewAttributeOpen = false; + var attribute = { + type: type, + input: input, + label: 'New field', + required: false, + options: [], + form_stage_id: $scope.currentStageId + }; + + $scope.form.attributes.push(attribute); + $scope.editIsOpen[$scope.form.attributes.length - 1] = true; + }; + // End add new attribute + + // Attribute Functions + $scope.saveAttribute = function (attribute, $index) { + var persist = attribute.id ? FormAttributeEndpoint.update : FormAttributeEndpoint.save; + persist(_.extend(attribute, { + formId: $scope.form.id + })).$promise.then(function (attributeUpdate) { + $scope.editIsOpen[$index] = false; + $scope.form.attributes[$index] = attributeUpdate; + }); + }; + + $scope.deleteAttribute = function (attribute, $index) { + + $translate('notify.form.delete_attribute_confirm') + .then(function (message) { + if (Notify.showConfirm(message)) { + if (attribute.id) { + FormAttributeEndpoint.delete({ + formId: $scope.form.id, + id: attribute.id + }).$promise.then(function () { + // Remove attribute from scope, binding should take care of the rest + delete $scope.form.attributes[$index]; + }); + } else { // If this was a new attribute, just remove from scope + // Remove attribute from scope, binding should take care of the rest + delete $scope.form.attributes[$index]; + } + } + }); + }; + + $scope.changePriority = function (attribute, increment) { + var attributes = $scope.form.attributes, + // Find our current stage + index = _.indexOf(attributes, attribute), + // Grab prev/next stage + next = attributes[index + increment]; + + // Check we're not at the end of the list + if (_.isUndefined(next)) { + return; + } + + // Swap priorities + next.priority = attribute.priority; + attribute.priority = attribute.priority + increment; + + // Save attribute + FormAttributeEndpoint.update(_.extend(attribute, { + formId: $scope.form.id + })); + + // Save adjacent attribute + FormAttributeEndpoint.update(_.extend(next, { + formId: $scope.form.id + })); + + // Resort attribute list + $scope.form.attributes = _.sortBy(attributes, 'priority'); + }; + + // Options functions + $scope.hasOptions = function (attribute) { + return _.contains(['checkbox', 'radio', 'select'], attribute.input); + }; + $scope.removeOption = function (attribute, key) { + attribute.options.splice(key, 1); + }; + $scope.addOption = function (attribute) { + attribute.options.push(''); + }; + + // Update key based on label + $scope.labelChanged = function (attribute) { + if (!attribute.id) { + attribute.key = attribute.label.replace(/\s+/g, '-').replace(/[^a-zA-Z0-9-_]+/g, '').toLowerCase(); + } + }; + } + }; +}]; diff --git a/app/setting/setting-module.js b/app/setting/setting-module.js index 52699ae140..9d162a75b6 100644 --- a/app/setting/setting-module.js +++ b/app/setting/setting-module.js @@ -5,4 +5,6 @@ angular.module('ushahidi.tools', [ 'colorpicker.module', 'xeditable' ]) +.directive('formEditor', require('./directives/setting-form-editor-directive.js')) +.directive('formStageEditor', require('./directives/setting-form-stage-editor-directive.js')) .config(require('./setting-routes.js')); diff --git a/app/setting/setting-routes.js b/app/setting/setting-routes.js index 94e1cfaf4c..d9e06cfe03 100644 --- a/app/setting/setting-routes.js +++ b/app/setting/setting-routes.js @@ -22,7 +22,23 @@ function ( }) .when('/settings/forms', { controller: require('./controllers/setting-forms-controller.js'), - templateUrl: 'templates/settings/todo.html' + templateUrl: 'templates/settings/forms.html' + }) + .when('/settings/forms/create', { + controller: require('./controllers/setting-forms-create-controller.js'), + templateUrl: 'templates/settings/forms-create.html' + }) + .when('/settings/forms/create/:id', { + controller: require('./controllers/setting-forms-create-template-controller.js'), + templateUrl: 'templates/settings/forms-create-template.html' + }) + .when('/settings/forms/:id', { + controller: require('./controllers/setting-forms-edit-controller.js'), + templateUrl: 'templates/settings/forms-edit.html' + }) + .when('/settings/forms/:formId/stages/:id', { + controller: require('./controllers/setting-forms-edit-stage-controller.js'), + templateUrl: 'templates/settings/forms-edit-stage.html' }) .when('/settings/categories', { controller: require('./controllers/setting-categories-controller.js'), diff --git a/server/www/templates/partials/form-editor.html b/server/www/templates/partials/form-editor.html new file mode 100644 index 0000000000..5492b3bacc --- /dev/null +++ b/server/www/templates/partials/form-editor.html @@ -0,0 +1,71 @@ +
+

form.edit_post_type

+ + form.post_type_settings + +
+ + +

form.post_type_settings

+
+ +
+ + + + +
+ + +
+ +
+ +

Steps

+ +
+
+
+ + +
+

{{ stage.label }} + +

+ +
+ +
+ + form.delete_post_type + + +
+ + + +
+ + +
+ +
diff --git a/server/www/templates/partials/form-stage-editor.html b/server/www/templates/partials/form-stage-editor.html new file mode 100644 index 0000000000..6b5792cf8a --- /dev/null +++ b/server/www/templates/partials/form-stage-editor.html @@ -0,0 +1,154 @@ +
+

form.edit_post_step

+ + form.post_step_settings + + +

form.post_step_settings

+
+ +
+ + + +
+ + +
+ +
+ + + +
+ +
+
+
+ + +
+

{{ attribute.label }}

+
+ + +
+
+ + + + + + + +
+ + + + + +
+
+ +
+ + +
+ +
+ +

+ +

+

+ + +

+

+ + +

+ + +
+
+ +
+ +
+ + + + + + + + +
+ + + +
+ + +
+
diff --git a/server/www/templates/partials/main-menu.html b/server/www/templates/partials/main-menu.html index 6436523bfc..6c9392a9e9 100644 --- a/server/www/templates/partials/main-menu.html +++ b/server/www/templates/partials/main-menu.html @@ -19,8 +19,8 @@
  • nav.general
  • nav.appearance
  • +
  • nav.plugins
  • --> +
  • nav.posts_and_entities
  • nav.categories
  • nav.users
  • diff --git a/server/www/templates/settings/forms-create-template.html b/server/www/templates/settings/forms-create-template.html new file mode 100644 index 0000000000..f96042032d --- /dev/null +++ b/server/www/templates/settings/forms-create-template.html @@ -0,0 +1,13 @@ +
    + + +

    {{title}}

    + +
    + + +
    diff --git a/server/www/templates/settings/forms-create.html b/server/www/templates/settings/forms-create.html new file mode 100644 index 0000000000..4abd266662 --- /dev/null +++ b/server/www/templates/settings/forms-create.html @@ -0,0 +1,30 @@ +
    + + +

    {{title}}

    + +
    + + + +
    diff --git a/server/www/templates/settings/forms-edit-stage.html b/server/www/templates/settings/forms-edit-stage.html new file mode 100644 index 0000000000..c5fbf091ee --- /dev/null +++ b/server/www/templates/settings/forms-edit-stage.html @@ -0,0 +1,11 @@ +
    + + + + +
    diff --git a/server/www/templates/settings/forms-edit.html b/server/www/templates/settings/forms-edit.html new file mode 100644 index 0000000000..b50d978c7c --- /dev/null +++ b/server/www/templates/settings/forms-edit.html @@ -0,0 +1,10 @@ +
    + + + + +
    diff --git a/server/www/templates/settings/forms.html b/server/www/templates/settings/forms.html new file mode 100644 index 0000000000..55431350a0 --- /dev/null +++ b/server/www/templates/settings/forms.html @@ -0,0 +1,52 @@ +
    + + +

    {{title}}

    +

    + Post types define the structure of posts in your deployment. +

    + +
    + +

    Start from scratch:

    + + +
    +

    Or edit existing post types:

    + + +
    + + +

    form.post_type_settings

    +
    + +
    + + + + +
    + + +
    + +