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
20 changes: 14 additions & 6 deletions app/controllers/better_together/content/blocks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ def index
end

def create
@block = resource_class.new(block_params)
@block = resource_class.new(block_params.except(:media_signed_id))
attach_signed_media(@block)

if @block.save
redirect_to content_block_path(@block),
Expand All @@ -27,11 +28,13 @@ def create
end
end

def update # rubocop:todo Metrics/MethodLength
def update
@block.assign_attributes(block_params.except(:media_signed_id))
attach_signed_media(@block)

respond_to do |format|
if @block.update(block_params)
redirect_to edit_content_block_path(@block),
notice: t('flash.generic.updated', resource: t('resources.block'))
if @block.save
redirect_to edit_content_block_path(@block), notice: t('flash.generic.updated', resource: t('resources.block'))
else
format.turbo_stream do
render turbo_stream: turbo_stream.replace(helpers.dom_id(@block, 'form'), partial: 'form',
Expand All @@ -57,7 +60,7 @@ def destroy

def block_params
params.require(:block).permit(
:type, :media, :identifier,
:type, :media, :media_signed_id, :identifier,
*resource_class.localized_block_attributes,
*resource_class.storext_keys
)
Expand All @@ -67,6 +70,11 @@ def set_block
@block = set_resource_instance
end

def attach_signed_media(record)
signed_id = params.dig(:block, :media_signed_id)
record.media.attach(signed_id) if signed_id.present?
end

def resource_class
BetterTogether::Content::Block
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Controller } from "@hotwired/stimulus"
// import { Modal } from "bootstrap"

export default class extends Controller {
static targets = ["modal", "signedIdField"]

connect() {
this.modal = new bootstrap.Modal(this.modalTarget)
}

open() {
this.modal.show()
}

select(event) {
const { signedId, url } = event.currentTarget.dataset
this.signedIdFieldTarget.value = signedId
const previewController = this.application.getControllerForElementAndIdentifier(this.element, "better_together--image-preview")
if (previewController && typeof previewController.previewFromUrl === "function") {
previewController.previewFromUrl(url)
}
this.modal.hide()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ export default class extends Controller {
this.updateHeight(); // Update the height of the container
}

previewFromUrl(url) {
this.existingImageUrl = url;
this.clearInput();
this.previewExistingImage();
this.deleteFieldTarget.value = '0';
this.updateDeleteButtonState();
}

toggleDelete() {
if (this.deleteFieldTarget.value === '0' && (this.inputTarget.files.length > 0 || this.existingImageUrl)) {
this.deleteFieldTarget.value = '1'; // Mark for deletion
Expand Down
26 changes: 25 additions & 1 deletion app/views/better_together/content/blocks/fields/_image.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<%- scope = local_assigns[:scope] ? local_assigns[:scope] : BetterTogether::Content::Block.block_name %>
<div class="image-fields" data-controller="better_together--image-preview">
<div class="image-fields" data-controller="better_together--image-preview better_together--image-library">
<%= label_tag do %>
<%= block.class.human_attribute_name('media') %>
<% if block.media.attached? %>
Expand All @@ -9,6 +9,8 @@
<% end %>
<div class="input-group">
<%= file_field_tag "#{scope}[media]", required: !block.media.attached?, accept: acceptable_image_file_types, "data-better_together--image-preview-target" => "input", data: { 'action' => "better_together--image-preview#preview" }, class: "form-control" %>
<%= button_tag 'Choose from library',
{ type: 'button', class: 'btn btn-outline-secondary', data: { action: 'better_together--image-library#open' } } %>
<%= hidden_field_tag "#{scope}[remove_media]", { value: '0' }, "data-better_together--image-preview-target" => "deleteField" %>
<%= button_tag t('globals.clear'),
{
Expand All @@ -23,11 +25,33 @@
"data-better_together--image-preview-target" => "deleteButton",
} %>
</div>
<%= hidden_field_tag "#{scope}[media_signed_id]", nil, "data-better_together--image-library-target" => 'signedIdField' %>
<!-- Image preview container (empty initially) -->
<div class="my-3 text-center" data-better_together--image-preview-target="preview" data-url="<%= block.media.url if block.media.attached? %>">
<!-- The image preview will be dynamically inserted here -->
</div>

<div class="modal fade" tabindex="-1" data-better_together--image-library-target="modal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Choose from library</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row g-2">
<% BetterTogether::Upload.with_creator(current_person).each do |upload| %>
<% next unless upload.content_type.start_with?('image/') %>
<div class="col-3">
<%= image_tag upload.url, class: 'img-fluid', data: { action: 'click->better_together--image-library#select', signed_id: upload.file.blob.signed_id, url: upload.url } %>
</div>
<% end %>
</div>
</div>
</div>
</div>
</div>

<div class="row row-cols-1 row-cols-sm-2 align-items-end">
<div class="col mb-3 pb-3 border-bottom">
<%= render partial: 'better_together/content/blocks/fields/shared/translatable_string_field', locals: { model: block, attribute: 'alt_text', scope: } %>
Expand Down
34 changes: 34 additions & 0 deletions spec/requests/better_together/content/blocks_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'Content Blocks', type: :request do
describe 'POST /content/blocks' do
let(:user) { create(:better_together_user, :confirmed, :platform_manager) }

before do
login(user)
end

it 'attaches existing blob when media_signed_id is provided' do
blob = ActiveStorage::Blob.create_and_upload!(
io: StringIO.new('fake image'),
filename: 'test.png',
content_type: 'image/png'
)

expect {
post better_together.content_blocks_path, params: {
block: {
type: 'BetterTogether::Content::Image',
media_signed_id: blob.signed_id
}
}
}.to change(BetterTogether::Content::Image, :count).by(1)

block = BetterTogether::Content::Image.last
expect(block.media).to be_attached
expect(block.media.blob).to eq(blob)
end
end
end
Loading