Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/assets/stylesheets/carbuncle.css
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,8 @@ div div.elem:last-of-type

.submit_field{
padding-top: 15px;
}

.clickable {
cursor: pointer;
}
4 changes: 2 additions & 2 deletions app/controllers/administration/manage_users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def destroy
@user.destroy
end

redirect_to administration_users_path
redirect_to administration_manage_users_path
end

private
Expand All @@ -63,7 +63,7 @@ def save_form
@user.attributes = user_params
if @user.save
flash[:notice] = "Successfully saved #{@user.email}"
redirect_to administration_users_url
redirect_to administration_manage_users_url
else
setup_form
end
Expand Down
91 changes: 91 additions & 0 deletions app/controllers/notes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
class NotesController < ApplicationController
before_action :setup_sorting_variables, only: [:index]
before_action :find_note, except: [:index]

def index
sort_key = [:value, :email, :created, :updated][@sort]
direction = (@asc == 1) ? :asc : :desc

@notes = Note.similar_notes(params[:search]).
ordered_by(sort_key, direction).page(@page).per_page(10)
end

def search_users
@users = User.similar_emails(params[:partial_email]).
ordered_by(:email, :asc).limit(10)

respond_to do |format|
format.html { render partial: "/layouts/user_list" }
format.json { render :search_users }
end
end

def show
end

def new
setup_form
end

def edit
setup_form
end

def create
save_form
end

def update
save_form
end

def destroy
if @note.nil?
flash[:error] = "Can't find note"
elsif @note.new_record?
flash[:error] = "Can't destroy new note"
else
flash[:notice] = "You destroyed #{@note.value}"
@note.destroy
end

redirect_to notes_path
end

private
def find_note
@note = if params[:id].blank?
Note.new
else
Note.where(id: params[:id]).first
end
end

def setup_form
render :form
end

def save_form
@note.attributes = note_params
if @note.save
flash[:notice] = "Successfully saved #{@note.value}"
redirect_to notes_url
else
setup_form
end
end

def note_params
params.require(:note).permit(:value, :user_id)
end

def view_content
render params[:action]
end

def setup_sorting_variables
@sort = params[:sort].blank? ? 0 : params[:sort].to_i
@asc = params[:asc].blank? ? 0 : params[:asc].to_i
@page = params[:page].blank? ? 1 : params[:page].to_i
end
end
2 changes: 1 addition & 1 deletion app/controllers/products_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class ProductsController < ApplicationController
before_action :find_product, except: [:index]

def index
sort_key = [:name, :descritpion, :cost, :created, :updated][@sort]
sort_key = [:name, :description, :cost, :created, :updated][@sort]
direction = (@asc == 1) ? :asc : :desc

@products = Product.similar_names(params[:search]).
Expand Down
2 changes: 1 addition & 1 deletion app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module ApplicationHelper
def sortable(column, title = nil)
title ||= column.titleize
css_class = (column == @sort) ? "current &crarr; #{(@asc == 1) ? 'asc' : 'desc'}" : nil
css_class = (column == @sort) ? "current #{(@asc == 1) ? 'asc' : 'desc'}" : nil
direction = (column == @sort && @asc == 1) ? 0 : 1
#link_to title, {:sort => column, :direction => direction}, {:class => css_class}
link_to title, params.merge(sort: column, asc: direction, page: nil), {:class => css_class}
Expand Down
22 changes: 22 additions & 0 deletions app/models/note.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class Note < ActiveRecord::Base
belongs_to :user

validates :value, presence: true

scope :similar_notes, -> (partial) { partial.blank? ? all : where{ value =~ "%#{partial}%" } }

def self.ordered_by(sort, asc)
case sort
when :value
order{ value.send(asc) }
when :email
joins{ user.outer }.order{ user.email.send(asc) }
when :created
order{ created_at.send(asc) }
when :updated
order{ updated_at.send(asc) }
else
all
end
end
end
4 changes: 2 additions & 2 deletions app/models/painting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ class Painting < ActiveRecord::Base

mount_uploader :image, ImageUploader

before_create :default_title
before_validation :default_title

def default_title
self.title ||= File.basename(image.filename, '.*').titleize if image
self.title ||= File.basename(image.filename.to_s, '.*').titleize if image
end

def self.ordered_by(sort, asc)
Expand Down
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class User < ActiveRecord::Base
has_many :notes, dependent: :destroy
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :omniauthable,
Expand Down
12 changes: 12 additions & 0 deletions app/presenters/note_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class NotePresenter < BasePresenter
presents :note

delegate :value, :user, :created_at, :updated_at, to: :note

def creator
unless note.user.nil?
note.user.email
end
end
# Other presenter methods to help show user information
end
19 changes: 0 additions & 19 deletions app/views/administration/manage_users/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,8 @@
- else
No users match your search criteria


%br/
%br/

.white_link.small_margin
= link_to "New User", new_administration_manage_user_path, class: 'btn btn-default'


:javascript
// Add click event to each of the headers of the products table, and pagination
$(function () {
$('#users_table th a, #users_table .pagination a').on('click', &crarr;
function () {
$.getScript(this.href);
return false;
}
);

// Search form.
$('#user_search').submit(function () {
$.get(this.action, $(this).serialize(), null, 'script');
return false;
});
});
6 changes: 6 additions & 0 deletions app/views/layouts/_user_list.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- unless @users.empty?
.elem
Select from users with similar emails
- @users.each do |u|
.selection{ id: u.id }
= u.email
22 changes: 15 additions & 7 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
<div class="row">

