Permalink
Browse files

Added category management

  • Loading branch information...
wlodars committed Jul 6, 2008
1 parent e8a40d4 commit fbcb87c1c5134dc216a68f9a0ac78a63dab51bd7
@@ -2,9 +2,62 @@ class Admin::CategoriesController < ApplicationController
before_filter :login_required
layout 'admin'
- # GET /admin/jobs/1
+ # GET /admin/categories
+ def index
+ @categories = Category.all(:order => 'position ASC')
+ end
+
+ # GET /admin/categories/1
def show
@category = Category.find_by_value(params[:id])
@jobs = @category.jobs.find_all_by_is_active(true, :order => "created_at DESC")
end
+
+ # POST /admin/categories
+ def create
+ temp = Category.find_by_sql "SELECT MAX(position) as position FROM categories"
+ @category = Category.new(:name => 'New category', :value => 'newcategory', :position => temp[0].position + 1)
+ @category.save
+
+ respond_to do |format|
+ format.html { redirect_to admin_categories_url }
+ format.js # admin/categories/create.js.rjs
+ end
+ end
+
+ # PUT /admin/categories/1
+ def update
+ @category = Category.find(params[:id])
+
+ respond_to do |format|
+ if @category.update_attributes(:name => params[:name], :value => params[:url])
+ format.html { redirect_to admin_categories_url }
+ format.js # admin/categories/update.js.rjs
+ end
+ end
+ end
+
+ # PUT /admin/categories/saveorder
+ def saveorder
+ params[:categoriesContainer].each_with_index do |id, position|
+ category = Category.find(id)
+ category.update_attribute('position', position)
+ end
+
+ respond_to do |format|
+ format.html { redirect_to admin_categories_url }
+ format.js # admin/categories/saveorder.js.rjs
+ end
+ end
+
+ # DELETE /admin/categories/1
+ def destroy
+ @category = Category.find(params[:id])
+ @category.destroy if @category.jobs.empty?
+
+ respond_to do |format|
+ format.html { redirect_to admin_categories_url }
+ format.js # admin/categories/destroy.js.rjs
+ end
+ end
end
@@ -2,4 +2,8 @@ module Admin::CategoriesHelper
def admin_category_nav_item(category)
category_nav_item(category, true)
end
+
+ def show_save_category(category_id)
+ "Element.show('saveCategory#{category_id}');Element.replace('messagesContainer', '<div id=\"messagesContainer\" style=\"display:none\">Value changed. You must save the change!</div>');Element.show('messagesContainer')"
+ end
end
@@ -8,7 +8,7 @@ def category_nav_item(category, admin = false)
li_options[:class] = "selected"
end
- link = link_to "<span>#{category.name.pluralize}</span><span class='cnr'>&nbsp;</span>", (admin ? admin_category_url(category) : category_url(category)), :title => category.name.pluralize
+ link = link_to "<span>#{category.name}</span><span class='cnr'>&nbsp;</span>", (admin ? admin_category_url(category) : category_url(category)), :title => category.name
return content_tag(:li, link, li_options)
end
@@ -0,0 +1,14 @@
+.categoryItem{:id => "category_#{category.id}"}
+ .categoryHandle
+ .categoryWrapper
+ .categoryManagement{:style => 'float:right;width:10%;'}
+ = link_to_remote(image_tag("icon-delete.png", :alt => 'Delete') + " Delete", {:url => admin_category_url(category.id), :confirm => 'Are you sure you want to delete this category?', :method => :delete}, {:class => 'deleteCategory'})
+ = link_to_remote(image_tag("disk.png", :alt => 'Save') + " Save", {:url => admin_category_url(category.id), :method => :put, :with => "'name='+$F('name[#{category.id}]')+'&url='+$F('url[#{category.id}]')"}, {:id => "saveCategory#{category.id}", :class => 'saveCategory', :style => 'display:none;'})
+ %label
+ %span Name:
+ = text_field_tag "name[#{category.id}]", category.name, :size => 60
+ = observe_field "name[#{category.id}]", :frequency => 1, :function => show_save_category(category.id)
+ %label
+ %span URL:
+ = text_field_tag "url[#{category.id}]", category.value, :size => 60
+ = observe_field "url[#{category.id}]", :frequency => 1, :function => show_save_category(category.id)
@@ -1,5 +1,4 @@
-#categories
- %ul
- - Category.list.each do |category|
- = admin_category_nav_item(category)
- = clear
+%ul
+ - Category.list.each do |category|
+ = admin_category_nav_item(category)
+= clear
@@ -0,0 +1,9 @@
+page.insert_html :bottom, 'categoriesContainer', :partial => 'admin/categories/category'
+page.sortable 'categoriesContainer', :tag => 'div', :url => saveorder_admin_categories_path
+@category = nil
+page.replace_html "categories", :partial => 'admin/categories/list'
+page.replace_html "messagesContainer", "Category has been added"
+page.show "messagesContainer"
+page.delay(3) do
+ page.visual_effect :fade, "messagesContainer"
+end
@@ -0,0 +1,12 @@
+if @category.jobs.empty?
+ page["category_#{@category.id}"].visual_effect :switch_off, "category_#{@category.id}"
+ page.remove "category_#{@category.id}"
+ page.replace_html "categories", :partial => 'admin/categories/list'
+ page.replace_html "messagesContainer", "Category has been deleted"
+ page.show "messagesContainer"
+ page.delay(3) do
+ page.visual_effect :fade, "messagesContainer"
+ end
+else
+ page.alert("You cannot delete this category because there are jobs in this category!")
+end
@@ -0,0 +1,11 @@
+%h2 Categories
+
+#categoriesContainer
+ = partial @categories
+
+= sortable_element "categoriesContainer", :url => saveorder_admin_categories_path, :tag => "div", :complete => visual_effect(:highlight, 'categoriesContainer')
+
+#overlay{:style => "display: none; top: 145px; left: 157px;height: 72px;"}
+ = image_tag("ajax-loader.gif", :alt => "Loading...")
+%p
+ = link_to_remote image_tag("add.png", :alt => 'Add') + " Add new category", :url => admin_categories_path, :method => :post, :loading => "Element.show('overlay')", :complete => "Element.hide('overlay');"
@@ -0,0 +1,6 @@
+page.replace_html "categories", :partial => 'admin/categories/list'
+page.replace_html "messagesContainer", "Categories order changed. Saving ..."
+page.show "messagesContainer"
+page.delay(3) do
+ page.visual_effect :fade, "messagesContainer"
+end
@@ -0,0 +1,9 @@
+page["category_#{@category.id}"].visual_effect :pulsate, "category_#{@category.id}"
+page.hide "saveCategory#{@category.id}"
+@category = nil
+page.replace_html "categories", :partial => 'admin/categories/list'
+page.replace_html "messagesContainer", "Category has been updated"
+page.show "messagesContainer"
+page.delay(3) do
+ page.visual_effect :fade, "messagesContainer"
+end
@@ -16,7 +16,8 @@
%td{:style => 'text-align:left;width:15%'}
-# activate/deactivate link
- = link_to_remote(activation_image_tag(job), :url => admin_job_url(job.id), :method => :put)
+ = link_to_remote(activation_image_tag(job), {:url => admin_job_url(job.id), :method => :put, :loading => "Element.hide('activ_butt_#{job.id}');Element.show('loading_#{job.id}')", :complete => "Element.hide('loading_#{job.id}');Element.show('activ_butt_#{job.id}')"}, {:id => "activ_butt_#{job.id}"})
+ = image_tag("ajax-loader.gif", :alt => "Saving...", :style => 'display:none', :id => "loading_#{job.id}")
-# delete link
= link_to_remote(image_tag("icon-delete.png", :alt => 'Delete'), :url => admin_job_url(job.id), :confirm => 'Are you sure you want to delete this post?', :method => :delete)
@@ -1 +1,6 @@
-page["job_#{@job.id}"].visual_effect :fade, "job_#{@job.id}"
+page["job_#{@job.id}"].visual_effect :fade, "job_#{@job.id}"
+page.replace_html "messagesContainer", "Job has been deleted"
+page.show "messagesContainer"
+page.delay(3) do
+ page.visual_effect :fade, "messagesContainer"
+end
@@ -1 +1,6 @@
-page.replace "activate_#{@job.id}", activation_image_tag(@job)
+page.replace "activate_#{@job.id}", activation_image_tag(@job)
+page.replace_html "messagesContainer", "Job has been activated/deactivated"
+page.show "messagesContainer"
+page.delay(3) do
+ page.visual_effect :fade, "messagesContainer"
+end
@@ -1,10 +1,10 @@
#header
%h1#logo= link_to AppConfig.site_name, root_path
- if logged_in?
- %ul#top
+ %ul#top{:style => 'padding-top:50px'}
%li= link_to "Pages", "#"
= bull
- %li= link_to "Categories", "#"
+ %li= link_to "Categories", admin_categories_path
= bull
%li= link_to "Change your password", "#"
= bull
@@ -13,7 +13,11 @@
#container
= partial "layouts/admin_header"
- if logged_in?
- = partial "admin/categories/list"
+ #categories
+ = partial "admin/categories/list"
#content
- = yield
+ = yield
+
+ .footer
+ #messagesContainer{:style => 'display:none'}
View
@@ -20,7 +20,7 @@
# Directs /admin/jobs/* to Admin::JobsController (app/controllers/admin/jobs_controller.rb)
admin.resources :jobs
# Directs /admin/categories/* to Admin::CategoriesController (app/controllers/admin/categories_controller.rb)
- admin.resources :categories
+ admin.resources :categories, :collection => {:saveorder => :put}
end
map.root :controller => "jobs"
@@ -948,4 +948,91 @@ div#categs-nav {
#no-ads {
color:#555555;
margin-top:10px;
+}
+
+#categoriesContainer {
+ position:relative;
+ width:670px;
+ padding-top:10px;
+ padding-bottom:10px;
+}
+
+.categoryItem {
+ background-color:#F5F5F5;
+ border:1px solid #CCCCCC;
+ margin:0pt 0pt 5px;
+ position:relative;
+ width:650px;
+ margin-left:10px;
+}
+
+.categoryHandle {
+ background:#0099CC none repeat scroll 0% 0%;
+ cursor:move;
+ height:10px;
+ margin-bottom:5px;
+ overflow:hidden;
+}
+
+.categoryWrapper {
+ padding:5px;
+}
+
+.categoryItem label {
+ display:block;
+ margin-bottom:5px;
+}
+
+.categoryItem label span {
+ clear:left;
+ display:block;
+ float:left;
+ font-weight:bold;
+ margin-bottom:5px;
+ width:70px;
+}
+
+a.deleteCategory, a.saveCategory {
+ float: right;
+}
+
+div.footer {
+ background:#F2FCFF url(/images/footer-bg.png) no-repeat scroll center top;
+ color:#888888;
+ float:left;
+ font-size:11px;
+ height:14em;
+ margin-top:30px;
+ padding-top:12px;
+ text-align:center;
+ width:100%;
+}
+
+#overlay {
+ vertical-align:middle;
+ background-color:#FFFFFF;
+ opacity:0.7;
+ width:650px;
+}
+
+#overlay img {
+ left:50%;
+ margin-left:-12px;
+ margin-top:-12px;
+ position:relative;
+ top:50%;
+ z-index:3000;
+}
+
+#messagesContainer {
+ left:50%;
+ margin-left:-150px;
+ position:absolute;
+ top:0pt;
+ width:300px;
+ background-color:#fff;
+ height:30px;
+ border:8px solid #eeeeee;
+ font-size:9px;
+ padding-top:10px;
}
@@ -6,4 +6,9 @@ programmer:
designer:
name: Designers
value: designers
- position: 2
+ position: 2
+
+administrator:
+ name: Administrators
+ value: administrators
+ position: 3
@@ -1,7 +1,7 @@
require 'test_helper'
class Admin::CategoriesControllerTest < ActionController::TestCase
- def test_should_show_active_jobs_in_category
+ def test_should_show_category_and_active_jobs
login_as(:mark)
get :show, :id => categories(:programmer).name
assert_response :success
@@ -11,4 +11,48 @@ def test_should_show_active_jobs_in_category
assert job.is_active
end
end
+
+ def test_should_get_categories
+ login_as(:admin)
+ get :index
+ assert_equal Category.count, assigns(:categories).size
+ end
+
+ def test_should_create_category
+ login_as(:mark)
+ assert_difference('Category.count') do
+ xhr :post, :create
+ end
+ end
+
+ def test_should_update_category
+ login_as(:admin)
+ xhr :put, :update, {:id => categories(:programmer).id, :name => "New name"}
+ categories(:programmer).reload
+ assert_equal('New name', categories(:programmer).name)
+ end
+
+ def test_should_delete_category_without_jobs
+ login_as(:bob)
+ assert_difference('Category.count', -1) do
+ xhr :delete, :destroy, :id => categories(:administrator).id
+ end
+ assert_response :success
+ end
+
+ def test_should_not_delete_category_with_jobs
+ login_as(:bob)
+ count = Category.count
+ xhr :delete, :destroy, :id => categories(:programmer).id
+ assert_equal(count, Category.count)
+ end
+
+ def test_should_change_order
+ login_as(:mark)
+ xhr :put, :saveorder, :categoriesContainer => [categories(:administrator).id, categories(:programmer).id, categories(:designer).id]
+ categories(:administrator).reload
+ assert_equal 0, categories(:administrator).position
+ categories(:designer).reload
+ assert_equal 2, categories(:designer).position
+ end
end

0 comments on commit fbcb87c

Please sign in to comment.