Permalink
Browse files

Add CRU interface and allow mappings to be filtered by tags

  • Loading branch information...
1 parent e0ee9db commit ef655cd9f1caa3098fd937a24e6105de372dc6f8 @JordanHatch JordanHatch committed Apr 30, 2012
@@ -1,7 +1,13 @@
class MappingsController < ApplicationController
+ before_filter :find_mapping, :only => [:edit, :update]
+
def index
- @mappings = Mapping.all
+ @tags_filter = params[:tags].split(",") if ! params[:tags].blank?
+ context = @tags_filter.blank? ? Mapping : Mapping.tagged_with_all(@tags_filter)
+
+ @tags = Mapping.tags
+ @mappings = context.all
respond_to do |format|
format.html
@@ -23,20 +29,58 @@ def show
render :status => 400, :json => { :status => 400, :message => 'URL not provided.' }
end
- def create
- @mapping = Mapping.new( JSON.parse params[:json] )
+ def new
+ @mapping = Mapping.new
+ end
+ def create
respond_to do |format|
- if @mapping.save
- format.json {
+ format.json {
+ @mapping = Mapping.new( JSON.parse params[:json] )
+
+ if @mapping.save
render :status => 201, :json => { :status => 201, :message => 'Mapping created.', :mapping => @mapping }
- }
- else
- format.json {
+ else
+ render :status => 422, :json => { :status => 422, :message => 'Unprocessable entity', :errors => @mapping.errors }
+ end
+ }
+ format.html {
+ @mapping = Mapping.new(params[:mapping])
+ if @mapping.save
+ flash[:success] = "Mapping created."
+ redirect_to mappings_url
+ else
+ render :action => :new
+ end
+ }
+ end
+ end
+
+ def edit; end
+
+ def update
+ respond_to do |format|
+ format.json {
+ if @mapping.update_attributes( JSON.parse params[:json] )
+ render :status => 200, :json => { :status => 201, :message => 'Mapping updated.', :mapping => @mapping }
+ else
render :status => 422, :json => { :status => 422, :message => 'Unprocessable entity', :errors => @mapping.errors }
- }
- end
+ end
+ }
+ format.html {
+ if @mapping.update_attributes( params[:mapping] )
+ flash[:success] = "Mapping updated."
+ redirect_to mappings_url
+ else
+ render :action => :edit
+ end
+ }
end
end
+ private
+ def find_mapping
+ @mapping = Mapping.find(params[:id])
+ end
+
end
@@ -1,7 +1,35 @@
module ApplicationHelper
- def mapping_path(mapping)
+ def find_mapping_path(mapping)
super({ :format => :json, :old_url => mapping.old_url })
end
+ def filter_group_from_tag(tag, group)
+ tag.sub(/#{group}:/,'')
+ end
+
+ def normalize_title(title)
+ title.sub(/ : Directgov( - .*)?$/,"")
+ end
+
+ def active_tags
+ @tags_filter || []
+ end
+
+ def tag_is_active?(tag)
+ active_tags.include?(tag)
+ end
+
+ def add_tag_to_filter_path(tag)
+ new_tags = active_tags.dup
+ new_tags << tag
+ filter_mappings_path(:tags => new_tags.join(','))
+ end
+
+ def remove_tag_from_filter_path(tag)
+ new_tags = active_tags.dup
+ new_tags.delete(tag)
+ new_tags.any? ? filter_mappings_path(:tags => new_tags.join(',')) : mappings_path
+ end
+
end
@@ -0,0 +1,7 @@
+module UrlHelper
+
+ def format_url_for_display(url)
+ truncate( URI(url).path ) unless url.blank?
+ end
+
+end
View
@@ -5,20 +5,40 @@ class Mapping
field :title, type: String
field :old_url, type: String
field :new_url, type: String
- field :status, type: Integer, default: 302
+ field :status, type: Integer, default: 301
field :notes, type: String, default: nil
field :search_query, type: String, default: nil
validates :old_url, :presence => true, :uniqueness => { :case_sensitive => false }
validates :new_url, :presence => true, :if => :is_redirect?
+ validates :status, :inclusion => { :in => [301, 410], :allow_blank => true }
+
+ before_validation :parameterize_tags
embeds_many :related_links
accepts_nested_attributes_for :related_links
# fix tags to accept our json key as an array
- alias_method :tags, :tags_array
+ alias_method :tags_list=, :tags=
alias_method :tags=, :tags_array=
+ # return a list of all the tags we know about and group them by their tag type
+ # (aka the bit before the first colon)
+ def self.tags
+ super.group_by {|tag| tag.split(":").size > 1 ? tag.split(":").first : "Other" }
+ end
+
+ # return all the tags for a mapping as an array of hashes, and split away the tag type
+ def tags
+ tags_array.map { |a|
+ { :type => a.split(":")[0], :name => (a.split(":")[1] || "").strip }
+ }
+ end
+
+ def tags_list
+ tags_array.join(", ")
+ end
+
def self.find_by_old_url(param)
raise URLNotProvided.new if !param or param.empty?
self.where( old_url: param ).first || raise(MappingNotFound.new)
@@ -31,4 +51,9 @@ def is_redirect?
class MappingNotFound < Exception; end
class URLNotProvided < Exception; end
+ private
+ def parameterize_tags
+ self.tags = tags_list.split(",").map{|tag| tag.strip.downcase.gsub(" ","-") }
+ end
+
end
@@ -0,0 +1,56 @@
+<div class="row">
+ <div class="span12">
+ <%= form_for @mapping, :html => { :class => "well" } do |f| %>
+
+ <% if @mapping.errors.any? %>
+ <% @mapping.errors.full_messages.each do |message| %>
+ <div class="alert alert-error"><%= message %></div>
+ <% end %>
+ <% end %>
+
+ <p>
+ <%= f.label :title %>
+ <%= f.text_field :title, :class => 'span6' %>
+ </p>
+
+ <p>
+ <%= f.label :old_url, "Old URL" %>
+ <%= f.text_field :old_url, :class => 'span6' %>
+ </p>
+
+ <p>
+ <%= f.label :new_url, "New URL" %>
+ <%= f.text_field :new_url, :class => 'span6' %>
+ </p>
+
+ <p>
+ <%= f.label :status %>
+ <%= f.select :status, [ ["301 - Redirect to new url", 301], ["410 - Show a gone page", 410] ], :include_blank => "Not yet decided" %>
+ </p>
+
+ <p>
+ <%= f.label :tags_list, "Tags (separate with semicolons)" %>
+ <%= f.text_field :tags_list, :class => 'span6' %>
+ </p>
+
+ <p>
+ <%= f.label :notes %>
+ <%= f.text_area :notes, :rows => 4, :class => "span6" %>
+ </p>
+
+ <h3>Related Links</h3>
+ <%= fields_for :related_links do |f| %>
+ <p>
+ <%= f.text_field :title, :placeholder => "Link Title" %>
+ <%= f.text_field :url, :placeholder => "http://" %>
+ </p>
+ <% end %>
+
+ <p>
+ <%= f.submit ( @mapping.persisted? ? "Update Mapping" : "Create Mapping"), :class => 'btn btn-primary' %> &nbsp; or &nbsp;
+ <%= link_to "Cancel", mappings_path, :class => 'btn' %>
+ </p>
+
+<% end %>
+ </div>
+</div>
@@ -0,0 +1,6 @@
+<tr>
+ <td><%= truncate normalize_title(mapping.title), :length => 60 %></td>
+ <td><%= truncate mapping.tags_list, :length => 50 %></td>
+ <td><%= mapping.status %></td>
+ <td><%= link_to "JSON", find_mapping_path(mapping) %>&nbsp;&bull;&nbsp;<%= link_to "Edit", edit_mapping_path(mapping) %></td>
+</tr>
@@ -0,0 +1,17 @@
+<div class="well" style="padding: 8px 0;">
+ <ul class="nav nav-list">
+ <% @tags.each do |group, tags| %>
+ <li class="nav-header"><%= group.capitalize %></li>
+ <% tags.each do |tag| %>
+ <% if tag_is_active? tag %>
+ <li class="active">
+ <%= filter_group_from_tag(tag, group) %>
+ <span class="badge"><%= link_to "x", remove_tag_from_filter_path(tag) %></span>
+ </li>
+ <% else %>
+ <li><%= link_to filter_group_from_tag(tag, group), add_tag_to_filter_path(tag) %></li>
+ <% end %>
+ <% end %>
+ <% end %>
+ </ul>
+</div>
@@ -0,0 +1,3 @@
+<h1>Edit Mapping</h1>
+
+<%= render :partial => 'form' %>
@@ -1,20 +1,29 @@
-<h1>List of mappings</h1>
+<div class="row">
+ <div class="span10">
+ <h1>List of mappings</h1>
+ </div>
+ <%= link_to "Add a new mapping", new_mapping_path, :class => 'btn', :style => 'float: right' %>
+</div>
-<table style="width: 100%">
- <thead>
- <tr>
- <th>Old URL</th>
- <th>New URL</th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- <% @mappings.each do |mapping| %>
- <tr>
- <td><%= mapping.old_url %></td>
- <td><%= mapping.new_url %></td>
- <td><%= link_to "JSON", mapping_path(mapping) %></td>
- </tr>
- <% end %>
- </tbody>
-</table>
+<div class="row">
+ <div class="span3">
+ <%= render :partial => "tag_list" %>
+ </div>
+ <div class="span9">
+
+ <table class="table table-striped">
+ <thead>
+ <tr>
+ <th>Title</th>
+ <th>Tags</th>
+ <th>Status</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <%= render :partial => "mapping", :collection => @mappings %>
+ </tbody>
+ </table>
+
+ </div>
+</div>
@@ -0,0 +1,3 @@
+<h1>New Mapping</h1>
+
+<%= render :partial => 'form' %>
@@ -1,7 +1,7 @@
object @mapping
attributes :id, :title, :old_url, :status, :new_url
-attribute :tags_array => :tags
+attribute :tags
attribute :notes
attribute :search_query
child :related_links => :related_links do
View
@@ -2,4 +2,8 @@
# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
- hello: "Hello world"
+ mongoid:
+ attributes:
+ mapping:
+ old_url: Old URL
+ new_url: New URL
View
@@ -1,6 +1,9 @@
Migratorator::Application.routes.draw do
- get 'mappings/find' => 'mappings#show', :as => :mapping
- resources :mappings, :except => [:show]
+ get 'mappings(/filter/:tags)' => 'mappings#index', :as => :filter_mappings, :constraints => { :tags => /.+/ }
+ get 'mappings/find' => 'mappings#show', :as => :find_mapping
+ resources :mappings
+
+ root :to => "mappings#index"
end

0 comments on commit ef655cd

Please sign in to comment.