diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index e4c4d343..26604d0b 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -630,4 +630,9 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } } +} + + +hr { + border-bottom: 1px solid #dee2e6; } diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 9d8c42a4..2d5c5a1e 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -157,7 +157,7 @@ class PostsController < ApplicationController # # @return [Hash] def filter_params - @filter_params ||= params.permit(:q, :category, :layout, :page).to_hash.select do |_, v| + @filter_params ||= params.permit(:q, :category, :page, layout: []).to_hash.select do |_, v| v.present? end.transform_keys(&:to_sym) end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 146846f0..2b64ead1 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -19,6 +19,25 @@ module ApplicationHelper [root, name] end + # Devuelve los params sin el valor para una llave, detectando si el + # valor es un array. + # + # @param filtering_params [Hash] + # @param key [Symbol,String] + # @param value [Any] + def filter_params_by(filtering_params, key, value) + filtering_params.map do |k, v| + if k == key + case v + when Array then [k, v - [value]] + else nil + end + else + [ k, v ] + end + end.compact.to_h + end + def plain_field_name_for(*names) root, name = field_name_for(*names) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index a21f46c1..b1e28f2c 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -7,10 +7,13 @@ @param :summary_class [String] Clases para el summary - local_assigns[:summary_class] ||= 'h3' +- local_assigns[:closed] ||= '▶'.html_safe; +- local_assigns[:open] ||= '▼'.html_safe; -%details.details.py-2{ id: local_assigns[:id], data: { controller: 'details', action: 'toggle->details#store' } } + +%details.details.py-2{ id: local_assigns[:id], data: { controller: 'details', action: 'toggle->details#store' }, class: local_assigns[:details_class] } %summary.d-flex.flex-row.align-items-center.justify-content-between{ class: local_assigns[:summary_class] } %span= summary - %span.hide-when-open ▶ - %span.show-when-open ▼ + %span.hide-when-open{ class: local_assigns[:open_class] }= local_assigns[:closed] + %span.show-when-open{ class: local_assigns[:closed_class] }= local_assigns[:open] = yield diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index f20d9fc9..184347ae 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -13,13 +13,30 @@ = render 'sites/build', site: @site, class: 'btn-block' = render 'sites/moderation_queue', site: @site, class: 'btn-block' - %h3= t('posts.new') - %table.table.table-sm.mb-3 - %tbody - - @site.schema_organization.each do |schema, _| - - schema = @site.layouts[schema] - - next if schema.hidden? - = render 'schemas/row', site: @site, schema: schema, filter: @filter_params + = render 'layouts/details', summary: t('posts.filters.title') do + + %form{method: :get} + .border.border-magenta.p-1 + - @filter_params.each do |param, values| + - next if param == :layout + - [values].flatten.each do |value| + %input{ type: 'hidden', name: values.is_a?(Array) ? "#{param}[]" : param, value: value } + %legend.font-weight-bold.m-0.h6= 'Tipo de contenido' + - @site.schema_organization.each do |key, _| + .custom-control.custom-checkbox + - schema = @site.layouts[key] + %input.custom-control-input.magenta{ type: 'checkbox', id: schema, name: "layout[]", class: "", value: schema.name, checked: @filter_params[:layout]&.include?(key.to_s) } + %label.custom-control-label.font-weight-normal{ for: schema }= schema.humanized_name + %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('.filters.submit') + = render 'layouts/details', summary: t('posts.new'), summary_class: "h4 magenta font-weight-bold m-0 px-2", details_class: "d-flex border border-magenta justify-content-between align-items-center w-100 mb-3", open: "+", closed: "+", open_class: "h1 magenta font-weight-bold m-0", closed_class: "h1 magenta font-weight-bold m-0" do + %table.table-sm.w-100 + %tbody + - @site.schema_organization.each do |schema, _| + - schema = @site.layouts[schema] + - next if schema.hidden? + = render 'schemas/row', site: @site, schema: schema, filter: @filter_params + + - if policy(@site_stat).index? = link_to t('stats.index.title'), site_stats_path(@site), class: 'btn btn-secondary' @@ -46,30 +63,13 @@ %section.col .d-flex.justify-content-between.align-items-center.pl-2-plus.pr-2-plus.mb-2 - %form{ action: site_posts_path } - - @filter_params.each do |param, value| - - next if param == 'q' - %input{ type: 'hidden', name: param, value: value } - .form-group.flex-grow-0.m-0 - %label.sr-only{for: 'q'}= t('.search') - %input#q.form-control.border.border-magenta{ type: 'search', placeholder: t('.search'), name: 'q', value: @filter_params[:q] } - %input.sr-only{ type: 'submit' } - if @site.locales.size > 1 %nav#locales - @site.locales.each do |locale| = link_to @site.data.dig(locale.to_s, 'locale') || locale, site_posts_path(@site, **@filter_params.merge(locale: locale)), class: "mr-2 mt-2 mb-2 #{locale == @locale ? 'active font-weight-bold' : ''}" - .pl-2-plus - - @filter_params.each do |param, value| - - if param == 'layout' - - value = @site.layouts[value.to_sym].humanized_name - = link_to site_posts_path(@site, **@filter_params.reject { |k, _| k == param }), - class: 'btn btn-secondary btn-sm', - title: t('posts.remove_filter_help', filter: value), - aria: { labelledby: "help-filter-#{param}" } do - = value - × + - if @posts.empty? %h2= t('posts.empty') - else diff --git a/app/views/schemas/_add.haml b/app/views/schemas/_add.haml index 0131a6bb..6aaf51c9 100644 --- a/app/views/schemas/_add.haml +++ b/app/views/schemas/_add.haml @@ -1 +1 @@ -= link_to t('.add'), new_site_post_path(site, layout: schema.value), class: 'btn btn-secondary btn-sm m-0' += link_to t(schema.humanized_name), new_site_post_path(site, layout: schema.value), class: 'stretched-link black text-decoration-none' diff --git a/app/views/schemas/_row.haml b/app/views/schemas/_row.haml index 1d1fca87..edea4f2f 100644 --- a/app/views/schemas/_row.haml +++ b/app/views/schemas/_row.haml @@ -1,12 +1,10 @@ -%tr - %th.w-100{ scope: 'row' } +%tr.border-top.border-magenta + + %th.font-weight-normal.w-100.position-relative{ scope: 'row' } - if local_assigns[:parent_schema] %span.text-muted — - = schema.humanized_name - %td.px-0.text-nowrap - = render 'schemas/add', **local_assigns - = render 'schemas/filter', **local_assigns - + = render 'schemas/add', schema: schema, **local_assigns + -# XXX: Solo un nivel de recursividad - unless local_assigns[:parent_schema] - schema.schemas.each do |s| diff --git a/app/views/sites/_header.haml b/app/views/sites/_header.haml index c8931041..d4302d34 100644 --- a/app/views/sites/_header.haml +++ b/app/views/sites/_header.haml @@ -1,3 +1,27 @@ .hyphens{ lang: site.default_locale } %h1= site.title %p.lead= site.description + %form.mb-3{ action: site_posts_path } + - @filter_params.each do |param, values| + - next if param == :q + - [values].flatten.each do |value| + %input{ type: 'hidden', name: values.is_a?(Array) ? "#{param}[]" : param, value: value } + .form-group.flex-grow-0.m-0 + %label.h3{for: 'q'}= t('posts.index.search') + .input-group + %input#q.form-control.border.border-magenta.border-right-0{ type: 'search', name: 'q', value: @filter_params[:q] } + .input-group-append + %span.input-group-text.background-white.magenta.border.border-magenta.border-top.border-left-0.border-right.border-bottom + %i.fa.fa-fw.fa-search + %input.sr-only{ type: 'submit' } + - @filter_params.each do |param, values| + - [values].flatten.each do |value| + = link_to site_posts_path(@site, **filter_params_by(@filter_params, param, value)), + class: 'btn btn-secondary btn-sm', + title: t('posts.remove_filter_help', filter: value), + aria: { labelledby: "help-filter-#{param}" } do + - if param == :layout + = @site.layouts[value.to_sym].humanized_name + - else + = value + × diff --git a/config/locales/en.yml b/config/locales/en.yml index 8fa82473..0463f25d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -705,6 +705,9 @@ en: next: Next page empty: "There are no results for those search parameters." caption: Post list + filters: + title: Filters + submit: Submit attribute_ro: file: download: Download file @@ -762,7 +765,7 @@ en: date: 'date' order: 'Order' content: 'Text' - new: 'Post types' + new: 'Add content' remove_filter_help: 'Remove the filter: %{filter}' categories: 'Everything' index: diff --git a/config/locales/es.yml b/config/locales/es.yml index 056491ac..1cbdd5fb 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -713,6 +713,9 @@ es: next: Página siguiente empty: No hay artículos con estos parámetros de búsqueda. caption: Lista de artículos + filters: + title: Filtros + submit: Aplicar attribute_ro: file: download: Descargar archivo @@ -771,7 +774,7 @@ es: order: 'Posición' content: 'Cuerpo del artículo' categories: 'Todos' - new: 'Tipos de artículos' + new: 'Agregar contenido' remove_filter_help: 'Quitar este filtro: %{filter}' index: search: 'Buscar'