diff --git a/app/controllers/surveillance_programs_controller.rb b/app/controllers/surveillance_programs_controller.rb
index c0306c49..9743dcc0 100644
--- a/app/controllers/surveillance_programs_controller.rb
+++ b/app/controllers/surveillance_programs_controller.rb
@@ -1,5 +1,24 @@
class SurveillanceProgramsController < ApplicationController
+ authorize_resource only: [:create]
+
def index
render json: SurveillanceProgram.all
end
+
+ def create
+ @surveillance_program = SurveillanceProgram.new(surveillance_program_params)
+ if SurveillanceProgram.find_by(name: @surveillance_program.name)
+ render json: { msg: "A surveillance program named #{@surveillance_program.name} already exists" }, status: :unprocessable_entity
+ elsif @surveillance_program.save
+ render json: SurveillanceProgram.all
+ else
+ render json: { msg: 'Error saving program - check format, name cannot be blank' }, status: :unprocessable_entity
+ end
+ end
+
+ private
+
+ def surveillance_program_params
+ params.permit(:name, :description, :acronym)
+ end
end
diff --git a/app/controllers/surveillance_systems_controller.rb b/app/controllers/surveillance_systems_controller.rb
index da0bd6a2..2746fb79 100644
--- a/app/controllers/surveillance_systems_controller.rb
+++ b/app/controllers/surveillance_systems_controller.rb
@@ -1,5 +1,24 @@
class SurveillanceSystemsController < ApplicationController
+ authorize_resource only: [:create]
+
def index
render json: SurveillanceSystem.all
end
+
+ def create
+ @surveillance_system = SurveillanceSystem.new(surveillance_system_params)
+ if SurveillanceSystem.find_by(name: @surveillance_system.name)
+ render json: { msg: "A surveillance system named #{@surveillance_system.name} already exists" }, status: :unprocessable_entity
+ elsif @surveillance_system.save
+ render json: SurveillanceSystem.all
+ else
+ render json: { msg: 'Error saving system - check format, name cannot be blank' }, status: :unprocessable_entity
+ end
+ end
+
+ private
+
+ def surveillance_system_params
+ params.permit(:name, :description, :acronym)
+ end
end
diff --git a/app/models/surveillance_program.rb b/app/models/surveillance_program.rb
index df48d4c6..e4543d7b 100644
--- a/app/models/surveillance_program.rb
+++ b/app/models/surveillance_program.rb
@@ -1,3 +1,4 @@
class SurveillanceProgram < ApplicationRecord
has_many :surveys
+ validates :name, presence: true
end
diff --git a/app/models/surveillance_system.rb b/app/models/surveillance_system.rb
index 84845a73..a20f4863 100644
--- a/app/models/surveillance_system.rb
+++ b/app/models/surveillance_system.rb
@@ -1,3 +1,4 @@
class SurveillanceSystem < ApplicationRecord
has_many :surveys
+ validates :name, presence: true
end
diff --git a/config/routes.rb b/config/routes.rb
index f13348c9..63b872ff 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,6 +1,6 @@
Rails.application.routes.draw do
- resources :surveillance_systems, only: [:index, :show]
- resources :surveillance_programs, only: [:index, :show]
+ resources :surveillance_systems, only: [:index, :create]
+ resources :surveillance_programs, only: [:index, :create]
get 'response_types', to: 'response_types#index', as: :response_types
get 'question_types', to: 'question_types#index', as: :question_types
get 'concepts', to: 'concepts#index', as: :concepts
diff --git a/features/admin_panel.feature b/features/admin_panel.feature
index a9814a10..fed0c2b1 100644
--- a/features/admin_panel.feature
+++ b/features/admin_panel.feature
@@ -30,3 +30,38 @@ Feature: Admin Panel
And I should see "admin@gmail.com"
When I click on the "remove_admin@gmail.com" button
Then I should not see "admin@gmail.com"
+
+ Scenario: Add program
+ Given I am the admin test_author@gmail.com
+ And there is an admin with the email admin@gmail.com
+ When I go to the dashboard
+ And I click on the "account-dropdown" link
+ And I click on the "Admin Panel" link
+ And I click on the "Program List" link
+ And I fill in the "program-name" field with "New Program"
+ And I click on the "submit-prog-sys" button
+ And I fill in the "program-name" field with "Just clearing the text"
+ Then I should see "New Program"
+
+ Scenario: Add System
+ Given I am the admin test_author@gmail.com
+ And there is an admin with the email admin@gmail.com
+ When I go to the dashboard
+ And I click on the "account-dropdown" link
+ And I click on the "Admin Panel" link
+ And I click on the "System List" link
+ And I fill in the "system-name" field with "New System"
+ And I click on the "submit-prog-sys" button
+ And I fill in the "system-name" field with "Just clearing the text"
+ Then I should see "New System"
+
+ Scenario: Add System with name error
+ Given I am the admin test_author@gmail.com
+ And there is an admin with the email admin@gmail.com
+ When I go to the dashboard
+ And I click on the "account-dropdown" link
+ And I click on the "Admin Panel" link
+ And I click on the "System List" link
+ And I fill in the "system-description" field with "Trying to add system with no name"
+ And I click on the "submit-prog-sys" button
+ Then I should see "Error saving system - check format, name cannot be blank"
diff --git a/test/controllers/surveillance_programs_controller_test.rb b/test/controllers/surveillance_programs_controller_test.rb
index 23148f7e..e843dea0 100644
--- a/test/controllers/surveillance_programs_controller_test.rb
+++ b/test/controllers/surveillance_programs_controller_test.rb
@@ -1,8 +1,24 @@
require 'test_helper'
class SurveillanceProgramsControllerTest < ActionDispatch::IntegrationTest
+ include Devise::Test::IntegrationHelpers
+
test 'should get index' do
get surveillance_programs_url
assert_response :success
end
+
+ test 'should not be allowed to create program' do
+ post surveillance_programs_url, params: { name: 'test prog' }
+ assert_response :forbidden
+ end
+
+ test 'should be allowed to create program' do
+ @admin = users(:admin)
+ @admin.add_role :admin
+ @admin.save!
+ sign_in @admin
+ post surveillance_programs_url, params: { name: 'test prog' }
+ assert_response :success
+ end
end
diff --git a/test/controllers/surveillance_systems_controller_test.rb b/test/controllers/surveillance_systems_controller_test.rb
index 653ca559..89eca01c 100644
--- a/test/controllers/surveillance_systems_controller_test.rb
+++ b/test/controllers/surveillance_systems_controller_test.rb
@@ -1,8 +1,24 @@
require 'test_helper'
class SurveillanceSystemsControllerTest < ActionDispatch::IntegrationTest
+ include Devise::Test::IntegrationHelpers
+
test 'should get index' do
get surveillance_systems_url
assert_response :success
end
+
+ test 'should not be allowed to create system' do
+ post surveillance_systems_url, params: { name: 'test sys' }
+ assert_response :forbidden
+ end
+
+ test 'should be allowed to create system' do
+ @admin = users(:admin)
+ @admin.add_role :admin
+ @admin.save!
+ sign_in @admin
+ post surveillance_systems_url, params: { name: 'test sys' }
+ assert_response :success
+ end
end
diff --git a/test/frontend/components/comment_test.js b/test/frontend/components/comment_test.js
index 3ad65962..f9c0b330 100644
--- a/test/frontend/components/comment_test.js
+++ b/test/frontend/components/comment_test.js
@@ -23,6 +23,7 @@ describe('Comment', () => {
};
component = renderComponent(Comment, {
comment: comment,
+ loggedIn: true,
addComment: function() {}
});
});
diff --git a/webpack/_routes.js b/webpack/_routes.js
index d760a0f3..f019d3a7 100644
--- a/webpack/_routes.js
+++ b/webpack/_routes.js
@@ -680,15 +680,9 @@ Based on Rails routes of Vocabulary::Application
// root => /
// function(options)
root_path: Utils.route([], {}, [7,"/",false]),
-// surveillance_program => /surveillance_programs/:id(.:format)
- // function(id, options)
- surveillance_program_path: Utils.route([["id",true],["format",false]], {}, [2,[7,"/",false],[2,[6,"surveillance_programs",false],[2,[7,"/",false],[2,[3,"id",false],[1,[2,[8,".",false],[3,"format",false]],false]]]]]),
// surveillance_programs => /surveillance_programs(.:format)
// function(options)
surveillance_programs_path: Utils.route([["format",false]], {}, [2,[7,"/",false],[2,[6,"surveillance_programs",false],[1,[2,[8,".",false],[3,"format",false]],false]]]),
-// surveillance_system => /surveillance_systems/:id(.:format)
- // function(id, options)
- surveillance_system_path: Utils.route([["id",true],["format",false]], {}, [2,[7,"/",false],[2,[6,"surveillance_systems",false],[2,[7,"/",false],[2,[3,"id",false],[1,[2,[8,".",false],[3,"format",false]],false]]]]]),
// surveillance_systems => /surveillance_systems(.:format)
// function(options)
surveillance_systems_path: Utils.route([["format",false]], {}, [2,[7,"/",false],[2,[6,"surveillance_systems",false],[1,[2,[8,".",false],[3,"format",false]],false]]]),
diff --git a/webpack/actions/surveillance_program_actions.js b/webpack/actions/surveillance_program_actions.js
index 21802395..d61d4143 100644
--- a/webpack/actions/surveillance_program_actions.js
+++ b/webpack/actions/surveillance_program_actions.js
@@ -1,7 +1,9 @@
import axios from 'axios';
import routes from '../routes';
+import { getCSRFToken } from './index';
import {
- FETCH_SURVEILLANCE_PROGRAMS
+ FETCH_SURVEILLANCE_PROGRAMS,
+ ADD_PROGRAM
} from './types';
export function fetchSurveillancePrograms() {
@@ -15,3 +17,24 @@ export function fetchSurveillancePrograms() {
})
};
}
+
+export function addProgram(name, description=null, acronym=null, callback=null, failureHandler=null) {
+ const postPromise = axios.post(routes.surveillanceProgramsPath(), {
+ headers: {
+ 'X-Key-Inflection': 'camel',
+ 'Accept': 'application/json'
+ },
+ authenticityToken: getCSRFToken(),
+ name, description, acronym
+ });
+ if (callback) {
+ postPromise.then(callback);
+ }
+ if (failureHandler) {
+ postPromise.catch(failureHandler);
+ }
+ return {
+ type: ADD_PROGRAM,
+ payload: postPromise
+ };
+}
diff --git a/webpack/actions/surveillance_system_actions.js b/webpack/actions/surveillance_system_actions.js
index 10666a23..183183a6 100644
--- a/webpack/actions/surveillance_system_actions.js
+++ b/webpack/actions/surveillance_system_actions.js
@@ -1,7 +1,9 @@
import axios from 'axios';
import routes from '../routes';
+import { getCSRFToken } from './index';
import {
- FETCH_SURVEILLANCE_SYSTEMS
+ FETCH_SURVEILLANCE_SYSTEMS,
+ ADD_SYSTEM
} from './types';
export function fetchSurveillanceSystems() {
@@ -15,3 +17,24 @@ export function fetchSurveillanceSystems() {
})
};
}
+
+export function addSystem(name, description=null, acronym=null, callback=null, failureHandler=null) {
+ const postPromise = axios.post(routes.surveillanceSystemsPath(), {
+ headers: {
+ 'X-Key-Inflection': 'camel',
+ 'Accept': 'application/json'
+ },
+ authenticityToken: getCSRFToken(),
+ name, description, acronym
+ });
+ if (callback) {
+ postPromise.then(callback);
+ }
+ if (failureHandler) {
+ postPromise.catch(failureHandler);
+ }
+ return {
+ type: ADD_SYSTEM,
+ payload: postPromise
+ };
+}
diff --git a/webpack/actions/types.js b/webpack/actions/types.js
index 9dec0b0c..bccd82d4 100644
--- a/webpack/actions/types.js
+++ b/webpack/actions/types.js
@@ -103,10 +103,14 @@ export const FETCH_TAGS_FULFILLED = 'FETCH_TAGS_FULFILLED';
// Surveillance System Types
export const FETCH_SURVEILLANCE_SYSTEMS = 'FETCH_SURVEILLANCE_SYSTEMS';
export const FETCH_SURVEILLANCE_SYSTEMS_FULFILLED = 'FETCH_SURVEILLANCE_SYSTEMS_FULFILLED';
+export const ADD_SYSTEM = 'ADD_SYSTEM';
+export const ADD_SYSTEM_FULFILLED = 'ADD_SYSTEM_FULFILLED';
// Surveillance Program Types
export const FETCH_SURVEILLANCE_PROGRAMS = 'FETCH_SURVEILLANCE_PROGRAMS';
export const FETCH_SURVEILLANCE_PROGRAMS_FULFILLED = 'FETCH_SURVEILLANCE_PROGRAMS_FULFILLED';
+export const ADD_PROGRAM = 'ADD_PROGRAM';
+export const ADD_PROGRAM_FULFILLED = 'ADD_PROGRAM_FULFILLED';
// Survey types
export const PUBLISH_SURVEY = 'PUBLISH_SURVEY';
diff --git a/webpack/components/Comment.js b/webpack/components/Comment.js
index 8dc0db3c..1231f265 100644
--- a/webpack/components/Comment.js
+++ b/webpack/components/Comment.js
@@ -13,8 +13,7 @@ class Comment extends Component {
- {this.props.comment.id}
- {distanceInWordsToNow(parse(this.props.comment.createdAt,''), {addSuffix: true})} by {this.props.comment.userName}
+
{this.props.comment.comment}
-{prog.name}
{prog.description}
{sys.name}
{sys.description}
No Comments Yet
) : (this.renderChildren(loggedIn))}Surveys, Forms, and Response Sets may all be tagged to facilitate content discovery and reuse. Currently, a tag consists of a name, a value or code, and a code system (which is optional depending on if the tag is coded or not).
+When editing content and a user starts typing in the tag column of the table a dropdown list will appear of all previously used tags. A user can use the arrow keys to navigate the list and select a tag that was previously used, or continue typing to enter a completely new tag.
+If the user wants to look for tags by the code or the code system typing these values into the tag field will filter the list by the code or code system as well.
+Getting to the panel (requires administrator role):
+Tabs:
+This list will populate with all of the users who have administrative privileges. The admin role allows access to all content and all functionality in the application. To the right of each user name and email is a remove button that will revoke the admin role from that user. The admin role can be granted by typing in the email of a user and clicking the plus button. The user will then appear on the admin list or an error will be displayed explaining any issues with the addition.
+For usage instructions please see the information about the Admin List above. Adding members to this list allows them to see draft content they did not author and publish that content to make it public.
+