<div class="col-md-8">
<%= link_to "Dashboard", root_path, {class: 'btn btn-primary'} %>
<%= link_to "Users", administration_manage_users_path, {class: 'btn btn-primary'} %>
<%= link_to "Images", paintings_path, {class: 'btn btn-primary'} %>
<%= link_to "Image Fader", fader_path, {class: 'btn btn-primary'} %>
<%= link_to "Products", products_path, {class: 'btn btn-primary'} %>
<%= link_to "Knockout test", knockout_test_path, {class: 'btn btn-primary'} %>

<nav>
<%= link_to "Dashboard", root_path, {class: 'btn btn-primary'} %>
<%= link_to "Users", administration_manage_users_path, {class: 'btn btn-primary'} %>
<%= link_to "Notes", notes_path, {class: 'btn btn-primary'} %>
<%= link_to "Images", paintings_path, {class: 'btn btn-primary'} %>
<%= link_to "Image Fader", fader_path, {class: 'btn btn-primary'} %>
<%= link_to "Products", products_path, {class: 'btn btn-primary'} %>
<%= link_to "Knockout test", knockout_test_path, {class: 'btn btn-primary'} %>
</nav>
</div>
<div class="col-md-4">
<% if user_signed_in? %>
Expand All @@ -34,6 +36,12 @@
</div>
</div>

<% unless flash[:alert].blank? %>
<div class="error">
<%= flash[:alert] %>
</div>
<% end %>

<% unless flash[:notice].blank? %>
<div class="notice">
<%= flash[:notice] %>
Expand Down
14 changes: 14 additions & 0 deletions app/views/notes/_list.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
= will_paginate @notes

= hidden_field_tag :sort, params[:sort]
= hidden_field_tag :page, params[:page]

%table.table.table-striped
%tr
- ["Value", "User", "Created", "Modified"].each_with_index do |title, index|
%th= sortable index, title
%th
%th
%th

= render partial: 'notes_table'
10 changes: 10 additions & 0 deletions app/views/notes/_notes_table.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- @notes.each do |note|
- present note do |n|
%tr
%td= n.value
%td= n.creator || "No user"
%td= n.created_at.strftime('%D')
%td= n.updated_at.strftime('%D')
%td= link_to "Show", n.note
%td= link_to 'Edit', edit_note_path(n.note)
%td= link_to 'Destroy', n.note, method: :delete, data: { confirm: "Are you sure?" }
89 changes: 89 additions & 0 deletions app/views/notes/form.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
%h1= (@note.new_record?) ? 'Create note' : 'Edit note'

- if @note.errors.any?
#error_explanation
%h2= pluralize(@note.errors.count, t(:error)).html_safe + t(:_prohibited_this_note_from_being_saved)
%ul
- @note.errors.full_messages.each do |msg|
%li= msg

.elem.generic_form
= form_for @note, as: :note, url: "/notes/#{@note.id}" do |f|
.elem
.labels
= f.label :value
= f.text_field :value, class: "form-control"

= f.hidden_field :user_id, "data-bind" => "value: userId"

.elem
.labels
= label_tag :user_email
= text_field_tag :user_email, f.object.user.nil? ? "" : f.object.user.email, "data-bind" => "value: email, valueUpdate: 'afterkeydown'", class: "form-control"

.results.well{ "data-bind" => "visible: showUserResults" }
%h5
Please select from the list below (If the user is not found, then no user will be set)
%span{ "data-bind" => "template: { name: 'users', foreach: emailList }" }

%script{ "id" => "users", "type" => "text/html" }
.clickable{ "data-bind" => "text: email, click: $parent.selectUser" }

.btn-group.submit_field
- if @note.new_record?
= f.submit 'Create', class: 'btn btn-success'
- else
= f.submit 'Update', class: 'btn btn-success'
= link_to 'Show', @note, { class: 'btn btn-default' }

= link_to 'Back', notes_path, { class: 'btn btn-default' }

:javascript

var initial_user = $('#user_email').val(),
initial_user_id = $('#note_user_id').val(),
viewModel = { email: ko.observable(initial_user || ''),
userId: ko.observable(initial_user_id || ''),
showUserResults: ko.observable(false),
emailList: ko.observableArray() };

viewModel.email.subscribe(function (partial) {
if (partial === '') {
viewModel.userId('');
} else {
var posting = {partial_email: ko.unwrap(partial)};
$.ajax({
url: '#{search_users_path}',
dataType: 'json',
method: 'post',
data: posting,
success: function (results) {
// If the only result is the partial, then hide results
if (results.length === 1 && results[0].email === partial) {
viewModel.showUserResults(false);
} else {
viewModel.showUserResults(true);
}
viewModel.emailList(results);
},
error: function (jqXHR, textStatus, errorThrown) {
alert(jqXHR.responseText);
}
});
}
});

viewModel.selectUser = function (data) {
viewModel.email(data.email);
};

//Before form submits check if the user id can be updated
$('#edit_note').submit(function () {
if ($('.results .clickable:hidden').length === 1) {
if (viewModel.emailList()[0].email === viewModel.email()) {
viewModel.userId(viewModel.emailList()[0].id);
}
}
});

ko.applyBindings(viewModel);
Loading