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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.

- support for `video/x-m4v` files (mapped to `video/mp4` for browser compatibility)
- `has_folio_positionable?` class method to `Folio::Positionable` and `Folio::PositionableDescending` concerns
- `created_by_folio_user` relation to `Folio::File` and "my files" filter to console

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ legend
z-index: 99999
background-color: $form-select-bg

.f-c-ui-input-with-buttons--1 .input-group--filled &
right: 30px

.form-control,
.form-select,
.form-check-input
Expand Down Expand Up @@ -112,4 +115,4 @@ legend
.form-control
border-top-right-radius: $border-radius !important
border-bottom-right-radius: $border-radius !important
padding-right: $form-select-indicator-padding
padding-right: $form-select-indicator-padding
2 changes: 1 addition & 1 deletion app/components/folio/console/files/show_component.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ window.Folio.Stimulus.register('f-c-files-show', class extends window.Stimulus.C
this.loadingValue = true

this.replacingFileData = {
s3_path: new URL(event.detail.result.uploadURL).pathname.replace(/^\//, ''),
s3_path: event.detail.file.s3_path,
jwt: event.detail.file.jwt,
type: this.fileTypeValue,
existing_id: this.idValue,
Expand Down
10 changes: 10 additions & 0 deletions app/components/folio/console/ui/index/filters_component.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ window.Folio.Stimulus.register('f-c-ui-index-filters', class extends window.Stim

// Only add non-empty values
for (const formControl of this.element.querySelectorAll('input, .form-control')) {
if (formControl.type === 'checkbox') {
if (!formControl.checked) {
continue
}
} else if (formControl.type === 'hidden') {
if (formControl.closest('.form-check')) {
continue
}
}

const value = formControl.value

if (value && value.toString().trim() !== '') {
Expand Down
49 changes: 38 additions & 11 deletions app/components/folio/console/ui/index/filters_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ def input(f, key)

if data[:as] == :collection
collection_input(f, key)
elsif data[:as] == :boolean
boolean_input(f, key)
elsif data[:as] == :date_range
date_range_input(f, key)
elsif data[:as] == :hidden
Expand All @@ -97,7 +99,7 @@ def input(f, key)

text_autocomplete_input(f, key, url:)
else
text_input(f, key)
text_input(f, key, icon: data[:icon])
end
elsif data[:autocomplete]
url = data[:url] || controller.folio.console_api_autocomplete_path(klass: data[:klass],
Expand Down Expand Up @@ -146,16 +148,26 @@ def numeric_range_input(f, key, type:)
clear_button: controller.params[full_key].present?
end

def text_input(f, key)
f.input key, label: false,
input_html: {
class: "f-c-ui-index-filters__text-input",
placeholder: blank_label(key),
value: controller.params[key]
},
wrapper_html: { class: "f-c-ui-index-filters__text-input-wrap input-group--#{controller.params[key].present? ? "filled" : "empty"}" },
wrapper: :input_group,
clear_button: controller.params[key].present?
def text_input(f, key, icon: nil)
captured_input = capture do
f.input key, label: false,
input_html: {
class: "f-c-ui-index-filters__text-input",
placeholder: blank_label(key),
value: controller.params[key]
},
wrapper_html: { class: "f-c-ui-index-filters__text-input-wrap input-group--#{controller.params[key].present? ? "filled" : "empty"}" },
wrapper: :input_group,
clear_button: controller.params[key].present?
end

if icon
buttons_kwargs = [{ variant: :icon, icon: icon, type: :submit }]

render(Folio::Console::Ui::InputWithButtonsComponent.new(input: captured_input, buttons_kwargs:))
else
captured_input
end
end

def text_autocomplete_input(f, key, url:)
Expand Down Expand Up @@ -203,6 +215,17 @@ def collapsible_class_name(config)
end
end

def boolean_input(f, key)
f.input key, as: :boolean,
label: label_for_key(key),
input_html: {
class: "f-c-ui-index-filters__boolean-input",
value: "1",
checked: controller.params[key] == "1",
},
wrapper_html: { class: "f-c-ui-index-filters__boolean-input-wrap" }
end

def filter_style(config, filtered: false)
width = if config[:width]
if config[:width].is_a?(Numeric)
Expand All @@ -214,6 +237,10 @@ def filter_style(config, filtered: false)
"auto"
elsif filtered && config[:as] == :date_range
"250px"
elsif config[:as] == :boolean
"auto"
elsif config[:as] == :text && config[:icon]
"290px"
else
"235px"
end
Expand Down
16 changes: 16 additions & 0 deletions app/components/folio/console/ui/index/filters_component.sass
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@
svg
transition: transform 0.2s ease

&__boolean-input-wrap
.form-check
margin: 0
min-height: $input-height
display: flex
align-items: center
padding: 0
gap: 0.75ch

.form-label
margin: 0

.form-check-input
margin: 0
float: none

&--expanded &__toggle svg
transform: rotate(180deg)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ div[
.f-c-ui-index-filters__filter[
class=collapsible_class_name(config)
class="f-c-ui-index-filters__filter--#{key}"
class="f-c-ui-index-filters__filter--as-#{config[:as]}"
style=filter_style(config, filtered:)
]
- if config[:as] == :numeric_range
Expand Down
16 changes: 4 additions & 12 deletions app/controllers/concerns/folio/console/api/file_controller_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

module Folio::Console::Api::FileControllerBase
extend ActiveSupport::Concern
include Folio::Console::FileControllerIndexFilters

S3_PATH_DOWNLOAD_BASE = "tmp/folio-files-batch-download"

Expand Down Expand Up @@ -78,8 +79,10 @@ def destroy
def pagination
@pagy, _records = pagy(folio_console_records, items: Folio::Console::FileControllerBase::PAGY_ITEMS)

pagination_params = filter_params.to_h.merge("page" => params[:page])

@pagy_options = {
reload_url: url_for([:pagination, :console, :api, @klass, page: params[:page]]),
reload_url: url_for([:pagination, :console, :api, @klass, pagination_params]),
request_path: pagination_request_path
}

Expand Down Expand Up @@ -351,17 +354,6 @@ def folio_console_collection_includes
includes
end

def filter_params
params.permit(:by_file_name,
:by_placement,
:by_tags,
:by_used,
:by_photo_archive,
:by_usage_constraints,
:by_allowed_site_slug,
:by_media_source)
end

def file_params_whitelist
ary = [
:tag_list,
Expand Down
25 changes: 4 additions & 21 deletions app/controllers/concerns/folio/console/file_controller_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

module Folio::Console::FileControllerBase
extend ActiveSupport::Concern
include Folio::Console::FileControllerIndexFilters

PAGY_ITEMS = 64

Expand Down Expand Up @@ -126,8 +127,10 @@ def set_file_for_show_modal
end

def set_pagy_options
pagination_params = filter_params.to_h.merge("page" => params[:page])

@pagy_options = {
reload_url: url_for([:pagination, :console, :api, @klass, page: params[:page]]),
reload_url: url_for([:pagination, :console, :api, @klass, pagination_params]),
skip_default_layout_pagination: true,
}

Expand Down Expand Up @@ -159,26 +162,6 @@ def message_bus_broadcast_update
user_ids:
end

def index_filters
filters = {
by_used: [true, false],
by_tag_id: {
klass: "ActsAsTaggableOn::Tag",
},
}

if @klass.included_modules.include?(Folio::File::HasUsageConstraints)
filters[:by_usage_constraints] = @klass.usage_constraints_for_select
filters[:by_media_source] = { klass: "Folio::MediaSource", order_scope: :ordered }

if Rails.application.config.folio_shared_files_between_sites
filters[:by_allowed_site_slug] = Folio::Site.ordered.map { |site| [site.to_label, site.slug] }
end
end

filters
end

def allowed_record_sites
if Rails.application.config.folio_shared_files_between_sites
[Folio::File.correct_site(Folio::Current.site), Folio::Current.site]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

module Folio::Console::FileControllerIndexFilters
extend ActiveSupport::Concern

private
def index_filters
filters = {
# TODO: enable with the rest of the filtering changes
# by_query: { as: :text, icon: :magnify },
created_by_current_user: { as: :boolean },
by_used: [true, false],
by_tag_id: {
klass: "ActsAsTaggableOn::Tag",
},
}

if @klass.included_modules.include?(Folio::File::HasUsageConstraints)
filters[:by_usage_constraints] = @klass.usage_constraints_for_select
filters[:by_media_source] = { klass: "Folio::MediaSource", order_scope: :ordered }

if Rails.application.config.folio_shared_files_between_sites
filters[:by_allowed_site_slug] = Folio::Site.ordered.map { |site| [site.to_label, site.slug] }
end
end

filters
end
end
4 changes: 4 additions & 0 deletions app/jobs/folio/s3/create_file_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ def prepare_file_model(klass, id:, web_session_id:, user_id:, attributes: {})
@file.web_session_id = web_session_id if @file.respond_to?("web_session_id=")
@file.user = Folio::User.find(user_id) if user_id && @file.respond_to?("user=")

if user_id && @file.respond_to?("created_by_folio_user_id=")
@file.created_by_folio_user_id = Folio::User.find(user_id).id
end

if attributes.present?
if attributes[:site_id].present? && @file.respond_to?("site_id=")
@file.assign_attributes(attributes)
Expand Down
44 changes: 31 additions & 13 deletions app/models/folio/file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ class Folio::File < Folio::ApplicationRecord
# Relations
has_many :file_placements, class_name: "Folio::FilePlacement::Base"
has_many :placements, through: :file_placements
belongs_to :created_by_folio_user, class_name: "Folio::User",
optional: true,
inverse_of: :created_files

# Validations
validates :file, :type,
Expand All @@ -97,6 +100,14 @@ class Folio::File < Folio::ApplicationRecord

scope :by_placement, -> (placement_title) { order(created_at: :desc) }

scope :created_by_current_user, Proc.new {
if Folio::Current.user.present?
where(created_by_folio_user_id: Folio::Current.user.id)
else
none
end
}

scope :by_used, -> (used) do
case used
when true, "true"
Expand All @@ -112,13 +123,17 @@ class Folio::File < Folio::ApplicationRecord
by_file_name_for_search(sanitize_filename_for_search(query))
end

pg_search_scope :by_query,
against: [:file_name, :headline, :description],
pg_search_scope :by_query_raw,
against: [:file_name_for_search, :headline, :description],
ignoring: :accents,
using: {
tsearch: { prefix: true }
}

scope :by_query, -> (query) do
by_query_raw(sanitize_filename_for_search(query))
end

pg_search_scope :by_file_name_for_search,
against: [:file_name_for_search],
ignoring: :accents,
Expand Down Expand Up @@ -537,23 +552,26 @@ def dispatch_destroyed_message
# attribution_max_usage_count :integer
# published_usage_count :integer default(0), not null
# thumbnail_configuration :jsonb
# created_by_folio_user_id :bigint(8)
#
# Indexes
#
# index_folio_files_on_by_author (to_tsvector('simple'::regconfig, folio_unaccent(COALESCE((author)::text, ''::text)))) USING gin
# index_folio_files_on_by_file_name (to_tsvector('simple'::regconfig, folio_unaccent(COALESCE((file_name)::text, ''::text)))) USING gin
# index_folio_files_on_by_file_name_for_search (to_tsvector('simple'::regconfig, folio_unaccent(COALESCE((file_name_for_search)::text, ''::text)))) USING gin
# index_folio_files_on_created_at (created_at)
# index_folio_files_on_file_name (file_name)
# index_folio_files_on_media_source_id (media_source_id)
# index_folio_files_on_published_usage_count (published_usage_count)
# index_folio_files_on_site_id (site_id)
# index_folio_files_on_slug (slug)
# index_folio_files_on_type (type)
# index_folio_files_on_updated_at (updated_at)
# index_folio_files_on_by_author (to_tsvector('simple'::regconfig, folio_unaccent(COALESCE((author)::text, ''::text)))) USING gin
# index_folio_files_on_by_file_name (to_tsvector('simple'::regconfig, folio_unaccent(COALESCE((file_name)::text, ''::text)))) USING gin
# index_folio_files_on_by_file_name_for_search (to_tsvector('simple'::regconfig, folio_unaccent(COALESCE((file_name_for_search)::text, ''::text)))) USING gin
# index_folio_files_on_created_at (created_at)
# index_folio_files_on_created_by_folio_user_id (created_by_folio_user_id)
# index_folio_files_on_file_name (file_name)
# index_folio_files_on_media_source_id (media_source_id)
# index_folio_files_on_published_usage_count (published_usage_count)
# index_folio_files_on_site_id (site_id)
# index_folio_files_on_slug (slug)
# index_folio_files_on_type (type)
# index_folio_files_on_updated_at (updated_at)
#
# Foreign Keys
#
# fk_rails_... (created_by_folio_user_id => folio_users.id) ON DELETE => nullify
# fk_rails_... (media_source_id => folio_media_sources.id)
# fk_rails_... (site_id => folio_sites.id)
#
Loading