-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from nihonjinrxs/add-pod
New DistributionPoints feature
- Loading branch information
Showing
32 changed files
with
835 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
App.distribution_point = App.cable.subscriptions.create("DistributionPointChannel", { | ||
connected: function() {}, | ||
received: function(data) { | ||
App.updatedDistributionPoints.add(data.distribution_point) | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
class DistributionPointChannel < ApplicationCable::Channel | ||
def subscribed | ||
stream_for "distribution_points" | ||
end | ||
|
||
def unsubscribed | ||
# Any cleanup needed when channel is unsubscribed | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
class Api::V1::DistributionPointsController < ApplicationController | ||
include FilterByParams | ||
|
||
before_action do | ||
request.format = :json | ||
end | ||
|
||
filterable_params [ | ||
{ type: :geocoords }, | ||
{ type: :text, param: :county, field: 'county' }, | ||
{ type: :text, param: :name, field: 'facility_name' }, | ||
{ type: :boolean, param: :active, field: 'active' } | ||
] | ||
|
||
def index | ||
@distribution_points, @filters = apply_filters(DistributionPoint.all) | ||
end | ||
|
||
def outdated | ||
@distribution_points, @filters = apply_filters(DistributionPoint.outdated.order('updated_at DESC')) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,42 @@ | ||
class Api::V1::SheltersController < ApplicationController | ||
include FilterByParams | ||
|
||
before_action do | ||
request.format = :json | ||
end | ||
|
||
filterable_params [ | ||
{ type: :geocoords }, | ||
{ type: :text, param: :county, field: 'county' }, | ||
{ type: :text, param: :name, field: 'shelter' }, | ||
{ type: :text, param: :shelter, field: 'shelter' }, | ||
{ type: :boolean, param: :active, field: 'active' }, | ||
{ type: :boolean, param: :special_needs, field: 'special_needs' }, | ||
{ type: :text, param: :accessibility, field: 'accessibility' }, | ||
{ type: :boolean, param: :unofficial, field: 'unofficial' }, | ||
{ | ||
type: :callback, | ||
param: :accepting, | ||
fn: lambda do |query, value, filters| | ||
filters[:accepting] = | ||
case value | ||
when 'yes', 'no', 'unknown' | ||
value.to_sym | ||
when 'false' | ||
:no | ||
else | ||
:yes | ||
end | ||
query.where(accepting: filters[:accepting]) | ||
end | ||
} | ||
] | ||
|
||
def index | ||
@shelters, @filters = apply_params(Shelter.all) | ||
@shelters, @filters = apply_filters(Shelter.all) | ||
end | ||
|
||
def outdated | ||
@outdated, @filters = apply_params(Shelter.outdated.order('updated_at DESC')) | ||
end | ||
|
||
private | ||
|
||
def apply_params(shelters) | ||
filters = {} | ||
|
||
if params[:lat].present? && params[:lon].present? | ||
filters[:lon] = params[:lon] | ||
filters[:lat] = params[:lat] | ||
shelters = shelters.near([params[:lat], params[:lon]], 100) | ||
end | ||
|
||
if params[:county].present? | ||
filters[:county] = params[:county] | ||
shelters = shelters.where("county ILIKE ?", "%#{filters[:county]}%") | ||
end | ||
|
||
if params[:shelter].present? | ||
filters[:shelter] = params[:shelter] | ||
shelters = shelters.where("shelter ILIKE ?", "%#{filters[:shelter]}%") | ||
end | ||
|
||
if params[:accepting].present? | ||
val = case params[:accepting] | ||
when 'yes', 'no', 'unknown' | ||
params[:accepting].to_sym | ||
when 'true' | ||
:yes | ||
when 'false' | ||
:no | ||
else | ||
:yes | ||
end | ||
filters[:accepting] = val | ||
shelters = shelters.where(accepting: val) | ||
end | ||
|
||
if params[:special_needs].present? | ||
filters[:special_needs] = params[:special_needs] | ||
shelters = shelters.where(special_needs: true) | ||
end | ||
|
||
if params[:accessibility].present? | ||
filters[:accessibility] = params[:accessibility] | ||
shelters = shelters.where("accessibility ILIKE ?", "%#{filters[:accessibility]}%") | ||
end | ||
|
||
if params[:unofficial].present? | ||
filters[:unofficial] = params[:unofficial] | ||
shelters = shelters.where(unofficial: true) | ||
end | ||
|
||
if params[:limit].to_i.positive? | ||
shelters = shelters.limit(params[:limit].to_i) | ||
end | ||
|
||
[shelters, filters] | ||
@outdated, @filters = apply_filters(Shelter.outdated.order('updated_at DESC')) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
module FilterByParams | ||
extend ActiveSupport::Concern | ||
|
||
|
||
# | ||
# filterable_params creates a parameter function `apply_filters` that | ||
# automatically filters activerecord results by params when applied | ||
# | ||
# valid `types` include: | ||
# :exact => search where the field is an exact match to the parameter | ||
# :text => where clause using ILIKE | ||
# :boolean => where if the value is true | ||
# :callback => uses a lambda to determine how to move forward | ||
# the passed function must be a lambda of signature: | ||
# `lambda do |query, value, filters|` | ||
# AND MUST RETURN AN ACTIVERECORD QUERY OBJECT | ||
# Does not support joins or fields outside the calling model | ||
# | ||
|
||
included do | ||
def self.filterable_params(filterables) | ||
define_method(:apply_filters) do |to_filter| | ||
filters = {} | ||
list = filterables.reduce(to_filter) do |m, f| | ||
if f[:type] == :geocoords && params[:lat].present? && params[:lon].present? && m.respond_to?(:near) | ||
filters[:lon] = params[:lon] | ||
filters[:lat] = params[:lat] | ||
m.near([params[:lat], params[:lon]], 100) | ||
elsif params[f[:param]].present? | ||
filters[f[:param]] = params[f[:param]] | ||
|
||
case f[:type] | ||
when :exact | ||
m.where(f[:field] => filters[f[:param]]) | ||
when :text | ||
cls = m.table.name.classify.constantize | ||
m.where(cls.arel_table[f[:field]].matches("%#{filters[f[:param]]}%")) | ||
when :boolean | ||
m.where(f[:field] => true) | ||
when :callback | ||
f[:fn].call(m, filters[f[:param]], filters) | ||
else | ||
m | ||
end | ||
else | ||
m | ||
end | ||
end | ||
|
||
list = list.limit(params[:limit].to_i) if params[:limit].to_i.positive? | ||
|
||
[list, filters] | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
class DistributionPointsController < ApplicationController | ||
before_action :set_headers, except: [:index] | ||
before_action :set_index_headers, only: [:index] | ||
before_action :set_distribution_point, only: [:show, :edit, :update, :destroy, :archive] | ||
|
||
# GET /distribution_points | ||
# GET /distribution_points.json | ||
def index | ||
@distribution_points = DistributionPoint.all | ||
@page = Page.distribution_points.first_or_initialize | ||
respond_to do |format| | ||
format.html | ||
format.csv { send_data @distribution_points.to_csv, filename: "distribution_points-#{Date.today}.csv" } | ||
end | ||
end | ||
|
||
# GET /distribution_points/new | ||
def new | ||
@distribution_point = DistributionPoint.new | ||
end | ||
|
||
# GET /distribution_points/1 | ||
# GET /distribution_points/1.json | ||
def show | ||
end | ||
|
||
# GET /distribution_points/1/edit | ||
def edit | ||
end | ||
|
||
# POST /distribution_points | ||
# POST /distribution_points.json | ||
def create | ||
if admin? | ||
@distribution_point = DistributionPoint.new(distribution_point_params) | ||
|
||
if @distribution_point.save | ||
redirect_to distribution_points_path, notice: 'Distribution Point was successfully created.' | ||
else | ||
render :new | ||
end | ||
else | ||
draft = Draft.new(info: distribution_point_params, created_by: current_user, record_type: DistributionPoint) | ||
|
||
if draft.save | ||
redirect_to draft, notice: 'Your new distribution point is pending approval.' | ||
else | ||
@distribution_point = DistributionPoint.new(distribution_point_params) | ||
render :new | ||
end | ||
end | ||
end | ||
|
||
# PATCH/PUT /distribution_points/1 | ||
# PATCH/PUT /distribution_points/1.json | ||
def update | ||
if admin? | ||
if @distribution_point.update(distribution_point_params) | ||
redirect_to distribution_points_path, notice: 'Distribution Point was successfully updated.' | ||
else | ||
render :edit | ||
end | ||
else | ||
draft = Draft.new(record: @distribution_point, info: distribution_point_params, created_by: current_user) | ||
|
||
if draft.save | ||
redirect_to draft, notice: 'Your distribution point update is pending approval.' | ||
else | ||
render :edit | ||
end | ||
end | ||
end | ||
|
||
# DELETE /distribution_points/1 | ||
# DELETE /distribution_points/1.json | ||
def destroy | ||
end | ||
|
||
def archive | ||
if admin? | ||
@distribution_point.update_attributes(active: false) | ||
redirect_to distribution_points_path, notice: "Archived!" | ||
else | ||
redirect_to distribution_points_path, notice: "You must be an admin to archive." | ||
end | ||
end | ||
|
||
def drafts | ||
@drafts = Draft.includes(:record).where("record_type = ? OR info->>'record_type' = ?", DistributionPoint.name, DistributionPoint.name).where(accepted_by_id: nil).where(denied_by_id: nil) | ||
end | ||
|
||
def csv | ||
render :index, format: :csv | ||
end | ||
|
||
def outdated | ||
@distribution_points = DistributionPoint.outdated.order('updated_at DESC') | ||
@columns = DistributionPoint::OutdatedViewColumnNames - DistributionPoint::IndexHiddenColumnNames | ||
@headers = @columns.map(&:titleize) | ||
end | ||
|
||
private | ||
# This is the definition of a beautiful hack. 1 part gross, 2 parts simplicity. Does something neat not clever. | ||
def set_headers | ||
@columns = | ||
if admin? | ||
DistributionPoint::ColumnNames + DistributionPoint::PrivateFields | ||
else | ||
DistributionPoint::ColumnNames | ||
end | ||
@headers = @columns.map(&:titleize) | ||
end | ||
|
||
def set_index_headers | ||
@columns = | ||
if admin? | ||
(DistributionPoint::ColumnNames + DistributionPoint::PrivateFields) - DistributionPoint::IndexHiddenColumnNames | ||
else | ||
DistributionPoint::ColumnNames - DistributionPoint::IndexHiddenColumnNames | ||
end | ||
@headers = @columns.map(&:titleize) | ||
end | ||
|
||
# Use callbacks to share common setup or constraints between actions. | ||
def set_distribution_point | ||
@distribution_point = DistributionPoint.find(params[:id]) | ||
end | ||
|
||
# Never trust parameters from the scary internet, only allow the white list through. | ||
def distribution_point_params | ||
if admin? | ||
params.require(:distribution_point).permit(DistributionPoint::UpdateFields + DistributionPoint::PrivateFields).keep_if { |_,v| v.present? } | ||
else | ||
params.require(:distribution_point).permit(DistributionPoint::UpdateFields).keep_if { |_,v| v.present? } | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
class DistributionPointUpdateNotifierJob < ApplicationJob | ||
queue_as :default | ||
|
||
def perform distribution_point | ||
ShelterChannel.broadcast_to "distribution_points", distribution_point: render(distribution_point) | ||
end | ||
|
||
def render distribution_point | ||
ApplicationController.render partial: 'api/v1/distribution_points/distribution_point', | ||
locals: { | ||
distribution_point: distribution_point | ||
} | ||
end | ||
|
||
end |
Oops, something went wrong.