Skip to content

Commit 641410a

Browse files
committed
Merge pull request #181 from codeforamerica/admin-interface
Add Admin interface to API app
2 parents 83e0c01 + dcda003 commit 641410a

218 files changed

Lines changed: 5411 additions & 492 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@ Style/ClassLength:
2828
CountComments: false
2929
Max: 100
3030

31+
Style/GuardClause:
32+
MinBodyLength: 3
33+
3134
Rails/HasAndBelongsToMany:
3235
Enabled: false

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ end
6767
group :test do
6868
gem 'database_cleaner', '>= 1.0.0.RC1'
6969
gem 'capybara'
70+
gem 'poltergeist'
7071
gem 'shoulda-matchers', require: false
7172
gem 'coveralls', require: false
7273
gem 'rubocop'

Gemfile.lock

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
GEM
22
remote: https://rubygems.org/
33
specs:
4-
actionmailer (4.1.2)
5-
actionpack (= 4.1.2)
6-
actionview (= 4.1.2)
4+
actionmailer (4.1.4)
5+
actionpack (= 4.1.4)
6+
actionview (= 4.1.4)
77
mail (~> 2.5.4)
8-
actionpack (4.1.2)
9-
actionview (= 4.1.2)
10-
activesupport (= 4.1.2)
8+
actionpack (4.1.4)
9+
actionview (= 4.1.4)
10+
activesupport (= 4.1.4)
1111
rack (~> 1.5.2)
1212
rack-test (~> 0.6.2)
13-
actionview (4.1.2)
14-
activesupport (= 4.1.2)
13+
actionview (4.1.4)
14+
activesupport (= 4.1.4)
1515
builder (~> 3.1)
1616
erubis (~> 2.7.0)
1717
active_model_serializers (0.8.1)
1818
activemodel (>= 3.0)
19-
activemodel (4.1.2)
20-
activesupport (= 4.1.2)
19+
activemodel (4.1.4)
20+
activesupport (= 4.1.4)
2121
builder (~> 3.1)
22-
activerecord (4.1.2)
23-
activemodel (= 4.1.2)
24-
activesupport (= 4.1.2)
22+
activerecord (4.1.4)
23+
activemodel (= 4.1.4)
24+
activesupport (= 4.1.4)
2525
arel (~> 5.0.0)
26-
activesupport (4.1.2)
26+
activesupport (4.1.4)
2727
i18n (~> 0.6, >= 0.6.9)
2828
json (~> 1.7, >= 1.7.7)
2929
minitest (~> 5.1)
@@ -44,15 +44,16 @@ GEM
4444
bootstrap-sass (2.3.2.2)
4545
sass (~> 3.2)
4646
builder (3.2.2)
47-
bullet (4.11.2)
47+
bullet (4.11.3)
4848
activesupport (>= 3.0.0)
4949
uniform_notifier (>= 1.6.0)
50-
capybara (2.3.0)
50+
capybara (2.4.1)
5151
mime-types (>= 1.16)
5252
nokogiri (>= 1.3.3)
5353
rack (>= 1.0.0)
5454
rack-test (>= 0.5.4)
5555
xpath (~> 2.0)
56+
cliver (0.3.2)
5657
coderay (1.1.0)
5758
coffee-rails (4.0.1)
5859
coffee-script (>= 2.2.0)
@@ -125,7 +126,7 @@ GEM
125126
nokogiri (1.6.2.1)
126127
mini_portile (= 0.6.0)
127128
orm_adapter (0.5.0)
128-
parser (2.2.0.pre.2)
129+
parser (2.2.0.pre.3)
129130
ast (>= 1.1, < 3.0)
130131
slop (~> 3.4, >= 3.4.5)
131132
passenger (4.0.45)
@@ -137,6 +138,11 @@ GEM
137138
activerecord (>= 3.1)
138139
activesupport (>= 3.1)
139140
arel
141+
poltergeist (1.5.1)
142+
capybara (~> 2.1)
143+
cliver (~> 0.3.1)
144+
multi_json (~> 1.0)
145+
websocket-driver (>= 0.2.0)
140146
polyglot (0.3.5)
141147
powerpack (0.0.9)
142148
protected_attributes (1.0.8)
@@ -148,24 +154,24 @@ GEM
148154
rack-test (0.6.2)
149155
rack (>= 1.0)
150156
rack-timeout (0.0.4)
151-
rails (4.1.2)
152-
actionmailer (= 4.1.2)
153-
actionpack (= 4.1.2)
154-
actionview (= 4.1.2)
155-
activemodel (= 4.1.2)
156-
activerecord (= 4.1.2)
157-
activesupport (= 4.1.2)
157+
rails (4.1.4)
158+
actionmailer (= 4.1.4)
159+
actionpack (= 4.1.4)
160+
actionview (= 4.1.4)
161+
activemodel (= 4.1.4)
162+
activerecord (= 4.1.4)
163+
activesupport (= 4.1.4)
158164
bundler (>= 1.3.0, < 2.0)
159-
railties (= 4.1.2)
165+
railties (= 4.1.4)
160166
sprockets-rails (~> 2.0)
161167
rails_12factor (0.0.2)
162168
rails_serve_static_assets
163169
rails_stdout_logging
164170
rails_serve_static_assets (0.0.1)
165171
rails_stdout_logging (0.0.2)
166-
railties (4.1.2)
167-
actionpack (= 4.1.2)
168-
activesupport (= 4.1.2)
172+
railties (4.1.4)
173+
actionpack (= 4.1.4)
174+
activesupport (= 4.1.4)
169175
rake (>= 0.8.7)
170176
thor (>= 0.18.1, < 2.0)
171177
rainbow (2.0.0)
@@ -193,9 +199,9 @@ GEM
193199
rspec-mocks (~> 3.0.0)
194200
rspec-support (~> 3.0.0)
195201
rspec-support (3.0.0)
196-
rubocop (0.24.0)
202+
rubocop (0.24.1)
197203
json (>= 1.7.7, < 2)
198-
parser (>= 2.2.0.pre.2, < 3.0)
204+
parser (>= 2.2.0.pre.3, < 3.0)
199205
powerpack (~> 0.0.6)
200206
rainbow (>= 1.99.1, < 3.0)
201207
ruby-progressbar (~> 1.4)
@@ -214,8 +220,8 @@ GEM
214220
simplecov-html (~> 0.8.0)
215221
simplecov-html (0.8.0)
216222
slop (3.5.0)
217-
spring (1.1.2)
218-
spring-commands-rspec (1.0.1)
223+
spring (1.1.3)
224+
spring-commands-rspec (1.0.2)
219225
spring (>= 0.9.1)
220226
sprockets (2.11.0)
221227
hike (~> 1.2)
@@ -243,6 +249,7 @@ GEM
243249
uniform_notifier (1.6.2)
244250
warden (1.2.3)
245251
rack (>= 1.0)
252+
websocket-driver (0.3.3)
246253
xpath (2.0.0)
247254
nokogiri (~> 1.3)
248255

