├── .rspec ├── .ruby-gemset ├── spec ├── dummy │ ├── log │ │ └── .gitkeep │ ├── app │ │ ├── mailers │ │ │ └── .gitkeep │ │ ├── models │ │ │ ├── .gitkeep │ │ │ └── user.rb │ │ ├── helpers │ │ │ ├── base_helper.rb │ │ │ └── application_helper.rb │ │ ├── views │ │ │ ├── base │ │ │ │ └── index.html.erb │ │ │ └── layouts │ │ │ │ └── application.html.erb │ │ ├── controllers │ │ │ ├── base_controller.rb │ │ │ └── application_controller.rb │ │ └── assets │ │ │ ├── stylesheets │ │ │ ├── base.css │ │ │ └── application.css │ │ │ └── javascripts │ │ │ ├── base.js │ │ │ └── application.js │ ├── lib │ │ └── assets │ │ │ └── .gitkeep │ ├── public │ │ ├── favicon.ico │ │ ├── 500.html │ │ ├── 422.html │ │ └── 404.html │ ├── Procfile │ ├── .DS_Store │ ├── test │ │ ├── unit │ │ │ ├── helpers │ │ │ │ └── base_helper_test.rb │ │ │ └── user_test.rb │ │ ├── functional │ │ │ └── base_controller_test.rb │ │ └── fixtures │ │ │ └── users.yml │ ├── config.ru │ ├── config │ │ ├── environment.rb │ │ ├── locales │ │ │ ├── en.yml │ │ │ ├── devise.en.yml │ │ │ ├── helpdesk.en.yml │ │ │ └── helpdesk.pl.yml │ │ ├── initializers │ │ │ ├── mime_types.rb │ │ │ ├── kaminari.rb │ │ │ ├── secret_token.rb │ │ │ ├── backtrace_silencers.rb │ │ │ ├── session_store.rb │ │ │ ├── wrap_parameters.rb │ │ │ ├── inflections.rb │ │ │ └── helpdesk.rb │ │ ├── boot.rb │ │ ├── database.yml │ │ ├── environments │ │ │ ├── development.rb │ │ │ ├── test.rb │ │ │ └── production.rb │ │ ├── routes.rb │ │ └── application.rb │ ├── .gitignore │ ├── db │ │ ├── migrate │ │ │ ├── 20120420204444_add_helpdesk_admin_to_user.rb │ │ │ ├── 20140326084236_create_helpdesk_comments.helpdesk.rb │ │ │ ├── 20140326084239_create_helpdesk_subscribers.helpdesk.rb │ │ │ ├── 20141106132701_add_parent_id_to_helpdesk_faqs.helpdesk.rb │ │ │ ├── 20140326084235_create_helpdesk_tickets.helpdesk.rb │ │ │ ├── 20140326084238_create_helpdesk_faqs.helpdesk.rb │ │ │ ├── 20140326084237_create_helpdesk_ticket_types.helpdesk.rb │ │ │ └── 20120405124828_devise_create_users.rb │ │ └── schema.rb │ ├── Gemfile │ ├── Rakefile │ ├── script │ │ └── rails │ └── Gemfile.lock ├── .DS_Store ├── support │ ├── kaminari.rb │ ├── factories │ │ ├── ticket_types.rb │ │ ├── tickets.rb │ │ ├── users.rb │ │ └── comments.rb │ ├── signin_helpers.rb │ └── mailer_macros.rb ├── ci.sh ├── requests │ └── admin │ │ ├── tickets_spec.rb │ │ └── dashboard_spec.rb ├── models │ ├── comment_spec.rb │ └── ticket_spec.rb └── spec_helper.rb ├── .ruby-version ├── app ├── assets │ ├── images │ │ └── helpdesk │ │ │ └── .gitkeep │ ├── stylesheets │ │ └── helpdesk │ │ │ ├── custom.css │ │ │ ├── custom_admin.css │ │ │ ├── admin │ │ │ ├── bootstrap_overrides.css │ │ │ └── faqs.css.sass │ │ │ ├── admin.css.scss │ │ │ ├── tickets.css.sass │ │ │ ├── application.css │ │ │ └── faqs.css.scss │ └── javascripts │ │ └── helpdesk │ │ ├── dashboard.js │ │ ├── subscribers.js │ │ ├── admin │ │ ├── dashboard.js │ │ └── tickets.js │ │ ├── faqs.js │ │ ├── application.js │ │ └── ckeditor.js ├── views │ ├── helpdesk │ │ ├── admin │ │ │ ├── dashboard │ │ │ │ └── index.html.erb │ │ │ ├── faqs │ │ │ │ ├── new.html.haml │ │ │ │ ├── edit.html.haml │ │ │ │ ├── show.html.haml │ │ │ │ ├── index.html.haml │ │ │ │ ├── _menu.html.haml │ │ │ │ ├── _faq.html.haml │ │ │ │ ├── _form.html.haml │ │ │ │ ├── inactive.html.haml │ │ │ │ └── sorting.html.haml │ │ │ ├── tickets │ │ │ │ ├── new.html.haml │ │ │ │ ├── list.html.haml │ │ │ │ ├── _menu.html.haml │ │ │ │ ├── _form.html.haml │ │ │ │ ├── edit.html.haml │ │ │ │ ├── index.html.haml │ │ │ │ ├── show.html.haml │ │ │ │ └── _ticket.html.haml │ │ │ ├── subscribers │ │ │ │ ├── new.html.haml │ │ │ │ ├── edit.html.haml │ │ │ │ ├── _form.html.haml │ │ │ │ ├── _menu.html.haml │ │ │ │ └── index.html.haml │ │ │ └── ticket_types │ │ │ │ ├── new.html.haml │ │ │ │ ├── show.html.haml │ │ │ │ ├── edit.html.haml │ │ │ │ ├── _form.html.haml │ │ │ │ ├── _menu.html.haml │ │ │ │ └── index.html.haml │ │ ├── dashboard │ │ │ └── index.html.erb │ │ ├── subscribers │ │ │ ├── index.html.erb │ │ │ ├── edit.html.erb │ │ │ ├── _form.html.haml │ │ │ └── show.html.erb │ │ ├── tickets │ │ │ ├── new.html.haml │ │ │ ├── _menu.html.haml │ │ │ ├── index.html.haml │ │ │ ├── _form.html.haml │ │ │ ├── show.html.haml │ │ │ └── _ticket.html.haml │ │ ├── faqs │ │ │ ├── _faq.html.haml │ │ │ ├── index.html.haml │ │ │ ├── _menu.html.haml │ │ │ ├── show.html.haml │ │ │ └── search.html.haml │ │ └── notifications_mailer │ │ │ ├── send_activate_subscription.html.haml │ │ │ ├── comment_by_helpdesk_confirmation.html.haml │ │ │ ├── comment_by_helpdesk_notification.html.haml │ │ │ ├── ticket_created_confirmation.html.haml │ │ │ ├── comment_by_requester_confirmation.html.haml │ │ │ ├── ticket_created_notification.html.haml │ │ │ └── comment_by_requester_notification.html.haml │ └── layouts │ │ ├── mailer_layout.html.haml │ │ └── helpdesk │ │ ├── user.html.haml │ │ ├── admin.html.haml │ │ ├── _topmenu.html.haml │ │ └── _topuser.html.haml ├── helpers │ └── helpdesk │ │ ├── faqs_helper.rb │ │ ├── dashboard_helper.rb │ │ ├── subscribers_helper.rb │ │ ├── tickets_helper.rb │ │ ├── admin │ │ ├── dashboard_helper.rb │ │ └── tickets_helper.rb │ │ └── helpdesk_helper.rb ├── controllers │ └── helpdesk │ │ ├── admin │ │ ├── dashboard_controller.rb │ │ ├── base_controller.rb │ │ ├── subscribers_controller.rb │ │ ├── ticket_types_controller.rb │ │ ├── tickets_controller.rb │ │ └── faqs_controller.rb │ │ ├── faqs_controller.rb │ │ ├── rooter_controller.rb │ │ ├── application_controller.rb │ │ ├── dashboard_controller.rb │ │ ├── subscribers_controller.rb │ │ └── tickets_controller.rb ├── models │ └── helpdesk │ │ ├── ticket_type.rb │ │ ├── subscriber.rb │ │ ├── comment.rb │ │ ├── faq.rb │ │ └── ticket.rb └── mailers │ └── helpdesk │ └── notifications_mailer.rb ├── db ├── .DS_Store └── migrate │ ├── 20120423113938_create_helpdesk_comments.rb │ ├── 20141105112734_add_parent_id_to_helpdesk_faqs.rb │ ├── 20130522090420_create_helpdesk_subscribers.rb │ ├── 20120420104051_create_helpdesk_tickets.rb │ ├── 20130522085614_create_helpdesk_faqs.rb │ └── 20130521105605_create_helpdesk_ticket_types.rb ├── lib ├── helpdesk │ ├── version.rb │ └── engine.rb ├── route_constraints_faqs.rb ├── route_constraints_tickets.rb ├── templates │ └── erb │ │ └── scaffold │ │ └── _form.html.erb ├── tasks │ └── prepare_ci_env.rake ├── helpdesk.rb └── generators │ └── helpdesk │ ├── install_generator.rb │ └── templates │ ├── README │ └── helpdesk.rb ├── config ├── locales │ ├── helpdesk_routes.yml │ ├── simple_form.pl.yml │ ├── simple_form.en.yml │ ├── helpdesk.pt-BR.yml │ ├── helpdesk.en.yml │ └── helpdesk.pl.yml ├── initializers │ ├── globalize.rb │ ├── action_mailer.rb │ └── simple_form.rb └── routes.rb ├── test ├── fixtures │ └── helpdesk │ │ ├── comments.yml │ │ ├── faqs.yml │ │ └── subscribers.yml ├── unit │ ├── helpers │ │ └── helpdesk │ │ │ ├── faqs_helper_test.rb │ │ │ └── subscribers_helper_test.rb │ └── helpdesk │ │ ├── faq_test.rb │ │ └── subscriber_test.rb └── functional │ └── helpdesk │ ├── faqs_controller_test.rb │ └── subscribers_controller_test.rb ├── .gitignore ├── script └── rails ├── .travis.yml ├── Gemfile ├── Rakefile ├── MIT-LICENSE ├── helpdesk.gemspec ├── README.md └── Gemfile.lock /.rspec: -------------------------------------------------------------------------------- 1 | --colour 2 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | helpdesk -------------------------------------------------------------------------------- /spec/dummy/log/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.1.5 2 | -------------------------------------------------------------------------------- /spec/dummy/app/mailers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/lib/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/helpdesk/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec rails s 2 | -------------------------------------------------------------------------------- /spec/dummy/app/helpers/base_helper.rb: -------------------------------------------------------------------------------- 1 | module BaseHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/dummy/app/views/base/index.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome!

2 | 3 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/dashboard/index.html.erb: -------------------------------------------------------------------------------- 1 |

Dashboard

2 | 3 | -------------------------------------------------------------------------------- /db/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wacaw/helpdesk/HEAD/db/.DS_Store -------------------------------------------------------------------------------- /lib/helpdesk/version.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | VERSION = "0.0.42" 3 | end 4 | -------------------------------------------------------------------------------- /spec/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wacaw/helpdesk/HEAD/spec/.DS_Store -------------------------------------------------------------------------------- /spec/dummy/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/dummy/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wacaw/helpdesk/HEAD/spec/dummy/.DS_Store -------------------------------------------------------------------------------- /app/helpers/helpdesk/faqs_helper.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | module FaqsHelper 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/helpers/helpdesk/dashboard_helper.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | module DashboardHelper 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/views/helpdesk/dashboard/index.html.erb: -------------------------------------------------------------------------------- 1 |

Help Desk

2 |

Some kind of dashboard

3 | 4 | -------------------------------------------------------------------------------- /app/views/helpdesk/subscribers/index.html.erb: -------------------------------------------------------------------------------- 1 |

New subscriber

