diff --git a/Gemfile b/Gemfile index 002f2f8b2..ba37b0091 100644 --- a/Gemfile +++ b/Gemfile @@ -109,6 +109,8 @@ gem 'prawn_rails', '~> 0.0.11' gem 'chunky_png' gem 'sentry-raven' +gem "administrate" + gem 'rack-mini-profiler' group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 9acba8c16..83e48ec2b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -59,6 +59,18 @@ GEM tzinfo (~> 1.1) addressable (2.5.1) public_suffix (~> 2.0, >= 2.0.2) + administrate (0.4.0) + autoprefixer-rails (~> 6.0) + bourbon (~> 4.2) + datetime_picker_rails (~> 0.0.7) + jquery-rails (~> 4.0) + kaminari (~> 0.16) + momentjs-rails (~> 2.8) + neat (~> 1.1) + normalize-rails (~> 3.0) + rails (>= 4.2, < 5.1) + sass-rails (~> 5.0) + selectize-rails (~> 0.6) apipie-rails (0.3.7) json arel (7.1.4) @@ -79,6 +91,9 @@ GEM sass (>= 3.3.4) bootstrap-wysihtml5-rails (0.3.3.8) railties (>= 3.0) + bourbon (4.3.4) + sass (~> 3.4) + thor (~> 0.19) brakeman (3.7.0) browser (2.3.0) builder (3.2.3) @@ -116,6 +131,8 @@ GEM safe_yaml (~> 1.0.0) daemons (1.2.4) database_cleaner (1.5.3) + datetime_picker_rails (0.0.7) + momentjs-rails (>= 2.8.1) debug_inspector (0.0.2) deep_cloneable (2.2.2) activerecord (>= 3.1.0, < 5.2.0) @@ -396,15 +413,21 @@ GEM mimemagic (0.3.2) mini_portile2 (2.3.0) minitest (5.10.3) + momentjs-rails (2.17.1) + railties (>= 3.1) multi_json (1.12.1) multi_xml (0.6.0) multipart-post (2.0.0) mustermann (1.0.1) + neat (1.9.0) + sass (>= 3.3) + thor (~> 0.19) nenv (0.3.0) netrc (0.11.0) nio4r (1.2.1) nokogiri (1.8.1) mini_portile2 (~> 2.3.0) + normalize-rails (3.0.3) notiffany (0.1.1) nenv (~> 0.1) shellany (~> 0.0) @@ -589,6 +612,7 @@ GEM securecompare (1.0.0) select2-rails (4.0.3) thor (~> 0.14) + selectize-rails (0.12.4.1) sentry-raven (2.2.0) faraday (>= 0.7.6, < 1.0) sexp_processor (4.10.0) @@ -693,6 +717,7 @@ PLATFORMS DEPENDENCIES active_model_serializers + administrate apipie-rails bootstrap-datepicker-rails bootstrap-sass (~> 3.3.5) diff --git a/app/controllers/manager/administrateurs_controller.rb b/app/controllers/manager/administrateurs_controller.rb new file mode 100644 index 000000000..71b37a9ed --- /dev/null +++ b/app/controllers/manager/administrateurs_controller.rb @@ -0,0 +1,21 @@ +module Manager + class AdministrateursController < Manager::ApplicationController + # To customize the behavior of this controller, + # simply overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Administrateur. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Administrateur.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/manager/application_controller.rb b/app/controllers/manager/application_controller.rb new file mode 100644 index 000000000..8d2db8e84 --- /dev/null +++ b/app/controllers/manager/application_controller.rb @@ -0,0 +1,23 @@ +# All Administrate controllers inherit from this `Admin::ApplicationController`, +# making it the ideal place to put authentication logic or other +# before_actions. +# +# If you want to add pagination or other controller-level concerns, +# you're free to overwrite the RESTful controller actions. +module Manager + class ApplicationController < Administrate::ApplicationController + before_action :authenticate_administration! + before_action :default_params + + # Override this value to specify the number of elements to display at a time + # on index pages. Defaults to 20. + # def records_per_page + # params[:per_page] || 20 + # end + + def default_params + params[:order] ||= "created_at" + params[:direction] ||= "desc" + end + end +end diff --git a/app/controllers/manager/procedures_controller.rb b/app/controllers/manager/procedures_controller.rb new file mode 100644 index 000000000..7fae3e53c --- /dev/null +++ b/app/controllers/manager/procedures_controller.rb @@ -0,0 +1,21 @@ +module Manager + class ProceduresController < Manager::ApplicationController + # To customize the behavior of this controller, + # simply overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Procedure. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Procedure.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/dashboards/administrateur_dashboard.rb b/app/dashboards/administrateur_dashboard.rb new file mode 100644 index 000000000..a5cc3b366 --- /dev/null +++ b/app/dashboards/administrateur_dashboard.rb @@ -0,0 +1,50 @@ +require "administrate/base_dashboard" + +class AdministrateurDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + email: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + procedures: Field::HasMany, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :email, + :created_at, + :procedures, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :id, + :email, + :created_at, + :updated_at, + :procedures, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [].freeze + + # Overwrite this method to customize how procedures are displayed + # across all pages of the admin dashboard. + # + def display_resource(administrateur) + administrateur.email + end +end diff --git a/app/dashboards/procedure_dashboard.rb b/app/dashboards/procedure_dashboard.rb new file mode 100644 index 000000000..8b0f4f650 --- /dev/null +++ b/app/dashboards/procedure_dashboard.rb @@ -0,0 +1,77 @@ +require "administrate/base_dashboard" + +class ProcedureDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + types_de_piece_justificative: TypesDePieceJustificativeCollectionField, + types_de_champ: TypesDeChampCollectionField, + dossiers: Field::HasMany, + procedure_path: Field::HasOne, + administrateur: Field::BelongsTo, + id: Field::Number, + libelle: Field::String, + description: Field::String, + organisation: Field::String, + direction: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + for_individual: Field::Boolean, + individual_with_siret: Field::Boolean, + auto_archive_on: Field::DateTime, + published_at: Field::DateTime, + hidden_at: Field::DateTime, + archived_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :id, + :created_at, + :libelle, + :organisation, + :dossiers, + :published_at, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :id, + :administrateur, + :libelle, + :description, + :organisation, + :direction, + :created_at, + :updated_at, + :published_at, + :hidden_at, + :archived_at, + :types_de_champ, + :types_de_piece_justificative, + :for_individual, + :individual_with_siret, + :auto_archive_on, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [].freeze + + # Overwrite this method to customize how procedures are displayed + # across all pages of the admin dashboard. + # + # def display_resource(procedure) + # "Procedure ##{procedure.id}" + # end +end diff --git a/app/fields/types_de_champ_collection_field.rb b/app/fields/types_de_champ_collection_field.rb new file mode 100644 index 000000000..99d5a5f83 --- /dev/null +++ b/app/fields/types_de_champ_collection_field.rb @@ -0,0 +1,7 @@ +require "administrate/field/base" + +class TypesDeChampCollectionField < Administrate::Field::Base + def to_s + data + end +end diff --git a/app/fields/types_de_piece_justificative_collection_field.rb b/app/fields/types_de_piece_justificative_collection_field.rb new file mode 100644 index 000000000..a19b5249f --- /dev/null +++ b/app/fields/types_de_piece_justificative_collection_field.rb @@ -0,0 +1,7 @@ +require "administrate/field/base" + +class TypesDePieceJustificativeCollectionField < Administrate::Field::Base + def to_s + data + end +end diff --git a/app/views/fields/types_de_champ_collection_field/_form.html.haml b/app/views/fields/types_de_champ_collection_field/_form.html.haml new file mode 100644 index 000000000..9fd2d81b7 --- /dev/null +++ b/app/views/fields/types_de_champ_collection_field/_form.html.haml @@ -0,0 +1,4 @@ +.field-unit__label + = f.label field.attribute +.field-unit__field + = f.text_field field.attribute diff --git a/app/views/fields/types_de_champ_collection_field/_index.html.haml b/app/views/fields/types_de_champ_collection_field/_index.html.haml new file mode 100644 index 000000000..1249b4899 --- /dev/null +++ b/app/views/fields/types_de_champ_collection_field/_index.html.haml @@ -0,0 +1 @@ += field.to_s diff --git a/app/views/fields/types_de_champ_collection_field/_show.html.haml b/app/views/fields/types_de_champ_collection_field/_show.html.haml new file mode 100644 index 000000000..c54bb1c64 --- /dev/null +++ b/app/views/fields/types_de_champ_collection_field/_show.html.haml @@ -0,0 +1,15 @@ +- if field.data.any? + %table.collection-data{ "aria-labelledby": "page-title" } + %thead + %tr + %td.cell-label Libelle + %td.cell-label Type de champ + %tbody + - field.data.order(:order_place).each do |f| + %tr + %td.cell-data + = f.libelle + %td.cell-data + = I18n.t("activerecord.attributes.type_de_champ.type_champs.#{f.type_champ}") +- else + Aucun diff --git a/app/views/fields/types_de_piece_justificative_collection_field/_form.html.haml b/app/views/fields/types_de_piece_justificative_collection_field/_form.html.haml new file mode 100644 index 000000000..9fd2d81b7 --- /dev/null +++ b/app/views/fields/types_de_piece_justificative_collection_field/_form.html.haml @@ -0,0 +1,4 @@ +.field-unit__label + = f.label field.attribute +.field-unit__field + = f.text_field field.attribute diff --git a/app/views/fields/types_de_piece_justificative_collection_field/_index.html.haml b/app/views/fields/types_de_piece_justificative_collection_field/_index.html.haml new file mode 100644 index 000000000..1249b4899 --- /dev/null +++ b/app/views/fields/types_de_piece_justificative_collection_field/_index.html.haml @@ -0,0 +1 @@ += field.to_s diff --git a/app/views/fields/types_de_piece_justificative_collection_field/_show.html.haml b/app/views/fields/types_de_piece_justificative_collection_field/_show.html.haml new file mode 100644 index 000000000..732f086c1 --- /dev/null +++ b/app/views/fields/types_de_piece_justificative_collection_field/_show.html.haml @@ -0,0 +1,12 @@ +- if field.data.any? + %table.collection-data{ "aria-labelledby": "page-title" } + %thead + %tr + %td.cell-label Libelle + %tbody + - field.data.order(:order_place).each do |f| + %tr + %td.cell-data + = f.libelle +- else + Aucun diff --git a/app/views/layouts/manager/application.html.haml b/app/views/layouts/manager/application.html.haml new file mode 100644 index 000000000..04fefd638 --- /dev/null +++ b/app/views/layouts/manager/application.html.haml @@ -0,0 +1,32 @@ +-# # Application Layout +-# +-# This view template is used as the layout +-# for every page that Administrate generates. +-# +-# By default, it renders: +-# - Sidebar for navigation +-# - Content for a search bar +-# (if provided by a `content_for` block in a nested page) +-# - Flashes +-# - Links to stylesheets and Javascripts + +!!! +%html{ lang: I18n.locale } + %head + %meta{ charset: "utf-8" } + %meta{ content: "NOODP", :name => "ROBOTS" } + %meta{ content: "initial-scale=1", :name => "viewport" } + %title + = content_for(:title) + | #{Rails.application.class.parent_name.titlecase} + = render "stylesheet" + = csrf_meta_tags + %body + .app-container + .sidebar + = render "sidebar" + %main.main-content{ role: "main" } + = content_for(:search) + = render "flashes" + = yield + = render "javascript" diff --git a/app/views/manager/application/_collection.html.haml b/app/views/manager/application/_collection.html.haml new file mode 100644 index 000000000..96b51ca15 --- /dev/null +++ b/app/views/manager/application/_collection.html.haml @@ -0,0 +1,38 @@ +-# # Collection +-# +-# This partial is used on the `index` and `show` pages +-# to display a collection of resources in an HTML table. +-# +-# ## Local variables: +-# +-# - `collection_presenter`: +-# An instance of [Administrate::Page::Collection][1]. +-# The table presenter uses `ResourceDashboard::COLLECTION_ATTRIBUTES` to determine +-# the columns displayed in the table +-# - `resources`: +-# An ActiveModel::Relation collection of resources to be displayed in the table. +-# By default, the number of resources is limited by pagination +-# or by a hard limit to prevent excessive page load times +-# +-# [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection + +%table.collection-data{ "aria-labelledby": "page-title" } + %thead + %tr + - collection_presenter.attribute_types.each do |attr_name, attr_type| + %th.cell-label{ class: "cell-label--#{attr_type.html_class} cell-label--#{collection_presenter.ordered_html_class(attr_name)}", scope: "col" } + = link_to(sanitized_order_params.merge(collection_presenter.order_params_for(attr_name))) do + = t("helpers.label.#{resource_name}.#{attr_name}", default: attr_name.to_s).titleize + + - if collection_presenter.ordered_by?(attr_name) + %span.cell-label__sort-indicator{ class: "cell-label__sort-indicator--#{collection_presenter.ordered_html_class(attr_name)}" } + = svg_tag("administrate/sort_arrow.svg", "sort_arrow", width: "13", height: "13") + %th{ colspan: "2", scope: "col" } + + %tbody + - resources.each do |resource| + %tr.table__row{ role: "link", tabindex: "0", "data-url": polymorphic_path([namespace, resource]) } + - collection_presenter.attributes_for(resource).each do |attribute| + %td.cell-data{ class: "cell-data--#{attribute.html_class}" } + = link_to polymorphic_path([namespace, resource]), class: "action-show table__link-plain" do + = render_field attribute diff --git a/app/views/manager/application/_flashes.html.haml b/app/views/manager/application/_flashes.html.haml new file mode 100644 index 000000000..dcb80f65f --- /dev/null +++ b/app/views/manager/application/_flashes.html.haml @@ -0,0 +1,16 @@ +-# # Flash Partial +-# +-# This partial renders flash messages on every page. +-# +-# ## Relevant Helpers: +-# +-# - `flash`: +-# Returns a hash, +-# where the keys are the type of flash (alert, error, notice, etc) +-# and the values are the message to be displayed. + +- if flash.any? + .flashes + - flash.each do |key, value| + .flash{ class: "flash--#{key}" } + = value diff --git a/app/views/manager/application/_javascript.html.haml b/app/views/manager/application/_javascript.html.haml new file mode 100644 index 000000000..94b427358 --- /dev/null +++ b/app/views/manager/application/_javascript.html.haml @@ -0,0 +1,16 @@ +-# # Javascript Partial +-# +-# This partial imports the necessary javascript on each page. +-# By default, it includes the application JS, +-# but each page can define additional JS sources +-# by providing a `content_for(:javascript)` block. + +- Administrate::Engine.javascripts.each do |js_path| + = javascript_include_tag js_path + += yield :javascript + +- if Rails.env.test? + = javascript_tag do + $.fx.off = true; + $.ajaxSetup({ async: false }); diff --git a/app/views/manager/application/_sidebar.html.haml b/app/views/manager/application/_sidebar.html.haml new file mode 100644 index 000000000..cd3499d18 --- /dev/null +++ b/app/views/manager/application/_sidebar.html.haml @@ -0,0 +1,17 @@ +-# # Sidebar +-# +-# This partial is used to display the sidebar in Administrate. +-# By default, the sidebar contains navigation links +-# for all resources in the admin dashboard, +-# as defined by the routes in the `admin/` namespace + +%ul.sidebar__list + %li + = link_to "Se déconnecter", administrations_sign_out_path, method: :delete, class: "sidebar__link" + +%hr{ style: "margin-bottom: 0;" } + +%ul.sidebar__list + - Administrate::Namespace.new(namespace).resources.each do |resource| + %li + = link_to(display_resource_name(resource), [namespace, resource], class: "sidebar__link sidebar__link--#{nav_link_state(resource)}") diff --git a/app/views/manager/application/index.html.haml b/app/views/manager/application/index.html.haml new file mode 100644 index 000000000..1e69b1213 --- /dev/null +++ b/app/views/manager/application/index.html.haml @@ -0,0 +1,38 @@ +-# # Index +-# +-# This view is the template for the index page. +-# It is responsible for rendering the search bar, header and pagination. +-# It renders the `_table` partial to display details about the resources. +-# +-# ## Local variables: +-# +-# - `page`: +-# An instance of [Administrate::Page::Collection][1]. +-# Contains helper methods to help display a table, +-# and knows which attributes should be displayed in the resource's table. +-# - `resources`: +-# An instance of `ActiveRecord::Relation` containing the resources +-# that match the user's search criteria. +-# By default, these resources are passed to the table partial to be displayed. +-# - `search_term`: +-# A string containing the term the user has searched for, if any. +-# - `show_search_bar`: +-# A boolean that determines if the search bar should be shown. +-# +-# [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection + +- content_for(:title) do + = display_resource_name(page.resource_name) + +- content_for(:search) do + - if show_search_bar + = render "search", search_term: search_term + +%header.header + %h1.header__heading#page-title + = content_for(:title) + .header__actions + += render "collection", collection_presenter: page, resources: resources + += paginate resources diff --git a/app/views/manager/application/show.html.haml b/app/views/manager/application/show.html.haml new file mode 100644 index 000000000..e6f79a723 --- /dev/null +++ b/app/views/manager/application/show.html.haml @@ -0,0 +1,29 @@ +-# # Show +-# +-# This view is the template for the show page. +-# It renders the attributes of a resource, +-# as well as a link to its edit page. +-# +-# ## Local variables: +-# +-# - `page`: +-# An instance of [Administrate::Page::Show][1]. +-# Contains methods for accessing the resource to be displayed on the page, +-# as well as helpers for describing how each attribute of the resource +-# should be displayed. +-# +-# [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Show + +- content_for(:title) { page.page_title } + +%header.header + %h1.header__heading= content_for(:title) + .header__actions + +%dl + - page.attributes.each do |attribute| + %dt.attribute-label + = t("helpers.label.#{resource_name}.#{attribute.name}", default: attribute.name.titleize) + + %dd.attribute-data{ class: "attribute-data--#{attribute.html_class}" } + = render_field attribute diff --git a/config/routes.rb b/config/routes.rb index 455e99de3..103d760ef 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,11 @@ Rails.application.routes.draw do + namespace :manager do + resources :procedures, only: [:index, :show] + resources :administrateurs, only: [:index, :show] + + root to: "procedures#index" + end + get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/} devise_for :administrations,