@@ -275,6 +282,7 @@ DEPENDENCIES
275282
passenger
276283
pg
277284
pg_search
285+
poltergeist
278286
protected_attributes
279287
quiet_assets (>= 1.0.2)
280288
rack-cors

INSTALL.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ local [Admin Interface][admin] if it's pointing to your local API.
7575

7676
### Verify the app is returning JSON
7777

78-
[http://localhost:8080/api/locations](http://localhost:8080/api/locations)
78+
[http://lvh.me:8080/api/locations](http://lvh.me:8080/api/locations)
7979

80-
[http://localhost:8080/api/search?keyword=food](http://localhost:8080/api/search?keyword=food)
80+
[http://lvh.me:8080/api/search?keyword=food](http://lvh.me:8080/api/search?keyword=food)
8181

8282
We recommend the [JSONView][jsonview] Google Chrome extension for formatting
8383
the JSON response so it is easier to read in the browser.
@@ -151,11 +151,17 @@ To reset your local database and populate it again with your clean data:
151151
script/import
152152
```
153153

154-
### User authentication (for the developer portal)
154+
### User and Admin authentication (for the developer portal and admin interface)
155155

156-
The app automatically sets up users you can [sign in][sign_in] with.
156+
The app automatically sets up users and admins you can sign in with.
157157
Their username and password are stored in [db/seeds.rb][seeds].
158158

159-
[sign_in]: http://localhost:8080/users/sign_in
160159
[seeds]: https://github.com/codeforamerica/ohana-api/blob/master/db/seeds.rb
161160

161+
To set an admin as a Super Admin:
162+
163+
psql ohana_api_development
164+
UPDATE "admins" SET super_admin = true WHERE id = 3;
165+
\q
166+
167+
To access the admin interface, visit [http://lvh.me:8080/admin/](http://lvh.me:8080/admin/).

README.md

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,33 @@
22

33
[![Stories in Ready](https://badge.waffle.io/codeforamerica/ohana-api.png?label=ready)](https://waffle.io/codeforamerica/ohana-api) [![Build Status](https://travis-ci.org/codeforamerica/ohana-api.png?branch=master)](https://travis-ci.org/codeforamerica/ohana-api)
44

5-
This is the API portion of the [Ohana API](http://ohanapi.org) project, an open source community resource platform developed by [@monfresh](https://github.com/monfresh), [@spara](https://github.com/spara), and [@anselmbradford](https://github.com/anselmbradford) during their Code for America Fellowship in 2013, in partnership with San Mateo County's Human Services Agency. The goal of the project is to make it easier for residents in need to find services they are eligible for.
5+
This is the API + Admin Interface portion of the [Ohana API](http://ohanapi.org) project, an open source community resource platform developed by [@monfresh](https://github.com/monfresh), [@spara](https://github.com/spara), and [@anselmbradford](https://github.com/anselmbradford) during their Code for America Fellowship in 2013, in partnership with San Mateo County's Human Services Agency. Ohana makes it easy for communities to publish a database of social services, and allows developers to build impactful applications that serve underprivileged residents.
66

7-
Before we started working on the Ohana API, the search interface that residents and social workers in San Mateo County had access to was the Peninsula Library System's [CIP portal](http://catalog.plsinfo.org:81/). As a demonstration of the kind of applications that can be built on top of the Ohana API, we developed a [better search interface](http://smc-connect.org) ([repo link](https://github.com/codeforamerica/human_services_finder)) that consumes the API via our [Ruby wrapper](https://github.com/codeforamerica/ohanakapa). We also built an [admin site](https://github.com/codeforamerica/ohana-api-admin) to allow organizations to update their own information.
7+
Before we started working on the Ohana API, the search interface that residents and social workers in San Mateo County had access to was the Peninsula Library System's [CIP portal](http://catalog.plsinfo.org:81/). As a demonstration of the kind of applications that can be built on top of the Ohana API, we developed a [better search interface](http://smc-connect.org) ([repo link](https://github.com/codeforamerica/ohana-web-search)) that consumes the API via our [Ruby wrapper](https://github.com/codeforamerica/ohanakapa).
88

99
## Stack Overview
1010

1111
* Ruby version 2.1.1
12-
* Rails version 4.1.1
12+
* Rails version 4.1.4
1313
* Postgres
1414
* Testing Frameworks: RSpec, Factory Girl, Capybara
1515

1616
## Demo
17-
You can see a running version of the application at
18-
[http://ohana-api-demo.herokuapp.com/](http://ohana-api-demo.herokuapp.com/).
17+
You can see a running version of the different parts of the application here:
18+
19+
**Developer portal**: [http://ohana-api-demo.herokuapp.com/](http://ohana-api-demo.herokuapp.com/) (see [db/seeds.rb][seeds] for a list of usernames and passwords you can sign in with.)
20+
21+
**API**: [http://ohana-api-demo.herokuapp.com/api](http://ohana-api-demo.herokuapp.com/api)
22+
23+
**Admin Interface**: [http://ohana-api-demo.herokuapp.com/admin](http://ohana-api-demo.herokuapp.com/admin) (see [db/seeds.rb][seeds] for a list of usernames and passwords you can sign in with.)
24+
25+
[seeds]: https://github.com/codeforamerica/ohana-api/blob/master/db/seeds.rb
1926

2027
## Current Status
2128
We are happy to announce that this project has been awarded a [grant from the Knight Foundation](http://www.knightfoundation.org/grants/201447979/), which means we get to keep working on it in 2014! Our primary goals this year are: simplifying the installation process, streamlining the code, reducing dependencies, and preparing the project for broader installation by a variety of organizations and governments.
2229

2330
## Data Schema
24-
If you would like to try out the current version of the project that uses Postgres, please read the Wiki article about [Populating the Postgres DB from a JSON file](https://github.com/codeforamerica/ohana-api/wiki/Populating-the-Postgres-database-from-a-JSON-file). That article documents the current schema and data dictionary, but please note that this will be in flux as we are working with various interested parties to define a [Human Services Data Specification](https://github.com/codeforamerica/OpenReferral).
31+
If you would like to try out the current version of the project, please read the Wiki article about [Populating the Postgres DB from a JSON file](https://github.com/codeforamerica/ohana-api/wiki/Populating-the-Postgres-database-from-a-JSON-file). That article documents the current schema and data dictionary, but please note that this will be in flux as we are working with various interested parties to define a [Human Services Data Specification](https://github.com/codeforamerica/OpenReferral).
2532

2633
## API documentation
2734
[http://ohanapi.herokuapp.com/api/docs](http://ohana-api-demo.herokuapp.com/api/docs)
@@ -41,12 +48,10 @@ If you've built one, let us know and we'll add it here.
4148
By default, this project uses the [Open Eligibility](http://openeligibility.org) taxonomy to assign Services to [Categories](https://github.com/codeforamerica/ohana-api/blob/master/app/models/category.rb).
4249
If you would like to use your own taxonomy, feel free to update this rake task to [create your own hierarchy or tree structure](https://github.com/codeforamerica/ohana-api/blob/master/lib/tasks/oe.rake). Then run `rake create_categories`.
4350

44-
The easiest way to assign categories to a service is to use the [Ohana API Admin](https://github.com/codeforamerica/ohana-api-admin/blob/master/app/controllers/hsa_controller.rb#L183-187) interface. Here's a screenshot:
51+
The easiest way to assign categories to a service is to use the Admin interface. Here's a screenshot:
4552

4653
![Editing categories in Ohana API Admin](https://github.com/codeforamerica/ohana-api/raw/master/categories-in-ohana-api-admin.png)
4754

48-
You can also try it from the Rails console, mimicking how the API would do it when it receives a [PUT request to update a service's categories](https://github.com/codeforamerica/ohana-api/blob/master/app/api/ohana.rb#L239-257).
49-
5055
## Apps that are using the Ohana API
5156
[SMC-Connect](http://www.smc-connect.org)
5257
[GitHub repo for SMC-Connect](https://github.com/codeforamerica/human_services_finder)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
var main = (function () {
2+
"use strict";
3+
4+
var NUM_LEVELS = 2;
5+
6+
// initalize the application
7+
function init()
8+
{
9+
var checkboxes = $('#categories input');
10+
11+
var currentCheckbox;
12+
for (var i=0; i < checkboxes.length; i++)
13+
{
14+
currentCheckbox = checkboxes[i];
15+
_checkState('depth',0,currentCheckbox);
16+
}
17+
18+
var lnks = $('#categories input');
19+
20+
var curr;
21+
for (var l=0; l < lnks.length; l++)
22+
{
23+
curr = lnks[l];
24+
$(curr).click(_linkClickedHandler)
25+
}
26+
}
27+
28+
function _linkClickedHandler(evt)
29+
{
30+
var el = evt.target;
31+
if (el.nodeName == 'INPUT')
32+
{
33+
_checkState('depth',0,el);
34+
}
35+
36+
}
37+
38+
function _checkState(prefix,depth,checkbox)
39+
{
40+
var item = $(checkbox).parent(); // parent li item
41+
var id = prefix+String(depth);
42+
while(!item.hasClass(id))
43+
{
44+
depth++;
45+
id = prefix+String(depth);
46+
}
47+
48+
id = 'li.'+prefix+String(depth+1);
49+
var lnks = $(id,item);
50+
var curr;
51+
for (var l=0; l < lnks.length; l++)
52+
{
53+
curr = lnks[l];
54+
if (checkbox.checked)
55+
{
56+
$(curr).removeClass('hide');
57+
}
58+
else
59+
{
60+
$(curr).addClass('hide');
61+
checkbox = $('input',$(curr))
62+
checkbox.prop('checked', false);
63+
_checkState(prefix,depth,checkbox)
64+
}
65+
}
66+
67+
}
68+
69+
// return internally scoped var as value of globally scoped object
70+
return {
71+
init:init
72+
};
73+
74+
})();
75+
76+
$(document).ready(function(){
77+
main.init();
78+
});

app/assets/javascripts/application.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@
1313
//= require jquery
1414
//= require jquery_ujs
1515
//= require bootstrap
16+
//= require bootstrap-modal
1617
//= require_tree .
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
jQuery ->
2+
$('.edit_entry').on 'click', '.delete_association', (event) ->
3+
$(this).prevAll('input[type=hidden]').val('1')
4+
$(this).closest('fieldset').hide()
5+
event.preventDefault()
6+
7+
$('.edit_entry').on 'click', '.delete_attribute', (event) ->
8+
$(this).closest('fieldset').find('input').val('')
9+
$(this).closest('fieldset').hide()
10+
event.preventDefault()
11+
12+
$('.edit_entry').on 'click', '.add_fields', (event) ->
13+
time = new Date().getTime()
14+
regexp = new RegExp($(this).data('id'), 'g')
15+
$(this).before($(this).data('fields').replace(regexp, time))
16+
event.preventDefault()
17+
18+
$('.edit_entry').on 'click', '.add_array_fields', (event) ->
19+
time = new Date().getTime()
20+
$(this).before($(this).data('fields'))
21+
inputs = $(this).parent().find('input')
22+
inputs[inputs.length - 1].setAttribute('id', time)
23+
event.preventDefault()

0 commit comments

Comments
 (0)