From a406bff75be126b52cdb70fe422bf65af3beab5d Mon Sep 17 00:00:00 2001 From: Arnaud Levy Date: Mon, 17 Aug 2026 10:00:55 +0200 Subject: [PATCH 01/83] Branchement des medias --- .../apps/media-picker/MediaPickerApp.vue | 25 ++++++++++++------- app/javascript/apps/picker/Picker.vue | 6 ++++- .../library/medias/_picker.html.erb | 1 + 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/app/javascript/apps/media-picker/MediaPickerApp.vue b/app/javascript/apps/media-picker/MediaPickerApp.vue index 9a24d8cda..3b82ea360 100644 --- a/app/javascript/apps/media-picker/MediaPickerApp.vue +++ b/app/javascript/apps/media-picker/MediaPickerApp.vue @@ -1,16 +1,18 @@ - - diff --git a/app/javascript/apps/media-picker/components/medias/Categories.vue b/app/javascript/apps/media-picker/components/medias/Categories.vue deleted file mode 100644 index f78998834..000000000 --- a/app/javascript/apps/media-picker/components/medias/Categories.vue +++ /dev/null @@ -1,38 +0,0 @@ - - - diff --git a/app/javascript/apps/media-picker/components/medias/Taxonomies.vue b/app/javascript/apps/media-picker/components/medias/Taxonomies.vue deleted file mode 100644 index 990f8ce8a..000000000 --- a/app/javascript/apps/media-picker/components/medias/Taxonomies.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/app/views/admin/communication/library/medias/_picker.html.erb b/app/views/admin/communication/library/medias/_picker.html.erb index 9f477ab5d..9c8cfdc14 100644 --- a/app/views/admin/communication/library/medias/_picker.html.erb +++ b/app/views/admin/communication/library/medias/_picker.html.erb @@ -22,7 +22,6 @@ cloud = { data-formats-accepted-hint="<%= images_formats_accepted_hint %>" data-cloud="<%= cloud.to_json %>" data-keycdn="<%= ENV["KEYCDN_HOST"] %>" - data-media-endpoint="<%= admin_communication_medias_url(website_id: nil, extranet_id: nil, journal_id: nil, format: :json) %>" data-picker-endpoint="<%= picker_admin_communication_medias_path(website_id: nil, extranet_id: nil, journal_id: nil, format: :json) %>" > diff --git a/app/views/admin/communication/library/medias/index.json.jbuilder b/app/views/admin/communication/library/medias/index.json.jbuilder deleted file mode 100644 index 1d82c1987..000000000 --- a/app/views/admin/communication/library/medias/index.json.jbuilder +++ /dev/null @@ -1,20 +0,0 @@ -json.total @medias.total_count -json.total_pages @medias.total_pages -json.collections @collections do |collection| - json.id collection.id - json.name collection.to_s_in(current_language) -end - -json.partial! 'admin/application/categories/list', categories: @categories - -json.results @medias do |media| - next unless media.original_blob.variable? - thumb_path = ENV["KEYCDN_HOST"].present? ? media.keycdn_thumb_url - : url_for(media.original_blob.variant(resize_to_fit: [600, nil])) - l10n = media.best_localization_for(current_language) - json.id media.id - json.name l10n.name - json.credit l10n.credit.to_s - json.alt l10n.alt.to_s - json.thumb thumb_path -end diff --git a/config/locales/vue/en.yml b/config/locales/vue/en.yml index 5f84e6ae5..574b4d48f 100644 --- a/config/locales/vue/en.yml +++ b/config/locales/vue/en.yml @@ -115,12 +115,6 @@ en: title: Image too heavy medias: button: Choose from photo library - collections: Collections - next: Next images - nothing: No results for this search - placeholder: Type your search here - previous: Previous images - search: Search title: Photo library remove: Remove image title: Image diff --git a/config/locales/vue/fr.yml b/config/locales/vue/fr.yml index 7c6c02924..fba0768f1 100644 --- a/config/locales/vue/fr.yml +++ b/config/locales/vue/fr.yml @@ -115,12 +115,6 @@ fr: title: Image trop lourde medias: button: Choisir dans la photothèque - collections: Collections - next: Images suivantes - nothing: Aucun résultat pour cette recherche - placeholder: Tapez votre recherche - previous: Images précédentes - search: Chercher title: Photothèque remove: Supprimer l'image title: Image From 0f1aa03c072d8744c3ffec3cdb4ebf3247cd3657 Mon Sep 17 00:00:00 2001 From: Arnaud Levy Date: Mon, 17 Aug 2026 13:25:25 +0200 Subject: [PATCH 04/83] =?UTF-8?q?Image=20choisie=20dans=20la=20biblioth?= =?UTF-8?q?=C3=A8que?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/components/inputs/MediaInput.vue | 102 ++++++++++++++++++ .../inputs/media-input}/Cloud.vue | 2 +- .../inputs/media-input}/ImageUploader.vue | 4 +- .../selected-objects/SelectedMedia.vue | 20 ++-- .../FeaturedImageApp.vue} | 64 ++++------- app/javascript/apps/i18n.js | 1 + app/javascript/apps/index.js | 8 +- app/services/osuny/media/picker.rb | 1 + .../library/medias/_picker.html.erb | 4 +- .../library/medias/show.json.jbuilder | 5 + 10 files changed, 147 insertions(+), 64 deletions(-) create mode 100644 app/javascript/apps/components/inputs/MediaInput.vue rename app/javascript/apps/{media-picker/components => components/inputs/media-input}/Cloud.vue (99%) rename app/javascript/apps/{media-picker/components => components/inputs/media-input}/ImageUploader.vue (97%) rename app/javascript/apps/{media-picker/MediaPickerApp.vue => featured-image/FeaturedImageApp.vue} (54%) create mode 100644 app/views/admin/communication/library/medias/show.json.jbuilder diff --git a/app/javascript/apps/components/inputs/MediaInput.vue b/app/javascript/apps/components/inputs/MediaInput.vue new file mode 100644 index 000000000..575bb439a --- /dev/null +++ b/app/javascript/apps/components/inputs/MediaInput.vue @@ -0,0 +1,102 @@ + + + diff --git a/app/javascript/apps/media-picker/components/Cloud.vue b/app/javascript/apps/components/inputs/media-input/Cloud.vue similarity index 99% rename from app/javascript/apps/media-picker/components/Cloud.vue rename to app/javascript/apps/components/inputs/media-input/Cloud.vue index 81ce7beea..699ae94a0 100644 --- a/app/javascript/apps/media-picker/components/Cloud.vue +++ b/app/javascript/apps/components/inputs/media-input/Cloud.vue @@ -89,7 +89,7 @@ export default { }, }, beforeMount() { - const dataset = document.getElementById('media-picker-app').dataset; + const dataset = document.getElementById('featured-image-app').dataset; this.lang = dataset.lang; this.query = JSON.parse(dataset.current).about.name; this.settings = JSON.parse(dataset.cloud); diff --git a/app/javascript/apps/media-picker/components/ImageUploader.vue b/app/javascript/apps/components/inputs/media-input/ImageUploader.vue similarity index 97% rename from app/javascript/apps/media-picker/components/ImageUploader.vue rename to app/javascript/apps/components/inputs/media-input/ImageUploader.vue index fdf23b17c..24a17e22e 100644 --- a/app/javascript/apps/media-picker/components/ImageUploader.vue +++ b/app/javascript/apps/components/inputs/media-input/ImageUploader.vue @@ -1,6 +1,6 @@ diff --git a/app/javascript/apps/media-picker/MediaPickerApp.vue b/app/javascript/apps/featured-image/FeaturedImageApp.vue similarity index 54% rename from app/javascript/apps/media-picker/MediaPickerApp.vue rename to app/javascript/apps/featured-image/FeaturedImageApp.vue index 71572c902..ec3fd5d9f 100644 --- a/app/javascript/apps/media-picker/MediaPickerApp.vue +++ b/app/javascript/apps/featured-image/FeaturedImageApp.vue @@ -1,21 +1,20 @@ @@ -84,14 +71,16 @@ export default { :value="uploadProgress" max="100" style="width: 100%;" /> - +
+ :endpoint="cloudSelectEndpoint" + @selected="mediaSelected" /> diff --git a/app/javascript/apps/components/inputs/media-input/Cloud.vue b/app/javascript/apps/components/inputs/media-input/Cloud.vue index 1f856a4c9..7726dcdb8 100644 --- a/app/javascript/apps/components/inputs/media-input/Cloud.vue +++ b/app/javascript/apps/components/inputs/media-input/Cloud.vue @@ -7,6 +7,12 @@ export default { ArrowRight, ArrowLeft }, + emits: [ + 'selected' + ], + props: { + endpoint: { type: String, required: true }, + }, data () { return { modal: false, @@ -44,14 +50,14 @@ export default { this.searchPexels(); }, searchUnsplash() { - var url = this.settings.unsplash.endpoint + let url = this.settings.unsplash.endpoint + '?query=' + encodeURIComponent(this.query) + '&page=' + this.unsplash.page + '&per_page=12&lang=' + this.lang; this.loadSearchResults(url, this.unsplash); }, searchPexels() { - var url = this.settings.pexels.endpoint + let url = this.settings.pexels.endpoint + '?query=' + encodeURIComponent(this.query) + '&page=' + this.pexels.page + '&per_page=12&lang=' + this.lang; @@ -61,23 +67,36 @@ export default { if (!this.query) { return null; } - var xhr = new XMLHttpRequest(); + let xhr = new XMLHttpRequest(); + xhr.open("GET", url, false); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { source.data.results = []; source.data = JSON.parse(xhr.responseText); } }.bind(this); - xhr.open("GET", url, false); xhr.send(); }, - selectUnsplash(image) { - this.$emit('unsplashSelected', image); + selectUnsplash(data) { this.close(); + this.upload('unsplash', data) }, - selectPexels(image) { - this.$emit('pexelsSelected', image); + selectPexels(data) { this.close(); + this.upload('pexels', data) + }, + upload(origin, data) { + let xhr = new XMLHttpRequest(); + xhr.open("POST", this.endpoint, false); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.setRequestHeader('X-CSRF-Token', document.querySelector('[name="csrf-token"]').content); + xhr.onreadystatechange = function() { + if (xhr.readyState == 4 && xhr.status == 200) { + this.$emit('selected', xhr.responseText); + } + }.bind(this); + data.origin = origin; + xhr.send(JSON.stringify(data)); }, }, watch: { @@ -89,7 +108,7 @@ export default { }, }, beforeMount() { - const dataset = document.getElementById('featured-image-app').dataset; + const dataset = document.getElementById('featured-media-app').dataset; this.lang = dataset.lang; this.query = JSON.parse(dataset.current).about.name; this.settings = JSON.parse(dataset.cloud); diff --git a/app/javascript/apps/components/inputs/media-input/ImageUploader.vue b/app/javascript/apps/components/inputs/media-input/ImageUploader.vue index 595033b0b..eabe9c669 100644 --- a/app/javascript/apps/components/inputs/media-input/ImageUploader.vue +++ b/app/javascript/apps/components/inputs/media-input/ImageUploader.vue @@ -7,6 +7,12 @@ export default { Upload, CropperModal, }, + props: { + endpoint: { type: String, required: true }, + }, + emits: [ + 'uploaded' + ], computed: { sizeWarningSentence: { get() { @@ -19,7 +25,6 @@ export default { }, data () { return { - endpoint: "/rails/active_storage/direct_uploads", input: { field: null, object: null, @@ -70,18 +75,19 @@ export default { }, uploadFile() { this.directUpload = new ActiveStorage.DirectUpload(this.input.object, this.endpoint, this); - this.directUpload.create(function (error, blob) { + this.directUpload.create(function (error, data) { if (error) { console.error(error); return; } - - this.setBlob(blob); - if (this.isResizable(this.input.object)) { - this.$refs.cropper.launch(this.blob); - } else { - this.$emit('uploaded', this.blob); - } + this.$emit('uploaded', data.media); + // TODO + // this.setBlob(blob); + // if (this.isResizable(this.input.object)) { + // this.$refs.cropper.launch(this.blob); + // } else { + // this.$emit('uploaded', this.blob); + // } }.bind(this)); }, setBlob(blob) { @@ -111,7 +117,7 @@ export default { }, }, beforeMount() { - const dataset = document.getElementById('featured-image-app').dataset + const dataset = document.getElementById('featured-media-app').dataset if (dataset.keycdn !== '') { this.keycdnUrl = "https://" + dataset.keycdn; } diff --git a/app/javascript/apps/components/selected-objects/_mixin.js b/app/javascript/apps/components/selected-objects/_mixin.js index 426664e05..f70e92040 100644 --- a/app/javascript/apps/components/selected-objects/_mixin.js +++ b/app/javascript/apps/components/selected-objects/_mixin.js @@ -19,7 +19,8 @@ export default { this.loading = true; this.resource = null; try { - const res = await fetch(`${this.endpoint}/${this.id}.json`); + const url = this.endpoint + '/' + this.id + '.json'; + const res = await fetch(url); if (!res.ok) throw new Error(res.statusText); this.resource = await res.json(); } catch (error) { diff --git a/app/javascript/apps/featured-image/FeaturedImageApp.vue b/app/javascript/apps/featured-media/FeaturedMediaApp.vue similarity index 80% rename from app/javascript/apps/featured-image/FeaturedImageApp.vue rename to app/javascript/apps/featured-media/FeaturedMediaApp.vue index 4fdd6dad1..cbcf32b7a 100644 --- a/app/javascript/apps/featured-image/FeaturedImageApp.vue +++ b/app/javascript/apps/featured-media/FeaturedMediaApp.vue @@ -24,11 +24,10 @@ export default { remove() { this.resetOrigin(); this.current.media = ''; - this.current.origin.blob.delete = true; }, }, beforeMount() { - this.dataset = document.getElementById('featured-image-app').dataset + this.dataset = document.getElementById('featured-media-app').dataset this.summernoteLang = this.dataset.summernoteLang; this.current = JSON.parse(this.dataset.current); }, @@ -39,6 +38,7 @@ export default {