diff --git a/Dashboard/app/cljs/src/org/akvo/flow/dashboard/user_auth/store.cljs b/Dashboard/app/cljs/src/org/akvo/flow/dashboard/user_auth/store.cljs index 57ea8f1c53..76a3d4dd0d 100644 --- a/Dashboard/app/cljs/src/org/akvo/flow/dashboard/user_auth/store.cljs +++ b/Dashboard/app/cljs/src/org/akvo/flow/dashboard/user_auth/store.cljs @@ -45,15 +45,17 @@ (dispatch-loop :user-auth/create auth - (let [{:keys [user role object-path]} auth] + (let [{:keys [user role object-path object-id]} auth] (assert (integer? user)) (assert (integer? role)) (assert (string? object-path)) + (assert (integer? object-id)) (POST "/rest/user_auth" (merge ajax/default-ajax-config {:params {"userId" user "roleId" role - "objectPath" object-path} + "objectPath" object-path + "securedObjectId" object-id} :handler (fn [{:strs [user_auth]}] (swap! app-state assoc-in [:user-auth :by-id (get user_auth "keyId")] user_auth) (swap! app-state update-in [:user-auth :by-user-id (get user_auth "userId")] conj user_auth))})))) diff --git a/Dashboard/app/cljs/src/org/akvo/flow/dashboard/users/user_details.cljs b/Dashboard/app/cljs/src/org/akvo/flow/dashboard/users/user_details.cljs index 6da75f210c..30e9f28706 100644 --- a/Dashboard/app/cljs/src/org/akvo/flow/dashboard/users/user_details.cljs +++ b/Dashboard/app/cljs/src/org/akvo/flow/dashboard/users/user_details.cljs @@ -147,7 +147,7 @@ [:h2 (t> _roles_and_permissions) ":"] [:div.form-inline.text-left.paddingTop.roleEditSelect {:role "name"} [:div.form-group - (om/build b/dropdown ;;b/select + (om/build b/dropdown {:placeholder (t> _select_a_role) :selected selected-role :data (store/get-roles roles-store) @@ -183,7 +183,7 @@ current-user-id)))] (contains? object-paths "/"))))) (cons {"name" (t> _all_folders) "keyId" 0 "projectType" "PROJECT_FOLDER"} - (projects-store/get-projects projects-store nil)) + (projects-store/get-projects projects-store 0)) (projects-store/get-projects projects-store (get (peek selected-folders) "keyId")))] (om/build b/dropdown {:placeholder (t> _select_a_folder_or_survey) @@ -207,7 +207,8 @@ (str "/" (->> selected-folders (map #(get % "name")) - (str/join "/"))))}))} + (str/join "/")))) + :object-id (or (get (last selected-folders) "keyId") 0)}))} :plus (t> _add))]] (om/build grid {:data (when-let [user-id (get user "keyId")] diff --git a/Dashboard/app/css/library.scss b/Dashboard/app/css/library.scss index 256d51c088..554bda61ee 100644 --- a/Dashboard/app/css/library.scss +++ b/Dashboard/app/css/library.scss @@ -137,3 +137,28 @@ $width-large: 1200px; color: $color; } } + + +@mixin flexbox { + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} + +@mixin flex($values) { + -webkit-box-flex: $values; + -moz-box-flex: $values; + -webkit-flex: $values; + -ms-flex: $values; + flex: $values; +} + +@mixin order($val) { + -webkit-box-ordinal-group: $val; + -moz-box-ordinal-group: $val; + -ms-flex-order: $val; + -webkit-order: $val; + order: $val; +} \ No newline at end of file diff --git a/Dashboard/app/css/main.scss b/Dashboard/app/css/main.scss index a96ccd9f0b..729d458076 100644 --- a/Dashboard/app/css/main.scss +++ b/Dashboard/app/css/main.scss @@ -502,50 +502,52 @@ input[type="submit"] { } } + .editAnswerMenu { position: relative; margin: 10px auto; width: 100%; background: rgb(205, 205, 205); ul { - position: relative; - width: 100%; - padding: 1.5em 0.5em; + @include flexbox; + -webkit-align-items: center; + align-items: center; + -webkit-align-content: center; + align-content: center; + -webkit-justify-content: space-around; + justify-content: space-around; + padding:15px 0; li { - display: inline; - margin: 0 0 10px 0; + flex-grow:1; + text-align:center; + &.deleteBtn { + position: initial; + display: relative; + top:10px; + left:45%; + } + &:first-child { + margin-left: 0.5%; + text-align: left; + } + &:last-child { + margin-right: 0.5%; + text-align:right; + } } } } .prevNext { - position: relative; - display: block; margin: 0 auto; padding: 1em 2% 1.5em 2%; width: 96%; background: $darkGrey; - .prevBtn { - position: absolute; - top: 0; - left: 0; - a { - font-weight: bold; - font-size: 1.2em; - display: inline-block; - padding: 0.5em 1em 1em 1em; - } - } - .nextBtn { - position: absolute; - top: 0; - right: 0; - a { - font-weight: bold; - font-size: 1.2em; - display: inline-block; - padding: 0.5em 1em 1em 1em; - } + a { + font-weight: bold; + font-size: 1.2em; + display: inline-block; + padding: 0.5em 1em 1em 1em; } } diff --git a/Dashboard/app/js/lib/controllers/data-controllers.js b/Dashboard/app/js/lib/controllers/data-controllers.js index 57eccafcd1..a77663e44e 100644 --- a/Dashboard/app/js/lib/controllers/data-controllers.js +++ b/Dashboard/app/js/lib/controllers/data-controllers.js @@ -211,8 +211,9 @@ FLOW.surveyInstanceControl = Ember.ArrayController.create({ this.set('content', FLOW.store.findQuery(FLOW.SurveyInstance, {})); }, - doInstanceQuery: function (surveyId, deviceId, since, beginDate, endDate, submitterName, countryCode, level1, level2) { + doInstanceQuery: function (surveyInstanceId, surveyId, deviceId, since, beginDate, endDate, submitterName, countryCode, level1, level2) { this.set('content', FLOW.store.findQuery(FLOW.SurveyInstance, { + 'surveyInstanceId': surveyInstanceId, 'surveyId': surveyId, 'deviceId': deviceId, 'since': since, diff --git a/Dashboard/app/js/lib/controllers/survey-controllers.js b/Dashboard/app/js/lib/controllers/survey-controllers.js index f9d5aa680d..e69c5e26b6 100644 --- a/Dashboard/app/js/lib/controllers/survey-controllers.js +++ b/Dashboard/app/js/lib/controllers/survey-controllers.js @@ -148,9 +148,9 @@ FLOW.surveyGroupControl = Ember.ArrayController.create({ // load all Survey Groups populate: function (f) { - var fn = (f && $.isFunction(f) && f) || FLOW.alwaysTrue; - FLOW.store.find(FLOW.SurveyGroup); - this.setFilteredContent(fn); + var fn = (f && $.isFunction(f) && f) || FLOW.alwaysTrue; + FLOW.store.find(FLOW.SurveyGroup); + this.setFilteredContent(fn); }, // checks if data store contains surveys within this survey group. @@ -193,16 +193,16 @@ FLOW.surveyGroupControl = Ember.ArrayController.create({ path whether or not a user is able to delete data in the group. Used for monitoring groups */ userCanDeleteData: function(surveyGroupId) { - var surveyGroupPath; + var ancestorIds; var surveyGroups = FLOW.store.filter(FLOW.SurveyGroup, function(sg){ return sg.get('keyId') === surveyGroupId; }); if(surveyGroups && surveyGroups.get('firstObject')) { - surveyGroupPath = surveyGroups.get('firstObject').get('path'); - return FLOW.userControl.canDeleteData(surveyGroupPath); + ancestorIds = surveyGroups.get('firstObject').get('ancestorIds'); + return FLOW.userControl.canDeleteData(ancestorIds); } else { - return false; // need survey group and path, otherwise prevent delete + return false; // need survey group and ancestorIds, otherwise prevent delete } }, }); @@ -229,30 +229,43 @@ FLOW.projectControl = Ember.ArrayController.create({ window.scrollTo(0,0); }, - /* return true if the given SurveyGroup's path (partially) matches or is one of the ancestors (paths) of a path for which the data cleaning permission is present. The ancestor SurveyGroups are needed in order to be able to browse to the actual path to which the permission is assigned */ + /* return true if the given SurveyGroup's has the data cleaning permission + * associated with it, or if one of the ancestors or descendants of the SurveyGroup + * has data cleaning permission associated with it. In the case of descendants we + * return true in order to be able to browse to the descendant */ dataCleaningEnabled: function(surveyGroup) { - var pathPermissions = FLOW.userControl.currentUserPathPermissions(); - var permissionList; - var pathStartsWithPattern; - var matched = false; - for (var key in pathPermissions) { - permissionList = pathPermissions[key]; - if(permissionList.indexOf("DATA_CLEANING") > -1){ - pathStartsWithPattern = new RegExp('^' + key); - if(surveyGroup.get('path').match(pathStartsWithPattern)) { - matched = true; - break; - } else { - // match all the ancestor paths to enable browsing to lower level paths - FLOW.surveyGroupControl.ancestorPaths(key).forEach(function (path) { - if(!matched && surveyGroup.get('path') === path) { - matched = true; - } - }); + var permissions = FLOW.userControl.currentUserPathPermissions(); + var keyedSurvey; + + for (var key in permissions) { + if(permissions[key].indexOf("DATA_CLEANING") > -1){ + // check key against survey group + if(surveyGroup.get('keyId') === +key) { + return true; + } + + // check ancestors to for matching permission from higher level in hierarchy + var ancestorIds = surveyGroup.get('ancestorIds'); + for(var i = 0; i < ancestorIds.length; i++){ + if(ancestorIds[i] === +key) { + return true; + } + } + + // finally check for all descendents that may have surveyGroup.keyId in their + // ancestor list otherwise will not be able to browse to them. + keyedSurvey = FLOW.store.find(FLOW.SurveyGroup, key); + if (keyedSurvey) { + var keyedAncestorIds = keyedSurvey.get('ancestorIds'); + for (var j = 0; j < keyedAncestorIds.length; j++) { + if(keyedAncestorIds[j] === surveyGroup.get('keyId')) { + return true; + } } + } } } - return matched; + return false; }, /* Computed properties */ @@ -264,7 +277,7 @@ FLOW.projectControl = Ember.ArrayController.create({ return []; } var id = currentProject.get('keyId'); - while(id !== null) { + while(id !== null && id !== 0) { project = FLOW.store.find(FLOW.SurveyGroup, id); result.push(project); id = project.get('parentId'); @@ -275,7 +288,7 @@ FLOW.projectControl = Ember.ArrayController.create({ currentFolders: function() { var self = this; var currentProject = this.get('currentProject'); - var parentId = currentProject ? currentProject.get('keyId') : null; + var parentId = currentProject ? currentProject.get('keyId') : 0; return this.get('content').filter(function(project) { return project.get('parentId') === parentId; }).sort(function(a, b) { @@ -320,24 +333,48 @@ FLOW.projectControl = Ember.ArrayController.create({ } }.property('breadCrumbs'), - currentPathPermissions: function() { - var currentProjectAncestors = this.get('breadCrumbs').slice(); - currentProjectAncestors.reverse();// reversed to start matching from the most specific path. - var i; - var path; - for(i = 0; i < currentProjectAncestors.length; i++) { - path = currentProjectAncestors[i].get('path'); - if(path in FLOW.currentUser.pathPermissions){ - return FLOW.currentUser.pathPermissions[path]; - } + currentFolderPermissions: function() { + var currentFolder = this.get('currentProject'); + var currentUserPermissions = FLOW.userControl.currentUserPathPermissions(); + var folderPermissions = []; + + if (!currentUserPermissions) { + return []; } - // check for the root path - if("/" in FLOW.currentUser.pathPermissions){ - return FLOW.currentUser.pathPermissions["/"]; + // root folder + if (!currentFolder) { + if (currentUserPermissions[0]) { + currentUserPermissions[0].forEach(function(item){ + folderPermissions.push(item); + }); + } + return folderPermissions; + } + + // first check current object id + if (currentFolder.get('keyId') in currentUserPermissions) { + currentUserPermissions[currentFolder.get('keyId')].forEach(function(item){ + folderPermissions.push(item); + }); + } + + var ancestorIds = currentFolder.get('ancestorIds'); + if (!ancestorIds) { + return folderPermissions; } - return []; - }.property('breadCrumbs'), + + var i; + for(i = 0; i < ancestorIds.length; i++){ + if (ancestorIds[i] in currentUserPermissions) { + currentUserPermissions[ancestorIds[i]].forEach(function(item){ + folderPermissions.push(item); + }); + } + } + + return folderPermissions; + }.property('currentProject'), /* Actions */ selectProject: function(evt) { @@ -369,7 +406,7 @@ FLOW.projectControl = Ember.ArrayController.create({ createNewProject: function(folder) { var currentFolder = this.get('currentProject'); - var currentFolderId = currentFolder ? currentFolder.get('keyId') : null; + var currentFolderId = currentFolder ? currentFolder.get('keyId') : 0; var name = folder ? Ember.String.loc('_new_folder').trim() : Ember.String.loc('_new_survey').trim(); var projectType = folder ? "PROJECT_FOLDER" : "PROJECT"; @@ -413,7 +450,7 @@ FLOW.projectControl = Ember.ArrayController.create({ }, endMoveProject: function(evt) { - var newFolderId = this.get('currentProject') ? this.get('currentProject').get('keyId') : null; + var newFolderId = this.get('currentProject') ? this.get('currentProject').get('keyId') : 0; var project = this.get('moveTarget'); var path = this.get('currentProjectPath') + "/" + project.get('name'); project.set('parentId', newFolderId); @@ -428,7 +465,7 @@ FLOW.projectControl = Ember.ArrayController.create({ FLOW.store.findQuery(FLOW.Action, { action: 'copyProject', targetId: this.get('copyTarget').get('keyId'), - folderId: currentFolder ? currentFolder.get('keyId') : null, + folderId: currentFolder ? currentFolder.get('keyId') : 0, }); FLOW.store.commit(); @@ -593,11 +630,40 @@ FLOW.surveyControl = Ember.ArrayController.create({ }); if(survey && survey.get('path')) { - return FLOW.userControl.canDeleteData(survey.get('path')) + return FLOW.userControl.canDeleteData(survey.get('path')); } else { return false; // need survey and survey path, otherwise prevent delete } }, + + /* retrieve the list of permissions associated with the currently + active form */ + currentFormPermissions: function() { + var currentForm = FLOW.selectedControl.get('selectedSurvey'); + var currentUserPermissions = FLOW.userControl.currentUserPathPermissions(); + var formPermissions = []; + + if (!currentForm || !currentUserPermissions) { + return []; + } + + var ancestorIds = currentForm.get('ancestorIds'); + if (!ancestorIds) { + return []; + } + + var i; + for(i = 0; i < ancestorIds.length; i++){ + if (ancestorIds[i] in currentUserPermissions) { + currentUserPermissions[ancestorIds[i]].forEach(function(item){ + formPermissions.push(item); + }); + } + } + + return formPermissions; + + }.property('FLOW.selectedControl.selectedSurvey'), }); diff --git a/Dashboard/app/js/lib/controllers/user-controllers.js b/Dashboard/app/js/lib/controllers/user-controllers.js index c833623df5..74dacb863f 100644 --- a/Dashboard/app/js/lib/controllers/user-controllers.js +++ b/Dashboard/app/js/lib/controllers/user-controllers.js @@ -44,14 +44,14 @@ FLOW.userControl = Ember.ArrayController.create({ return ancestors; }, - /* query based on survey (group) path whether a user has + /* query based on survey (group) ancestorIds whether a user has permissions for data deletion */ - canDeleteData: function(surveyPath) { - var canDelete = false; + canDeleteData: function(ancestorIds) { var pathPermissions = this.currentUserPathPermissions(); - this.ancestorPaths(surveyPath).forEach(function(path){ - if(path in pathPermissions && pathPermissions[path].indexOf("DATA_DELETE") > -1) { + var canDelete = false; + ancestorIds.forEach(function(id){ + if(id in pathPermissions && pathPermissions[id].indexOf("DATA_DELETE") > -1) { canDelete = true; } }); diff --git a/Dashboard/app/js/lib/models/FLOWrest-adapter-v2-common.js b/Dashboard/app/js/lib/models/FLOWrest-adapter-v2-common.js index 86d503443c..2fc1a98fbe 100644 --- a/Dashboard/app/js/lib/models/FLOWrest-adapter-v2-common.js +++ b/Dashboard/app/js/lib/models/FLOWrest-adapter-v2-common.js @@ -108,6 +108,11 @@ DS.FLOWRESTAdapter = DS.RESTAdapter.extend({ }, ajax: function (url, type, hash) { + if (type === 'GET' && url.indexOf('rest/survey_groups/0') >= 0) { + // Don't fetch the root folder. It doesn't exist. + return; + } + this._super(url, type, hash); if (type == "GET") { if (url.indexOf('rest/survey_groups') >= 0) { diff --git a/Dashboard/app/js/lib/models/models.js b/Dashboard/app/js/lib/models/models.js index 62c2e15587..59024b5a49 100644 --- a/Dashboard/app/js/lib/models/models.js +++ b/Dashboard/app/js/lib/models/models.js @@ -63,6 +63,9 @@ FLOW.SurveyGroup = FLOW.BaseModel.extend({ path: DS.attr('string', { defaultValue: null }), + ancestorIds: DS.attr('array', { + defaultValue: [] + }), createdDateTime: DS.attr('string', { defaultValue: '' }), @@ -99,7 +102,7 @@ FLOW.SurveyGroup = FLOW.BaseModel.extend({ }), surveyList: DS.attr('array', { - defaultValue: null + defaultValue: null }) }); @@ -123,6 +126,7 @@ FLOW.Survey = FLOW.BaseModel.extend({ description: DS.attr('string'), name: DS.attr('string'), path: DS.attr('string'), + ancestorIds: DS.attr('array'), pointType: DS.attr('string'), surveyGroupId: DS.attr('number'), createdDateTime: DS.attr('number'), @@ -347,6 +351,7 @@ FLOW.Placemark = FLOW.BaseModel.extend({ FLOW.SurveyInstance = FLOW.BaseModel.extend({ approvedFlag: DS.attr('string'), approximateLocationFlag: DS.attr('string'), + surveyInstanceId: DS.attr('number'), surveyId: DS.attr('number'), surveyedLocaleId:DS.attr('number'), collectionDate: DS.attr('number'), diff --git a/Dashboard/app/js/lib/views/data/inspect-data-table-views.js b/Dashboard/app/js/lib/views/data/inspect-data-table-views.js index c596688a32..f658c21f3e 100644 --- a/Dashboard/app/js/lib/views/data/inspect-data-table-views.js +++ b/Dashboard/app/js/lib/views/data/inspect-data-table-views.js @@ -1,5 +1,6 @@ FLOW.inspectDataTableView = FLOW.View.extend({ selectedSurvey: null, + surveyInstanceId: null, surveyId: null, deviceId: null, submitterName: null, @@ -79,7 +80,17 @@ FLOW.inspectDataTableView = FLOW.View.extend({ this.set('selectedLevel2',null); } - FLOW.surveyInstanceControl.doInstanceQuery(this.get('surveyId'), this.get('deviceId'),this.get('since'), this.get('beginDate'), this.get('endDate'), this.get('submitterName'),this.get('selectedCountryCode'), this.get('selectedLevel1'), this.get('selectedLevel2')); + FLOW.surveyInstanceControl.doInstanceQuery( + this.get('surveyInstanceId'), + this.get('surveyId'), + this.get('deviceId'), + this.get('since'), + this.get('beginDate'), + this.get('endDate'), + this.get('submitterName'), + this.get('selectedCountryCode'), + this.get('selectedLevel1'), + this.get('selectedLevel2')); }, doNextPage: function () { @@ -194,13 +205,9 @@ FLOW.inspectDataTableView = FLOW.View.extend({ }, showSurveyInstanceDeleteButton: function() { - var currentSurveyId = this.get('surveyId'); - if(currentSurveyId) { - return FLOW.surveyControl.userCanDeleteData(currentSurveyId); - } else { - return false; - } - }.property('surveyId'), + var permissions = FLOW.surveyControl.get('currentFormPermissions'); + return permissions.indexOf("DATA_DELETE") >= 0; + }.property('FLOW.selectedControl.selectedSurvey'), doShowDeleteSIDialog: function (event) { FLOW.dialogControl.set('activeAction', 'delSI'); @@ -218,7 +225,23 @@ FLOW.inspectDataTableView = FLOW.View.extend({ FLOW.store.commit(); } this.set('showEditSurveyInstanceWindowBool', false); - } + }, + + validSurveyInstanceId: function() { + return this.surveyInstanceId === null || + this.surveyInstanceId === "" || + this.surveyInstanceId.match(/^\d+$/); + }.property('this.surveyInstanceId'), + + noResults: function() { + var content = FLOW.surveyInstanceControl.get('content'); + if (content && content.get('isLoaded')) { + return content.get('length') === 0; + } else { + return false; + } + }.property('FLOW.surveyInstanceControl.content', 'FLOW.surveyInstanceControl.content.isLoaded') + }); FLOW.DataItemView = FLOW.View.extend({ @@ -232,11 +255,11 @@ FLOW.DataItemView = FLOW.View.extend({ SL = FLOW.store.filter(FLOW.SurveyedLocale,function(item){ return item.get('keyId') == slKey; }); - // if we have found the surveyedLocale, check if there are more + // if we have found the surveyedLocale, check if there are more // formInstances inside it if (!Ember.empty(SL)){ // are there any other formInstances loaded for this surveyedLocale? - // if not, we also need to not show the locale any more. + // if not, we also need to not show the locale any more. // it will also be deleted automatically in the backend, // so this is just to not show it in the UI SiList = FLOW.store.filter(FLOW.SurveyInstance,function(item){ diff --git a/Dashboard/app/js/lib/views/reports/report-views.js b/Dashboard/app/js/lib/views/reports/report-views.js index c8a369e0a2..d2ceedcb62 100644 --- a/Dashboard/app/js/lib/views/reports/report-views.js +++ b/Dashboard/app/js/lib/views/reports/report-views.js @@ -97,7 +97,7 @@ FLOW.chartView = FLOW.View.extend({ var percentage = 100.0 * item.get('count') / total, percString = percentage.toFixed(1); chartData.push({ - "legendLabel": (item.get('response') + ", " + percString + "%"), + "legendLabel": (item.get('response') + ", " + percString + "%") + " (" + item.get('count') + ")" , "percentage": 100.0 * item.get('count') / total }); }); @@ -143,7 +143,8 @@ FLOW.chartView = FLOW.View.extend({ FLOW.surveyQuestionSummaryControl.get('content').forEach(function (item) { chartData.push({ "legendLabel": (item.get('response')), - "percentage": 100.0 * item.get('count') / total + "percentage": 100.0 * item.get('count') / total, + "itemCount": item.get('count') }); }); @@ -161,7 +162,8 @@ FLOW.chartView = FLOW.View.extend({ FLOW.surveyQuestionSummaryControl.get('content').forEach(function (item) { chartData.push({ "legendLabel": (item.get('response')), - "percentage": 100.0 * item.get('count') / total + "percentage": 100.0 * item.get('count') / total, + "itemCount": item.get('count') }); }); diff --git a/Dashboard/app/js/lib/views/surveys/question-view.js b/Dashboard/app/js/lib/views/surveys/question-view.js index e6d814f319..1dd662f016 100644 --- a/Dashboard/app/js/lib/views/surveys/question-view.js +++ b/Dashboard/app/js/lib/views/surveys/question-view.js @@ -155,6 +155,16 @@ FLOW.QuestionView = FLOW.View.extend({ } }.property('this.type').cacheable(), + showLocaleName: function () { + if (!this.type) { + return false; + } + return this.type.get('value') == 'FREE_TEXT' + || this.type.get('value') == 'NUMBER' + || this.type.get('value') == 'OPTION' + || this.type.get('value') == 'CASCADE'; + }.property('this.type').cacheable(), + // when we change the question type to GEO, we turn on the // localeLocationFLag by default. If we change to something else, we // turn the flag of. diff --git a/Dashboard/app/js/lib/views/surveys/survey-group-views.js b/Dashboard/app/js/lib/views/surveys/survey-group-views.js index 1cfab3314d..5fe7b01ae1 100644 --- a/Dashboard/app/js/lib/views/surveys/survey-group-views.js +++ b/Dashboard/app/js/lib/views/surveys/survey-group-views.js @@ -3,12 +3,13 @@ function capitaliseFirstLetter(string) { } if (!String.prototype.trim) { - String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g, '');}; + String.prototype.trim = function(){ + return this.replace(/^\s+|\s+$/g, ''); + }; } FLOW.ProjectListView = FLOW.View.extend({ templateName: 'navSurveys/project-list' - }); FLOW.ProjectView = FLOW.View.extend({ @@ -82,8 +83,12 @@ FLOW.Project = FLOW.View.extend({ isPublished: function() { var form = FLOW.selectedControl.get('selectedSurvey'); return form.get('status') === 'PUBLISHED' - }.property('FLOW.selectedControl.selectedSurvey.status') + }.property('FLOW.selectedControl.selectedSurvey.status'), + disableFolderSurveyInputField: function() { + var permissions = FLOW.projectControl.get('currentFolderPermissions'); + return permissions.indexOf("PROJECT_FOLDER_UPDATE") < 0; + }.property('FLOW.projectControl.currentProjectPath'), }); @@ -132,8 +137,8 @@ FLOW.ProjectMainView = FLOW.View.extend({ }.property('FLOW.projectControl.currentProject'), disableAddFolderButton: function() { - var permissions = FLOW.projectControl.get('currentPathPermissions'); - return !FLOW.role.get('SUPER_ADMIN') && $.inArray("PROJECT_FOLDER_CREATE", permissions) === -1; + var permissions = FLOW.projectControl.get('currentFolderPermissions'); + return permissions.indexOf("PROJECT_FOLDER_CREATE") < 0; }.property('FLOW.projectControl.currentProjectPath'), disableAddSurveyButtonInRoot: function() { @@ -141,8 +146,8 @@ FLOW.ProjectMainView = FLOW.View.extend({ }.property('FLOW.projectControl.currentProjectPath'), disableAddSurveyButton: function() { - var permissions = FLOW.projectControl.get('currentPathPermissions'); - return !FLOW.role.get('SUPER_ADMIN') && $.inArray("PROJECT_FOLDER_CREATE", permissions) === -1; + var permissions = FLOW.projectControl.get('currentFolderPermissions'); + return permissions.indexOf("PROJECT_FOLDER_CREATE") < 0; }.property('FLOW.projectControl.currentProjectPath'), }); @@ -207,9 +212,10 @@ FLOW.ProjectItemView = FLOW.View.extend({ return langs[this.content.get('defaultLanguageCode')]; }.property(), - hideDeleteButton: function () { + hideFolderSurveyDeleteButton: function () { var c = this.get('content'); - return !Ember.empty(c.get('surveyList')) || c.get('deleteDisabled'); + var permissions = FLOW.projectControl.get('currentFolderPermissions'); + return permissions.indexOf("PROJECT_FOLDER_DELETE") < 0 || !Ember.empty(c.get('surveyList')); }.property() }); @@ -417,8 +423,8 @@ FLOW.SurveyGroupMainView = FLOW.View.extend({ saveNewSurveyGroupName: function () { if (!Ember.empty(this.get('surveyGroupName').trim())){ FLOW.store.createRecord(FLOW.SurveyGroup, { - "code": capitaliseFirstLetter(this.get('surveyGroupName')), - "name": capitaliseFirstLetter(this.get('surveyGroupName')) + "code": capitaliseFirstLetter(this.get('surveyGroupName')), + "name": capitaliseFirstLetter(this.get('surveyGroupName')) }); FLOW.store.commit(); } diff --git a/Dashboard/app/js/lib/views/views.js b/Dashboard/app/js/lib/views/views.js index 9ee4427fd5..b7944f1719 100644 --- a/Dashboard/app/js/lib/views/views.js +++ b/Dashboard/app/js/lib/views/views.js @@ -738,7 +738,7 @@ FLOW.SurveySelectionView = Ember.ContainerView.extend({ init: function() { this._super(); this.get('childViews').pushObject(FLOW.SelectFolder.create({ - parentId: null, + parentId: 0, // start with the root folder idx: 0, showMonitoringSurveysOnly: this.get('showMonitoringSurveysOnly') || false })); @@ -754,7 +754,7 @@ FLOW.DataCleaningSurveySelectionView = Ember.ContainerView.extend({ init: function() { this._super(); this.get('childViews').pushObject(FLOW.SelectFolder.create({ - parentId: null, + parentId: 0, // start with the root folder idx: 0, showMonitoringSurveysOnly: this.get('showMonitoringSurveysOnly') || false, selectionFilter : FLOW.projectControl.dataCleaningEnabled diff --git a/Dashboard/app/js/templates/navData/inspect-data.handlebars b/Dashboard/app/js/templates/navData/inspect-data.handlebars index 6a2f72c753..fc439a47b0 100644 --- a/Dashboard/app/js/templates/navData/inspect-data.handlebars +++ b/Dashboard/app/js/templates/navData/inspect-data.handlebars @@ -18,10 +18,17 @@
- | {{t _id}} | +{{t _instance_id}} | {{t _form}} | {{t _submitter}} | {{t _device}} | @@ -53,11 +64,15 @@{{#with SI}}{{date1 collectionDate}}{{/with}} | - {{t _edit}} - - {{#if view.showSurveyInstanceDeleteButton }} {{#view FLOW.DataItemView contentBinding="SI"}} - {{t _delete}} - {{/view}} {{/if}} + {{t _edit}} + + {{#if view.showSurveyInstanceDeleteButton }} + {{#view FLOW.DataItemView contentBinding="SI"}} + + {{t _delete}} + + {{/view}} + {{/if}} |
---|