Skip to content

Add position to steps#137

Merged
mrcasals merged 19 commits intomasterfrom
add_position_to_steps
Oct 25, 2016
Merged

Add position to steps#137
mrcasals merged 19 commits intomasterfrom
add_position_to_steps

Conversation

@mrcasals
Copy link
Copy Markdown
Contributor

@mrcasals mrcasals commented Oct 20, 2016

🎩 What? Why?

We need to reorder steps. This can be done now with a drag&drop of table rows.

📋 Subtasks

👻 GIF

@codecov-io
Copy link
Copy Markdown

codecov-io commented Oct 20, 2016

Current coverage is 97.70% (diff: 100%)

Merging #137 into master will increase coverage by 0.04%

@@             master       #137   diff @@
==========================================
  Files           154        156     +2   
  Lines          2257       2348    +91   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits           2204       2294    +90   
- Misses           53         54     +1   
  Partials          0          0          

Powered by Codecov. Last update 4c266f1...cf9cb74

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong docs?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes :(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either the docs or the var name are wrong.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get the comment. Names match :/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was confused because the var name says order_stirng, but then it's an Array of IDs, I didn't get it was a JSON string or similar (maybe it could be added)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order_string should be something like: "[2, 1, 3, 5, 7, 9, 8]", so a String representing an Array of IDs. Each element of the array is an ID of a step, and its index is the position field value.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is weird. Coercing that string into an array should be the transport's responsibility (ujs via the controller).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to rescue a JSON parsing in the controller but yeah, feels weird to me too. Changing it!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing new line after return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing new line before return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd move this to a method (order). This way you can do return broadcast(:invalid) unless order and encapsulate all the JSON and presence logic in a method.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this method. Also:

order.each_with_index.inject({}) do |data, (id, index)|
  data.update(id: { position: index })
end

Copy link
Copy Markdown
Contributor Author

@mrcasals mrcasals Oct 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your version does an update for every single element in the collection. My version uses a single update for all the collection:

https://github.com/rails/rails/blob/a419a4d9ade48e777166ff956dd7bb24e37b2181/activerecord/lib/active_record/relation.rb#L363

Edit: OK checking the code it actually does an update for every element in the array :/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's why I said I didn't understand, what is this doing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should create another controller or not.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, with a create action. Will do.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about on(:valid) ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't do anything. If I put a render or a redirect here, then page refreshes and misses all the point.

We could render some JS here and then do something in the layout, but if we need to show a success message every time the user drags and drops... I think it's too much.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you should do is put a spinner when you start the request, and delete that spinner when it finishes. But hey, ujs is a hack, this won't last long as we'll replace this with React+GraphQL (already working on it).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this to a JS file?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't accept any JS inside html templates... 👎

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add some validations to the model (numericality, minimum, maximum, etc). Should we set the position on creation or do we allow nil values?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, steps are created with position: nil, thus positioning themselves in the beginning of the list. I don't know if this is the expected or we'd rather have them in the end. If we want to have them in the end, I can create the steps with a really high position (position: 9999 for example). Once the user reorders this, position will go back to a "normal" number

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add validations allowing blank values. Regarding default values, I'd expect new steps to be added to the end, not the begining. Maybe the default value can be the previous + 1 (resort solves this 😝)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validations are in the model. As for the default value, I don't know if resort would be too much for just this (could be a before_save method or similar), and I don't know if I'll need other resort features by now :/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed offline to just add a before_create action to set the value when it's nil.

@beagleknight
Copy link
Copy Markdown
Contributor

I recommend adding a javascript linter before it is too late. I recommend eslint (https://github.com/appfolio/eslint-rails) and adding this as a CI step.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

@oriolgual oriolgual Oct 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd go with "No news good news" for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Protip: You can run rubocop -a and will probably auto-fix this.

@mrcasals mrcasals force-pushed the add_position_to_steps branch from 9593bb6 to d85c3a3 Compare October 24, 2016 14:14
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is weird. Coercing that string into an array should be the transport's responsibility (ujs via the controller).

@mrcasals mrcasals force-pushed the add_position_to_steps branch from d85c3a3 to 1cf6bab Compare October 25, 2016 07:46
def create
authorize ParticipatoryProcessStep

byebug
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOL

expect { subject.call }.to broadcast(:ok)
end

it "deactivates it" do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong text?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return if position.present?
return self.position = 0 if participatory_process.steps.empty?

self.position = participatory_process.steps.last.position + 1
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about participatory_process.steps.pluck(:position).last ? (I know we'll load more rows, but we'll load less data, not sure which is best though.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

# manually, it will be set to 0, and when it is not the only one it will be
# set to the last step's position + 1.
#
# Note: This allows manual positioning, so it can cause different steps to
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we add a unique validation then? (And also to the index)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

class AddPositionToSteps < ActiveRecord::Migration[5.0]
def change
add_column :decidim_participatory_process_steps, :position, :integer
add_index :decidim_participatory_process_steps, [:decidim_participatory_process_id, :position], order: { position: :desc }, name: "index_check_position_for_steps"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This order doesn't match the one at the relation scope

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@mrcasals mrcasals merged commit 2dc8195 into master Oct 25, 2016
@mrcasals mrcasals deleted the add_position_to_steps branch October 25, 2016 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants