Skip to content

Commit

Permalink
Merge pull request #2864 from manyfold3d/split-models
Browse files Browse the repository at this point in the history
Split selected files into new model when bulk editing
  • Loading branch information
Floppy authored Oct 4, 2024
2 parents 55faaf5 + 061e731 commit 0994e34
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 16 deletions.
20 changes: 12 additions & 8 deletions app/controllers/model_files_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,25 @@ def update
end

def bulk_edit
@files = @model.model_files.select(&:is_3d_model?)
@files = policy_scope(ModelFile).where(model: @model).select(&:is_3d_model?)
end

def bulk_update
hash = bulk_update_params
params[:model_files].each_pair do |id, selected|
if selected == "1"
file = @model.model_files.find_param(id)
ids_to_update = params[:model_files].keep_if { |key, value| value == "1" }.keys
files = policy_scope(ModelFile).where(model: @model, public_id: ids_to_update)
files.each do |file|
ActiveRecord::Base.transaction do
current_user.set_list_state(file, :printed, params[:printed] === "1")
if file.update(hash)
file.save
end
file.update(hash)
end
end
redirect_back_or_to model_path(@model), notice: t(".success")
if params[:split]
new_model = @model.split! files: files
redirect_to model_path(new_model), notice: t(".success")
else
redirect_back_or_to model_path(@model), notice: t(".success")
end
end

def destroy
Expand Down
20 changes: 20 additions & 0 deletions app/models/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,26 @@ def organize!
save!
end

def split!(files: [])
new_model = dup
new_model.name = "Copy of #{name}"
new_model.public_id = nil
new_model.organize!
# Move files
files.each do |file|
file.update!(model: new_model)
file.reattach!
end
# Clear preview file appropriately
if files.include?(preview_file)
update!(preview_file: nil)
else
new_model.update!(preview_file: nil)
end
# Done!
new_model
end

private

def normalize_license
Expand Down
1 change: 1 addition & 0 deletions app/views/model_files/bulk_edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@
</div>
</div>
<%= form.submit translate(".submit"), class: "btn btn-primary" %>
<%= form.submit translate(".split"), name: "split", class: "btn btn-warning" %>
<% end %>
3 changes: 2 additions & 1 deletion config/locales/model_files/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ en:
form_subtitle: 'Select changes to make:'
select: Select file '%{name}'
select_all: Select all files
submit: Update Selected Files
split: Split selected files into new model
submit: Update selected files
title: Bulk Edit Files
bulk_update:
success: Files updated successfully.
Expand Down
51 changes: 51 additions & 0 deletions spec/models/model_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,57 @@
end
end

context "when splitting" do
subject!(:model) {
m = create(:model)
create(:model_file, model: m)
create(:model_file, model: m)
m
}

it "creates a new model" do
expect { model.split! }.to change(described_class, :count).by(1)
end

it "copies old model metadata" do # rubocop:todo RSpec/MultipleExpectations
new_model = model.split!
expect(new_model.name).to eq "Copy of #{model.name}"
[:notes, :caption, :collection, :creator, :license].each do |field|
expect(new_model.send(field)).to eq model.send(field)
end
end

it "creates an empty model if no files are specified" do
new_model = model.split!
expect(new_model.model_files).to be_empty
end

it "does not add or remove files" do
expect { model.split! }.not_to change(ModelFile, :count)
end

it "adds selected files to new model" do
new_model = model.split! files: [model.model_files.first]
expect(new_model.model_files.count).to eq 1
end

it "retains existing preview file for new model if selected for split" do # rubocop:todo RSpec/MultipleExpectations
file_to_split = model.model_files.first
model.update!(preview_file: file_to_split)
new_model = model.split! files: [file_to_split]
expect(new_model.preview_file).to eq file_to_split
expect(model.reload.preview_file).to be_nil
end

it "new model gets no preview file if not selected" do # rubocop:todo RSpec/MultipleExpectations
preview_file = model.model_files.first
model.update!(preview_file: preview_file)
new_model = model.split! files: [model.model_files.last]
expect(new_model.reload.preview_file).to be_nil
expect(model.preview_file).to eq preview_file
end
end

context "with filesystem conflicts" do
around do |ex|
MockDirectory.create([
Expand Down
44 changes: 37 additions & 7 deletions spec/requests/model_files_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
end

context "when signed in" do
let(:jpg_file) { create(:model_file, model: model, filename: "test.jpg") }
let(:stl_file) { create(:model_file, model: model, filename: "test.stl") }
let(:model) { create(:model, library: library, path: "model_one") }
let!(:jpg_file) { create(:model_file, model: model, filename: "test.jpg") }
let!(:stl_file) { create(:model_file, model: model, filename: "test.stl") }
let!(:model) { create(:model, library: library, path: "model_one") }
let(:library) { create(:library, path: @library_path) } # rubocop:todo RSpec/InstanceVariable

around do |ex|
Expand All @@ -33,15 +33,45 @@

describe "GET /models/:model_id/model_files/edit", :as_moderator do
it "shows bulk update form" do
get bulk_edit_model_model_files_path(model, stl_file)
get bulk_edit_model_model_files_path(model)
expect(response).to have_http_status(:success)
end
end

describe "PATCH /models/:model_id/model_files/update", :as_moderator do
it "bulk updates the files" do
patch model_model_file_path(model, stl_file), params: {model_file: {name: "name"}}
expect(response).to redirect_to(model_model_file_path(model, stl_file))
let(:params) do
{
model_files: {stl_file.public_id => "1", jpg_file.public_id => "0"},
y_up: "1",
printed: "1",
presupported: "1"
}
end

it "bulk updates Y Up on the selected files" do
patch bulk_update_model_model_files_path(model, params: params)
expect(stl_file.reload.y_up).to be_truthy
end

it "bulk updates presupported flag on the selected files" do
patch bulk_update_model_model_files_path(model, params: params)
expect(stl_file.reload.presupported).to be_truthy
end

it "bulk updates printed flag on the selected files" do
patch bulk_update_model_model_files_path(model, params: params)
expect(stl_file.listers(:printed)).to include controller.current_user
end

it "does not modify non-selected files" do
patch bulk_update_model_model_files_path(model, params: params)
expect(jpg_file.reload.y_up).to be_falsy
end

it "splits model" do
expect {
patch bulk_update_model_model_files_path(model, params: params.merge(split: "split"))
}.to change(Model, :count).by(1)
end
end

Expand Down

0 comments on commit 0994e34

Please sign in to comment.