2 | 3 | <%= render 'form' %> 4 | 5 | -------------------------------------------------------------------------------- /app/helpers/helpdesk/subscribers_helper.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | module SubscribersHelper 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /config/locales/helpdesk_routes.yml: -------------------------------------------------------------------------------- 1 | en: 2 | routes: 3 | 4 | pl: 5 | routes: 6 | tickets: zgloszenia 7 | -------------------------------------------------------------------------------- /app/helpers/helpdesk/tickets_helper.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | module TicketsHelper 3 | 4 | 5 | 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/base_controller.rb: -------------------------------------------------------------------------------- 1 | class BaseController < ApplicationController 2 | def index 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /config/initializers/globalize.rb: -------------------------------------------------------------------------------- 1 | # Globalize.fallbacks = { 2 | # :en => [:en, :pl], 3 | # :pl => [:pl, :en], 4 | # } 5 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/faqs/new.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | - content_for :title do 3 | New FAQ 4 | 5 | = render 'form' 6 | 7 | -------------------------------------------------------------------------------- /spec/dummy/test/unit/helpers/base_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class BaseHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/faqs/edit.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | - content_for :title do 4 | Edycja pytania 5 | 6 | = render 'form' 7 | -------------------------------------------------------------------------------- /app/views/helpdesk/tickets/new.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | - content_for :title do 3 | = t('helpdesk.new_ticket') 4 | = render 'form' 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/helpdesk/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Place all the styles what You want in Your app/assets/stylesheets/helpdesk/cutom.css 3 | */ 4 | -------------------------------------------------------------------------------- /app/helpers/helpdesk/admin/dashboard_helper.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | module Admin 3 | module DashboardHelper 4 | end 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/tickets/new.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | - content_for :title do 3 | = t('helpdesk.new_ticket') 4 | = render 'form' 5 | -------------------------------------------------------------------------------- /test/fixtures/helpdesk/comments.yml: -------------------------------------------------------------------------------- 1 | 2 | one: 3 | public: true 4 | text: MyString 5 | 6 | two: 7 | public: false 8 | text: MyString 9 | -------------------------------------------------------------------------------- /config/initializers/action_mailer.rb: -------------------------------------------------------------------------------- 1 | ActionMailer::Base.default :from => "test@example.com" 2 | ActionMailer::Base.default :to => "test@example.com" 3 | -------------------------------------------------------------------------------- /lib/route_constraints_faqs.rb: -------------------------------------------------------------------------------- 1 | class RouteConstraintsFaqs 2 | def matches?(request) 3 | Helpdesk.root_controller == 'faqs' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/route_constraints_tickets.rb: -------------------------------------------------------------------------------- 1 | class RouteConstraintsTickets 2 | def matches?(request) 3 | Helpdesk.root_controller != 'faqs' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/support/kaminari.rb: -------------------------------------------------------------------------------- 1 | module Kaminari::ActionViewExtension::InstanceMethods 2 | def paginate(scope, options = {}, &block) 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/helpdesk/custom_admin.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Place all the styles what You want in Your app/assets/stylesheets/helpdesk/custom_admin.css 3 | */ 4 | -------------------------------------------------------------------------------- /test/unit/helpers/helpdesk/faqs_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | module Helpdesk 4 | class FaqsHelperTest < ActionView::TestCase 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle/ 2 | .DS_Store 3 | log/*.log 4 | pkg/ 5 | spec/dummy/db/*.sqlite3 6 | spec/dummy/log/*.log 7 | spec/dummy/tmp/ 8 | spec/dummy/.sass-cache 9 | .env 10 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/subscribers/new.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :title do 2 | New subscriber 3 | 4 | = render 'form' 5 | 6 | \| 7 | = link_to 'Back', admin_subscribers_path 8 | -------------------------------------------------------------------------------- /spec/dummy/test/unit/user_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UserTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/unit/helpers/helpdesk/subscribers_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | module Helpdesk 4 | class SubscribersHelperTest < ActionView::TestCase 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/stylesheets/base.css: -------------------------------------------------------------------------------- 1 | /* 2 | Place all the styles related to the matching controller here. 3 | They will automatically be included in application.css. 4 | */ 5 | -------------------------------------------------------------------------------- /spec/support/factories/ticket_types.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :ticket_type, class: Helpdesk::TicketType do 3 | position 1 4 | title "MyString" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Dummy::Application 5 | -------------------------------------------------------------------------------- /app/views/helpdesk/subscribers/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing subscriber

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Show', @subscriber %> | 6 | <%= link_to 'Back', subscribers_path %> 7 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/javascripts/base.js: -------------------------------------------------------------------------------- 1 | // Place all the behaviors and hooks related to the matching controller here. 2 | // All this logic will automatically be available in application.js. 3 | -------------------------------------------------------------------------------- /app/assets/javascripts/helpdesk/dashboard.js: -------------------------------------------------------------------------------- 1 | // Place all the behaviors and hooks related to the matching controller here. 2 | // All this logic will automatically be available in application.js. 3 | -------------------------------------------------------------------------------- /app/assets/javascripts/helpdesk/subscribers.js: -------------------------------------------------------------------------------- 1 | // Place all the behaviors and hooks related to the matching controller here. 2 | // All this logic will automatically be available in application.js. 3 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/ticket_types/new.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | - content_for :title do 4 | New ticket_type 5 | 6 | = render 'form' 7 | 8 | = link_to 'Back', admin_ticket_types_path 9 | -------------------------------------------------------------------------------- /spec/dummy/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Dummy::Application.initialize! 6 | -------------------------------------------------------------------------------- /app/assets/javascripts/helpdesk/admin/dashboard.js: -------------------------------------------------------------------------------- 1 | // Place all the behaviors and hooks related to the matching controller here. 2 | // All this logic will automatically be available in application.js. 3 | -------------------------------------------------------------------------------- /spec/dummy/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore bundler config 2 | /.bundle 3 | 4 | # Ignore the default SQLite database. 5 | /db/*.sqlite3 6 | 7 | # Ignore all logfiles and tempfiles. 8 | /log/*.log 9 | /tmp 10 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20120420204444_add_helpdesk_admin_to_user.rb: -------------------------------------------------------------------------------- 1 | class AddHelpdeskAdminToUser < ActiveRecord::Migration 2 | def change 3 | add_column :users, :helpdesk_admin, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/ci.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | cd spec/dummy && bundle install --without debug && bundle exec rake helpdesk:prepare_ci_env db:create db:migrate && cd ../.. && bundle exec rake db:migrate && bundle exec rspec -bfs spec 3 | -------------------------------------------------------------------------------- /test/unit/helpdesk/faq_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | module Helpdesk 4 | class FaqTest < ActiveSupport::TestCase 5 | # test "the truth" do 6 | # assert true 7 | # end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/admin/dashboard_controller.rb: -------------------------------------------------------------------------------- 1 | class Helpdesk::Admin::DashboardController < Helpdesk::Admin::BaseController 2 | 3 | def index 4 | #@tickets = Helpdesk::Ticket.all 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /test/unit/helpdesk/subscriber_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | module Helpdesk 4 | class SubscriberTest < ActiveSupport::TestCase 5 | # test "the truth" do 6 | # assert true 7 | # end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/dummy/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'jquery-rails' 4 | gem "devise" 5 | gem 'kaminari' 6 | gem 'haml-rails' 7 | gem 'sass-rails' 8 | 9 | 10 | gem 'helpdesk', :path => '../../' 11 | gem 'sqlite3', '~> 1.3' 12 | 13 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/subscribers/edit.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | - content_for :title do 4 | Editing sub 5 | 6 | = render 'form' 7 | 8 | = link_to 'Show', [:admin,@subscriber] 9 | \| 10 | = link_to 'Back', admin_subscribers_path 11 | -------------------------------------------------------------------------------- /spec/dummy/test/functional/base_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class BaseControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index 6 | assert_response :success 7 | end 8 | 9 | end 10 | -------------------------------------------------------------------------------- /spec/dummy/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/ticket_types/show.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | %p#notice= notice 4 | 5 | %p 6 | = @ticket_type.title 7 | 8 | 9 | = link_to 'Edit', edit_admin_ticket_type_path(@ticket_type) 10 | \| 11 | = link_to 'Back', admin_ticket_types_path 12 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/ticket_types/edit.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | - content_for :title do 4 | Editing ticket_type 5 | 6 | = render 'form' 7 | 8 | = link_to 'Show', admin_ticket_type_path(@ticket_type) 9 | \| 10 | = link_to 'Back', admin_ticket_types_path 11 | -------------------------------------------------------------------------------- /spec/support/factories/tickets.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :ticket, class: Helpdesk::Ticket do 3 | subject "MyString" 4 | description "MyString" 5 | association :requester, factory: :user 6 | association :ticket_type, factory: :ticket_type 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/assets/javascripts/helpdesk/faqs.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | $('body').scrollspy({ 3 | target: '.bs-docs-sidebar', 4 | offset: 80 5 | }); 6 | 7 | $(".bs-docs-sidebar").affix({ 8 | offset: { 9 | top: 122 10 | } 11 | }); 12 | }); 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/assets/stylesheets/helpdesk/admin/bootstrap_overrides.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 30px; /* 60px to make the container go all the way to the bottom of the topbar */ 3 | } 4 | 5 | /*.container, .navbar-fixed-top .container, .navbar-fixed-bottom .container { 6 | width: 1170px; 7 | }*/ 8 | 9 | -------------------------------------------------------------------------------- /spec/support/factories/users.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :user do 3 | email { "bob#{rand(100000)}@boblaw.com" } 4 | password "password" 5 | password_confirmation "password" 6 | 7 | factory :admin do 8 | helpdesk_admin true 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/dummy/Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Dummy::Application.load_tasks 8 | -------------------------------------------------------------------------------- /test/fixtures/helpdesk/faqs.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 2 | 3 | one: 4 | title: MyString 5 | text: MyText 6 | position: 1 7 | active: false 8 | 9 | two: 10 | title: MyString 11 | text: MyText 12 | position: 1 13 | active: false 14 | -------------------------------------------------------------------------------- /spec/support/factories/comments.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :comment, class: Helpdesk::Comment do 3 | comment "MyText" 4 | association :author, factory: :user 5 | association :ticket, factory: :ticket 6 | factory :comment_public do 7 | public true 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/assets/stylesheets/helpdesk/admin.css.scss: -------------------------------------------------------------------------------- 1 | /* 2 | *= require helpdesk/admin/bootstrap_overrides 3 | *= require select2 4 | *= require helpdesk/admin/tickets 5 | *= require_self 6 | *= require_tree ./admin 7 | *= require helpdesk/custom_admin 8 | */ 9 | 10 | @import "bootstrap-sprockets"; 11 | @import "bootstrap"; 12 | -------------------------------------------------------------------------------- /spec/dummy/script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | 4 | helper_method :helpdesk_user,:helpdesk_admin? 5 | def helpdesk_user 6 | current_user 7 | end 8 | 9 | def helpdesk_admin? 10 | current_user.helpdesk_admin 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/faqs/show.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | %p#notice= notice 4 | 5 | %p 6 | %b Aktywne: 7 | = @faq.active 8 | %p 9 | %b Title: 10 | = @faq.title 11 | %p 12 | %b Text: 13 | = raw @faq.text 14 | 15 | 16 | 17 | = link_to 'Edit', edit_admin_faq_path(@faq) 18 | \| 19 | = link_to 'Back', admin_faqs_path 20 | -------------------------------------------------------------------------------- /db/migrate/20120423113938_create_helpdesk_comments.rb: -------------------------------------------------------------------------------- 1 | class CreateHelpdeskComments < ActiveRecord::Migration 2 | def change 3 | create_table :helpdesk_comments do |t| 4 | t.integer :ticket_id 5 | t.text :comment 6 | t.integer :author_id 7 | t.boolean :public 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | ENGINE_ROOT = File.expand_path('../..', __FILE__) 5 | ENGINE_PATH = File.expand_path('../../lib/helpdesk/engine', __FILE__) 6 | 7 | require 'rails/all' 8 | require 'rails/engine/commands' 9 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/kaminari.rb: -------------------------------------------------------------------------------- 1 | require 'kaminari' 2 | 3 | Kaminari.configure do |config| 4 | config.default_per_page = 20 5 | config.max_per_page = nil 6 | config.window = 4 7 | config.outer_window = 0 8 | config.left = 0 9 | config.right = 0 10 | config.page_method_name = :page 11 | config.param_name = :page 12 | end 13 | 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.1.10 4 | 5 | env: 6 | - "CI_DB_ADAPTER=sqlite3" 7 | before_script: 8 | - cd spec/dummy 9 | - bundle install --without debug 10 | - bundle exec rake helpdesk:prepare_ci_env 11 | - bundle exec rake db:create 12 | - bundle exec rake db:migrate 13 | - cd ../.. 14 | script: 15 | - bundle exec rspec 16 | -------------------------------------------------------------------------------- /app/models/helpdesk/ticket_type.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class TicketType < ActiveRecord::Base 3 | translates :title 4 | accepts_nested_attributes_for :translations 5 | 6 | default_scope ->{order('position ASC')} 7 | 8 | scope :active, -> {where(active: true)} 9 | scope :inactive, -> {where(active: false)} 10 | 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/helpdesk/faqs/_faq.html.haml: -------------------------------------------------------------------------------- 1 | - faqs.each do |faq| 2 | %li{:id=>faq.to_param} 3 | %h3 4 | = link_to faq.title, link_type=='anchor' ? faq.anchor : faqs_path(anchor:faq) 5 | = raw faq.text 6 | - if faq.children.present? 7 | %ul 8 | = render partial:'/helpdesk/faqs/faq', locals:{ faqs:faq.children.active,link_type:link_type} 9 | -------------------------------------------------------------------------------- /test/fixtures/helpdesk/subscribers.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 2 | 3 | one: 4 | name: MyString 5 | email: MyString 6 | lang: MyString 7 | hashcode: MyString 8 | confirmed: MyString 9 | 10 | two: 11 | name: MyString 12 | email: MyString 13 | lang: MyString 14 | hashcode: MyString 15 | confirmed: MyString 16 | -------------------------------------------------------------------------------- /db/migrate/20141105112734_add_parent_id_to_helpdesk_faqs.rb: -------------------------------------------------------------------------------- 1 | class AddParentIdToHelpdeskFaqs < ActiveRecord::Migration 2 | def change 3 | add_column :helpdesk_faqs, :parent_id, :integer 4 | add_column :helpdesk_faqs, :depth, :integer, null:false, default:0 5 | add_column :helpdesk_faqs, :children_count, :integer, null:false, default:0 6 | add_index :helpdesk_faqs, :parent_id 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/views/helpdesk/faqs/index.html.haml: -------------------------------------------------------------------------------- 1 | = content_for :left do 2 | %nav.bs-docs-sidebar.col 3 | %ul#sidebar.nav.nav-stacked 4 | = render partial: 'menu', locals:{faqs:@faqs,link_type:'anchor'} 5 | 6 | %div.content 7 | %div#pageContainer 8 | %h2 9 | = t('helpdesk.faqs.title_s') 10 | %ul#faq 11 | = render partial:'/helpdesk/faqs/faq', locals:{faqs:@faqs,link_type:'anchor'} 12 | -------------------------------------------------------------------------------- /db/migrate/20130522090420_create_helpdesk_subscribers.rb: -------------------------------------------------------------------------------- 1 | class CreateHelpdeskSubscribers < ActiveRecord::Migration 2 | def change 3 | create_table :helpdesk_subscribers do |t| 4 | t.string :name 5 | t.string :email 6 | t.string :lang 7 | t.string :hashcode 8 | t.boolean :confirmed,:default=>false,:null=>false 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/faqs_controller.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class FaqsController < Helpdesk::ApplicationController 3 | 4 | def search 5 | @faqs = Helpdesk::Faq.search(params[:search],params[:page]) 6 | end 7 | 8 | def index 9 | @faqs = Helpdesk::Faq.active.roots 10 | end 11 | 12 | def show 13 | @faq = Helpdesk::Faq.active.find(params[:id]) 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /db/migrate/20120420104051_create_helpdesk_tickets.rb: -------------------------------------------------------------------------------- 1 | class CreateHelpdeskTickets < ActiveRecord::Migration 2 | def change 3 | create_table :helpdesk_tickets do |t| 4 | t.string :subject 5 | t.text :description 6 | t.integer :requester_id 7 | t.integer :assignee_id 8 | t.string :status 9 | t.integer :ticket_type_id 10 | 11 | t.timestamps 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/dummy/test/fixtures/users.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /spec/requests/admin/tickets_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe "tickets" do 4 | 5 | context "dashboard" do 6 | before do 7 | sign_in(FactoryGirl.create(:admin)) 8 | end 9 | 10 | it "should show the admin dashboad" do 11 | visit admin_root_path 12 | expect(current_path).to eql(admin_root_path) 13 | expect(page).to have_content "www.example.com" 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/views/helpdesk/tickets/_menu.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :left do 2 | = menu_left t('helpdesk.tickets.title') do 3 | 4 | = menu_li ico('pencil') + t('helpdesk.new_ticket'), new_ticket_url 5 | 6 | %li.divider 7 | 8 | 9 | = menu_li ico('bullhorn') + "#{t('helpdesk.tickets.active')}", tickets_url(:tickets => 'active') 10 | = menu_li ico('hdd') + "#{t('helpdesk.tickets.closed')}", tickets_url(:tickets => 'closed') 11 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140326084236_create_helpdesk_comments.helpdesk.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from helpdesk (originally 20120423113938) 2 | class CreateHelpdeskComments < ActiveRecord::Migration 3 | def change 4 | create_table :helpdesk_comments do |t| 5 | t.integer :ticket_id 6 | t.text :comment 7 | t.integer :author_id 8 | t.boolean :public 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | 8 | Dummy::Application.config.secret_key_base = 'x' * 30 9 | -------------------------------------------------------------------------------- /lib/templates/erb/scaffold/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%%= simple_form_for(@<%= singular_table_name %>) do |f| %> 2 | <%%= f.error_notification %> 3 | 4 |
5 | <%- attributes.each do |attribute| -%> 6 | <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %> 7 | <%- end -%> 8 |
9 | 10 |
11 | <%%= f.button :submit %> 12 |
13 | <%% end %> 14 | -------------------------------------------------------------------------------- /app/views/helpdesk/faqs/_menu.html.haml: -------------------------------------------------------------------------------- 1 | - faqs.each do |faq| 2 | %li 3 | - link = link_type=='anchor' ? faq.anchor : faqs_path(anchor:faq) 4 | - if(faq.id==params[:id].to_i) 5 | = link_to faq.title, link, class: :active 6 | - else 7 | = link_to faq.title, link 8 | -if faq.children.present? 9 | %ul.nav.nav-stacked 10 | = render partial:'/helpdesk/faqs/menu', locals:{faqs:faq.children, link_type:link_type} 11 | 12 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/rooter_controller.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class RooterController < Helpdesk::ApplicationController 3 | def index 4 | case Helpdesk.root_controller 5 | when 'faqs' 6 | redirect_to faqs_url 7 | when 'tickets' 8 | redirect_to tickets_url 9 | when 'subscribers' 10 | redirect_to subscribers_url 11 | else 12 | redirect_to faqs_url 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/faqs/index.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | - content_for :title do 4 | -if params[:faqs] && params[:faqs] == 'active' 5 | = t('helpdesk.faqs.active') 6 | -elsif params[:faqs] && params[:faqs] == 'inactive' 7 | = t('helpdesk.faqs.inactive') 8 | -else 9 | = t('helpdesk.faqs.all') 10 | 11 | 12 | 13 | 14 | 15 | %ul.faqs_list.faqs_list_main 16 | = render partial:'/helpdesk/admin/faqs/faq', locals:{ faqs:@faqs } 17 | 18 | 19 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Dummy::Application.config.session_store :cookie_store, key: '_dummy_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Dummy::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /app/views/helpdesk/tickets/index.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :title do 2 | -if params[:tickets] && params[:tickets] == 'closed' 3 | = t('helpdesk.tickets.closed') 4 | -else 5 | = t('helpdesk.tickets.active') 6 | ="(#{@tickets.count})" 7 | 8 | 9 | = render 'menu' 10 | 11 | 12 | - if @tickets.size == 0 13 | = t('helpdesk.tickets.you_have_no_tickets') 14 | - @tickets.each do |ticket| 15 | = render 'ticket', ticket: ticket, show_button:true 16 | = paginate @tickets 17 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/subscribers/_form.html.haml: -------------------------------------------------------------------------------- 1 | = simple_form_for [:admin,@subscriber] do |f| 2 | - if @subscriber.errors.any? 3 | #error_explanation 4 | %h2= "#{pluralize(@subscriber.errors.count, "error")} prohibited this subscriber from being saved:" 5 | %ul 6 | - @subscriber.errors.full_messages.each do |msg| 7 | %li= msg 8 | 9 | = f.input :confirmed 10 | = f.input :name 11 | = f.input :email 12 | = f.submit 'Save',:class=>'btn btn-primary' 13 | -------------------------------------------------------------------------------- /app/views/helpdesk/notifications_mailer/send_activate_subscription.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :title do 2 | Please Confirm Subscription 3 | %p 4 | = link_to 'Yes, subscribe me to this list.',subscribers_activation_url(locale:I18n.locale,hashcode: @subscriber.hashcode) 5 | %p 6 | If you received this email by mistake, simply delete it. You won't be subscribed if you don't click the confirmation link above. 7 | 8 | %p 9 | = "For questions about this list, please contact: #{Helpdesk.email}" 10 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140326084239_create_helpdesk_subscribers.helpdesk.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from helpdesk (originally 20130522090420) 2 | class CreateHelpdeskSubscribers < ActiveRecord::Migration 3 | def change 4 | create_table :helpdesk_subscribers do |t| 5 | t.string :name 6 | t.string :email 7 | t.string :lang 8 | t.string :hashcode 9 | t.boolean :confirmed,:default=>false,:null=>false 10 | 11 | t.timestamps 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141106132701_add_parent_id_to_helpdesk_faqs.helpdesk.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from helpdesk (originally 20141105112734) 2 | class AddParentIdToHelpdeskFaqs < ActiveRecord::Migration 3 | def change 4 | add_column :helpdesk_faqs, :parent_id, :integer 5 | add_column :helpdesk_faqs, :depth, :integer, null:false, default:0 6 | add_column :helpdesk_faqs, :children_count, :integer, null:false, default:0 7 | add_index :helpdesk_faqs, :parent_id 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130522085614_create_helpdesk_faqs.rb: -------------------------------------------------------------------------------- 1 | class CreateHelpdeskFaqs < ActiveRecord::Migration 2 | def up 3 | create_table :helpdesk_faqs do |t| 4 | t.integer :position 5 | t.boolean :active,:default=>false,:null=>false 6 | 7 | t.timestamps 8 | end 9 | Helpdesk::Faq.create_translation_table! :title => :string, :text => :text 10 | end 11 | 12 | def down 13 | drop_table :helpdesk_faqs 14 | Helpdesk::Faq.drop_translation_table! 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /app/views/helpdesk/faqs/show.html.haml: -------------------------------------------------------------------------------- 1 | = content_for :left do 2 | %nav.bs-docs-sidebar 3 | %ul#sidebar.nav.nav-stacked.fixed 4 | = render partial: 'menu', locals:{lvl:1,tree:[0],faqs:Helpdesk::Faq.roots,link_type:''} 5 | 6 | %ol.breadcrumb 7 | = menu_li 'FAQ',faqs_url 8 | - @faq.ancestors.reverse_each do |faq| 9 | = menu_li faq.title, faq_url(faq) 10 | = menu_li @faq.title, faq_url(@faq) 11 | 12 | 13 | %ol#faq 14 | = render partial:'/helpdesk/faqs/faq', locals:{faqs:[@faq]} 15 | 16 | -------------------------------------------------------------------------------- /config/locales/simple_form.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | simple_form: 3 | "yes": 'Tak' 4 | "no": 'Nie' 5 | required: 6 | text: 'wymagane' 7 | mark: '*' 8 | # You can uncomment the line below if you need to overwrite the whole required html. 9 | # When using html, text and mark won't be used. 10 | # html: '*' 11 | error_notification: 12 | default_message: "Znaleziono błędy, prosimy poprawić:" 13 | register: 14 | submit: "Zarejestruj" 15 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140326084235_create_helpdesk_tickets.helpdesk.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from helpdesk (originally 20120420104051) 2 | class CreateHelpdeskTickets < ActiveRecord::Migration 3 | def change 4 | create_table :helpdesk_tickets do |t| 5 | t.string :subject 6 | t.text :description 7 | t.integer :requester_id 8 | t.integer :assignee_id 9 | t.string :status 10 | t.integer :ticket_type_id 11 | 12 | t.timestamps 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/assets/javascripts/helpdesk/admin/tickets.js: -------------------------------------------------------------------------------- 1 | // Place all the behaviors and hooks related to the matching controller here. 2 | 3 | // All this logic will automatically be available in application.js. 4 | 5 | $(document).ready(function(){ 6 | $('a[href*="#"]').click(function(){ 7 | $($(this).attr("href")).effect("highlight", {}, 1500); 8 | }); 9 | }); 10 | 11 | 12 | (function() { 13 | $(function() { 14 | return $('.chosen-select').select2({width:'resolve'}); 15 | }); 16 | 17 | }).call(this) 18 | -------------------------------------------------------------------------------- /spec/support/signin_helpers.rb: -------------------------------------------------------------------------------- 1 | module SignInHelpers 2 | def sign_in(user) 3 | visit '/users/sign_in' 4 | fill_in 'Email', :with => user.email 5 | fill_in 'Password', :with => 'password' 6 | click_button 'Log in' 7 | #page.should have_content("Signed in successfully") 8 | end 9 | 10 | def sign_out 11 | click_link 'Sign out' 12 | #page.should have_content("Signed out successfully") 13 | end 14 | end 15 | 16 | RSpec.configure do |c| 17 | c.include SignInHelpers#, :type => :controller 18 | end 19 | -------------------------------------------------------------------------------- /app/helpers/helpdesk/admin/tickets_helper.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | module Admin::TicketsHelper 3 | def humanize_with_i18n(string, scope = []) 4 | I18n.t string, scope: scope, default: string.humanize 5 | end 6 | 7 | # The method prefix tells me that this should be in an object 8 | # But it doesn't belong in our model, does it? 9 | def tickets_statuses_for_select 10 | Helpdesk::Ticket::STATUSES.map { |s| [humanize_with_i18n(s[0].to_s,'helpdesk.tickets.statuses'),s[0]] } 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/views/helpdesk/subscribers/_form.html.haml: -------------------------------------------------------------------------------- 1 | = simple_form_for @subscriber do |f| 2 | .form-inputs 3 | - if @subscriber.errors.any? 4 | #error_explanation 5 | %ul 6 | - @subscriber.errors.full_messages.each do |msg| 7 | %li= msg 8 | = f.input :name 9 | = f.input :email 10 | = f.input :lang, collections: I18n.available_locales 11 | 12 | 13 | 14 | .form-actions 15 | = f.submit 'Save', class:'btn btn-primary' 16 | = link_to 'Back', admin_faqs_path,class: 'btn btn-default' 17 | 18 | 19 | -------------------------------------------------------------------------------- /spec/dummy/config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) && !ENV['TRAVIS'] 7 | #require 'rubygems' 8 | #gemfile = File.expand_path('../../../../Gemfile', __FILE__) 9 | # 10 | #if File.exist?(gemfile) 11 | # ENV['BUNDLE_GEMFILE'] = gemfile 12 | # require 'bundler' 13 | # Bundler.setup 14 | #end 15 | # 16 | #$:.unshift File.expand_path('../../../../lib', __FILE__) 17 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/application_controller.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class ApplicationController < ::ApplicationController 3 | before_filter :ensure_user, :if => Proc.new { Helpdesk.require_user } 4 | 5 | helper Helpdesk::Engine.helpers 6 | 7 | layout 'helpdesk/user' 8 | 9 | def ensure_user 10 | unless helpdesk_user 11 | redirect_to main_app.send(Helpdesk.sign_in_url) 12 | end 13 | end 14 | 15 | def default_url_options(options={}) 16 | { :locale => I18n.locale} 17 | end 18 | 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/dashboard_controller.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class DashboardController < Helpdesk::ApplicationController 3 | 4 | 5 | before_filter :my_tickets 6 | 7 | def index 8 | end 9 | 10 | 11 | def show 12 | end 13 | 14 | 15 | def my_tickets 16 | @my_tickets = Helpdesk::Ticket 17 | .includes(:comments=>[:author]) 18 | .includes(:requester) 19 | .includes(:assignee) 20 | .includes(:ticket_type) 21 | .where('requester_id = ?', helpdesk_user.id) 22 | end 23 | 24 | 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /spec/dummy/app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | # Include default devise modules. Others available are: 3 | # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable 4 | devise :database_authenticatable, :registerable, 5 | :recoverable, :rememberable, :trackable, :validatable 6 | 7 | # Setup accessible (or protected) attributes for your model 8 | # attr_accessible :email, :password, :password_confirmation, :remember_me 9 | # attr_accessible :title, :body 10 | def to_s 11 | email 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140326084238_create_helpdesk_faqs.helpdesk.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from helpdesk (originally 20130522085614) 2 | class CreateHelpdeskFaqs < ActiveRecord::Migration 3 | def up 4 | create_table :helpdesk_faqs do |t| 5 | t.integer :position 6 | t.boolean :active,:default=>false,:null=>false 7 | 8 | t.timestamps 9 | end 10 | Helpdesk::Faq.create_translation_table! :title => :string, :text => :text 11 | end 12 | 13 | def down 14 | drop_table :helpdesk_faqs 15 | Helpdesk::Faq.drop_translation_table! 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /app/views/helpdesk/subscribers/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

4 | Name: 5 | <%= @subscriber.send Helpdesk.display_user.to_sym %> 6 |

7 | 8 |

9 | Email: 10 | <%= @subscriber.email %> 11 |

12 | 13 |

14 | Lang: 15 | <%= @subscriber.lang %> 16 |

17 | 18 |

19 | Hashcode: 20 | <%= @subscriber.hashcode %> 21 |

22 | 23 |

24 | Confirmed: 25 | <%= @subscriber.confirmed %> 26 |

