diff --git a/.gitignore b/.gitignore index 7a0e072c2c..df4b755d6e 100644 --- a/.gitignore +++ b/.gitignore @@ -31,9 +31,6 @@ /public/packs /public/packs-test -# Vue i18n messages generated at boot (cf. config/initializers/vue_i18n.rb) -/public/vue/*.json - # Ignore some JS stuff /node_modules /yarn-error.log diff --git a/app/controllers/admin/communication/library/files_controller.rb b/app/controllers/admin/communication/library/files_controller.rb index 7092e9a40e..f09f5ed855 100644 --- a/app/controllers/admin/communication/library/files_controller.rb +++ b/app/controllers/admin/communication/library/files_controller.rb @@ -13,6 +13,14 @@ def index @feature_nav = 'navigation/admin/communication/files' end + def picker + @picker = Communication::File::Picker.new( + objects: @files, + language: current_language, + params: params + ) + end + def show @contexts = @l10n.contexts breadcrumb @@ -30,10 +38,6 @@ def direct_upload @file = @localization.file end - def pick - # TODO generic picker - end - def edit @categories = categories breadcrumb diff --git a/app/javascript/apps/blocks-editor/components/Editor.vue b/app/javascript/apps/blocks-editor/components/Editor.vue index 5befbb3e0b..cb6f419080 100644 --- a/app/javascript/apps/blocks-editor/components/Editor.vue +++ b/app/javascript/apps/blocks-editor/components/Editor.vue @@ -1,11 +1,13 @@ + + diff --git a/app/javascript/apps/picker/PickerTestApp.vue b/app/javascript/apps/picker/PickerTestApp.vue new file mode 100644 index 0000000000..e442b0aad5 --- /dev/null +++ b/app/javascript/apps/picker/PickerTestApp.vue @@ -0,0 +1,30 @@ + + + diff --git a/app/javascript/apps/picker/components/Pagination.vue b/app/javascript/apps/picker/components/Pagination.vue new file mode 100644 index 0000000000..1a0007921d --- /dev/null +++ b/app/javascript/apps/picker/components/Pagination.vue @@ -0,0 +1,63 @@ + + + diff --git a/app/javascript/apps/picker/components/Parameters.vue b/app/javascript/apps/picker/components/Parameters.vue new file mode 100644 index 0000000000..96285e9fb4 --- /dev/null +++ b/app/javascript/apps/picker/components/Parameters.vue @@ -0,0 +1,46 @@ + + + diff --git a/app/javascript/apps/picker/components/Results.vue b/app/javascript/apps/picker/components/Results.vue new file mode 100644 index 0000000000..212606dce0 --- /dev/null +++ b/app/javascript/apps/picker/components/Results.vue @@ -0,0 +1,18 @@ + + + diff --git a/app/models/communication/file/picker.rb b/app/models/communication/file/picker.rb new file mode 100644 index 0000000000..bbd0ce98ed --- /dev/null +++ b/app/models/communication/file/picker.rb @@ -0,0 +1,101 @@ +class Communication::File::Picker + attr_reader :objects, :language, :params + + def initialize(objects:, language:, params:) + @objects = objects + @language = language + @params = params + end + + def parameters + { + search: search, + filters: filters, + sorts: sorts, + query_parameters: '', + } + end + + def pagination + { + current_page: current_page, + limit_value: results.limit_value, + total_count: results.total_count, + total_pages: results.total_pages, + query_parameters: "&page=#{current_page}" + } + end + + def results + @results ||= objects_paginated.any? ? objects_paginated : objects_on_first_page + end + + protected + + # Actions successives + # 1. filter + # 2. sort + # 3. paginate (avec gestion du retour page 1) + + def objects_filtered + @objects_filtered ||= objects.filter_by(params[:filters], language) + end + + def objects_sorted + @objects_sorted ||= objects_filtered.ordered(language) + end + + def objects_paginated + @objects_paginated ||= objects_sorted.page(params[:page]).per(2) + end + + def objects_on_first_page + @objects_on_first_page ||= objects_sorted.page(1).per(2) + end + + def search + { + term: term, + query_parameters: "&filters[for_search_term]=#{term}" + } + end + + def current_page + [results.current_page, results.total_pages].min + end + + def term + params.dig(:filters, :for_search_term).to_s + end + + def filters + [ + { + id: 'categories', + name: 'Catégories', + values: [ + { + id: 'cat-1', + name: 'Catégorie 1', + selected: false, + query_parameters: '&filters[for_category][]=d05ab9f9-a8fb-42e3-8aca-8fe73fa08913' } + ] + } + ] + end + + def sorts + [ + { + id: 'date-desc', + name: 'Les plus récents d\'abord', + selected: true + }, + { + id: 'date-asc', + name: 'Les plus anciens d\'abord', + selected: false + } + ] + end +end \ No newline at end of file diff --git a/app/views/admin/communication/blocks/components/file/_edit.html.erb b/app/views/admin/communication/blocks/components/file/_edit.html.erb index 87e5fe62a0..49e7b589d8 100644 --- a/app/views/admin/communication/blocks/components/file/_edit.html.erb +++ b/app/views/admin/communication/blocks/components/file/_edit.html.erb @@ -4,6 +4,11 @@ remove = t('admin.communication.blocks.components.file.input.remove') hint = file_hint if hint.blank? accept ||= '*' %> + + + +
+
\ No newline at end of file diff --git a/app/views/admin/communication/library/files/picker.json.jbuilder b/app/views/admin/communication/library/files/picker.json.jbuilder new file mode 100644 index 0000000000..5a53b4652a --- /dev/null +++ b/app/views/admin/communication/library/files/picker.json.jbuilder @@ -0,0 +1,17 @@ +json.parameters @picker.parameters +json.pagination @picker.pagination +json.results do + json.list @picker.results do |file| + l10n = file.localized_in(current_language) + json.data do + json.communication_file_id file.id + json.filename l10n.original_filename + json.name l10n.name + end + json.snippet render( + partial: 'admin/communication/library/files/file', + locals: { file: file }, + formats: [:html] + ) + end +end \ No newline at end of file diff --git a/app/views/admin/layouts/application.html.erb b/app/views/admin/layouts/application.html.erb index 63a1b4decf..fd49d221ad 100644 --- a/app/views/admin/layouts/application.html.erb +++ b/app/views/admin/layouts/application.html.erb @@ -1,5 +1,5 @@ - +"> diff --git a/config/initializers/vue_i18n.rb b/config/initializers/vue_i18n.rb index 22f123e897..1d3b492081 100644 --- a/config/initializers/vue_i18n.rb +++ b/config/initializers/vue_i18n.rb @@ -1,13 +1,15 @@ -# Génère les fichiers de traduction statiques des apps Vue dans -# public/vue/.json. Ils servent de messages à vue-i18n (cf. -# app/javascript/apps/index.js) et sont chargés une seule fois, en statique -# cacheable, plutôt que sérialisés dans chaque page. +# Génère les messages de traduction des apps Vue dans app/assets/builds/vue/, +# aux côtés de vue-apps.js (cf. app/assets/config/manifest.js: link_tree +# ../builds). Sprockets les prend donc en charge comme n'importe quel asset : +# digest de cache-busting et far-future cache-control automatiques, servis via +# asset_path("vue/#{locale}.json") (cf. layout admin et app/javascript/apps/i18n.js). # -# after_initialize garantit que tous les config/locales/**/*.yml sont bien -# ajoutés à I18n.load_path. En dev, redémarrer le serveur régénère les fichiers -# après modification d'une traduction. Rails.application.config.after_initialize do - output_dir = Rails.root.join('public', 'vue') + # after_initialize garantit que tous les config/locales/**/*.yml sont bien + # ajoutés à I18n.load_path, et s'exécute avant assets:precompile (jsbundling-rails + # le fait dépendre de la tâche `environment`). En dev, redémarrer le serveur + # régénère les fichiers après modification d'une traduction. + output_dir = Rails.root.join('app', 'assets', 'builds', 'vue') FileUtils.mkdir_p(output_dir) I18n.available_locales.each do |locale| translations = I18n.t('vue', locale: locale, default: {}) diff --git a/config/locales/vue/en.yml b/config/locales/vue/en.yml index cf32651fd1..47125fa183 100644 --- a/config/locales/vue/en.yml +++ b/config/locales/vue/en.yml @@ -115,6 +115,21 @@ en: title: Photo library remove: Remove image title: Image + picker: + pagination: + next: Next page + previous: Previous page + parameters: + search: + title: Search + placeholder: Type your search here + filters: Filter + sorts: Sort + kind: + files: + button: Choose a file in the library + modal: + title: File library timeSlots: add: Add a time slot datetime: diff --git a/config/locales/vue/fr.yml b/config/locales/vue/fr.yml index 94f65e3cad..fcde6ad5fd 100644 --- a/config/locales/vue/fr.yml +++ b/config/locales/vue/fr.yml @@ -115,6 +115,21 @@ fr: title: Photothèque remove: Supprimer l'image title: Image + picker: + pagination: + next: Page suivante + previous: Page précédente + parameters: + search: + title: Chercher + placeholder: Tapez le texte + filters: Filtrer + sorts: Trier + kind: + files: + button: Choisir un fichier dans la bibliothèque + modal: + title: Bibliothèque de fichiers timeSlots: add: Ajouter un créneau horaire datetime: diff --git a/config/routes/admin/communication.rb b/config/routes/admin/communication.rb index 58cfb1278f..890f7bd80d 100644 --- a/config/routes/admin/communication.rb +++ b/config/routes/admin/communication.rb @@ -292,7 +292,7 @@ resources :files do collection do post 'direct-upload' => 'files#direct_upload', as: :direct_upload - post 'pick' => 'files#pick', as: :pick + get 'picker' => 'files#picker', as: :picker resources :categories, controller: '/admin/communication/library/files/categories', as: 'file_categories' do collection do post :reorder