27 | 28 | 29 | <%= link_to 'Edit', edit_subscriber_path(@subscriber) %> | 30 | <%= link_to 'Back', subscribers_path %> 31 | -------------------------------------------------------------------------------- /app/views/helpdesk/notifications_mailer/comment_by_helpdesk_confirmation.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :title do 2 | = t('helpdesk.mailer.comment_by_helpdesk_confirmation.title') 3 | %p 4 | = t('helpdesk.mailer.comment_by_helpdesk_confirmation.re_ticket') 5 | = @comment.ticket.subject 6 | %p 7 | = t('helpdesk.mailer.comment_by_helpdesk_confirmation.response_content') 8 | %br 9 | = simple_format(@comment.comment) 10 | %br 11 | %p 12 | = t('helpdesk.mailer.ticket_url_title') 13 | %a{:href=>ticket_url(:locale=>I18n.locale, :id=>@comment.ticket)}<> 14 | = ticket_url(:locale=>I18n.locale, :id=>@comment.ticket) 15 | %br 16 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | # 12 | # These inflection rules are supported but not enabled by default: 13 | # ActiveSupport::Inflector.inflections do |inflect| 14 | # inflect.acronym 'RESTful' 15 | # end 16 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require_tree . 13 | */ 14 | -------------------------------------------------------------------------------- /app/views/helpdesk/notifications_mailer/comment_by_helpdesk_notification.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :title do 2 | = t('helpdesk.mailer.comment_by_helpdesk_notification.title', user: @comment.ticket.requester.send(Helpdesk.display_user.to_sym)) 3 | = @comment.ticket.subject 4 | 5 | %p 6 | = t('helpdesk.mailer.comment_by_helpdesk_notification.comment_content') 7 | %br 8 | = simple_format(@comment.comment) 9 | %br 10 | %p 11 | = t('helpdesk.mailer.ticket_url_title') 12 | %a{:href=>ticket_url(:locale=>I18n.locale, :id=>@comment.ticket, :anchor=>"comment#{@comment.id}") }<> 13 | = ticket_url(:locale=>I18n.locale, :id=>@comment.ticket) 14 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/ticket_types/_form.html.haml: -------------------------------------------------------------------------------- 1 | = simple_form_for [:admin, @ticket_type] do |f| 2 | - if @ticket_type.errors.any? 3 | #error_explanation 4 | %h2= "#{pluralize(@ticket_type.errors.count, "error")} prohibited this ticket_type from being saved:" 5 | %ul 6 | - @ticket_type.errors.full_messages.each do |msg| 7 | %li= msg 8 | 9 | 10 | 11 | - I18n.available_locales.each do |locale| 12 | %h1 13 | = locale 14 | = f.globalize_fields_for locale do |g| 15 | = g.input :title 16 | 17 | 18 | = f.input :tr_class 19 | = f.input :active 20 | = f.submit 'Save',:class=>'btn btn-promary' 21 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/tickets/list.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | - content_for :title do 4 | -if params[:tickets] && params[:tickets] == 'unassigned' 5 | = t('helpdesk.tickets.unassigned') 6 | -elsif params[:tickets] && params[:tickets] == 'closed' 7 | = t('helpdesk.tickets.closed') 8 | -elsif params[:tickets] && params[:tickets] == 'active' 9 | = t('helpdesk.tickets.active') 10 | -elsif params[:tickets] && params[:tickets] == 'all' 11 | = t('helpdesk.tickets.all') 12 | -else 13 | = t('helpdesk.tickets.my') 14 | 15 | - @tickets.each do |ticket| 16 | = render 'ticket', ticket: ticket, show_button:true 17 | 18 | = paginate @tickets 19 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/faqs/_menu.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :left do 2 | = menu_left t('helpdesk.faqs.title') do 3 | = menu_li ico('pencil') + t('helpdesk.faqs.new'), new_admin_faq_url 4 | %li.divider 5 | = menu_li ico('envelope') + "#{t('helpdesk.faqs.active')} (#{Helpdesk::Faq.active.count})", admin_faqs_url(:faqs => 'active') 6 | 7 | = menu_li ico('info-sign') + "#{t('helpdesk.faqs.inactive')} (#{Helpdesk::Faq.inactive.count})", admin_faqs_url(:faqs => 'inactive') 8 | 9 | = menu_li ico('signal') + "#{t('helpdesk.faqs.sorting')}", sorting_admin_faq_url(:all) 10 | 11 | %li.divider 12 | = menu_li ico('list') + t('helpdesk.faqs.all'), admin_faqs_url(:faqs => 'all') 13 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/subscribers/_menu.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :left do 2 | = menu_left t('helpdesk.subscribers.title') do 3 | = menu_li ico('pencil') + t('helpdesk.subscribers.new'), new_admin_subscriber_url 4 | %li.divider 5 | = menu_li ico('envelope') + "#{t('helpdesk.subscribers.confirmed')} (#{Helpdesk::Subscriber.confirmed.count})", admin_subscribers_url(:subscribers => 'confirmed') 6 | 7 | = menu_li ico('info-sign') + "#{t('helpdesk.subscribers.unconfirmed')} (#{Helpdesk::Subscriber.unconfirmed.count})", admin_subscribers_url(:subscribers => 'unconfirmed') 8 | %li.divider 9 | = menu_li ico('list') + t('helpdesk.subscribers.all'), admin_subscribers_url(:subscribers => 'all') -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Declare your gem's dependencies in helpdesk.gemspec. 4 | # Bundler will treat runtime dependencies like base dependencies, and 5 | # development dependencies will be added by default to the :development group. 6 | gemspec 7 | 8 | # jquery-rails is used by the dummy application 9 | gem "jquery-rails" 10 | 11 | # Declare any dependencies that are still in development here instead of in 12 | # your gemspec. These might include edge Rails or gems from your path or 13 | # Git. Remember to move these dependencies to your gemspec before releasing 14 | # your gem to rubygems.org. 15 | 16 | # To use debugger 17 | # gem 'ruby-debug19', :require => 'ruby-debug' 18 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/ticket_types/_menu.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :left do 2 | = menu_left t('helpdesk.ticket_types.title') do 3 | = menu_li ico('pencil') + t('helpdesk.ticket_types.new'), new_admin_ticket_type_url 4 | %li.divider 5 | = menu_li ico('eye-open') + "#{t('helpdesk.ticket_types.active')} ", admin_ticket_types_url(:ticket_types => 'active') 6 | = menu_li ico('folder-open') + "#{t('helpdesk.tickets.unassigned')} ", admin_ticket_types_url(:ticket_types => 'inactive') 7 | %li.divider 8 | = menu_li ico('list') + t('helpdesk.ticket_types.all'), admin_ticket_types_url(:ticket_types => 'all') 9 | 10 | / (#{Helpdesk::TicketType.active.count}) 11 | / (#{Helpdesk::TicketType.inactive.count}) -------------------------------------------------------------------------------- /app/views/helpdesk/notifications_mailer/ticket_created_confirmation.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :title do 2 | = t('helpdesk.mailer.ticket_created_confirmation.title', user: @ticket.requester.send(Helpdesk.display_user.to_sym) ) 3 | %p 4 | = t('helpdesk.mailer.ticket_created_confirmation.subject') 5 | = @ticket.subject 6 | %p 7 | = t('helpdesk.mailer.ticket_created_confirmation.ticket_content') 8 | %br 9 | = simple_format(@ticket.description) 10 | %br 11 | %p 12 | = t('helpdesk.mailer.ticket_url_title') 13 | %a{:href=>ticket_url(:locale=>I18n.locale, :id=>@ticket)}<> 14 | = ticket_url(:locale=>I18n.locale, :id=>@ticket) 15 | %br 16 | = t('helpdesk.mailer.ticket_created_confirmation.info_time') 17 | -------------------------------------------------------------------------------- /spec/dummy/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # # gem install sqlite3 3 | # # 4 | # # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require_tree . 16 | -------------------------------------------------------------------------------- /spec/requests/admin/dashboard_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe "dashboard" do 4 | 5 | context "a logged in user" do 6 | 7 | before do 8 | sign_in(FactoryGirl.create(:user)) 9 | end 10 | 11 | it "should not have access" do 12 | visit admin_root_path 13 | expect(current_path).not_to eql(admin_root_path) 14 | end 15 | 16 | end 17 | 18 | context "a logged in admin user" do 19 | before do 20 | sign_in(FactoryGirl.create(:admin)) 21 | end 22 | 23 | it "should show the admin dashboad" do 24 | visit admin_root_path 25 | expect(current_path).to eql(admin_root_path) 26 | expect(page).to have_content "www.example.com" 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/support/mailer_macros.rb: -------------------------------------------------------------------------------- 1 | module MailerMacros 2 | 3 | def last_email 4 | ActionMailer::Base.deliveries.last 5 | end 6 | 7 | def last_email_address 8 | last_email.to.join 9 | end 10 | 11 | def reset_email 12 | ActionMailer::Base.deliveries = [] 13 | end 14 | 15 | def reset_with_delayed_job_deliveries 16 | ActionMailer::Base.deliveries = [] 17 | end 18 | 19 | def all_emails 20 | ActionMailer::Base.deliveries 21 | end 22 | 23 | def all_emails_sent_count 24 | ActionMailer::Base.deliveries.count 25 | end 26 | 27 | def all_email_addresses 28 | all_emails.map(&:to).flatten 29 | end 30 | 31 | def all_email_subjects 32 | all_emails.map(&:subject).flatten 33 | end 34 | 35 | end 36 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | begin 3 | require 'bundler/setup' 4 | rescue LoadError 5 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks' 6 | end 7 | begin 8 | require 'rdoc/task' 9 | rescue LoadError 10 | require 'rdoc/rdoc' 11 | require 'rake/rdoctask' 12 | RDoc::Task = Rake::RDocTask 13 | end 14 | 15 | RDoc::Task.new(:rdoc) do |rdoc| 16 | rdoc.rdoc_dir = 'rdoc' 17 | rdoc.title = 'Helpdesk' 18 | rdoc.options << '--line-numbers' 19 | rdoc.rdoc_files.include('README.rdoc') 20 | rdoc.rdoc_files.include('lib/**/*.rb') 21 | end 22 | 23 | APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__) 24 | load 'rails/tasks/engine.rake' 25 | 26 | 27 | Bundler::GemHelper.install_tasks 28 | 29 | -------------------------------------------------------------------------------- /app/views/helpdesk/notifications_mailer/comment_by_requester_confirmation.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :title do 2 | = t('helpdesk.mailer.comment_by_requester_confirmation.title', user: @comment.ticket.requester.send(Helpdesk.display_user.to_sym)) 3 | %p 4 | = t('helpdesk.mailer.comment_by_requester_confirmation.subject', subject: @comment.ticket.subject) 5 | %p 6 | = t('helpdesk.mailer.comment_by_requester_confirmation.comment_content') 7 | %br 8 | = simple_format(@comment.comment) 9 | %br 10 | %p 11 | = t('helpdesk.mailer.ticket_url_title') 12 | %a{:href=>ticket_url(:locale=>I18n.locale, :id=>@comment.ticket)}<> 13 | = ticket_url(:locale=>I18n.locale, :id=>@comment.ticket) 14 | %br 15 | = t('helpdesk.mailer.ticket_created_confirmation.info_time') 16 | 17 | -------------------------------------------------------------------------------- /spec/dummy/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /app/views/helpdesk/notifications_mailer/ticket_created_notification.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :title do 2 | = t('helpdesk.mailer.ticket_created_notification.title') 3 | = @ticket.ticket_type_title 4 | %p 5 | = t('helpdesk.mailer.ticket_created_notification.ticket_content') 6 | %br 7 | = simple_format(@ticket.description) 8 | %br 9 | %br 10 | %p 11 | = t('helpdesk.mailer.ticket_created_notification.requester_info') 12 | %br 13 | = @ticket.requester.send Helpdesk.display_user.to_sym 14 | %br 15 | = @ticket.requester.send Helpdesk.display_user_uniq_info.to_sym 16 | %br 17 | %p 18 | = t('helpdesk.mailer.ticket_url_title') 19 | %a{:href=>admin_ticket_url(:locale=>I18n.locale, :id=>@ticket)}<> 20 | = admin_ticket_url(:locale=>I18n.locale, :id=>@ticket) 21 | 22 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/faqs/_faq.html.haml: -------------------------------------------------------------------------------- 1 | - faqs.each do |faq| 2 | %li 3 | %span.title 4 | = faq.title 5 | %span.buttons 6 | = link_to t('helpdesk.show'), faqs_path(anchor:faq.to_param), class: 'icon btn btn-info btn-xs', target: :faq_preview 7 | = link_to t('helpdesk.edit'), edit_admin_faq_path(faq),class: 'icon btn btn-primary btn-xs' 8 | = link_to t('helpdesk.add'), new_admin_faq_path(faq:{parent_id:faq.id}),class: 'icon btn btn-success btn-xs' 9 | = link_to t('helpdesk.destroy'), admin_faq_path(faq), method: :delete, data: { confirm: 'Are you sure?' },class: 'icon btn btn-danger btn-xs' 10 | 11 | - if faq.children.present? 12 | %ul.faqs_list 13 | = render partial:'/helpdesk/admin/faqs/faq', locals:{ faqs:faq.children.active } 14 | -------------------------------------------------------------------------------- /app/models/helpdesk/subscriber.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class Subscriber < ActiveRecord::Base 3 | scope :confirmed, ->{ where('confirmed = ? ',true)} 4 | scope :unconfirmed, ->{ where('confirmed = ? ',false)} 5 | 6 | validates_presence_of :email 7 | validates_uniqueness_of :email 8 | 9 | before_create :generate_token 10 | after_create :send_activate_subscription 11 | 12 | def generate_token 13 | self.hashcode = loop do 14 | random_token = SecureRandom.urlsafe_base64(nil, false) 15 | break random_token unless Helpdesk::Subscriber.where(hashcode: random_token).exists? 16 | end 17 | end 18 | 19 | def send_activate_subscription 20 | Helpdesk::NotificationsMailer.send_activate_subscription(self).deliver 21 | end 22 | 23 | 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /config/locales/simple_form.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | simple_form: 3 | "yes": 'Yes' 4 | "no": 'No' 5 | required: 6 | text: 'required' 7 | mark: '*' 8 | # You can uncomment the line below if you need to overwrite the whole required html. 9 | # When using html, text and mark won't be used. 10 | # html: '*' 11 | error_notification: 12 | default_message: "Some errors were found, please take a look:" 13 | # Labels and hints examples 14 | # labels: 15 | # password: 'Password' 16 | # user: 17 | # new: 18 | # email: 'E-mail para efetuar o sign in.' 19 | # edit: 20 | # email: 'E-mail.' 21 | # hints: 22 | # username: 'User name to sign in.' 23 | # password: 'No special characters, please.' 24 | 25 | -------------------------------------------------------------------------------- /app/assets/stylesheets/helpdesk/tickets.css.sass: -------------------------------------------------------------------------------- 1 | form 2 | .checkbox 3 | input[type="checkbox"] 4 | margin: 4px 5px 0px 0px 5 | 6 | body 7 | div.panel-body 8 | min-height: 400px 9 | 10 | form.feedback 11 | 12 | > fieldset 13 | margin: 0px auto 14 | padding: 0px 15 | width: 500px 16 | 17 | 18 | > div 19 | clear: both 20 | display: block 21 | 22 | div.subject input[type=text] 23 | float: left 24 | width: 350px 25 | 26 | > div.content 27 | padding-top: 20px 28 | 29 | textarea 30 | height: 100px 31 | width: 482px 32 | 33 | > div.agreement 34 | input[type=checkbox] 35 | vertical-align: middle 36 | 37 | > div.form-actions 38 | .button 39 | margin-left: 12px 40 | -------------------------------------------------------------------------------- /app/assets/stylesheets/helpdesk/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | 12 | *= require helpdesk/admin 13 | *= require helpdesk/admin/bootstrap_overrides 14 | *= require helpdesk/admin/tickets 15 | *= require helpdesk/faqs 16 | *= require helpdesk/tickets 17 | *= require_self 18 | *= require helpdesk/custom 19 | */ 20 | -------------------------------------------------------------------------------- /app/views/helpdesk/notifications_mailer/comment_by_requester_notification.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :title do 2 | = t('helpdesk.mailer.comment_by_requester_notification.title') 3 | = @comment.ticket.subject 4 | %p 5 | = t('helpdesk.mailer.comment_by_requester_notification.comment_content') 6 | %br 7 | = simple_format(@comment.comment) 8 | %br 9 | %br 10 | %p 11 | = t('helpdesk.mailer.ticket_created_notification.requester_info') 12 | %br 13 | = @comment.author.send Helpdesk.display_user.to_sym 14 | %br 15 | = @comment.author.send Helpdesk.display_user_uniq_info.to_sym 16 | %br 17 | %p 18 | = t('helpdesk.mailer.ticket_url_title') 19 | %a{:href=>admin_ticket_url(:locale=>I18n.locale, :id=>@comment.ticket)}<> 20 | = admin_ticket_url(:locale=>I18n.locale, :id=>@comment.ticket) 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /spec/dummy/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /app/assets/javascripts/helpdesk/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require bootstrap-sprockets 16 | //= require ckeditor/init 17 | //= require jquery-ui 18 | //= require select2 19 | //= require_tree . 20 | -------------------------------------------------------------------------------- /spec/dummy/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/subscribers/index.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | - content_for :title do 4 | Subscribers 5 | 6 | %table.table.table-hover 7 | %tr 8 | %th Confirmed 9 | %th Name 10 | %th Email 11 | %th Lang 12 | %th Created 13 | %th 14 | %th 15 | 16 | - @subscribers.each do |subscriber| 17 | %tr 18 | %td 19 | - if subscriber.confirmed 20 | = ico('ok') 21 | %td= subscriber.send Helpdesk.display_user.to_sym 22 | %td= subscriber.email 23 | 24 | %td= subscriber.lang 25 | %td= I18n::l(subscriber.created_at, :format=>:short) 26 | / %td= link_to 'Show', admin_subscriber_path(subscriber) 27 | %td= link_to 'Edit', edit_admin_subscriber_path(subscriber) 28 | %td= link_to 'Destroy', admin_subscriber_path(subscriber), method: :delete, data: { confirm: 'Are you sure?' } 29 | = paginate @subscribers 30 | %br 31 | 32 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/faqs/_form.html.haml: -------------------------------------------------------------------------------- 1 | = simple_form_for [:admin,@faq],html: {novalidate: true} do |f| 2 | .form-inputs 3 | - if @faq.errors.any? 4 | #error_explanation 5 | %h2= "#{pluralize(@faq.errors.count, "error")} prohibited this faq from being saved:" 6 | %ul 7 | - @faq.errors.full_messages.each do |msg| 8 | %li= msg 9 | = f.input :active, wrapper: :inline_checkbox 10 | = f.input :parent_id, collection: Helpdesk::Faq.collection,label_method: :name_with_depth 11 | 12 | - I18n.available_locales.each do |locale| 13 | %h1 14 | = locale 15 | = f.globalize_fields_for locale do |g| 16 | = g.input :title 17 | = g.input :text, :as => :ckeditor, :input_html => { :ckeditor => {:width=>'100%',:height => 200,:toolbar => 'Full'} } 18 | 19 | .form-actions 20 | = f.submit 'Save', class:'btn btn-primary' 21 | = link_to 'Back', admin_faqs_path,class: 'btn btn-default' 22 | -------------------------------------------------------------------------------- /spec/dummy/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Your website 5 | <%= stylesheet_link_tag "application", :media => "all" %> 6 | <%= javascript_include_tag "application" %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 |

My Awesome website

11 | <% if current_user %> 12 | <%= current_user.email %>
13 | <%= link_to 'Logout', main_app.destroy_user_session_path %> 14 | <% else %> 15 | <%= link_to 'Login', new_user_session_path %> 16 | <% end %> 17 |
18 | 29 | <%= yield %> 30 | 31 | 32 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Helpdesk::Engine.routes.draw do 2 | require 'route_constraints_faqs' 3 | require 'route_constraints_tickets' 4 | # Rails.application.routes.draw do 5 | scope "(:locale)", :locale => /pl|pt|en/ do 6 | # Admin only roots 7 | namespace :admin do 8 | resources :tickets do 9 | get :assign, on: :member 10 | end 11 | resources :ticket_types 12 | resources :faqs do 13 | post :sort, on: :collection 14 | get :sorting, on: :member 15 | end 16 | resources :subscribers 17 | root :to => 'tickets#index' 18 | end 19 | 20 | get 'subscribers/a/:hashcode'=>'subscribers#activation',as:'subscribers_activation' 21 | resources :subscribers, :only => [:index, :create, :destroy] 22 | resources :faqs, :only => [ :index, :show ] do 23 | get :search, on: :collection 24 | end 25 | resources :tickets, :except => [ :edit, :destroy ] 26 | 27 | 28 | root :to => 'rooter#index' 29 | 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/tasks/prepare_ci_env.rake: -------------------------------------------------------------------------------- 1 | namespace :helpdesk do 2 | desc "Prepare Continuous Integration environment" 3 | task :prepare_ci_env do 4 | ENV['SKIP_HELPDESK_INITIALIZER'] = 'true' 5 | adapter = ENV["CI_DB_ADAPTER"] || "sqlite3" 6 | database = ENV["CI_DB_DATABASE"] || ("sqlite3" == adapter ? "db/development.sqlite3" : "ci_helpdesk") 7 | 8 | configuration = { 9 | "test" => { 10 | "adapter" => adapter, 11 | "database" => database, 12 | "username" => ENV["CI_DB_USERNAME"], 13 | "password" => ENV["CI_DB_PASSWORD"], 14 | "host" => ENV["CI_DB_HOST"] || "localhost", 15 | "encoding" => ENV["CI_DB_ENCODING"] || "utf8", 16 | "pool" => (ENV["CI_DB_POOL"] || 5).to_int, 17 | "timeout" => (ENV["CI_DB_TIMEOUT"] || 5000).to_int 18 | } 19 | } 20 | 21 | filename = Rails.root.join("config/database.yml") 22 | 23 | File.open(filename, "w") do |f| 24 | f.write(configuration.to_yaml) 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/ticket_types/index.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | - content_for :title do 4 | -if params[:ticket_types] && params[:ticket_types] == 'active' 5 | = t('helpdesk.ticket_types.active') 6 | -elsif params[:ticket_types] && params[:ticket_types] == 'inactive' 7 | = t('helpdesk.ticket_types.inactive') 8 | -else 9 | = t('helpdesk.ticket_types.all') 10 | 11 | 12 | %table.table.table-hover 13 | %tr 14 | %th Active 15 | %th Title 16 | %th 17 | %th 18 | %th 19 | 20 | - @ticket_types.each do |ticket_type| 21 | %tr{:class=>ticket_type.tr_class} 22 | %td= ticket_type.active 23 | %td= ticket_type.title 24 | %td= link_to 'Show', admin_ticket_type_path(ticket_type) 25 | %td= link_to 'Edit', edit_admin_ticket_type_path(ticket_type) 26 | %td= link_to 'Destroy', admin_ticket_type_path(ticket_type), :method => :delete, :data => { :confirm => 'Are you sure?' } 27 | 28 | %br 29 | 30 | = link_to 'New Sugestion type', new_admin_ticket_type_path 31 | -------------------------------------------------------------------------------- /app/views/layouts/mailer_layout.html.haml: -------------------------------------------------------------------------------- 1 | :plain 2 | 3 | %html 4 | %head 5 | %body 6 | %div{:style=>'margin: 0px; padding: 20px 0px; background-color: #f0f0f0;'} 7 | %div{:style=>'margin: 0px auto; width: 600px; background-color: #fafafa; padding: 20px; border-radius: 2px; box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.3);'} 8 | %h2 9 | =yield :title 10 | %div 11 | = yield 12 | %p 13 | = t('helpdesk.mailer.footer_nice') 14 | %br 15 | = Helpdesk.site_name 16 | %br 17 | %a{:href=>'http://'+Helpdesk.site_address} 18 | = Helpdesk.site_address 19 | %div{:style=>'padding: 8px 0px; font-size: 12px; font-family: "Helvetica", "Arial", Sans-serif; text-align: justify; border-top: 0px solid #c0c0c0; color: #808080; '} 20 | = t('helpdesk.mailer.footer_info', url: root_url).html_safe 21 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/tickets/_menu.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :left do 2 | = menu_left t('helpdesk.tickets.title') do 3 | = menu_li ico('pencil') + t('helpdesk.ticket.new'), new_admin_ticket_url 4 | %li.divider 5 | = menu_li ico('eye-open') + "#{t('helpdesk.tickets.my')} (#{@my_tickets.size})", admin_tickets_url 6 | = menu_li ico('bullhorn') + "#{t('helpdesk.tickets.active')} ", admin_tickets_url(:tickets => 'active') 7 | /(#{Helpdesk::Ticket.active.count}) 8 | 9 | %li.divider 10 | = menu_li ico('folder-open') + "#{t('helpdesk.tickets.unassigned')} (#{Helpdesk::Ticket.unassigned.count})", admin_tickets_url(:tickets => 'unassigned') 11 | = menu_li ico('hdd') + "#{t('helpdesk.tickets.closed')} ", admin_tickets_url(:tickets => 'closed') 12 | / (#{Helpdesk::Ticket.closed.count}) 13 | = menu_li ico('list-alt') + t('helpdesk.tickets.all'), admin_tickets_url(:tickets => 'all') 14 | 15 | %li.divider 16 | %li.divider 17 | = menu_li ico('edit') + t('helpdesk.ticket_types.title'), admin_ticket_types_url -------------------------------------------------------------------------------- /lib/helpdesk.rb: -------------------------------------------------------------------------------- 1 | require "helpdesk/engine" 2 | 3 | module Helpdesk 4 | mattr_accessor :require_user 5 | @@require_user = false 6 | 7 | mattr_accessor :sign_in_url 8 | 9 | mattr_accessor :user_class 10 | 11 | mattr_accessor :display_user 12 | 13 | mattr_accessor :display_user_uniq_info 14 | 15 | mattr_accessor :mail_server 16 | 17 | mattr_accessor :email 18 | 19 | mattr_accessor :send_confirmation_emails 20 | @@send_confirmation_emails = false 21 | 22 | mattr_accessor :site_name 23 | 24 | mattr_accessor :site_address 25 | 26 | mattr_accessor :helpdesk_name 27 | @@helpdesk_name = "Helpdesk" 28 | 29 | mattr_accessor :root_controller 30 | @@root_controller = "faqs" 31 | 32 | mattr_accessor :menu_items 33 | @@menu_items = ['app_root','helpdesk_root','tickets','faqs','subscribers','search','user','language'] 34 | 35 | def self.setup 36 | yield self 37 | end 38 | 39 | def self.user_class 40 | if @@user_class.is_a?(String) 41 | @@user_class.constantize 42 | end 43 | end 44 | 45 | end 46 | -------------------------------------------------------------------------------- /lib/helpdesk/engine.rb: -------------------------------------------------------------------------------- 1 | require 'rails' 2 | require 'simple_form' 3 | require 'state_machine' 4 | require 'bootstrap-sass' 5 | require 'rails_autolink' 6 | require 'simple_form' 7 | require 'globalize' 8 | require 'batch_translations' 9 | require 'ckeditor' 10 | require 'select2-rails' 11 | require 'kaminari' 12 | require 'jquery-ui-rails' 13 | require 'acts_as_ordered_tree' 14 | 15 | module Helpdesk 16 | class Engine < ::Rails::Engine 17 | isolate_namespace Helpdesk 18 | 19 | initializer "Helpdesk precompile hook" do |app| 20 | app.config.assets.precompile += ['helpdesk/admin.css','helpdesk/application.css','helpdesk/custom.css','helpdesk/application.js'] 21 | end 22 | 23 | config.to_prepare do 24 | if Helpdesk.user_class 25 | Helpdesk.user_class.has_many :helpdesk_tickets, :class_name => "Helpdesk::Ticket", :foreign_key => "requester_id" 26 | #Helpdesk.user_class.has_many :helpdesk_tickets, :class_name => "Helpdesk::Ticket", :foreign_key => "assignee_id" 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/helpdesk.rb: -------------------------------------------------------------------------------- 1 | require 'helpdesk' 2 | 3 | ::Helpdesk.setup do |config| 4 | # Class that represents the user/admin 5 | config.user_class = "User" 6 | 7 | # Method usign to display information about user for users 8 | config.display_user = "email" 9 | 10 | # Method usign to display information about user for admins (name+id?) 11 | config.display_user_uniq_info = "email" 12 | 13 | # Require User to be present in order to access Helpdesk 14 | config.require_user = true 15 | 16 | # Base application sign in route name 17 | config.sign_in_url = 'new_user_session_path' 18 | 19 | # Helpdesk email for notification 20 | config.email = 'helpdesk@example.com' 21 | 22 | # Send confirmation emails 23 | config.send_confirmation_emails = true 24 | 25 | # Site name in email footer 26 | config.site_name = "Example Helpdesk Team" 27 | 28 | # Site address in email footer 29 | config.site_address = "www.example.com" 30 | 31 | # Helpdesk title 32 | config.helpdesk_name = "Example Helpdesk" 33 | end 34 | -------------------------------------------------------------------------------- /lib/generators/helpdesk/install_generator.rb: -------------------------------------------------------------------------------- 1 | require 'securerandom' 2 | 3 | module Helpdesk 4 | module Generators 5 | class InstallGenerator < Rails::Generators::Base 6 | source_root File.expand_path("../templates", __FILE__) 7 | 8 | desc "Creates a Helpdesk initializer and copy locale files to your application." 9 | 10 | def copy_initializer 11 | template "helpdesk.rb", "config/initializers/helpdesk.rb" 12 | end 13 | 14 | def copy_locale 15 | copy_file "../../../../config/locales/helpdesk.en.yml", "config/locales/helpdesk.en.yml" 16 | copy_file "../../../../config/locales/helpdesk.pl.yml", "config/locales/helpdesk.pl.yml" 17 | end 18 | 19 | def run_rake 20 | rake "helpdesk:install:migrations" 21 | rake "db:migrate" 22 | end 23 | 24 | def add_engine_to_route 25 | route "mount Helpdesk::Engine, :at => '/helpdesk'" 26 | end 27 | 28 | def show_readme 29 | readme "README" if behavior == :invoke 30 | end 31 | 32 | 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/admin/base_controller.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | module Admin 3 | class BaseController < Helpdesk::ApplicationController 4 | 5 | helper Helpdesk::Engine.helpers 6 | # helper Helpdesk::ApplicationHelper 7 | before_filter :ensure_user 8 | before_filter :authenticate_helpdesk_admin 9 | before_filter :my_tickets 10 | 11 | layout 'helpdesk/admin' 12 | 13 | private 14 | #methods helpdesk_user & helpdesk_admin? - must by defined in file app/application_controller 15 | 16 | def authenticate_helpdesk_admin 17 | unless helpdesk_admin? 18 | redirect_to main_app.root_url, notice:'You have no power here!' 19 | end 20 | end 21 | 22 | def my_tickets 23 | @my_tickets = Helpdesk::Ticket 24 | .includes(:comments=>[:author]) 25 | .includes(:requester) 26 | .includes(:assignee) 27 | .includes(:ticket_type) 28 | .where('assignee_id = ?', helpdesk_user.id) 29 | .active 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /db/migrate/20130521105605_create_helpdesk_ticket_types.rb: -------------------------------------------------------------------------------- 1 | class CreateHelpdeskTicketTypes < ActiveRecord::Migration 2 | def up 3 | create_table :helpdesk_ticket_types do |t| 4 | t.integer :position 5 | t.boolean :active,:default=>true,:null=>false 6 | t.string :tr_class 7 | t.timestamps 8 | end 9 | 10 | Helpdesk::TicketType.create_translation_table! :title => :string 11 | 12 | 13 | tt = [["Sugestia","Sugestion","warning"], 14 | ["Pochwała","Appreciation","success"], 15 | ["Błąd","Complaint","error"], 16 | ["Pytanie","Enquiry","info"], 17 | ["Kontakt","Contact","contact"]] 18 | 19 | tt.each do |item| 20 | I18n.locale = :pl 21 | type = Helpdesk::TicketType.new 22 | type.title = item[0] 23 | I18n.locale = :en 24 | type.title = item[1] 25 | type.tr_class = item[2] 26 | type.active = true 27 | type.save! 28 | end 29 | 30 | end 31 | 32 | def down 33 | drop_table :helpdesk_ticket_types 34 | Helpdesk::TicketType.drop_translation_table! 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /app/views/helpdesk/faqs/search.html.haml: -------------------------------------------------------------------------------- 1 | = content_for :left do 2 | %nav.bs-docs-sidebar.col 3 | %ul#sidebar.nav.nav-stacked 4 | = render partial: 'menu', locals:{faqs:Helpdesk::Faq.roots,link_type:'link'} 5 | 6 | %div.content 7 | %div.pageContainer 8 | - if params[:search] 9 | .alert.alert-info 10 | = t('helpdesk.faqs.search_count', count: @faqs.total_count, query:params[:search]) 11 | 12 | %h1 13 | = t('helpdesk.faqs.title_s') 14 | %ol#faq 15 | - @faqs.each do |faq| 16 | %li.callout 17 | %span.title 18 | = link_to faqs_url(anchor:faq.to_param) do 19 | = highlight(faq.title, params[:search], highlighter: '\1') 20 | %span.body 21 | - if faq.text.index(params[:search]) 22 | - start_index = [0, faq.text.index(params[:search])-30].max 23 | - else 24 | - start_index = 0 25 | 26 | = highlight("..."+faq.text[start_index,params[:search].length+40].strip+"...", params[:search], highlighter: '\1') 27 | 28 | =paginate @faqs 29 | -------------------------------------------------------------------------------- /lib/generators/helpdesk/templates/README: -------------------------------------------------------------------------------- 1 | =============================================================================== 2 | 3 | You need to do some manual setup to get Helpdesk working: 4 | 5 | 1. Review settings in new config/initializers/helpdesk.rb and update where 6 | neccessary. 7 | 8 | 2. Add 3 methods to your applications application_controller.rb 9 | * helpdesk_user - to exposes your current_user 10 | * helpdesk_admin? - to check privileges 11 | * helpdesk_admins_collection - to list all admin 12 | 13 | Example, for app with devise&rolify gems: 14 | application_controller.rb: 15 | 16 | helper_method :helpdesk_user,:helpdesk_admin?,:helpdesk_admin_collection 17 | def helpdesk_user 18 | current_user 19 | end 20 | 21 | def helpdesk_admin? 22 | current_user.has_role? :admin 23 | end 24 | 25 | def helpdesk_admin_collection 26 | (Helpdesk.user_class).with_role(:admin) 27 | end 28 | 29 | 3. Restart app 30 | 31 | =============================================================================== 32 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Show full error reports and disable caching 10 | config.consider_all_requests_local = true 11 | config.action_controller.perform_caching = false 12 | 13 | # Don't care if the mailer can't send 14 | config.action_mailer.raise_delivery_errors = false 15 | 16 | # Print deprecation notices to the Rails logger 17 | config.active_support.deprecation = :log 18 | 19 | # Only use best-standards-support built into browsers 20 | config.action_dispatch.best_standards_support = :builtin 21 | 22 | # Do not compress assets 23 | config.assets.compress = false 24 | 25 | # Expands the lines which load the assets 26 | config.assets.debug = true 27 | end 28 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012 John Beynon 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/tickets/_form.html.haml: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @ticket]) do |f| 2 | - if @ticket.errors.any? 3 | %div.error_explanation 4 | %h2 5 | = "#{pluralize(@ticket.errors.count, "error")} prohibited this ticket from being saved:" 6 | %ul 7 | - @ticket.errors.full_messages.each do |msg| 8 | %li 9 | = msg 10 | = f.association :requester, :collection => (Helpdesk.user_class).all,:label_method=>Helpdesk.display_user_uniq_info.to_sym, input_html: { class: 'chosen-select' } 11 | = f.input :subject 12 | = f.input :status, :collection => tickets_statuses_for_select, include_blank: false 13 | = f.input :assignee, :collection => helpdesk_admin_collection 14 | = f.input :ticket_type_id, :collection => Helpdesk::TicketType.active,include_blank: false 15 | - if @ticket.new_record? 16 | = f.input :description,input_html:{rows:4} 17 | - else 18 | = simple_format @ticket.description 19 | 20 | 21 | %div.form-actions 22 | = f.button :submit, :class => 'btn btn-primary' 23 | = submit_tag t('helpdesk..tickets.cancel'), :type => :reset, :class => "btn btn-danger" 24 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/faqs/inactive.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | - content_for :title do 4 | -if params[:faqs] && params[:faqs] == 'active' 5 | = t('helpdesk.faqs.active') 6 | -elsif params[:faqs] && params[:faqs] == 'inactive' 7 | = t('helpdesk.faqs.inactive') 8 | -else 9 | = t('helpdesk.faqs.all') 10 | 11 | %ul.faqs_list.faqs_list_main 12 | - @faqs.each do |faq| 13 | %li 14 | %span.title 15 | = faq.title 16 | %span.buttons 17 | = link_to t('helpdesk.show'), faqs_path(anchor:faq.to_param), class: 'icon btn btn-info btn-xs', target: :faq_preview 18 | = link_to t('helpdesk.edit'), edit_admin_faq_path(faq),class: 'icon btn btn-primary btn-xs' 19 | = link_to t('helpdesk.add'), new_admin_faq_path(faq:{parent_id:faq.id}),class: 'icon btn btn-success btn-xs' 20 | = link_to t('helpdesk.destroy'), admin_faq_path(faq), method: :delete, data: { confirm: 'Are you sure?' },class: 'icon btn btn-danger btn-xs' 21 | 22 | - if faq.children.present? 23 | %ul.faqs_list 24 | = render partial:'/helpdesk/admin/faqs/faq', locals:{ faqs:faq.children } 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/tickets/edit.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | - content_for :title do 3 | = t('helpdesk.ticket') 4 | = "##{@ticket.subject}" 5 | = render 'form' 6 | %h2 7 | = t('helpdesk.comments.title') 8 | 9 | %ul.comments.unstyled 10 | - @ticket.comments.each do |comment| 11 | - if comment.persisted? 12 | %li.comment{:id=>"comment#{comment.id}"} 13 | %div.comment-left 14 | - if comment.public 15 | = status_label ico('envelope') + t('helpdesk.comments.send') ,'label-success' 16 | - else 17 | = status_label t('helpdesk.comments.note'),'' 18 | %br 19 | %a{class:'anchor', href: "#comment#{comment.id}"} 20 | = "#" 21 | %div.comment-header 22 | -if comment.author == @ticket.requester 23 | = status_label ico('user')+ t('helpdesk.comments.author'),'label-info' 24 | 25 | = comment.author.send Helpdesk.display_user.to_sym if comment.author 26 | %small 27 | = time_ago_in_words(comment.created_at) 28 | temu 29 | %div.comment-body 30 | = simple_format comment.comment 31 | -------------------------------------------------------------------------------- /spec/models/comment_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | describe Helpdesk::Comment do 3 | it { should belong_to :author } 4 | it { should belong_to :ticket } 5 | 6 | describe "Mailers" do 7 | 8 | it "confirmation email is sent to the user" do 9 | comment = FactoryGirl.create(:comment_public) 10 | expect(all_email_addresses).to include comment.ticket.requester.email 11 | end 12 | if Helpdesk.send_confirmation_emails 13 | it "confirmation email is sent to the helpdesk" do 14 | FactoryGirl.create(:comment_public) 15 | expect(all_email_addresses).to include Helpdesk.email 16 | end 17 | else 18 | it "confirmation email is not sent to the helpdesk" do 19 | FactoryGirl.create(:comment_public) 20 | expect(all_email_addresses).not_to include Helpdesk.email 21 | end 22 | end 23 | 24 | it "if comment is note email is not sent" do 25 | ticket = FactoryGirl.create(:ticket) 26 | reset_email 27 | comment = FactoryGirl.create(:comment, ticket:ticket, public: false) 28 | expect(all_emails_sent_count).to eq 0 29 | end 30 | 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140326084237_create_helpdesk_ticket_types.helpdesk.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from helpdesk (originally 20130521105605) 2 | class CreateHelpdeskTicketTypes < ActiveRecord::Migration 3 | def up 4 | create_table :helpdesk_ticket_types do |t| 5 | t.integer :position 6 | t.boolean :active,:default=>true,:null=>false 7 | t.string :tr_class 8 | t.timestamps 9 | end 10 | 11 | Helpdesk::TicketType.create_translation_table! :title => :string 12 | 13 | 14 | tt = [["Sugestia","Sugestion","warning"], 15 | ["Pochwała","Appreciation","success"], 16 | ["Błąd","Complaint","error"], 17 | ["Pytanie","Enquiry","info"], 18 | ["Kontakt","Contact","contact"]] 19 | 20 | tt.each do |item| 21 | I18n.locale = :pl 22 | type = Helpdesk::TicketType.new 23 | type.title = item[0] 24 | I18n.locale = :en 25 | type.title = item[1] 26 | type.tr_class = item[2] 27 | type.active = true 28 | type.save! 29 | end 30 | 31 | end 32 | 33 | def down 34 | drop_table :helpdesk_ticket_types 35 | Helpdesk::TicketType.drop_translation_table! 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /app/models/helpdesk/comment.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class Comment < ActiveRecord::Base 3 | belongs_to :author, :class_name => Helpdesk.user_class.to_s 4 | belongs_to :ticket 5 | 6 | default_scope -> {includes(:author).order('id ASC')} 7 | scope :pub, -> { where(public: true)} 8 | 9 | after_create :send_email 10 | after_create :check_reopen 11 | 12 | def check_reopen 13 | if ticket.requester == author 14 | ticket.update_column(:status ,:waiting) 15 | end 16 | end 17 | 18 | 19 | def send_email 20 | if self.public? 21 | if ticket.requester == author 22 | Helpdesk::NotificationsMailer.comment_by_requester_notification(self).deliver_now if ticket.requester 23 | Helpdesk::NotificationsMailer.comment_by_requester_confirmation(self).deliver_now if Helpdesk.send_confirmation_emails 24 | else 25 | Helpdesk::NotificationsMailer.comment_by_helpdesk_notification(self).deliver_now if ticket.requester 26 | Helpdesk::NotificationsMailer.comment_by_helpdesk_confirmation(self).deliver_now if Helpdesk.send_confirmation_emails 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/subscribers_controller.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class SubscribersController < Helpdesk::ApplicationController 3 | 4 | def index 5 | @subscriber = Subscriber.new 6 | @subscriber.lang = locale 7 | end 8 | 9 | def create 10 | @subscriber = Subscriber.new(subscriber_params) 11 | if @subscriber.save 12 | redirect_to root_path, notice: 'Subscriber was successfully created.' 13 | else 14 | render action: "index" 15 | end 16 | end 17 | 18 | def activation 19 | @subscriber = Subscriber.where(hashcode:params[:hashcode],confirmed:false).first 20 | @subscriber.update_attributes(hashcode:nil,confirmed:true) if @subscriber 21 | redirect_to root_path,notice: 'Subscriber was successfully activated.' 22 | end 23 | 24 | def destroy 25 | @subscriber = Subscriber.where(hashcode:params[:hashcode],confirmed:true).first 26 | @subscriber.destroy if @subscriber 27 | redirect_to root_path,notice: 'Subscriber was successfully deleted.' 28 | end 29 | 30 | private 31 | 32 | def subscriber_params 33 | params.require(:subscriber).permit(:email,:lang, :name) 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /app/models/helpdesk/faq.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class Faq < ActiveRecord::Base 3 | translates :title, :text 4 | accepts_nested_attributes_for :translations 5 | 6 | acts_as_ordered_tree 7 | 8 | default_scope {order('position ASC').includes(:translations)} 9 | 10 | scope :active, -> {where(active: true)} 11 | scope :inactive, -> {where(active: false)} 12 | 13 | def name_with_depth 14 | "#{"    "*depth}\\_ #{title}".html_safe 15 | end 16 | 17 | def to_param 18 | id ? "#{id}-#{title.parameterize}" : nil 19 | end 20 | 21 | def self.search(query, page=1) 22 | query = "%#{query}%" 23 | arel_faqs_t = Arel::Table.new(:helpdesk_faq_translations) 24 | name_match = arel_faqs_t[:title].matches(query) 25 | postal_match = arel_faqs_t[:text].matches(query) 26 | with_translations.active.where(name_match.or(postal_match)).page(page) 27 | end 28 | 29 | def anchor 30 | "##{to_param}" 31 | end 32 | 33 | def self.collection 34 | arr = [] 35 | roots.each do |faq| 36 | arr << faq 37 | arr << faq.descendants 38 | end 39 | return arr.flatten 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/tickets/index.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | %h1 4 | -if params[:tickets] && params[:tickets] == 'unassigned' 5 | = t('helpdesk.unassigned_ticketes') 6 | -else 7 | = t('helpdesk.my_tickets') 8 | 9 | %table.table.table-hover 10 | %thead 11 | %tr 12 | %th= t('helpdesk.status') 13 | %th ID 14 | %th Issue Type 15 | %th Subject 16 | %th Requester 17 | %th Requested 18 | %th Assignee 19 | %th 20 | 21 | %tbody 22 | - @tickets.each do |ticket| 23 | %tr{:class=>ticket.ticket_type_tr_class} 24 | %td 25 | = Helpdesk::Ticket::STATUS_BY_KEY[ticket.status.to_sym] 26 | %td= ticket.id 27 | %td= ticket.ticket_type_title 28 | %td= ticket.subject 29 | %td 30 | - if ticket.requester 31 | = ticket.requester.send Helpdesk.display_user.to_sym 32 | %br 33 | = ticket.requester.phone 34 | %br 35 | = ticket.requester.email 36 | %td= I18n::l(ticket.created_at, :format=>:short) 37 | %td= ticket.assignee if ticket.assignee 38 | %td= link_to 'Show', admin_ticket_url(ticket) 39 | %br 40 | 41 | = paginate @tickets 42 | 43 | -------------------------------------------------------------------------------- /app/assets/stylesheets/helpdesk/admin/faqs.css.sass: -------------------------------------------------------------------------------- 1 | $cTextLight: #a0a0a0 2 | @CHARSET "UTF-8" 3 | @mixin transition($var...) 4 | -webkit-transition: $var 5 | transition: $var 6 | 7 | ul.faqs_list_main 8 | > li 9 | position: relative 10 | 11 | ul.faqs_list 12 | > li 13 | // display: block 14 | margin: 10px 0px 15 | padding: 2px 16 | // width: 90% 17 | min-width: 100px 18 | border: 1px solid $cTextLight 19 | border-radius: 2px 20 | background-color: #ffffff 21 | // background-color: $colorBluePastelLight 22 | line-height: 30px 23 | vertical-align: middle 24 | box-shadow: 0px 1px 2px 0px rgba(0,0,0,0.2) 25 | @include transition(opacity 0.2s ease-in-out) 26 | 27 | >span.title 28 | 29 | 30 | >span.buttons 31 | position: absolute 32 | right: 40px 33 | 34 | 35 | ul, ol 36 | margin: 10px auto 10px 10px 37 | list-style: disc 38 | 39 | 40 | &:hover 41 | >span 42 | 43 | > a.icon 44 | opacity: 1 45 | 46 | 47 | 48 | 49 | >span 50 | a.icon 51 | position: relative 52 | opacity: 0 53 | overflow: hidden 54 | vertical-align: middle 55 | @include transition(opacity 0.2s ease-in-out) 56 | -------------------------------------------------------------------------------- /app/views/layouts/helpdesk/user.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html 3 | %head 4 | %title 5 | = t :name, :scope => :helpdesk 6 | = javascript_include_tag "helpdesk/application" 7 | = stylesheet_link_tag "helpdesk/application", :media => "all" 8 | = javascript_tag "$(document).ready(function(){ $('.dropdown-toggle').dropdown();$('.alert').alert();})" 9 | = csrf_meta_tags 10 | = yield :head 11 | %body 12 | .container 13 | = render 'layouts/helpdesk/topuser' 14 | .content 15 | .row 16 | .col.col-md-3#site_leftmenu 17 | =yield :left 18 | .col.col-md-9#site_leftmenu 19 | .flash 20 | - flash.each do |type, message| 21 | %div{:class => "alert alert-#{type}", "data-alert"=>"alert"} 22 | =link_to "x",'#', :class=>'close', :'data-dismiss'=>"alert" 23 | %p= message 24 | - if content_for?(:title) 25 | .panel.panel-default 26 | .panel-heading 27 | %h3.panel-title 28 | = content_for?(:title) ? content_for(:title) : '' 29 | .panel-body 30 | = yield 31 | - else 32 | = yield 33 | =yield :scripts 34 | -------------------------------------------------------------------------------- /app/views/layouts/helpdesk/admin.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html 3 | %head 4 | %title 5 | = t :name, :scope => :helpdesk 6 | = javascript_include_tag "helpdesk/application" 7 | = stylesheet_link_tag "helpdesk/admin", :media => "all" 8 | = javascript_tag "$(document).ready(function(){ $('.dropdown-toggle').dropdown();$('.alert').alert();})" 9 | = csrf_meta_tags 10 | = yield :head 11 | %body 12 | .container 13 | = render 'layouts/helpdesk/topmenu' 14 | .content 15 | .row 16 | .col.col-md-3#site_leftmenu 17 | =yield :left 18 | .col.col-md-9#site_leftmenu 19 | .flash 20 | - flash.each do |type, message| 21 | %div{:class => "alert alert-#{type}", "data-alert"=>"alert"} 22 | =link_to "x",'#', :class=>'close', :'data-dismiss'=>"alert" 23 | %p= message 24 | - if content_for?(:title) 25 | .panel.panel-default 26 | .panel-heading 27 | %h3.panel-title 28 | = content_for?(:title) ? content_for(:title) : '' 29 | .panel-body 30 | = yield 31 | - else 32 | = yield 33 | =yield :scripts 34 | 35 | 36 | -------------------------------------------------------------------------------- /spec/models/ticket_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | describe Helpdesk::Ticket do 3 | 4 | it { should accept_nested_attributes_for :comments } 5 | it { should belong_to :requester } 6 | it { should belong_to :assignee } 7 | it { should have_many :comments } 8 | it { should belong_to :ticket_type } 9 | 10 | 11 | describe "Validations" do 12 | it { should validate_presence_of :description } 13 | end 14 | 15 | describe "Status" do 16 | it "should be :new for a new ticket" do 17 | expect(FactoryGirl.create(:ticket).status).to eq('new') 18 | end 19 | end 20 | 21 | describe "Mailers" do 22 | 23 | it "confirmation email is sent to the user" do 24 | ticket = FactoryGirl.create(:ticket) 25 | expect(all_email_addresses).to include ticket.requester.email 26 | end 27 | if Helpdesk.send_confirmation_emails 28 | it "confirmation email is sent to the helpdesk" do 29 | FactoryGirl.create(:ticket) 30 | expect(all_email_addresses).to include Helpdesk.email 31 | end 32 | else 33 | it "confirmation email is not sent to the helpdesk" do 34 | FactoryGirl.create(:ticket) 35 | expect(all_email_addresses).not_to include Helpdesk.email 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /app/helpers/helpdesk/helpdesk_helper.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | module HelpdeskHelper 3 | 4 | 5 | def menu_left(title,&block) 6 | panel_menu(title,'default',&block) 7 | end 8 | 9 | def panel_menu(title,type,&block) 10 | content_tag(:div,class: "panel panel-#{type}") do 11 | content_tag(:div ,class: 'panel-heading') do 12 | content_tag(:h3 ,title,class:'panel-title') 13 | end + 14 | content_tag( :ul, class: 'nav nav-pills nav-stacked ') do 15 | capture(&block) 16 | end 17 | end 18 | end 19 | 20 | def menu_li(lbl, path, *args) 21 | options = args.extract_options! 22 | (options[:class].nil? ? options.merge!(:class => "active") : options[:class] += " active" ) if url_for(path) == request.fullpath 23 | content_tag(:li, link_to(lbl, path), options) 24 | end 25 | 26 | def status_label(lbl,cls) 27 | content_tag(:span, class: "label #{cls}") do 28 | lbl 29 | end 30 | end 31 | 32 | def badge(num,css='pull-right') 33 | raw("#{num} ") 34 | end 35 | 36 | def ico(name) 37 | raw(" ") 38 | end 39 | 40 | def parent_layout(layout) 41 | @view_flow.set(:layout,output_buffer) 42 | self.output_buffer = render(:file => "layouts/#{layout}") 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/generators/helpdesk/templates/helpdesk.rb: -------------------------------------------------------------------------------- 1 | require 'helpdesk' 2 | 3 | ::Helpdesk.setup do |config| 4 | # Class that represents the user/admin 5 | config.user_class = "User" 6 | 7 | # Method usign to display information about user for users 8 | config.display_user = "name" 9 | 10 | # Method usign to display information about user for admins (name+id?) 11 | config.display_user_uniq_info = "email" 12 | 13 | # Require User to be present in order to access Helpdesk 14 | config.require_user = true 15 | 16 | # Base application sign in route name 17 | config.sign_in_url = 'new_user_session_path' 18 | 19 | # Helpdesk email for notification 20 | config.email = 'helpdesk@example.com' 21 | 22 | # Send confirmation emails 23 | config.send_confirmation_emails = true 24 | 25 | # Site name in email footer 26 | config.site_name = "Example Helpdesk Team" 27 | 28 | # Site address in email footer 29 | config.site_address = "www.example.com" 30 | 31 | # Helpdesk title 32 | config.helpdesk_name = "Example Helpdesk" 33 | 34 | # Helpdesk root controller for users: faqs or tickets 35 | config.root_controller = 'faqs' 36 | 37 | # Helpdesk user top menu item 38 | # possible options= ['app_root','helpdesk_root','tickets','faqs','subscribers','search','user','language'] 39 | config.menu_items = ['app_root','helpdesk_root','tickets','faqs','subscribers','search','user','language'] 40 | 41 | end 42 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/admin/subscribers_controller.rb: -------------------------------------------------------------------------------- 1 | class Helpdesk::Admin::SubscribersController < Helpdesk::Admin::BaseController 2 | 3 | def index 4 | @subscribers = Helpdesk::Subscriber.page(params[:page]) 5 | end 6 | 7 | def new 8 | @subscriber = Helpdesk::Subscriber.new() 9 | end 10 | 11 | def create 12 | @subscriber = Helpdesk::Subscriber.new(subscriber_params) 13 | if @subscriber.save 14 | redirect_to admin_subscribers_path, notice: t('subscribers.created') 15 | else 16 | render action: "index" 17 | end 18 | end 19 | 20 | def edit 21 | @subscriber = Helpdesk::Subscriber.find(params[:id]) 22 | end 23 | 24 | # PUT /subscribers/1 25 | # PUT /subscribers/1.json 26 | def update 27 | @subscriber = Helpdesk::Subscriber.find(params[:id]) 28 | 29 | if @subscriber.update_attributes(subscriber_params) 30 | redirect_to admin_subscribers_path, notice: 'Subscriber was successfully updated.' 31 | else 32 | render action: "edit" 33 | end 34 | end 35 | 36 | # DELETE /subscribers/1 37 | # DELETE /subscribers/1.json 38 | def destroy 39 | @subscriber = Helpdesk::Subscriber.find_by_hashcode(params[:hashcode]) 40 | @subscriber.destroy 41 | redirect_to root_path 42 | end 43 | 44 | private 45 | 46 | def subscriber_params 47 | params.require(:subscriber).permit(:confirmed, :email, :hashcode, :lang, :name) 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/faqs/sorting.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | %ol.breadcrumb 4 | = t('helpdesk.faqs.sorting') 5 | = menu_li 'FAQ Root',sorting_admin_faq_url(:all) 6 | - if @faq 7 | - @faq.ancestors.reverse_each do |faq| 8 | = menu_li faq.title, sorting_admin_faq_url(faq) 9 | = menu_li @faq.title, sorting_admin_faq_url(@faq) 10 | 11 | 12 | %ul.faqs_list#faqs 13 | - @faqs.each do |faq| 14 | %li{id:"faqs_#{faq.id}",style:'padding:5px 0px;'} 15 | %span.handle.span2{style:'cursor:move'} 16 | %span 17 | = ico('move') 18 | %span.title 19 | = faq.title 20 | %span.buttons 21 | - if faq.children.present? 22 | = link_to t('helpdesk.sort_this_childs'), sorting_admin_faq_url(faq), class: 'btn btn-info btn-xs' 23 | 24 | - content_for :scripts do 25 | :javascript 26 | $(document).ready(function(){ 27 | $('#faqs').sortable({ 28 | axis: 'y', 29 | dropOnEmpty: false, 30 | handle: '.handle', 31 | cursor: 'crosshair', 32 | items: 'li', 33 | opacity: 0.4, 34 | scroll: true, 35 | update: function(){ 36 | $.ajax({ 37 | type: 'post', 38 | data: $('#faqs').sortable('serialize'), 39 | dataType: 'script', 40 | complete: function(request){ 41 | $('#faqs').effect('highlight'); 42 | }, 43 | url: '#{sort_admin_faqs_path}' 44 | }) 45 | } 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /test/functional/helpdesk/faqs_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | module Helpdesk 4 | class FaqsControllerTest < ActionController::TestCase 5 | setup do 6 | @faq = faqs(:one) 7 | end 8 | 9 | test "should get index" do 10 | get :index 11 | assert_response :success 12 | assert_not_nil assigns(:faqs) 13 | end 14 | 15 | test "should get new" do 16 | get :new 17 | assert_response :success 18 | end 19 | 20 | test "should create faq" do 21 | assert_difference('Faq.count') do 22 | post :create, faq: { active: @faq.active, position: @faq.position, text: @faq.text, title: @faq.title } 23 | end 24 | 25 | assert_redirected_to faq_path(assigns(:faq)) 26 | end 27 | 28 | test "should show faq" do 29 | get :show, id: @faq 30 | assert_response :success 31 | end 32 | 33 | test "should get edit" do 34 | get :edit, id: @faq 35 | assert_response :success 36 | end 37 | 38 | test "should update faq" do 39 | put :update, id: @faq, faq: { active: @faq.active, position: @faq.position, text: @faq.text, title: @faq.title } 40 | assert_redirected_to faq_path(assigns(:faq)) 41 | end 42 | 43 | test "should destroy faq" do 44 | assert_difference('Faq.count', -1) do 45 | delete :destroy, id: @faq 46 | end 47 | 48 | assert_redirected_to faqs_path 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /app/views/helpdesk/tickets/_form.html.haml: -------------------------------------------------------------------------------- 1 | = simple_form_for @ticket,html:{class: :feedback} do |f| 2 | %fieldset<> 3 | - if @ticket.errors.any? 4 | %div.error_explanation 5 | %h2 6 | = "#{pluralize(@ticket.errors.count, "error")} prohibited this ticket from being saved:" 7 | %ul 8 | - @ticket.errors.full_messages.each do |msg| 9 | %li 10 | = msg 11 | = f.input :subject 12 | / = f.input :ticket_type_id, collection: Helpdesk::TicketType.active, include_blank: false 13 | = f.input :ticket_type_id, collection: Helpdesk::TicketType.active.includes(:translations).all, include_blank: false 14 | 15 | %hr 16 | - if @ticket.new_record? 17 | = f.input :description,:placeholder => t('helpdesk.tickets.description'),label:false, input_html:{rows:5} 18 | - else 19 | = @ticket.description 20 | 21 | = f.simple_fields_for :comments do |tickets_form| 22 | - unless tickets_form.object.persisted? 23 | = tickets_form.input :comment 24 | = tickets_form.input :public, :hint => 'Requester can see this comment (public comment)' 25 | = tickets_form.input :author_id, :as => :hidden, :input_html => { :value => helpdesk_user.id } 26 | %hr 27 | %div.textRight 28 | %a.class.btn.btn-default{href: root_path } 29 | = t('helpdesk.tickets.cancel') 30 | %input{:type => "submit",:value => t('helpdesk.tickets.send'), :class=>"btn btn-primary"} 31 | %div.clearBoth 32 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/admin/ticket_types_controller.rb: -------------------------------------------------------------------------------- 1 | class Helpdesk::Admin::TicketTypesController < Helpdesk::Admin::BaseController 2 | 3 | def index 4 | @ticket_types = Helpdesk::TicketType.all 5 | end 6 | 7 | def show 8 | @ticket_type = Helpdesk::TicketType.find(params[:id]) 9 | end 10 | 11 | def new 12 | @ticket_type = Helpdesk::TicketType.new 13 | end 14 | 15 | def edit 16 | @ticket_type = Helpdesk::TicketType.find(params[:id]) 17 | end 18 | 19 | def create 20 | @ticket_type = Helpdesk::TicketType.new(ticket_type_params) 21 | if @ticket_type.save 22 | redirect_to admin_ticket_types_url, notice: 'Ticket type was successfully created.' 23 | else 24 | render action: "new" 25 | end 26 | end 27 | 28 | def update 29 | @ticket_type = Helpdesk::TicketType.find(params[:id]) 30 | if @ticket_type.update_attributes(ticket_type_params) 31 | redirect_to admin_ticket_types_url, notice: 'Ticket type was successfully updated.' 32 | else 33 | render action: "edit" 34 | end 35 | end 36 | 37 | def destroy 38 | @ticket_type = Helpdesk::TicketType.find(params[:id]) 39 | @ticket_type.destroy 40 | 41 | respond_to do |format| 42 | format.html { redirect_to admin_ticket_types_url } 43 | format.json { head :no_content } 44 | end 45 | end 46 | 47 | private 48 | 49 | def ticket_type_params 50 | params.require(:ticket_type).permit(:active,:position,:title,:tr_class,translations_attributes:[:title, :id, :locale]) 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /app/mailers/helpdesk/notifications_mailer.rb: -------------------------------------------------------------------------------- 1 | class Helpdesk::NotificationsMailer < ActionMailer::Base 2 | 3 | layout 'mailer_layout' 4 | 5 | def ticket_created_notification(ticket) 6 | @ticket = ticket 7 | mail(:subject=>"#{Helpdesk.helpdesk_name} | #{ticket.subject}", 8 | :to => Helpdesk.email) 9 | end 10 | 11 | def ticket_created_confirmation(ticket) 12 | @ticket = ticket 13 | mail(:subject=>"#{Helpdesk.helpdesk_name} | #{ticket.subject}", 14 | :to => ticket.requester.email) 15 | end 16 | 17 | def comment_by_requester_notification(comment) 18 | @comment = comment 19 | mail(:subject=>"#{Helpdesk.helpdesk_name} | #{comment.ticket.subject}", 20 | :to => Helpdesk.email) 21 | end 22 | 23 | def comment_by_requester_confirmation(comment) 24 | @comment = comment 25 | mail(:subject=>"#{Helpdesk.helpdesk_name} | #{comment.ticket.subject}", 26 | :to => comment.ticket.requester.email) 27 | end 28 | 29 | 30 | def comment_by_helpdesk_notification(comment) 31 | @comment = comment 32 | mail(:subject=>"#{Helpdesk.helpdesk_name} | #{comment.ticket.subject}", 33 | :to => comment.ticket.requester.email) 34 | end 35 | 36 | def comment_by_helpdesk_confirmation(comment) 37 | @comment = comment 38 | mail(:subject=>"#{t('helpdesk.name')} | #{comment.ticket.subject}", 39 | :to => Helpdesk.email) 40 | end 41 | 42 | def send_activate_subscription(subscriber) 43 | @subscriber = subscriber 44 | mail(:subject=>"#{t('helpdesk.name')}: Please Confirm Subscription", 45 | :to => @subscriber.email) 46 | end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /app/views/layouts/helpdesk/_topmenu.html.haml: -------------------------------------------------------------------------------- 1 | %nav.navbar.navbar-default#site_topmmenu{role: 'navigation'} 2 | .navbar-header 3 | %button.navbar-toggle{"data-target" => "#bs-navbar-collapse-1", "data-toggle" => "collapse", type: "button"} 4 | %span.sr-only Toggle navigation 5 | %span.icon-bar 6 | %span.icon-bar 7 | %span.icon-bar 8 | =link_to Helpdesk.site_address, main_app.root_path, :class=>'navbar-brand', :title => t('helpdesk.name') 9 | =link_to t('helpdesk.name'), admin_root_path, :class=>'navbar-brand', :title => t('helpdesk.name') 10 | #bs-navbar-collapse-1.collapse.navbar-collapse.in 11 | %ul.nav.navbar-nav 12 | = menu_li t('helpdesk.tickets.title'),admin_tickets_path 13 | = menu_li t('helpdesk.ticket_types.title'),admin_ticket_types_path 14 | = menu_li t('helpdesk.subscribers.title'),admin_subscribers_path 15 | = menu_li t('helpdesk.faqs.title'),admin_faqs_path 16 | 17 | 18 | 19 | %ul.nav.navbar-nav.navbar-right 20 | %li.dropdown.user 21 | = link_to current_user.send(Helpdesk.display_user.to_sym), "#",:class=>"dropdown-toggle",data:{toggle:"dropdown"} 22 | %ul.dropdown-menu 23 | %li=link_to 'Home',main_app.root_path 24 | %li=link_to t('users.sign_out'),main_app.destroy_user_session_path, :method => :delete, :class => 'icon exit blue' 25 | 26 | %li.dropdown 27 | = link_to t('helpdesk.lang'),"#",:class=>"dropdown-toggle",data:{toggle:"dropdown"} 28 | %ul.dropdown-menu 29 | %li= link_to "English", params.merge({:locale => :en}) 30 | %li= link_to "Polski", params.merge({:locale => :pl}) 31 | -------------------------------------------------------------------------------- /test/functional/helpdesk/subscribers_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | module Helpdesk 4 | class SubscribersControllerTest < ActionController::TestCase 5 | setup do 6 | @subscriber = subscribers(:one) 7 | end 8 | 9 | test "should get index" do 10 | get :index 11 | assert_response :success 12 | assert_not_nil assigns(:subscribers) 13 | end 14 | 15 | test "should get new" do 16 | get :new 17 | assert_response :success 18 | end 19 | 20 | test "should create subscriber" do 21 | assert_difference('Subscriber.count') do 22 | post :create, subscriber: { confirmed: @subscriber.confirmed, email: @subscriber.email, hashcode: @subscriber.hashcode, lang: @subscriber.lang, name: @subscriber.name } 23 | end 24 | 25 | assert_redirected_to subscriber_path(assigns(:subscriber)) 26 | end 27 | 28 | test "should show subscriber" do 29 | get :show, id: @subscriber 30 | assert_response :success 31 | end 32 | 33 | test "should get edit" do 34 | get :edit, id: @subscriber 35 | assert_response :success 36 | end 37 | 38 | test "should update subscriber" do 39 | put :update, id: @subscriber, subscriber: { confirmed: @subscriber.confirmed, email: @subscriber.email, hashcode: @subscriber.hashcode, lang: @subscriber.lang, name: @subscriber.name } 40 | assert_redirected_to subscriber_path(assigns(:subscriber)) 41 | end 42 | 43 | test "should destroy subscriber" do 44 | assert_difference('Subscriber.count', -1) do 45 | delete :destroy, id: @subscriber 46 | end 47 | 48 | assert_redirected_to subscribers_path 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/tickets/show.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | = render 'ticket', :ticket=>@ticket, show_button:false,edit_button:true 4 | 5 | %table.table 6 | %tbody 7 | %tr{:class=>@ticket.ticket_type_tr_class} 8 | 9 | %td 10 | 11 | - unless @ticket.open? 12 | = t('helpdesk.tickets.ticket_closed') 13 | -else 14 | = simple_form_for([:admin, @ticket]) do |f| 15 | - if @ticket.errors.any? 16 | %div.error_explanation 17 | %h2 18 | = "#{pluralize(@ticket.errors.count, "error")} prohibited this ticket from being saved:" 19 | %ul 20 | - @ticket.errors.full_messages.each do |msg| 21 | %li 22 | = msg 23 | = f.input :status, :collection => tickets_statuses_for_select, include_blank: false 24 | = f.input :assignee_id, :collection => helpdesk_admin_collection 25 | 26 | 27 | = f.simple_fields_for :comments,@ticket.comments.build do |tickets_form| 28 | - unless tickets_form.object.persisted? 29 | = tickets_form.input :comment, :input_html=>{class: 'comment-textarea'} 30 | / , :as => :ckeditor, :input_html => { :ckeditor => {:toolbar => 'mini'},:language => I18n.locale} 31 | 32 | = tickets_form.input :public, :hint => t('helpdesk.tickets.visible_to_autor') 33 | = tickets_form.input :author_id, :as => :hidden, :input_html => { :value => helpdesk_user.id } 34 | %div.form-actions 35 | = f.button :submit, :class => 'btn btn-primary' 36 | = submit_tag t('helpdesk..tickets.cancel'), :type => :reset, :class => "btn btn-danger" 37 | -------------------------------------------------------------------------------- /app/views/helpdesk/tickets/show.html.haml: -------------------------------------------------------------------------------- 1 | = render 'menu' 2 | 3 | = render 'ticket', :ticket=>@ticket, show_button:false 4 | 5 | 6 | - unless @ticket.open? 7 | %table.table 8 | %tbody 9 | %tr{:class=>@ticket.ticket_type_tr_class} 10 | %td{style:'width:100px'} 11 | %td 12 | = t('helpdesk.tickets.ticket_closed') 13 | - if @ticket.open? || helpdesk_user == @ticket.requester 14 | %table.table 15 | %tbody 16 | %tr{:class=>@ticket.ticket_type_tr_class} 17 | %td{style:'width:100px'} 18 | %td 19 | = simple_form_for(@ticket, :html => {:class => 'form-vertical' }) do |f| 20 | - if @ticket.errors.any? 21 | %div.error_explanation 22 | %h2 23 | = "#{pluralize(@ticket.errors.count, "error")} prohibited this ticket from being saved:" 24 | %ul 25 | - @ticket.errors.full_messages.each do |msg| 26 | %li 27 | = msg 28 | 29 | = f.simple_fields_for :comments,@ticket.comments.build do |tickets_form| 30 | - unless tickets_form.object.persisted? 31 | = tickets_form.input :comment, :input_html=>{class: 'comment-textarea',rows: 5} 32 | / , :as => :ckeditor, :input_html => { :ckeditor => {:toolbar => 'mini'},:language => I18n.locale} 33 | 34 | = tickets_form.input :public, :input_html => {:value=>1},:as=>:hidden 35 | = tickets_form.input :author_id, :as => :hidden, :input_html => { :value => helpdesk_user.id } 36 | %div 37 | = f.button :submit, :class => 'btn btn-primary' 38 | = submit_tag t('helpdesk..tickets.cancel'), :type => :reset, :class => "btn btn-default" 39 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20120405124828_devise_create_users.rb: -------------------------------------------------------------------------------- 1 | class DeviseCreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table(:users) do |t| 4 | ## Database authenticatable 5 | t.string :email, :null => false, :default => "" 6 | t.string :encrypted_password, :null => false, :default => "" 7 | 8 | ## Recoverable 9 | t.string :reset_password_token 10 | t.datetime :reset_password_sent_at 11 | 12 | ## Rememberable 13 | t.datetime :remember_created_at 14 | 15 | ## Trackable 16 | t.integer :sign_in_count, :default => 0 17 | t.datetime :current_sign_in_at 18 | t.datetime :last_sign_in_at 19 | t.string :current_sign_in_ip 20 | t.string :last_sign_in_ip 21 | 22 | ## Encryptable 23 | # t.string :password_salt 24 | 25 | ## Confirmable 26 | # t.string :confirmation_token 27 | # t.datetime :confirmed_at 28 | # t.datetime :confirmation_sent_at 29 | # t.string :unconfirmed_email # Only if using reconfirmable 30 | 31 | ## Lockable 32 | # t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts 33 | # t.string :unlock_token # Only if unlock strategy is :email or :both 34 | # t.datetime :locked_at 35 | 36 | ## Token authenticatable 37 | # t.string :authentication_token 38 | 39 | 40 | t.timestamps 41 | end 42 | 43 | add_index :users, :email, :unique => true 44 | add_index :users, :reset_password_token, :unique => true 45 | # add_index :users, :confirmation_token, :unique => true 46 | # add_index :users, :unlock_token, :unique => true 47 | # add_index :users, :authentication_token, :unique => true 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV["RAILS_ENV"] = 'test' 3 | require File.expand_path("../dummy/config/environment", __FILE__) 4 | require 'shoulda/matchers' 5 | require 'rspec/rails' 6 | require 'factory_girl' 7 | require 'email_spec' 8 | 9 | #ENGINE_RAILS_ROOT=File.join(File.dirname(__FILE__), '../') 10 | 11 | # Requires supporting ruby files with custom matchers and macros, etc, 12 | # in spec/support/ and its subdirectories. 13 | #Dir[File.join(ENGINE_RAILS_ROOT, "spec/support/**/*.rb")].each {|f| require f } 14 | # Load support files 15 | Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } 16 | 17 | 18 | RSpec.configure do |config| 19 | 20 | 21 | config.include Helpdesk::Engine.routes.url_helpers 22 | config.include Capybara::DSL 23 | 24 | 25 | 26 | config.include(EmailSpec::Helpers) 27 | config.include(EmailSpec::Matchers) 28 | 29 | 30 | config.include(MailerMacros) 31 | config.before(:each) { reset_email } 32 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: 33 | # 34 | # config.mock_with :mocha 35 | # config.mock_with :flexmock 36 | # config.mock_with :rr 37 | 38 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 39 | # config.fixture_path = "#{::Rails.root}/spec/fixtures" 40 | 41 | # If you're not using ActiveRecord, or you'd prefer not to run each of your 42 | # examples within a transaction, remove the following line or assign false 43 | # instead of true. 44 | config.use_transactional_fixtures = true 45 | 46 | # If true, the base class of anonymous controllers will be inferred 47 | # automatically. This will be the default behavior in future versions of 48 | # rspec-rails. 49 | config.infer_base_class_for_anonymous_controllers = false 50 | end 51 | -------------------------------------------------------------------------------- /app/assets/stylesheets/helpdesk/faqs.css.scss: -------------------------------------------------------------------------------- 1 | body { 2 | position: relative; 3 | } 4 | 5 | ul#faq{ 6 | margin-bottom: 200px; 7 | } 8 | 9 | .affix{ 10 | top: 0px; 11 | width:inherit; 12 | } 13 | 14 | /* sidebar */ 15 | .bs-docs-sidebar { 16 | padding-left: 0px; 17 | margin-top: 20px; 18 | margin-bottom: 20px; 19 | } 20 | 21 | /* all links */ 22 | .bs-docs-sidebar .nav>li>a { 23 | color: #999; 24 | border-left: 2px solid transparent; 25 | padding: 4px 20px; 26 | font-size: 13px; 27 | font-weight: 400; 28 | } 29 | 30 | /* nested links */ 31 | .bs-docs-sidebar .nav .nav>li>a { 32 | padding-top: 1px; 33 | padding-bottom: 1px; 34 | padding-left: 30px; 35 | font-size: 12px; 36 | } 37 | 38 | .bs-docs-sidebar .nav .nav .nav>li>a { 39 | padding-top: 1px; 40 | padding-bottom: 1px; 41 | padding-left: 40px; 42 | font-size: 12px; 43 | } 44 | 45 | .bs-docs-sidebar .nav .nav .nav .nav>li>a { 46 | padding-top: 1px; 47 | padding-bottom: 1px; 48 | padding-left: 50px; 49 | font-size: 12px; 50 | } 51 | 52 | /* active & hover links */ 53 | .bs-docs-sidebar .nav>.active>a, 54 | .bs-docs-sidebar .nav>li>a:hover, 55 | .bs-docs-sidebar .nav>li>a:focus { 56 | color: #563d7c; 57 | text-decoration: none; 58 | background-color: transparent; 59 | border-left-color: #563d7c; 60 | } 61 | /* all active links */ 62 | .bs-docs-sidebar .nav>.active>a, 63 | .bs-docs-sidebar .nav>.active:hover>a, 64 | .bs-docs-sidebar .nav>.active:focus>a { 65 | font-weight: 700; 66 | } 67 | /* nested active links */ 68 | .bs-docs-sidebar .nav .nav>.active>a, 69 | .bs-docs-sidebar .nav .nav>.active:hover>a, 70 | .bs-docs-sidebar .nav .nav>.active:focus>a { 71 | font-weight: 500; 72 | } 73 | 74 | /* hide inactive nested list */ 75 | .bs-docs-sidebar .nav ul.nav { 76 | display: none; 77 | } 78 | /* show active nested list */ 79 | .bs-docs-sidebar .nav>.active>ul.nav { 80 | display: block; 81 | } 82 | -------------------------------------------------------------------------------- /helpdesk.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path("../lib", __FILE__) 2 | 3 | # Maintain your gem's version: 4 | require "helpdesk/version" 5 | 6 | # Describe your gem and declare its dependencies: 7 | Gem::Specification.new do |s| 8 | s.name = "helpdesk" 9 | s.version = Helpdesk::VERSION 10 | s.authors = ["John Beynon Wacław Łuczak"] 11 | s.email = ["john@beynon.org.uk, waclaw@luczak.it"] 12 | s.homepage = "http://github.com/wacaw/helpdesk" 13 | s.summary = "Rails mountable engine providing basic helpdesk functionality for your applications" 14 | s.description = "Helpesk includes: tickets, ticket types, email-notification, FAQ, subscribers" 15 | s.license = 'MIT' 16 | 17 | s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile"] 18 | s.require_paths = ['lib'] 19 | 20 | s.add_development_dependency "launchy" 21 | s.add_development_dependency 'rspec-rails' 22 | s.add_development_dependency 'capybara' 23 | s.add_development_dependency 'devise' 24 | s.add_development_dependency "factory_girl_rails" 25 | s.add_development_dependency "foreman" 26 | s.add_development_dependency "sqlite3" 27 | s.add_development_dependency "shoulda" 28 | s.add_development_dependency "letter_opener" 29 | s.add_development_dependency "bullet" 30 | s.add_development_dependency "haml-rails" 31 | s.add_development_dependency 'compass' 32 | s.add_development_dependency 'email_spec' 33 | 34 | s.add_dependency 'kaminari' 35 | s.add_dependency 'jquery-ui-rails' 36 | s.add_dependency 'select2-rails' 37 | s.add_dependency 'rails_autolink' 38 | s.add_dependency 'bootstrap-sass' 39 | s.add_dependency 'rails' 40 | s.add_dependency 'sass-rails' 41 | s.add_dependency 'simple_form' 42 | s.add_dependency 'state_machine' 43 | s.add_dependency 'globalize' 44 | s.add_dependency 'batch_translations' 45 | s.add_dependency 'ckeditor' 46 | s.add_dependency 'acts_as_ordered_tree' 47 | #s.add_dependency 'kaminari' 48 | end 49 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static asset server for tests with Cache-Control for performance. 16 | config.serve_static_files = true 17 | config.static_cache_control = "public, max-age=3600" 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Print deprecation notices to the stderr. 35 | config.active_support.deprecation = :stderr 36 | config.action_mailer.default_url_options = { :host => 'localhost:3000'} 37 | 38 | config.action_mailer.smtp_settings = { 39 | :address => '', 40 | :port => 465, 41 | :domain => '', 42 | :user_name => '', 43 | :password => '', 44 | :enable_starttls_auto => false, 45 | :openssl_verify_mode => 'none', 46 | :ssl => true } 47 | end 48 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/admin/tickets_controller.rb: -------------------------------------------------------------------------------- 1 | class Helpdesk::Admin::TicketsController < Helpdesk::Admin::BaseController 2 | 3 | def index 4 | case params[:tickets] 5 | when 'unassigned' 6 | @tickets = Helpdesk::Ticket.unassigned 7 | when'closed' 8 | @tickets = Helpdesk::Ticket.closed 9 | when 'active' 10 | @tickets = Helpdesk::Ticket.active 11 | when 'all' 12 | @tickets = Helpdesk::Ticket 13 | else 14 | @tickets = my_tickets.active 15 | end 16 | @tickets = @tickets.includes(:requester) 17 | .includes(:assignee) 18 | .includes(:ticket_type) 19 | .page(params[:page]) 20 | 21 | render 'list' 22 | end 23 | 24 | def assign 25 | @ticket = Helpdesk::Ticket.find(params[:id]) 26 | if @ticket.update_column(:assignee_id, helpdesk_user) 27 | redirect_to admin_ticket_path, 28 | notice: t('helpdesk.tickets.is_now_assigned',subject: @ticket.subject) 29 | else 30 | redirect_to admin_ticket_path 31 | end 32 | end 33 | 34 | def new 35 | @ticket = Helpdesk::Ticket.new 36 | @ticket.status = Helpdesk::Ticket::STATUSES[0][0] 37 | end 38 | 39 | def edit 40 | @ticket = Helpdesk::Ticket.find(params[:id]) 41 | 42 | end 43 | 44 | def show 45 | @ticket = Helpdesk::Ticket.find(params[:id]) 46 | 47 | end 48 | 49 | def create 50 | @ticket = Helpdesk::Ticket.new(ticket_params) 51 | if @ticket.save 52 | redirect_to admin_ticket_path(@ticket) 53 | else 54 | render action: "new" 55 | end 56 | end 57 | 58 | def update 59 | @ticket = Helpdesk::Ticket.find(params[:id]) 60 | if @ticket.update_attributes(ticket_params) 61 | unless @ticket.assignee 62 | @ticket.update_column(:assignee_id, helpdesk_user) 63 | end 64 | redirect_to admin_ticket_path 65 | else 66 | render action: "new" 67 | end 68 | end 69 | 70 | 71 | private 72 | 73 | def ticket_params 74 | params.require(:ticket).permit(:status,:requester_id,:assignee_id,:ticket_type_id, :subject, :description,comments_attributes:[:author_id, :comment, :public]) 75 | end 76 | 77 | end 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Helpdesk [![Code Climate](https://codeclimate.com/github/wacaw/helpdesk.png)](https://codeclimate.com/github/wacaw/helpdesk) [![Build Status](https://travis-ci.org/wacaw/helpdesk.svg?branch=master)](https://travis-ci.org/wacaw/helpdesk) [![Gem Version](https://badge.fury.io/rb/helpdesk.png)](http://badge.fury.io/rb/helpdesk) 2 | Helpdesk is a Rails engine that provides simple helpdesk functionality directly into your site. 3 | 4 | 5 | 6 | ## Demo 7 | 8 | [http://helpdesk-demo.herokuapp.com](http://helpdesk-demo.herokuapp.com) 9 | 10 | Source of demo: [https://github.com/wacaw/helpdesk-demo](https://github.com/wacaw/helpdesk-demo). 11 | 12 | ## Installation 13 | ### 1. Install helpdesk gem 14 | In your `Gemfile`, add the following dependencies: 15 | In Rails 3, add this to your Gemfile and run the +bundle+ command. 16 | 17 | ```ruby 18 | gem "helpdesk", '0.0.14' 19 | ``` 20 | 21 | In Rails 4.1, add this to your Gemfile and run the +bundle+ command. 22 | 23 | ```ruby 24 | gem "helpdesk", ">= 0.0.42" 25 | ``` 26 | ### 2. Run installation/or migration if updated 27 | 28 | ``` 29 | rails g helpdesk:install 30 | ``` 31 | 32 | for update only 33 | ``` 34 | rake helpdesk:install:migrations 35 | ``` 36 | 37 | That creates a Helpdesk initializer and copy locale files to your application. 38 | 39 | ### 3. Add 3 methods to your applications application_controller.rb 40 | * helpdesk_user - to exposes your current_user 41 | * helpdesk_admin? - to check privileges 42 | * helpdesk_admins_collection - to list all admin 43 | 44 | Example, for app with devise&rolify gems: 45 | ```ruby 46 | class ApplicationController < ActionController::Base 47 | [...] 48 | helper_method :helpdesk_user,:helpdesk_admin?,:helpdesk_admin_collection 49 | def helpdesk_user 50 | current_user 51 | end 52 | 53 | def helpdesk_admin? 54 | current_user.has_role? :admin 55 | end 56 | 57 | def helpdesk_admin_collection 58 | (Helpdesk.user_class).with_role(:admin) 59 | end 60 | end 61 | ``` 62 | 63 | ### 4. Restart app 64 | and visit [http://0.0.0.0:3000/helpdesk](http://localhost:3000/helpdesk) 65 | 66 | 67 | 68 | License 69 | ------- 70 | 71 | MIT 72 | 73 | -------------------------------------------------------------------------------- /app/views/layouts/helpdesk/_topuser.html.haml: -------------------------------------------------------------------------------- 1 | %nav.navbar.navbar-default#site_topmmenu{role: 'navigation'} 2 | .navbar-header 3 | %button.navbar-toggle{"data-target" => "#bs-navbar-collapse-1", "data-toggle" => "collapse", type: "button"} 4 | %span.sr-only Toggle navigation 5 | %span.icon-bar 6 | %span.icon-bar 7 | %span.icon-bar 8 | =link_to Helpdesk.site_address, main_app.root_path, :class=>'navbar-brand', :title => Helpdesk.site_address 9 | =link_to Helpdesk.helpdesk_name, root_path, :class=>'navbar-brand', :title => Helpdesk.helpdesk_name 10 | #bs-navbar-collapse-1.collapse.navbar-collapse.in 11 | %ul.nav.navbar-nav 12 | = menu_li t('helpdesk.tickets.title'),tickets_path if Helpdesk.menu_items.include?('tickets') 13 | = menu_li t('helpdesk.faqs.title'),faqs_path if Helpdesk.menu_items.include?('faqs') 14 | = menu_li t('helpdesk.subscribers.title'),subscribers_path if Helpdesk.menu_items.include?('subscribers') 15 | - if Helpdesk.menu_items.include?('search') 16 | %form.navbar-form.navbar-left{role:'search',action:search_faqs_url} 17 | .form-group 18 | %input.form-control{type:'text', placeholder:t('helpdesk.faqs.search_in_faqs'),name:'search',value:params[:search]} 19 | %button.btn.btn-default{type:"submit"} 20 | = t('helpdesk.faqs.search') 21 | 22 | %ul.nav.navbar-nav.navbar-right 23 | - if Helpdesk.menu_items.include?('user') 24 | - if helpdesk_user 25 | %li.dropdown.user 26 | = link_to helpdesk_user.send(Helpdesk.display_user.to_sym), "#",:class=>"dropdown-toggle",data:{toggle:"dropdown"} 27 | %ul.dropdown-menu 28 | %li=link_to 'Home',main_app.root_path 29 | %li=link_to t('users.sign_out'),main_app.destroy_user_session_path, :method => :delete, :class => 'icon exit blue' 30 | 31 | - if Helpdesk.menu_items.include?('language') 32 | %li.dropdown 33 | = link_to t('helpdesk.lang'),"#",:class=>"dropdown-toggle",data:{toggle:"dropdown"} 34 | %ul.dropdown-menu 35 | %li= link_to "English", params.merge({:locale => :en}) 36 | %li= link_to "Polski", params.merge({:locale => :pl}) 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /spec/dummy/config/routes.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.routes.draw do 2 | 3 | devise_for :users 4 | get '/users/sign_in', :to => "devise/sessions#new", :as => "sign_in" 5 | 6 | mount Helpdesk::Engine => '/support' #, :constraints => { :subdomain => 'support' } 7 | # The priority is based upon order of creation: 8 | root :to => "base#index" 9 | # first created -> highest priority. 10 | 11 | # Sample of regular route: 12 | # match 'products/:id' => 'catalog#view' 13 | # Keep in mind you can assign values other than :controller and :action 14 | 15 | # Sample of named route: 16 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase 17 | # This route can be invoked with purchase_url(:id => product.id) 18 | 19 | # Sample resource route (maps HTTP verbs to controller actions automatically): 20 | # resources :products 21 | 22 | # Sample resource route with options: 23 | # resources :products do 24 | # member do 25 | # get 'short' 26 | # post 'toggle' 27 | # end 28 | # 29 | # collection do 30 | # get 'sold' 31 | # end 32 | # end 33 | 34 | # Sample resource route with sub-resources: 35 | # resources :products do 36 | # resources :comments, :sales 37 | # resource :seller 38 | # end 39 | 40 | # Sample resource route with more complex sub-resources 41 | # resources :products do 42 | # resources :comments 43 | # resources :sales do 44 | # get 'recent', :on => :collection 45 | # end 46 | # end 47 | 48 | # Sample resource route within a namespace: 49 | # namespace :admin do 50 | # # Directs /admin/products/* to Admin::ProductsController 51 | # # (app/controllers/admin/products_controller.rb) 52 | # resources :products 53 | # end 54 | 55 | # You can have the root of your site routed with "root" 56 | # just remember to delete public/index.html. 57 | # root :to => 'welcome#index' 58 | 59 | # See how all your routes lay out with "rake routes" 60 | 61 | # This is a legacy wild controller route that's not recommended for RESTful applications. 62 | # Note: This route will make all actions in every controller accessible via GET requests. 63 | # match ':controller(/:action(/:id))(.:format)' 64 | end 65 | -------------------------------------------------------------------------------- /app/views/helpdesk/tickets/_ticket.html.haml: -------------------------------------------------------------------------------- 1 | %table.table.table-bordered 2 | %tbody 3 | %tr{:class=>ticket.ticket_type_tr_class} 4 | %td{colspan:2} 5 | %h4 6 | ="##{ticket.subject}" 7 | %tr 8 | %td{style:'width:100px'} 9 | = I18n::l(ticket.created_at, :format=>:short) 10 | - if ticket.requester 11 | = ticket.requester.send Helpdesk.display_user.to_sym 12 | %td{rowspan:2} 13 | = status_label humanize_with_i18n(ticket.status,'helpdesk.tickets.statuses'), Helpdesk::Ticket::STATUS_CLASS_BY_KEY[ticket.status.to_sym] 14 | = ticket.ticket_type_title 15 | 16 | = auto_link(simple_format(ticket.description), :html => { :target => "_blank" }) 17 | %tr 18 | %td 19 | - if ticket.assignee 20 | = t('helpdesk.tickets.assignee_to') 21 | = ticket.assignee.send Helpdesk.display_user.to_sym 22 | %tr 23 | %td 24 | %span.btn.disabled 25 | = ico('comment') 26 | = ticket.comments.pub.size 27 | %td 28 | %ul.comments.unstyled 29 | - ticket.comments.pub.each do |comment| 30 | - if comment.persisted? 31 | %li.comment{:id=>"comment#{comment.id}"} 32 | %div.comment-left 33 | - if comment.public 34 | = status_label ico('envelope') + t('helpdesk.comments.send') ,'label-success' 35 | - else 36 | = status_label t('helpdesk.comments.note'),'' 37 | %br 38 | %a{class:'anchor', href: "#comment#{comment.id}"} 39 | = "#" 40 | %div.comment-header 41 | -if comment.author != ticket.requester 42 | = status_label ico('user')+ t('helpdesk.comments.helpdesk'),'label-info' 43 | 44 | = comment.author.send Helpdesk.display_user.to_sym 45 | %small 46 | = time_ago_in_words(comment.created_at) 47 | temu 48 | %div.comment-body 49 | = auto_link(simple_format(comment.comment), :html => { :target => "_blank" }) 50 | 51 | %tr{:class=>ticket.ticket_type_tr_class} 52 | %td{colspan:2} 53 | - if show_button 54 | = link_to ticket.subject, ticket_url(I18n.locale,ticket), class: 'btn btn-block' 55 | -------------------------------------------------------------------------------- /app/views/helpdesk/admin/tickets/_ticket.html.haml: -------------------------------------------------------------------------------- 1 | %table.table.table-bordered 2 | %tbody 3 | %tr{:class=>ticket.ticket_type_tr_class} 4 | %td{colspan:2} 5 | %h4 6 | ="##{ticket.subject}" 7 | %tr 8 | %td{style:'width:100px'} 9 | = I18n::l(ticket.created_at, :format=>:short) 10 | - if ticket.requester 11 | = ticket.requester.send Helpdesk.display_user_uniq_info.to_sym 12 | %td{rowspan:2} 13 | = status_label humanize_with_i18n(ticket.status,'helpdesk.tickets.statuses'), Helpdesk::Ticket::STATUS_CLASS_BY_KEY[ticket.status.to_sym] 14 | 15 | = ticket.ticket_type_title 16 | = auto_link(simple_format(ticket.description), :html => { :target => "_blank" }) 17 | %tr 18 | %td 19 | - if ticket.assignee 20 | = t('helpdesk.tickets.assignee_to') 21 | = ticket.assignee.send Helpdesk.display_user_uniq_info.to_sym 22 | - else 23 | = t('helpdesk.tickets.not_assigned') 24 | = link_to ico('star') + t('helpdesk.tickets.assign_me'), assign_admin_ticket_path(ticket),class: 'btn btn-mini btn-info' 25 | %tr 26 | %td 27 | %span.btn.disabled 28 | = ico('comment') 29 | = ticket.comments.size 30 | %td 31 | %ul.comments.unstyled 32 | - ticket.comments.each do |comment| 33 | - if comment.persisted? 34 | %li.comment{:id=>"comment#{comment.id}"} 35 | %div.comment-left 36 | - if comment.public 37 | = status_label ico('envelope') + t('helpdesk.comments.send') ,'label-success' 38 | - else 39 | = status_label t('helpdesk.comments.note'),'' 40 | %br 41 | %a{class:'anchor', href: "#comment#{comment.id}"} 42 | = "#" 43 | %div.comment-header 44 | -if comment.author == ticket.requester 45 | = status_label ico('user')+ t('helpdesk.comments.author'),'label-info' 46 | = comment.author.send Helpdesk.display_user_uniq_info.to_sym if comment.author 47 | %small 48 | = time_ago_in_words(comment.created_at) 49 | temu 50 | %div.comment-body 51 | = auto_link(simple_format(comment.comment), :html => { :target => "_blank" }) 52 | 53 | %tr{:class=>ticket.ticket_type_tr_class} 54 | %td{colspan:2} 55 | - if show_button 56 | = link_to 'Show', admin_ticket_url(ticket), class: 'btn btn-block' 57 | -elsif edit_button 58 | = link_to 'Edit', edit_admin_ticket_url(ticket), class: 'btn btn-primary' 59 | 60 | -------------------------------------------------------------------------------- /spec/dummy/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | Bundler.require 6 | require "helpdesk" 7 | require 'devise' 8 | require 'kaminari' 9 | require 'haml-rails' 10 | require 'jquery-ui-rails' 11 | 12 | 13 | module Dummy 14 | class Application < Rails::Application 15 | # Settings in config/environments/* take precedence over those specified here. 16 | # Application configuration should go into files in config/initializers 17 | # -- all .rb files in that directory are automatically loaded. 18 | 19 | # Custom directories with classes and modules you want to be autoloadable. 20 | # config.autoload_paths += %W(#{config.root}/extras) 21 | 22 | # Only load the plugins named here, in the order given (default is alphabetical). 23 | # :all can be used as a placeholder for all plugins not explicitly named. 24 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 25 | 26 | # Activate observers that should always be running. 27 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 28 | 29 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 30 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 31 | # config.time_zone = 'Central Time (US & Canada)' 32 | 33 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 34 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 35 | # config.i18n.default_locale = :de 36 | 37 | # Configure the default encoding used in templates for Ruby 1.9. 38 | config.encoding = "utf-8" 39 | 40 | # Configure sensitive parameters which will be filtered from the log file. 41 | config.filter_parameters += [:password] 42 | 43 | # Use SQL instead of Active Record's schema dumper when creating the database. 44 | # This is necessary if your schema can't be completely dumped by the schema dumper, 45 | # like if you have constraints or database-specific column types 46 | # config.active_record.schema_format = :sql 47 | 48 | # Enforce whitelist mode for mass assignment. 49 | # This will create an empty whitelist of attributes available for mass-assignment for all models 50 | # in your app. As such, your models will need to explicitly whitelist or blacklist accessible 51 | # parameters by using an attr_accessible or attr_protected declaration. 52 | 53 | # Enable the asset pipeline 54 | config.assets.enabled = true 55 | 56 | # Version of your assets, change this if you want to expire all your assets 57 | config.assets.version = '1.0' 58 | end 59 | end 60 | 61 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_files = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # Don't fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = false 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to Rails.root.join("public/assets") 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Prepend all log lines with the following tags 37 | # config.log_tags = [ :subdomain, :uuid ] 38 | 39 | # Use a different logger for distributed setups 40 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 41 | 42 | # Use a different cache store in production 43 | # config.cache_store = :mem_cache_store 44 | 45 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 46 | # config.action_controller.asset_host = "http://assets.example.com" 47 | 48 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 49 | # config.assets.precompile += %w( search.js ) 50 | 51 | # Disable delivery errors, bad email addresses will be ignored 52 | # config.action_mailer.raise_delivery_errors = false 53 | 54 | # Enable threaded mode 55 | # config.threadsafe! 56 | 57 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 58 | # the I18n.default_locale when a translation can not be found) 59 | config.i18n.fallbacks = true 60 | 61 | # Send deprecation notices to registered listeners 62 | config.active_support.deprecation = :notify 63 | 64 | # Log the query plan for queries taking more than this (works 65 | # with SQLite, MySQL, and PostgreSQL) 66 | # config.active_record.auto_explain_threshold_in_seconds = 0.5 67 | end 68 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/tickets_controller.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class TicketsController < Helpdesk::ApplicationController 3 | 4 | before_filter :ensure_user 5 | helper TicketsHelper 6 | 7 | # GET /tickets 8 | # GET /tickets.json 9 | def index 10 | if params[:tickets] == 'closed' 11 | @tickets = Helpdesk::Ticket.where(:requester_id => helpdesk_user.id).closed.page(params[:page]) 12 | else 13 | @tickets = Helpdesk::Ticket.where(:requester_id => helpdesk_user.id).active.page(params[:page]) 14 | end 15 | 16 | 17 | respond_to do |format| 18 | format.html # index.html.erb 19 | format.json { render json: @tickets } 20 | end 21 | end 22 | 23 | # GET /tickets/1 24 | # GET /tickets/1.json 25 | def show 26 | @tickets_count = Helpdesk::Ticket.where(:requester_id => helpdesk_user.id).active.count 27 | @ticket = Helpdesk::Ticket.find(params[:id]) 28 | 29 | respond_to do |format| 30 | format.html # show.html.erb 31 | format.json { render json: @ticket } 32 | end 33 | end 34 | 35 | # GET /tickets/new 36 | # GET /tickets/new.json 37 | def new 38 | @tickets_count = Helpdesk::Ticket.where(:requester_id => helpdesk_user.id).active.count 39 | @ticket = Helpdesk::Ticket.new 40 | @ticket.status = Helpdesk::Ticket::STATUSES[0][0] 41 | 42 | respond_to do |format| 43 | format.html # new.html.erb 44 | format.json { render json: @ticket } 45 | end 46 | end 47 | 48 | def create 49 | @ticket = Helpdesk::Ticket.new(ticket_params) 50 | @ticket.requester = helpdesk_user 51 | @ticket.status = Helpdesk::Ticket::STATUSES[0][0] 52 | 53 | respond_to do |format| 54 | if @ticket.save 55 | format.html { redirect_to tickets_url, notice: 'Ticket was successfully created.' } 56 | format.json { render json: @ticket, status: :created, location: @ticket } 57 | else 58 | format.html { render action: "new" } 59 | format.json { render json: @ticket.errors, status: :unprocessable_entity } 60 | end 61 | end 62 | end 63 | 64 | # PUT /tickets/1 65 | # PUT /tickets/1.json 66 | def update 67 | @ticket = Helpdesk::Ticket.find(params[:id]) 68 | 69 | respond_to do |format| 70 | if @ticket.update_attributes(ticket_params) 71 | format.html { redirect_to @ticket, notice: 'Ticket was successfully updated.'} 72 | format.json { head :no_content } 73 | else 74 | format.html { render action: "edit" } 75 | format.json { render json: @ticket.errors, status: :unprocessable_entity } 76 | end 77 | end 78 | end 79 | 80 | 81 | private 82 | 83 | def ticket_params 84 | params.require(:ticket).permit( :ticket_type_id, :subject, :description,comments_attributes:[:author_id, :comment, :public]) 85 | end 86 | 87 | end 88 | end 89 | -------------------------------------------------------------------------------- /app/models/helpdesk/ticket.rb: -------------------------------------------------------------------------------- 1 | module Helpdesk 2 | class Ticket < ActiveRecord::Base 3 | 4 | 5 | STATUSES = [ 6 | [ :new, 'label-primary',3], 7 | [ :open, 'label-warning',2], 8 | [ :waiting, 'label-info',2], 9 | [ :solved, 'label-success',0], 10 | [ :not_fixable, 'label-default',-1], 11 | [ :unreachable, 'label-default',-1], 12 | [ :bug, 'label-default',-1] 13 | ] 14 | STATUS_BY_KEY = Hash[*STATUSES.map { |i| [i[0], i[1]] }.flatten] 15 | STATUS_CLASS_BY_KEY= Hash[*STATUSES.map { |i| [i[0], i[1]] }.flatten] 16 | STATUS_STATUS_BY_KEY= Hash[*STATUSES.map { |i| [i[0], i[2]] }.flatten] 17 | OPEN_STATUSES_KEYS = STATUSES.map { |i| (i[2]>0 ? i[0] : nil)}.compact 18 | 19 | 20 | belongs_to :requester, :class_name => Helpdesk.user_class.to_s 21 | belongs_to :assignee, :class_name => Helpdesk.user_class.to_s 22 | belongs_to :ticket_type, :class_name => Helpdesk::TicketType 23 | has_many :comments, -> {order("created_at DESC")},:dependent => :destroy 24 | 25 | 26 | scope :active, -> {where('status IN (?) ',OPEN_STATUSES_KEYS)} 27 | scope :unassigned, -> {where('status IN (?) ',OPEN_STATUSES_KEYS).where('assignee_id is null')} 28 | scope :closed, -> { where('status NOT IN (?)',OPEN_STATUSES_KEYS)} 29 | default_scope -> { includes(:comments=>[:author]) 30 | .includes(:requester) 31 | .includes(:assignee) 32 | .includes(:ticket_type) 33 | .order('id DESC')} 34 | 35 | validates_presence_of :description,:requester,:ticket_type_id 36 | 37 | accepts_nested_attributes_for :comments,:reject_if => lambda { |a| a[:comment].blank? } 38 | 39 | 40 | before_create :set_subject 41 | before_create :set_status 42 | after_create :send_email 43 | 44 | def ticket_type_tr_class 45 | ticket_type.tr_class rescue '' 46 | end 47 | 48 | def ticket_type_title 49 | ticket_type.title rescue '' 50 | end 51 | 52 | def set_status 53 | if self.status.blank? 54 | self.status = :new 55 | end 56 | end 57 | 58 | def set_subject 59 | if self.created_at.nil? 60 | time = Time.now 61 | else 62 | time = self.created_at 63 | end 64 | 65 | new_subject = "#{sprintf '%02d',time.year-2000}#{sprintf '%02d',time.month}#{sprintf '%02d',time.day}" 66 | 67 | day_num = Helpdesk::Ticket.where(created_at: Date.today.beginning_of_day..Date.today.end_of_day).count+1 68 | new_subject += "-#{sprintf '%04d',day_num}: " 69 | self.subject = new_subject + subject.to_s 70 | self.subject.strip! 71 | end 72 | 73 | def send_email 74 | Helpdesk::NotificationsMailer.ticket_created_notification(self).deliver_now 75 | unless requester.email.empty? 76 | Helpdesk::NotificationsMailer.ticket_created_confirmation(self).deliver_now if Helpdesk.send_confirmation_emails 77 | end 78 | end 79 | 80 | def open? 81 | if self.status.blank? || STATUS_STATUS_BY_KEY[self.status.to_sym] > 0 82 | true 83 | else 84 | false 85 | end 86 | end 87 | 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /app/controllers/helpdesk/admin/faqs_controller.rb: -------------------------------------------------------------------------------- 1 | class Helpdesk::Admin::FaqsController < Helpdesk::Admin::BaseController 2 | 3 | def sort 4 | params[:faqs].each_with_index do |id, index| 5 | Helpdesk::Faq.find(id).update_column(:position, index+1) 6 | end 7 | render :nothing => true 8 | end 9 | 10 | def sorting 11 | if params[:id]=='all' 12 | 13 | @faqs = Helpdesk::Faq.roots 14 | else 15 | @faq = Helpdesk::Faq.find(params[:id]) 16 | @faqs = @faq.children 17 | end 18 | end 19 | 20 | # GET /faqs 21 | # GET /faqs.json 22 | def index 23 | if params[:faqs] == 'active' 24 | @faqs = Helpdesk::Faq.roots.active 25 | render action: 'index' 26 | elsif params[:faqs] == 'inactive' 27 | @faqs = Helpdesk::Faq.inactive 28 | render action: 'inactive' 29 | else 30 | @faqs = Helpdesk::Faq.roots 31 | render action: 'index' 32 | end 33 | end 34 | 35 | # GET /faqs/1 36 | # GET /faqs/1.json 37 | def show 38 | @faq = Helpdesk::Faq.find(params[:id]) 39 | 40 | respond_to do |format| 41 | format.html # show.html.erb 42 | format.json { render json: @faq } 43 | end 44 | end 45 | 46 | # GET /faqs/new 47 | # GET /faqs/new.json 48 | def new 49 | @faq = Helpdesk::Faq.active.new 50 | if params[:faq] && params[:faq][:parent_id] 51 | @faq.parent_id = params[:faq][:parent_id] 52 | end 53 | 54 | respond_to do |format| 55 | format.html # new.html.erb 56 | format.json { render json: @faq } 57 | end 58 | end 59 | 60 | # GET /faqs/1/edit 61 | def edit 62 | @faq = Helpdesk::Faq.find(params[:id]) 63 | end 64 | 65 | # POST /faqs 66 | # POST /faqs.json 67 | def create 68 | @faq = Helpdesk::Faq.new(faq_params) 69 | 70 | respond_to do |format| 71 | if @faq.save 72 | format.html { redirect_to admin_faqs_url, notice: 'Faq was successfully created.' } 73 | format.json { render json: @faq, status: :created, location: @faq } 74 | else 75 | format.html { render action: "new" } 76 | format.json { render json: @faq.errors, status: :unprocessable_entity } 77 | end 78 | end 79 | end 80 | 81 | # PUT /faqs/1 82 | # PUT /faqs/1.json 83 | def update 84 | @faq = Helpdesk::Faq.find(params[:id]) 85 | 86 | respond_to do |format| 87 | if @faq.update_attributes(faq_params) 88 | format.html { redirect_to admin_faqs_url, notice: 'Faq was successfully updated.' } 89 | format.json { head :no_content } 90 | else 91 | format.html { render action: "edit" } 92 | format.json { render json: @faq.errors, status: :unprocessable_entity } 93 | end 94 | end 95 | end 96 | 97 | # DELETE /faqs/1 98 | # DELETE /faqs/1.json 99 | def destroy 100 | @faq = Helpdesk::Faq.find(params[:id]) 101 | @faq.destroy 102 | 103 | respond_to do |format| 104 | format.html { redirect_to admin_faqs_url } 105 | format.json { head :no_content } 106 | end 107 | end 108 | 109 | private 110 | def faq_params 111 | params.require(:faq).permit(:active, :position, :title, :text,:parent_id, translations_attributes:[:id,:locale,:title,:text]) 112 | end 113 | end 114 | -------------------------------------------------------------------------------- /app/assets/javascripts/helpdesk/ckeditor.js: -------------------------------------------------------------------------------- 1 | 2 | CKEDITOR.config.toolbar = [ 3 | { name: 'document', groups: [ 'mode', 'document', 'doctools' ], items: [ 'Source', '-', 'Save', 'NewPage', 'Preview', 'Print', '-', 'Templates' ] }, 4 | { name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] }, 5 | { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ], items: [ 'Find', 'Replace', '-', 'SelectAll', '-', 'Scayt' ] }, 6 | { name: 'forms', items: [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] }, 7 | '/', 8 | { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] }, 9 | { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl', 'Language' ] }, 10 | { name: 'links', items: [ 'Link', 'Unlink', 'Anchor' ] }, 11 | { name: 'insert', items: [ 'Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak', 'Iframe' ] }, 12 | '/', 13 | { name: 'styles', items: [ 'Format', 'Font', 'FontSize' ] }, 14 | { name: 'colors', items: [ 'TextColor'] }, 15 | { name: 'tools', items: [ 'Maximize', 'ShowBlocks' ] }, 16 | { name: 'others', items: [ '-' ] }, 17 | { name: 'about', items: [ 'About' ] } 18 | ]; 19 | 20 | CKEDITOR.config.allowedContent = true; 21 | CKEDITOR.config.contentsCss = '/assets/helpdesk/application.css'; 22 | /* Filebrowser routes */ 23 | // The location of an external file browser, that should be launched when "Browse Server" button is pressed. 24 | CKEDITOR.config.filebrowserBrowseUrl = "/ckeditor/attachment_files"; 25 | 26 | // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog. 27 | CKEDITOR.config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files"; 28 | 29 | // The location of a script that handles file uploads in the Flash dialog. 30 | CKEDITOR.config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files"; 31 | 32 | // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog 33 | CKEDITOR.config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures"; 34 | 35 | // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog. 36 | CKEDITOR.config.filebrowserImageBrowseUrl = "/ckeditor/pictures"; 37 | 38 | // The location of a script that handles file uploads in the Image dialog. 39 | CKEDITOR.config.filebrowserImageUploadUrl = "/ckeditor/pictures"; 40 | 41 | // The location of a script that handles file uploads. 42 | CKEDITOR.config.filebrowserUploadUrl = "/ckeditor/attachment_files"; 43 | 44 | CKEDITOR.config.toolbarGroups = [ 45 | { name: 'document', groups: [ 'mode', 'document', 'doctools' ] }, 46 | { name: 'clipboard', groups: [ 'clipboard', 'undo' ] }, 47 | //{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] }, 48 | { name: 'tools' }, 49 | { name: 'about' }, 50 | '/', 51 | { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }, 52 | { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align' ] }, // , 'bidi' 53 | //{ name: 'forms' }, 54 | '/', 55 | { name: 'styles' }, 56 | { name: 'colors' }, 57 | { name: 'links' }, 58 | { name: 'insert' }, 59 | { name: 'others' } 60 | ]; 61 | 62 | -------------------------------------------------------------------------------- /spec/dummy/config/locales/devise.en.yml: -------------------------------------------------------------------------------- 1 | # Additional translations at https://github.com/plataformatec/devise/wiki/I18n 2 | 3 | en: 4 | errors: 5 | messages: 6 | expired: "has expired, please request a new one" 7 | not_found: "not found" 8 | already_confirmed: "was already confirmed, please try signing in" 9 | not_locked: "was not locked" 10 | not_saved: 11 | one: "1 error prohibited this %{resource} from being saved:" 12 | other: "%{count} errors prohibited this %{resource} from being saved:" 13 | 14 | devise: 15 | failure: 16 | already_authenticated: 'You are already signed in.' 17 | unauthenticated: 'You need to sign in or sign up before continuing.' 18 | unconfirmed: 'You have to confirm your account before continuing.' 19 | locked: 'Your account is locked.' 20 | invalid: 'Invalid email or password.' 21 | invalid_token: 'Invalid authentication token.' 22 | timeout: 'Your session expired, please sign in again to continue.' 23 | inactive: 'Your account was not activated yet.' 24 | sessions: 25 | signed_in: 'Signed in successfully.' 26 | signed_out: 'Signed out successfully.' 27 | passwords: 28 | send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.' 29 | updated: 'Your password was changed successfully. You are now signed in.' 30 | updated_not_active: 'Your password was changed successfully.' 31 | send_paranoid_instructions: "If your e-mail exists on our database, you will receive a password recovery link on your e-mail" 32 | confirmations: 33 | send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.' 34 | send_paranoid_instructions: 'If your e-mail exists on our database, you will receive an email with instructions about how to confirm your account in a few minutes.' 35 | confirmed: 'Your account was successfully confirmed. You are now signed in.' 36 | registrations: 37 | signed_up: 'Welcome! You have signed up successfully.' 38 | signed_up_but_unconfirmed: 'A message with a confirmation link has been sent to your email address. Please open the link to activate your account.' 39 | signed_up_but_inactive: 'You have signed up successfully. However, we could not sign you in because your account is not yet activated.' 40 | signed_up_but_locked: 'You have signed up successfully. However, we could not sign you in because your account is locked.' 41 | updated: 'You updated your account successfully.' 42 | update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address." 43 | destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.' 44 | unlocks: 45 | send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.' 46 | unlocked: 'Your account has been unlocked successfully. Please sign in to continue.' 47 | send_paranoid_instructions: 'If your account exists, you will receive an email with instructions about how to unlock it in a few minutes.' 48 | omniauth_callbacks: 49 | success: 'Successfully authorized from %{kind} account.' 50 | failure: 'Could not authorize you from %{kind} because "%{reason}".' 51 | mailer: 52 | confirmation_instructions: 53 | subject: 'Confirmation instructions' 54 | reset_password_instructions: 55 | subject: 'Reset password instructions' 56 | unlock_instructions: 57 | subject: 'Unlock Instructions' 58 | -------------------------------------------------------------------------------- /spec/dummy/config/locales/helpdesk.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | 3 | helpdesk: 4 | lang: Language 5 | Show: Show 6 | edit: Edit 7 | Destroy: Delete 8 | name: Helpdesk 9 | new_ticket: New 10 | tickets: 11 | new: New Issue 12 | my: My Issue 13 | unassigned: Unassigned 14 | closed: Closed Issues 15 | all: All issues 16 | title: Issues 17 | active: Active Issues 18 | assignee_to: Assigned to 19 | assign_me: I take it 20 | not_assigned: Not assigned 21 | is_now_assigned: "Issue %{subject} has been assigned to you" 22 | visible_to_autor: Visible to the author - send an email 23 | you_have_no_tickets: "No issues " 24 | ticket_closed: Issues closed 25 | subject: Subject of 26 | description: Content 27 | cancel: cancel 28 | send: Send 29 | ticket: Issue 30 | faq: FAQ 31 | comments: 32 | title: Comments 33 | note: Memo 34 | send: Sent 35 | received: Received 36 | note: note 37 | author: Re. author 38 | helpdesk: Re. BOK 39 | ticket_types: 40 | title: Types of issues 41 | new: A new type of issues 42 | all: All kinds of issues 43 | active: Active types of issues 44 | inactive: Inactive types of issues 45 | 46 | dashboard: Dashboard 47 | 48 | subscribers: 49 | title: Subscribers 50 | confirmed: Confirmed subskrybenci 51 | unconfirmed: Unconfirmed 52 | all: All Subscribers 53 | new: Add Subscriber 54 | 55 | faqs: 56 | title: FAQ 57 | title_s: Frequently Asked Questions 58 | active: Active Questions 59 | inactive: Inactive questions 60 | all: All the questions 61 | new: New Question 62 | by: by 63 | faq: 64 | active: active 65 | inactive: inactive 66 | 67 | mailer: 68 | comment_by_helpdesk_confirmation: 69 | title: "Response to the issue was sent" 70 | re_ticket: "New comment for Issue:" 71 | response_content: "Content of the comment:" 72 | comment_by_helpdesk_notification: 73 | title: "%{user}, new reply received for issue:" 74 | comment_content: "Content of the comment:" 75 | comment_by_requester_notification: 76 | title: "New reply received for issue:" 77 | comment_content: "Content of the comment:" 78 | comment_by_requester_confirmation: 79 | title: "%{user}, thank you for submitting a comment to the Issue" 80 | subject: "New comment for Issie - %{subject}" 81 | comment_content: "Content of the comment:" 82 | ticket_created_confirmation: 83 | title: "%{user}, thank you for submitting" 84 | subject: "Your issue subject is:" 85 | ticket_content: "Content of the issue:" 86 | info_time: "We appreciate your time, so we will try to respond as quickly as possible." 87 | ticket_created_notification: 88 | title: "New Issue was created" 89 | requester_info: "Author" 90 | ticket_content: "The content of the issue:" 91 | ticket_url_title: "At this address you can track the issue:" 92 | footer_info: "This message has been generated automatically. Do not answer it. If you do not have initiated action to send this message please report it to us clicking here ." 93 | footer_nice: "Have a nice day" 94 | 95 | activerecord: 96 | models: 97 | Helpdesk: helpdesk 98 | helpdesk/ticket: Issue 99 | helpdesk/comment: Comment 100 | attributes: 101 | helpdesk/comment: 102 | comment: Additional description 103 | public: Visible/Send Email 104 | helpdesk/ticket: 105 | requester_id: Requester 106 | subject: Subject 107 | Status: Status 108 | assignee_id: Assigned 109 | ticket_type_id: Type of notification 110 | Description: Description 111 | comments: More details 112 | -------------------------------------------------------------------------------- /config/locales/helpdesk.pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | 3 | helpdesk: 4 | lang: Idioma 5 | Show: Detalhes 6 | edit: Editar 7 | Destroy: Deletar 8 | name: Helpdesk 9 | new_ticket: Novo 10 | tickets: 11 | new: Novo Chamado 12 | my: Meu Chamado 13 | unassigned: Não atribuido 14 | closed: Chamados finalizados 15 | all: Todos chamados 16 | title: Chamados 17 | active: Chamados ativos 18 | assignee_to: Atribuido para 19 | assign_me: Eu faço isso 20 | not_assigned: Não atribuido 21 | is_now_assigned: "Chamado %{subject} foi atribuido a você com sucesso" 22 | visible_to_autor: Visivel para o autor - enviar um e-mail 23 | you_have_no_tickets: "Sem chamados " 24 | ticket_closed: Chamados finalizados 25 | subject: Assunto 26 | description: Conteúdo 27 | cancel: cancelar 28 | send: Enviar 29 | ticket: Chamado 30 | faq: FAQ 31 | comments: 32 | title: Comentários 33 | note: Nota 34 | send: Enviado 35 | received: Recebido 36 | note: note 37 | author: Re. autor 38 | helpdesk: Re. 39 | ticket_types: 40 | title: Tipos de chamados 41 | new: Um novo tipo de chamado 42 | all: Todos tipos de chamados 43 | active: Tipos ativos de chamados 44 | inactive: Tipos inativos de chamados 45 | 46 | dashboard: Dashboard 47 | 48 | subscribers: 49 | title: Inscritos 50 | confirmed: Inscrição confirmada 51 | unconfirmed: Sem confirmação 52 | all: Todos inscritos 53 | new: Adcionar inscrito 54 | 55 | faqs: 56 | title: FAQ 57 | active: Questões Ativas 58 | inactive: Questões Inativas 59 | all: Todas as questões 60 | new: Nova questão 61 | by: para 62 | faq: 63 | active: ativo 64 | inactive: inativo 65 | 66 | mailer: 67 | comment_by_helpdesk_confirmation: 68 | title: "Resposta para o chamado foi enviado" 69 | re_ticket: "Novo comentário no chamado:" 70 | response_content: "Conteúdo do comentário:" 71 | comment_by_helpdesk_notification: 72 | title: "%{user}, nova resposta recebida para o chamado:" 73 | comment_content: "Conteúdo do comentário:" 74 | comment_by_requester_notification: 75 | title: "Nova resposta recebida para o chamado:" 76 | comment_content: "Conteúdo do comentário:" 77 | comment_by_requester_confirmation: 78 | title: "%{user}, obrigado por enviar um comentário para o chamado" 79 | subject: "Novo comentário para o chamado - %{subject}" 80 | comment_content: "Conteúdo do comentário:" 81 | ticket_created_confirmation: 82 | title: "%{user}, obrigado por enviar" 83 | subject: "O assunto do seu chamado é:" 84 | ticket_content: "Conteúdo do chamado:" 85 | info_time: "Obrigado pela solicitação, nós responderemos o mais breve possível." 86 | ticket_created_notification: 87 | title: "Novo chamado criado" 88 | requester_info: "Autor" 89 | ticket_content: "O conteúdo do chamado:" 90 | ticket_url_title: "Segue link para verificar o andamento do seu chamado:" 91 | footer_info: "Esta mensagem foi gerada automaticamente. Não responsa isso. Se você não iniciou uma solicitação de chamado, reporte a nós clicando aqui ." 92 | footer_nice: "Tenha um bom dia" 93 | 94 | activerecord: 95 | models: 96 | Helpdesk: helpdesk 97 | helpdesk/ticket: Chamado 98 | helpdesk/comment: Comentário 99 | attributes: 100 | helpdesk/comment: 101 | comment: Descrição adcional 102 | public: Visivel/Enviar e-mail 103 | helpdesk/ticket: 104 | requester_id: Solicitante 105 | subject: Assunto 106 | Status: Status 107 | assignee_id: Atribuído 108 | ticket_type_id: Tipo da notificação 109 | Description: Descrição 110 | comments: Mais detalhes 111 | -------------------------------------------------------------------------------- /spec/dummy/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 20140326084239) do 15 | 16 | create_table "helpdesk_comments", force: true do |t| 17 | t.integer "ticket_id" 18 | t.text "comment" 19 | t.integer "author_id" 20 | t.boolean "public" 21 | t.datetime "created_at" 22 | t.datetime "updated_at" 23 | end 24 | 25 | create_table "helpdesk_faq_translations", force: true do |t| 26 | t.integer "helpdesk_faq_id", null: false 27 | t.string "locale", null: false 28 | t.datetime "created_at" 29 | t.datetime "updated_at" 30 | t.string "title" 31 | t.text "text" 32 | end 33 | 34 | add_index "helpdesk_faq_translations", ["helpdesk_faq_id"], name: "index_helpdesk_faq_translations_on_helpdesk_faq_id" 35 | add_index "helpdesk_faq_translations", ["locale"], name: "index_helpdesk_faq_translations_on_locale" 36 | 37 | create_table "helpdesk_faqs", force: true do |t| 38 | t.integer "position" 39 | t.boolean "active", default: false, null: false 40 | t.datetime "created_at" 41 | t.datetime "updated_at" 42 | end 43 | 44 | create_table "helpdesk_subscribers", force: true do |t| 45 | t.string "name" 46 | t.string "email" 47 | t.string "lang" 48 | t.string "hashcode" 49 | t.boolean "confirmed", default: false, null: false 50 | t.datetime "created_at" 51 | t.datetime "updated_at" 52 | end 53 | 54 | create_table "helpdesk_ticket_type_translations", force: true do |t| 55 | t.integer "helpdesk_ticket_type_id", null: false 56 | t.string "locale", null: false 57 | t.datetime "created_at" 58 | t.datetime "updated_at" 59 | t.string "title" 60 | end 61 | 62 | add_index "helpdesk_ticket_type_translations", ["helpdesk_ticket_type_id"], name: "index_554cec9438d399db021564d4a79520a28d0749cc" 63 | add_index "helpdesk_ticket_type_translations", ["locale"], name: "index_helpdesk_ticket_type_translations_on_locale" 64 | 65 | create_table "helpdesk_ticket_types", force: true do |t| 66 | t.integer "position" 67 | t.boolean "active", default: true, null: false 68 | t.string "tr_class" 69 | t.datetime "created_at" 70 | t.datetime "updated_at" 71 | end 72 | 73 | create_table "helpdesk_tickets", force: true do |t| 74 | t.string "subject" 75 | t.text "description" 76 | t.integer "requester_id" 77 | t.integer "assignee_id" 78 | t.string "status" 79 | t.integer "ticket_type_id" 80 | t.datetime "created_at" 81 | t.datetime "updated_at" 82 | end 83 | 84 | create_table "users", force: true do |t| 85 | t.string "email", default: "", null: false 86 | t.string "encrypted_password", default: "", null: false 87 | t.string "reset_password_token" 88 | t.datetime "reset_password_sent_at" 89 | t.datetime "remember_created_at" 90 | t.integer "sign_in_count", default: 0 91 | t.datetime "current_sign_in_at" 92 | t.datetime "last_sign_in_at" 93 | t.string "current_sign_in_ip" 94 | t.string "last_sign_in_ip" 95 | t.datetime "created_at" 96 | t.datetime "updated_at" 97 | t.boolean "helpdesk_admin" 98 | end 99 | 100 | add_index "users", ["email"], name: "index_users_on_email", unique: true 101 | add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true 102 | 103 | end 104 | -------------------------------------------------------------------------------- /config/locales/helpdesk.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | 3 | helpdesk: 4 | lang: Language 5 | Show: Show 6 | edit: Edit 7 | Destroy: Delete 8 | name: Helpdesk 9 | new_ticket: New 10 | tickets: 11 | new: New Issue 12 | my: My Issue 13 | unassigned: Unassigned 14 | closed: Closed Issues 15 | all: All issues 16 | title: Issues 17 | active: Active Issues 18 | assignee_to: Assigned to 19 | assign_me: I take it 20 | not_assigned: Not assigned 21 | is_now_assigned: "Issue %{subject} has been assigned to you" 22 | visible_to_autor: Visible to the author - send an email 23 | you_have_no_tickets: "No issues " 24 | ticket_closed: Issues closed 25 | subject: Subject of 26 | description: Content 27 | cancel: cancel 28 | send: Send 29 | ticket: Issue 30 | faq: FAQ 31 | comments: 32 | title: Comments 33 | note: Memo 34 | send: Sent 35 | received: Received 36 | note: note 37 | author: Re. author 38 | helpdesk: Re. BOK 39 | ticket_types: 40 | title: Types of issues 41 | new: A new type of issues 42 | all: All kinds of issues 43 | active: Active types of issues 44 | inactive: Inactive types of issues 45 | 46 | dashboard: Dashboard 47 | 48 | subscribers: 49 | title: Subscribers 50 | confirmed: Confirmed Subscribers 51 | unconfirmed: Unconfirmed 52 | all: All Subscribers 53 | new: Add Subscriber 54 | 55 | faqs: 56 | sorting: Sorting 57 | search: Search 58 | search_in_faqs: Search in FAQs 59 | title: FAQ 60 | title_s: Frequently Asked Questions 61 | active: Active Questions 62 | inactive: Inactive questions 63 | all: All the questions 64 | new: New Question 65 | by: by 66 | faq: 67 | active: active 68 | inactive: inactive 69 | search_count: 70 | zero: 'We could not find anything matching your query: "%{query}"' 71 | one: 'Found one result matching your query: "%{query}"' 72 | other: 'Found %{count} results matching your query: "%{query}"' 73 | back_to_fasq: '« Back to FAQ list' 74 | 75 | mailer: 76 | comment_by_helpdesk_confirmation: 77 | title: "Response to the issue was sent" 78 | re_ticket: "New comment for Issue:" 79 | response_content: "Content of the comment:" 80 | comment_by_helpdesk_notification: 81 | title: "%{user}, new reply received for issue:" 82 | comment_content: "Content of the comment:" 83 | comment_by_requester_notification: 84 | title: "New reply received for issue:" 85 | comment_content: "Content of the comment:" 86 | comment_by_requester_confirmation: 87 | title: "%{user}, thank you for submitting a comment to the Issue" 88 | subject: "New comment for Issie - %{subject}" 89 | comment_content: "Content of the comment:" 90 | ticket_created_confirmation: 91 | title: "%{user}, thank you for submitting" 92 | subject: "Your issue subject is:" 93 | ticket_content: "Content of the issue:" 94 | info_time: "We appreciate your time, so we will try to respond as quickly as possible." 95 | ticket_created_notification: 96 | title: "New Issue was created" 97 | requester_info: "Author" 98 | ticket_content: "The content of the issue:" 99 | ticket_url_title: "At this address you can track the issue:" 100 | footer_info: "This message has been generated automatically. Do not answer it. If you do not have initiated action to send this message please report it to us clicking here ." 101 | footer_nice: "Have a nice day" 102 | 103 | activerecord: 104 | models: 105 | Helpdesk: helpdesk 106 | helpdesk/ticket: Issue 107 | helpdesk/comment: Comment 108 | attributes: 109 | helpdesk/comment: 110 | comment: Additional description 111 | public: Visible/Send Email 112 | helpdesk/ticket: 113 | requester_id: Requester 114 | subject: Subject 115 | Status: Status 116 | assignee_id: Assigned 117 | ticket_type_id: Type of notification 118 | Description: Description 119 | comments: More details 120 | -------------------------------------------------------------------------------- /spec/dummy/config/locales/helpdesk.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | 3 | helpdesk: 4 | lang: Język 5 | show: Pokaż 6 | edit: Edytuj 7 | destroy: Usuń 8 | name: Helpdesk 9 | new_ticket: Nowe zgłoszenie 10 | tickets: 11 | new: Nowe zgłoszenie 12 | my: Moje zgłoszenia 13 | unassigned: Nieprzypisane zgłoszenia 14 | closed: Zamknięte zgłoszenia 15 | all: Wszystkie zgłoszenia 16 | title: Zgłoszenia 17 | active: Aktywne zgłoszenia 18 | assignee_to: Przypisane do 19 | assign_me: Biore to 20 | not_assigned: Nie przypisany 21 | is_now_assigned: "Zgłoszenie %{subject} zostało przypisane do Ciebie" 22 | visible_to_autor: Widoczny dla zgłaszającego - wyślij emaila 23 | you_have_no_tickets: "Brak zgłoszeń" 24 | ticket_closed: Zgłoszenie zamknięte 25 | subject: Temat zgłoszenia 26 | description: Treść 27 | cancel: Anuluj 28 | send: Wyślij 29 | statuses: 30 | new: "Nowe" 31 | open: "Otwarte" 32 | waiting: "Otwarte: oczekujące" 33 | solved: "Zamknięte: problem rozwiązany" 34 | not_fixable: "Zamknięte: nienaprawialne" 35 | unreachable: "Zamknięte: klient nieosiągalny" 36 | bug: "Zamknięte: Przeniesione do bug tracker'a" 37 | 38 | ticket: Zgłoszenie 39 | faq: FAQ 40 | comments: 41 | title: Komentarze 42 | note: Notatka 43 | send: Wysłane 44 | received: Odebrane 45 | note: notatka 46 | author: Odp. autora 47 | helpdesk: Odp. BOK 48 | ticket_types: 49 | title: Rodzaje zgłoszeń 50 | new: Nowy rodzaj zgłoszenia 51 | all: Wszystkie rodzaje zgłoszeń 52 | active: Aktywne rodzaje zgłoszeń 53 | inactive: Nieaktywne rodzaje zgłoszeń 54 | 55 | dashboard: Dashboard 56 | 57 | subscribers: 58 | title: Subskrybenci 59 | confirmed: Potwierdzeni subskrynenci 60 | unconfirmed: Niepotwierdzeni 61 | all: Wszyscy subskrybenci 62 | new: Dodaj subskrybenta 63 | 64 | faqs: 65 | title: FAQ 66 | title_s: Często zadawane pytania 67 | active: Aktywne pytania 68 | inactive: Nieaktywne pytania 69 | all: Wszystkie pytania 70 | new: Nowe pytanie 71 | by: przez 72 | faq: 73 | active: aktywne 74 | inactive: nieaktywne 75 | 76 | mailer: 77 | comment_by_helpdesk_confirmation: 78 | title: "Wysłano odpowiedź do zgłoszenia" 79 | re_ticket: "Odpowiedź dotyczy zgłoszenia" 80 | response_content: "Treść odpowiedzi:" 81 | comment_by_requester_notification: 82 | title: "Pojawiła się nowa odpowiedź do zgłoszenie:" 83 | comment_content: "Treść odpowiedzi:" 84 | comment_by_requester_confirmation: 85 | title: "%{user}, dziękujemy za przesłanie odpowiedzi do zgłoszenia" 86 | subject: "Odpowiedź dotyczy Twojego zgłoszenia - %{subject}" 87 | comment_content: "Treść odpowiedzi:" 88 | ticket_created_confirmation: 89 | title: "%{user}, dziękujemy za przesłanie zgłoszenia" 90 | subject: Temat Twojego zgłoszenia to 91 | ticket_content: "Treść zgłoszenia:" 92 | info_time: "Cenimy Twój czas, dlatego staramy się odpowiadać, tak szybko jak to możliwe." 93 | ticket_created_notification: 94 | title: "Pojawiło się nowe zgłoszenie:" 95 | requester_info: "Informacje o zgłaszającym:" 96 | ticket_content: "Treść zgłoszenia:" 97 | ticket_url_title: "Pod tym adresem można śledzić zgłoszenie:" 98 | footer_info: "Ta wiadomość została wygenerowana automatycznie. Nie odpowiadaj na nią. Jeśli nie zainicjowałeś akcji wysyłania tej wiadomości zgłoś to nam klikając tutaj." 99 | footer_nice: "Życzymy miłego dnia" 100 | 101 | 102 | 103 | activerecord: 104 | models: 105 | helpdesk: helpdesk 106 | helpdesk/ticket: Zgłoszenie 107 | helpdesk/comment: Komentarz 108 | attributes: 109 | helpdesk/comment: 110 | comment: Dodatkowy opis 111 | public: Widoczny/Wyślij 112 | helpdesk/ticket: 113 | requester_id: Zgłaszający 114 | subject: Temat 115 | status: Status 116 | assignee_id: Przypisane 117 | ticket_type_id: Rodzaj zgłoszenia 118 | description: Opis 119 | comments: Dodatkowy opis 120 | -------------------------------------------------------------------------------- /config/initializers/simple_form.rb: -------------------------------------------------------------------------------- 1 | inputs = %w[ 2 | CollectionSelectInput 3 | DateTimeInput 4 | FileInput 5 | GroupedCollectionSelectInput 6 | NumericInput 7 | PasswordInput 8 | RangeInput 9 | StringInput 10 | TextInput 11 | ] 12 | 13 | 14 | # Instead of creating top-level custom input classes like TextInput, we wrap it into a module and override 15 | # mapping in SimpleForm::FormBuilder directly 16 | # 17 | unless Module.const_defined?(:SimpleFormBootstrapInputs) 18 | SimpleFormBootstrapInputs = Module.new 19 | inputs.each do |input_type| 20 | superclass = "SimpleForm::Inputs::#{input_type}".constantize 21 | 22 | new_class = SimpleFormBootstrapInputs.const_set(input_type, Class.new(superclass) do 23 | def input_html_classes 24 | super.push('form-control') 25 | end 26 | end) 27 | 28 | # Now override existing usages of superclass with new_class 29 | SimpleForm::FormBuilder.mappings.each do |(type, target_class)| 30 | if target_class == superclass 31 | SimpleForm::FormBuilder.map_type(type, to: new_class) 32 | end 33 | end 34 | end 35 | end 36 | # inputs.each do |input_type| 37 | # superclass = "SimpleForm::Inputs::#{input_type}".constantize 38 | 39 | # new_class = Class.new(superclass) do 40 | # def input_html_classes 41 | # super.push('form-control') 42 | # end 43 | # end 44 | 45 | # Object.const_set(input_type, new_class) 46 | # end 47 | 48 | # Use this setup block to configure all options available in SimpleForm. 49 | SimpleForm.setup do |config| 50 | 51 | config.browser_validations = true 52 | 53 | config.boolean_style = :nested 54 | 55 | config.wrappers :bootstrap3, tag: 'div', class: 'form-group', error_class: 'has-error', 56 | defaults: { input_html: { class: 'default_class' } } do |b| 57 | 58 | b.use :html5 59 | b.use :min_max 60 | b.use :maxlength 61 | b.use :placeholder 62 | 63 | b.optional :pattern 64 | b.optional :readonly 65 | 66 | b.use :label_input 67 | b.use :hint, wrap_with: { tag: 'span', class: 'help-block' } 68 | b.use :error, wrap_with: { tag: 'span', class: 'help-block has-error' } 69 | end 70 | 71 | config.wrappers :prepend, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 72 | b.use :html5 73 | b.use :placeholder 74 | b.wrapper tag: 'div', class: 'controls' do |input| 75 | input.wrapper tag: 'div', class: 'input-group' do |prepend| 76 | prepend.use :label , wrap_with: {class: "input-group-addon"} ###Please note setting class here fro the label does not currently work (let me know if you know a workaround as this is the final hurdle) 77 | prepend.use :input 78 | end 79 | input.use :hint, wrap_with: { tag: 'span', class: 'help-block' } 80 | input.use :error, wrap_with: { tag: 'span', class: 'help-block has-error' } 81 | end 82 | end 83 | 84 | config.wrappers :append, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 85 | b.use :html5 86 | b.use :placeholder 87 | b.wrapper tag: 'div', class: 'controls' do |input| 88 | input.wrapper tag: 'div', class: 'input-group' do |prepend| 89 | prepend.use :input 90 | prepend.use :label , wrap_with: {class: "input-group-addon"} ###Please note setting class here fro the label does not currently work (let me know if you know a workaround as this is the final hurdle) 91 | end 92 | input.use :hint, wrap_with: { tag: 'span', class: 'help-block' } 93 | input.use :error, wrap_with: { tag: 'span', class: 'help-block has-error' } 94 | end 95 | end 96 | 97 | config.wrappers :inline_checkbox, :tag => 'div', :class => 'control-group', :error_class => 'error' do |b| 98 | b.use :html5 99 | b.wrapper :tag => 'div', :class => 'controls' do |ba| 100 | ba.wrapper :tag => 'label', :class => 'checkbox' do |bb| 101 | bb.use :label_text 102 | bb.use :input 103 | end 104 | ba.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } 105 | ba.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' } 106 | end 107 | end 108 | 109 | # Wrappers for forms and inputs using the Twitter Bootstrap toolkit. 110 | # Check the Bootstrap docs (http://getbootstrap.com/) 111 | # to learn about the different styles for forms and inputs, 112 | # buttons and other elements. 113 | config.default_wrapper = :bootstrap3 114 | end 115 | -------------------------------------------------------------------------------- /spec/dummy/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../../ 3 | specs: 4 | helpdesk (0.0.39) 5 | acts_as_ordered_tree 6 | batch_translations 7 | bootstrap-sass 8 | ckeditor 9 | globalize 10 | jquery-ui-rails 11 | kaminari 12 | rails 13 | rails_autolink 14 | sass-rails 15 | select2-rails 16 | simple_form 17 | state_machine 18 | 19 | GEM 20 | remote: https://rubygems.org/ 21 | specs: 22 | actionmailer (4.1.8) 23 | actionpack (= 4.1.8) 24 | actionview (= 4.1.8) 25 | mail (~> 2.5, >= 2.5.4) 26 | actionpack (4.1.8) 27 | actionview (= 4.1.8) 28 | activesupport (= 4.1.8) 29 | rack (~> 1.5.2) 30 | rack-test (~> 0.6.2) 31 | actionview (4.1.8) 32 | activesupport (= 4.1.8) 33 | builder (~> 3.1) 34 | erubis (~> 2.7.0) 35 | activemodel (4.1.8) 36 | activesupport (= 4.1.8) 37 | builder (~> 3.1) 38 | activerecord (4.1.8) 39 | activemodel (= 4.1.8) 40 | activesupport (= 4.1.8) 41 | arel (~> 5.0.0) 42 | activesupport (4.1.8) 43 | i18n (~> 0.6, >= 0.6.9) 44 | json (~> 1.7, >= 1.7.7) 45 | minitest (~> 5.1) 46 | thread_safe (~> 0.1) 47 | tzinfo (~> 1.1) 48 | acts_as_ordered_tree (1.3.1) 49 | activerecord (>= 3.0.0) 50 | arel (5.0.1.20140414130214) 51 | batch_translations (0.1.3) 52 | bcrypt (3.1.9) 53 | bootstrap-sass (3.3.1.0) 54 | sass (~> 3.2) 55 | builder (3.2.2) 56 | ckeditor (4.1.1) 57 | cocaine 58 | orm_adapter (~> 0.5.0) 59 | climate_control (0.0.3) 60 | activesupport (>= 3.0) 61 | cocaine (0.5.4) 62 | climate_control (>= 0.0.3, < 1.0) 63 | devise (3.4.1) 64 | bcrypt (~> 3.0) 65 | orm_adapter (~> 0.1) 66 | railties (>= 3.2.6, < 5) 67 | responders 68 | thread_safe (~> 0.1) 69 | warden (~> 1.2.3) 70 | erubis (2.7.0) 71 | globalize (4.0.3) 72 | activemodel (>= 4.0.0, < 5) 73 | activerecord (>= 4.0.0, < 5) 74 | haml (4.1.0.beta.1) 75 | tilt 76 | haml-rails (0.6.0) 77 | actionpack (>= 4.0.1) 78 | activesupport (>= 4.0.1) 79 | haml (>= 3.1, < 5.0) 80 | html2haml (>= 1.0.1) 81 | railties (>= 4.0.1) 82 | hike (1.2.3) 83 | hpricot (0.8.6) 84 | html2haml (1.0.1) 85 | erubis (~> 2.7.0) 86 | haml (>= 4.0.0.rc.1) 87 | hpricot (~> 0.8.6) 88 | ruby_parser (~> 3.1.1) 89 | i18n (0.6.11) 90 | jquery-rails (3.1.2) 91 | railties (>= 3.0, < 5.0) 92 | thor (>= 0.14, < 2.0) 93 | jquery-ui-rails (5.0.3) 94 | railties (>= 3.2.16) 95 | json (1.8.1) 96 | kaminari (0.16.1) 97 | actionpack (>= 3.0.0) 98 | activesupport (>= 3.0.0) 99 | mail (2.6.3) 100 | mime-types (>= 1.16, < 3) 101 | mime-types (2.4.3) 102 | minitest (5.4.3) 103 | multi_json (1.10.1) 104 | orm_adapter (0.5.0) 105 | rack (1.5.2) 106 | rack-test (0.6.2) 107 | rack (>= 1.0) 108 | rails (4.1.8) 109 | actionmailer (= 4.1.8) 110 | actionpack (= 4.1.8) 111 | actionview (= 4.1.8) 112 | activemodel (= 4.1.8) 113 | activerecord (= 4.1.8) 114 | activesupport (= 4.1.8) 115 | bundler (>= 1.3.0, < 2.0) 116 | railties (= 4.1.8) 117 | sprockets-rails (~> 2.0) 118 | rails_autolink (1.1.6) 119 | rails (> 3.1) 120 | railties (4.1.8) 121 | actionpack (= 4.1.8) 122 | activesupport (= 4.1.8) 123 | rake (>= 0.8.7) 124 | thor (>= 0.18.1, < 2.0) 125 | rake (10.4.2) 126 | responders (1.1.2) 127 | railties (>= 3.2, < 4.2) 128 | ruby_parser (3.1.3) 129 | sexp_processor (~> 4.1) 130 | sass (3.2.19) 131 | sass-rails (4.0.5) 132 | railties (>= 4.0.0, < 5.0) 133 | sass (~> 3.2.2) 134 | sprockets (~> 2.8, < 3.0) 135 | sprockets-rails (~> 2.0) 136 | select2-rails (3.5.9.1) 137 | thor (~> 0.14) 138 | sexp_processor (4.4.4) 139 | simple_form (3.1.0) 140 | actionpack (~> 4.0) 141 | activemodel (~> 4.0) 142 | sprockets (2.12.3) 143 | hike (~> 1.2) 144 | multi_json (~> 1.0) 145 | rack (~> 1.0) 146 | tilt (~> 1.1, != 1.3.0) 147 | sprockets-rails (2.2.2) 148 | actionpack (>= 3.0) 149 | activesupport (>= 3.0) 150 | sprockets (>= 2.8, < 4.0) 151 | sqlite3 (1.3.10) 152 | state_machine (1.2.0) 153 | thor (0.19.1) 154 | thread_safe (0.3.4) 155 | tilt (1.4.1) 156 | tzinfo (1.2.2) 157 | thread_safe (~> 0.1) 158 | warden (1.2.3) 159 | rack (>= 1.0) 160 | 161 | PLATFORMS 162 | ruby 163 | 164 | DEPENDENCIES 165 | devise 166 | haml-rails 167 | helpdesk! 168 | jquery-rails 169 | kaminari 170 | sass-rails 171 | sqlite3 (~> 1.3) 172 | -------------------------------------------------------------------------------- /config/locales/helpdesk.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | 3 | helpdesk: 4 | lang: Język 5 | show: Pokaż 6 | edit: Edytuj 7 | destroy: Usuń 8 | name: Helpdesk 9 | new_ticket: Nowe zgłoszenie 10 | add: Dodaj 11 | tickets: 12 | new: Nowe zgłoszenie 13 | my: Moje zgłoszenia 14 | unassigned: Nieprzypisane zgłoszenia 15 | closed: Zamknięte zgłoszenia 16 | all: Wszystkie zgłoszenia 17 | title: Zgłoszenia 18 | active: Aktywne zgłoszenia 19 | assignee_to: Przypisane do 20 | assign_me: Biore to 21 | not_assigned: Nie przypisany 22 | is_now_assigned: "Zgłoszenie %{subject} zostało przypisane do Ciebie" 23 | visible_to_autor: Widoczny dla zgłaszającego - wyślij emaila 24 | you_have_no_tickets: "Brak zgłoszeń" 25 | ticket_closed: Zgłoszenie zamknięte 26 | subject: Temat zgłoszenia 27 | description: Treść 28 | cancel: Anuluj 29 | send: Wyślij 30 | statuses: 31 | new: "Nowe" 32 | open: "Otwarte" 33 | waiting: "Otwarte: oczekujące" 34 | solved: "Zamknięte: problem rozwiązany" 35 | not_fixable: "Zamknięte: nienaprawialne" 36 | unreachable: "Zamknięte: klient nieosiągalny" 37 | bug: "Zamknięte: Przeniesione do bug tracker'a" 38 | 39 | ticket: Zgłoszenie 40 | faq: FAQ 41 | comments: 42 | title: Komentarze 43 | note: Notatka 44 | send: Wysłane 45 | received: Odebrane 46 | note: notatka 47 | author: Odp. autora 48 | helpdesk: Odp. BOK 49 | ticket_types: 50 | title: Rodzaje zgłoszeń 51 | new: Nowy rodzaj zgłoszenia 52 | all: Wszystkie rodzaje zgłoszeń 53 | active: Aktywne rodzaje zgłoszeń 54 | inactive: Nieaktywne rodzaje zgłoszeń 55 | 56 | dashboard: Dashboard 57 | 58 | subscribers: 59 | title: Subskrybcja 60 | confirmed: Potwierdzeni subskrynenci 61 | unconfirmed: Niepotwierdzeni 62 | all: Wszyscy subskrybenci 63 | new: Dodaj subskrybenta 64 | 65 | faqs: 66 | sorting: 'Sortowanie:' 67 | search: Szukaj 68 | search_in_faqs: Szukaj w FAQ 69 | title: FAQ 70 | title_s: Często zadawane pytania 71 | active: Aktywne pytania 72 | inactive: Nieaktywne pytania 73 | all: Wszystkie pytania 74 | new: Nowe pytanie 75 | by: przez 76 | faq: 77 | active: aktywne 78 | inactive: nieaktywne 79 | search_count: 80 | zero: 'Nic nie znaleziono dla zapytania: "%{query}"' 81 | one: 'Znaleziono jeden wynik, dla zapytania: "%{query}"' 82 | few: 'Znaleziono %{count} wyniki, dla zapytania: "%{query}"' 83 | many: 'Znaleziono %{count} wyników, dla zapytania: "%{query}"' 84 | other: 'Znaleziono %{count} wyników, dla zapytania: "%{query}"' 85 | back_to_fasq: '« Wróć do listy pojęć' 86 | 87 | 88 | mailer: 89 | comment_by_helpdesk_confirmation: 90 | title: "Wysłano odpowiedź do zgłoszenia" 91 | re_ticket: "Odpowiedź dotyczy zgłoszenia" 92 | response_content: "Treść odpowiedzi:" 93 | comment_by_requester_notification: 94 | title: "Pojawiła się nowa odpowiedź do zgłoszenie:" 95 | comment_content: "Treść odpowiedzi:" 96 | comment_by_requester_confirmation: 97 | title: "%{user}, dziękujemy za przesłanie odpowiedzi do zgłoszenia" 98 | subject: "Odpowiedź dotyczy Twojego zgłoszenia - %{subject}" 99 | comment_content: "Treść odpowiedzi:" 100 | ticket_created_confirmation: 101 | title: "%{user}, dziękujemy za przesłanie zgłoszenia" 102 | subject: Temat Twojego zgłoszenia to 103 | ticket_content: "Treść zgłoszenia:" 104 | info_time: "Cenimy Twój czas, dlatego staramy się odpowiadać, tak szybko jak to możliwe." 105 | ticket_created_notification: 106 | title: "Pojawiło się nowe zgłoszenie:" 107 | requester_info: "Informacje o zgłaszającym:" 108 | ticket_content: "Treść zgłoszenia:" 109 | ticket_url_title: "Pod tym adresem można śledzić zgłoszenie:" 110 | footer_info: "Ta wiadomość została wygenerowana automatycznie. Nie odpowiadaj na nią. Jeśli nie zainicjowałeś akcji wysyłania tej wiadomości zgłoś to nam klikając tutaj." 111 | footer_nice: "Życzymy miłego dnia" 112 | 113 | 114 | 115 | activerecord: 116 | models: 117 | helpdesk: helpdesk 118 | helpdesk/ticket: Zgłoszenie 119 | helpdesk/comment: Komentarz 120 | attributes: 121 | helpdesk/comment: 122 | comment: Dodatkowy opis 123 | public: Widoczny/Wyślij 124 | helpdesk/ticket: 125 | ticket_type: Rodzaj zgłoszenia 126 | requester_id: Zgłaszający 127 | subject: Temat 128 | status: Status 129 | assignee_id: Przypisane 130 | ticket_type_id: Rodzaj zgłoszenia 131 | description: Opis 132 | comments: Dodatkowy opis 133 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | helpdesk (0.0.42) 5 | acts_as_ordered_tree 6 | batch_translations 7 | bootstrap-sass 8 | ckeditor 9 | globalize 10 | jquery-ui-rails 11 | kaminari 12 | rails 13 | rails_autolink 14 | sass-rails 15 | select2-rails 16 | simple_form 17 | state_machine 18 | 19 | GEM 20 | remote: https://rubygems.org/ 21 | specs: 22 | actionmailer (4.2.7.1) 23 | actionpack (= 4.2.7.1) 24 | actionview (= 4.2.7.1) 25 | activejob (= 4.2.7.1) 26 | mail (~> 2.5, >= 2.5.4) 27 | rails-dom-testing (~> 1.0, >= 1.0.5) 28 | actionpack (4.2.7.1) 29 | actionview (= 4.2.7.1) 30 | activesupport (= 4.2.7.1) 31 | rack (~> 1.6) 32 | rack-test (~> 0.6.2) 33 | rails-dom-testing (~> 1.0, >= 1.0.5) 34 | rails-html-sanitizer (~> 1.0, >= 1.0.2) 35 | actionview (4.2.7.1) 36 | activesupport (= 4.2.7.1) 37 | builder (~> 3.1) 38 | erubis (~> 2.7.0) 39 | rails-dom-testing (~> 1.0, >= 1.0.5) 40 | rails-html-sanitizer (~> 1.0, >= 1.0.2) 41 | activejob (4.2.7.1) 42 | activesupport (= 4.2.7.1) 43 | globalid (>= 0.3.0) 44 | activemodel (4.2.7.1) 45 | activesupport (= 4.2.7.1) 46 | builder (~> 3.1) 47 | activerecord (4.2.7.1) 48 | activemodel (= 4.2.7.1) 49 | activesupport (= 4.2.7.1) 50 | arel (~> 6.0) 51 | activesupport (4.2.7.1) 52 | i18n (~> 0.7) 53 | json (~> 1.7, >= 1.7.7) 54 | minitest (~> 5.1) 55 | thread_safe (~> 0.3, >= 0.3.4) 56 | tzinfo (~> 1.1) 57 | acts_as_ordered_tree (1.3.1) 58 | activerecord (>= 3.0.0) 59 | addressable (2.4.0) 60 | arel (6.0.3) 61 | autoprefixer-rails (6.4.0.2) 62 | execjs 63 | batch_translations (0.1.3) 64 | bcrypt (3.1.11) 65 | bootstrap-sass (3.3.7) 66 | autoprefixer-rails (>= 5.2.1) 67 | sass (>= 3.3.4) 68 | builder (3.2.2) 69 | bullet (5.3.0) 70 | activesupport (>= 3.0.0) 71 | uniform_notifier (~> 1.10.0) 72 | capybara (2.8.0) 73 | addressable 74 | mime-types (>= 1.16) 75 | nokogiri (>= 1.3.3) 76 | rack (>= 1.0.0) 77 | rack-test (>= 0.5.4) 78 | xpath (~> 2.0) 79 | chunky_png (1.3.6) 80 | ckeditor (4.2.0) 81 | cocaine 82 | orm_adapter (~> 0.5.0) 83 | climate_control (0.0.3) 84 | activesupport (>= 3.0) 85 | cocaine (0.5.8) 86 | climate_control (>= 0.0.3, < 1.0) 87 | compass (1.0.3) 88 | chunky_png (~> 1.2) 89 | compass-core (~> 1.0.2) 90 | compass-import-once (~> 1.0.5) 91 | rb-fsevent (>= 0.9.3) 92 | rb-inotify (>= 0.9) 93 | sass (>= 3.3.13, < 3.5) 94 | compass-core (1.0.3) 95 | multi_json (~> 1.0) 96 | sass (>= 3.3.0, < 3.5) 97 | compass-import-once (1.0.5) 98 | sass (>= 3.2, < 3.5) 99 | concurrent-ruby (1.0.2) 100 | devise (4.2.0) 101 | bcrypt (~> 3.0) 102 | orm_adapter (~> 0.1) 103 | railties (>= 4.1.0, < 5.1) 104 | responders 105 | warden (~> 1.2.3) 106 | diff-lcs (1.2.5) 107 | email_spec (2.1.0) 108 | htmlentities (~> 4.3.3) 109 | launchy (~> 2.1) 110 | mail (~> 2.6.3) 111 | erubis (2.7.0) 112 | execjs (2.7.0) 113 | factory_girl (4.7.0) 114 | activesupport (>= 3.0.0) 115 | factory_girl_rails (4.7.0) 116 | factory_girl (~> 4.7.0) 117 | railties (>= 3.0.0) 118 | ffi (1.9.14) 119 | foreman (0.82.0) 120 | thor (~> 0.19.1) 121 | globalid (0.3.7) 122 | activesupport (>= 4.1.0) 123 | globalize (5.0.1) 124 | activemodel (>= 4.2.0, < 4.3) 125 | activerecord (>= 4.2.0, < 4.3) 126 | haml (4.0.7) 127 | tilt 128 | haml-rails (0.9.0) 129 | actionpack (>= 4.0.1) 130 | activesupport (>= 4.0.1) 131 | haml (>= 4.0.6, < 5.0) 132 | html2haml (>= 1.0.1) 133 | railties (>= 4.0.1) 134 | html2haml (2.0.0) 135 | erubis (~> 2.7.0) 136 | haml (~> 4.0.0) 137 | nokogiri (~> 1.6.0) 138 | ruby_parser (~> 3.5) 139 | htmlentities (4.3.4) 140 | i18n (0.7.0) 141 | jquery-rails (4.1.1) 142 | rails-dom-testing (>= 1, < 3) 143 | railties (>= 4.2.0) 144 | thor (>= 0.14, < 2.0) 145 | jquery-ui-rails (5.0.5) 146 | railties (>= 3.2.16) 147 | json (1.8.3) 148 | kaminari (0.17.0) 149 | actionpack (>= 3.0.0) 150 | activesupport (>= 3.0.0) 151 | launchy (2.4.3) 152 | addressable (~> 2.3) 153 | letter_opener (1.4.1) 154 | launchy (~> 2.2) 155 | loofah (2.0.3) 156 | nokogiri (>= 1.5.9) 157 | mail (2.6.4) 158 | mime-types (>= 1.16, < 4) 159 | mime-types (3.1) 160 | mime-types-data (~> 3.2015) 161 | mime-types-data (3.2016.0521) 162 | mini_portile2 (2.1.0) 163 | minitest (5.9.0) 164 | multi_json (1.12.1) 165 | nokogiri (1.6.8) 166 | mini_portile2 (~> 2.1.0) 167 | pkg-config (~> 1.1.7) 168 | orm_adapter (0.5.0) 169 | pkg-config (1.1.7) 170 | rack (1.6.4) 171 | rack-test (0.6.3) 172 | rack (>= 1.0) 173 | rails (4.2.7.1) 174 | actionmailer (= 4.2.7.1) 175 | actionpack (= 4.2.7.1) 176 | actionview (= 4.2.7.1) 177 | activejob (= 4.2.7.1) 178 | activemodel (= 4.2.7.1) 179 | activerecord (= 4.2.7.1) 180 | activesupport (= 4.2.7.1) 181 | bundler (>= 1.3.0, < 2.0) 182 | railties (= 4.2.7.1) 183 | sprockets-rails 184 | rails-deprecated_sanitizer (1.0.3) 185 | activesupport (>= 4.2.0.alpha) 186 | rails-dom-testing (1.0.7) 187 | activesupport (>= 4.2.0.beta, < 5.0) 188 | nokogiri (~> 1.6.0) 189 | rails-deprecated_sanitizer (>= 1.0.1) 190 | rails-html-sanitizer (1.0.3) 191 | loofah (~> 2.0) 192 | rails_autolink (1.1.6) 193 | rails (> 3.1) 194 | railties (4.2.7.1) 195 | actionpack (= 4.2.7.1) 196 | activesupport (= 4.2.7.1) 197 | rake (>= 0.8.7) 198 | thor (>= 0.18.1, < 2.0) 199 | rake (11.2.2) 200 | rb-fsevent (0.9.7) 201 | rb-inotify (0.9.7) 202 | ffi (>= 0.5.0) 203 | responders (2.3.0) 204 | railties (>= 4.2.0, < 5.1) 205 | rspec-core (3.5.2) 206 | rspec-support (~> 3.5.0) 207 | rspec-expectations (3.5.0) 208 | diff-lcs (>= 1.2.0, < 2.0) 209 | rspec-support (~> 3.5.0) 210 | rspec-mocks (3.5.0) 211 | diff-lcs (>= 1.2.0, < 2.0) 212 | rspec-support (~> 3.5.0) 213 | rspec-rails (3.5.1) 214 | actionpack (>= 3.0) 215 | activesupport (>= 3.0) 216 | railties (>= 3.0) 217 | rspec-core (~> 3.5.0) 218 | rspec-expectations (~> 3.5.0) 219 | rspec-mocks (~> 3.5.0) 220 | rspec-support (~> 3.5.0) 221 | rspec-support (3.5.0) 222 | ruby_parser (3.8.2) 223 | sexp_processor (~> 4.1) 224 | sass (3.4.22) 225 | sass-rails (5.0.6) 226 | railties (>= 4.0.0, < 6) 227 | sass (~> 3.1) 228 | sprockets (>= 2.8, < 4.0) 229 | sprockets-rails (>= 2.0, < 4.0) 230 | tilt (>= 1.1, < 3) 231 | select2-rails (4.0.3) 232 | thor (~> 0.14) 233 | sexp_processor (4.7.0) 234 | shoulda (3.5.0) 235 | shoulda-context (~> 1.0, >= 1.0.1) 236 | shoulda-matchers (>= 1.4.1, < 3.0) 237 | shoulda-context (1.2.1) 238 | shoulda-matchers (2.8.0) 239 | activesupport (>= 3.0.0) 240 | simple_form (3.2.1) 241 | actionpack (> 4, < 5.1) 242 | activemodel (> 4, < 5.1) 243 | sprockets (3.7.0) 244 | concurrent-ruby (~> 1.0) 245 | rack (> 1, < 3) 246 | sprockets-rails (3.1.1) 247 | actionpack (>= 4.0) 248 | activesupport (>= 4.0) 249 | sprockets (>= 3.0.0) 250 | sqlite3 (1.3.11) 251 | state_machine (1.2.0) 252 | thor (0.19.1) 253 | thread_safe (0.3.5) 254 | tilt (2.0.5) 255 | tzinfo (1.2.2) 256 | thread_safe (~> 0.1) 257 | uniform_notifier (1.10.0) 258 | warden (1.2.6) 259 | rack (>= 1.0) 260 | xpath (2.0.0) 261 | nokogiri (~> 1.3) 262 | 263 | PLATFORMS 264 | ruby 265 | 266 | DEPENDENCIES 267 | bullet 268 | capybara 269 | compass 270 | devise 271 | email_spec 272 | factory_girl_rails 273 | foreman 274 | haml-rails 275 | helpdesk! 276 | jquery-rails 277 | launchy 278 | letter_opener 279 | rspec-rails 280 | shoulda 281 | sqlite3 282 | --------------------------------------------------------------------------------