Skip to content

Import proposals from a spreadsheet#7084

Merged
mrcasals merged 59 commits intodecidim:developfrom
mainio:feature/import_proposals_spreadsheet
Feb 10, 2021
Merged

Import proposals from a spreadsheet#7084
mrcasals merged 59 commits intodecidim:developfrom
mainio:feature/import_proposals_spreadsheet

Conversation

@lahdeero
Copy link
Copy Markdown
Contributor

@lahdeero lahdeero commented Jan 7, 2021

🎩 What? Why?

Non-digital natives and people who don't want their personal information on the internet, tell their ideas (proposals) more preferably to a trusted person. Therefore, admin users want to bulk import paper collected ideas to Decidim. This PR has implementation for importing proposals from files (csv, xls and json). Implementation is similar to export feature and should be easily expandable to other components as well.

📌 Related Issues

https://meta.decidim.org/processes/roadmap/f/122/proposals/14939

Testing

Create a csv or excel spreadsheet with column names title/en and body/en (or another locale which you prefer eg. title/ca and body/ca). Also scope/id and category/id columns are supported. For each row enter valid title and body, then save. After saving the spreadsheet go to -> Admin dashboard -> Processes -> pick process -> Proposals -> Import -> Import from a file -> Browse -> -> Start import -> check out new proposals

📋 Checklist

🚨 Please review the guidelines for contributing to this repository.

  • CONSIDER adding a unit test if your PR resolves an issue.
  • ✔️ DO check open PR's to avoid duplicates.
  • ✔️ DO keep pull requests small so they can be easily reviewed.
  • ✔️ DO build locally before pushing.
  • ✔️ DO make sure tests pass.
  • ✔️ DO make sure any new changes are documented in docs/.
  • ✔️ DO add and modify seeds if necessary.
  • ✔️ DO add CHANGELOG upgrade notes if required.
  • ✔️ DO add to GraphQL API if there are new public fields.
  • ✔️ DO add link to MetaDecidim if it's a new feature.
  • AVOID breaking the continuous integration build.
  • AVOID making significant changes to the overall architecture.

📷 Screenshots

Please add screenshots of the changes you're proposing
image

♥️ Thank you!

@lahdeero lahdeero changed the title Feature/import proposals spreadsheet Feature/import proposals from spreadsheet Jan 7, 2021
@lahdeero lahdeero changed the title Feature/import proposals from spreadsheet Feature/import proposals from a spreadsheet Jan 7, 2021
@andreslucena andreslucena changed the title Feature/import proposals from a spreadsheet Import proposals from a spreadsheet Jan 11, 2021
@carolromero
Copy link
Copy Markdown
Member

Hi @lahdeero! Is there any staging where we can test this? Thanks!

@lahdeero
Copy link
Copy Markdown
Contributor Author

lahdeero commented Jan 14, 2021

Hello @carolromero! Unfortunately not currently, but we have plans to make one.

@oriolgual
Copy link
Copy Markdown
Contributor

Hello @carolromero! Unfortunately not currently, but we have plans to make one.

I'll create one


def call
return broadcast(:invalid) if form.invalid?
return broadcast(:invalid) unless form.creator
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.

Could this be moved to a form validation?

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.

Yep. I removed creator check from the command.

@mrcasals
Copy link
Copy Markdown
Contributor

@decidim/product this can be tested in https://decidim-staging-pr-264.herokuapp.com/

@carolromero
Copy link
Copy Markdown
Member

carolromero commented Jan 18, 2021

Hi @lahdeero the import works very well, good job!
A couple of comments/doubts:

  • I see that there is a drop-down list but with only one value -proposal creator- what is the reason? Are other "creators" expected?

imatge

  • We should add some guidance on the expected file format. Also for consistency with other existing import options in the admin panel, can we change the button name only to "Import"?

imatge

Thanks!

@lahdeero
Copy link
Copy Markdown
Contributor Author

lahdeero commented Jan 19, 2021

* I see that there is a drop-down list but with only one value -`proposal creator`- what is the reason? Are other "creators" expected?

Yes, other creators are expected. For proposals component probably not (maybe for comments), but for budgets for example, we could have separate creators for budgets and projects.

* We should add some guidance on the expected file format. Also for consistency with other existing import options in the admin panel, can we change the button name only to "Import"?

Yep. Added guidance and updated button label.

Thanks for the feedback!

@mrcasals
Copy link
Copy Markdown
Contributor

@lahdeero some tests seem to be failing after the latest changes, can you check them please? 😄

@lahdeero
Copy link
Copy Markdown
Contributor Author

@mrcasals Done 😅

@mrcasals
Copy link
Copy Markdown
Contributor

@lahdeero can you redeploy this so @decidim/product can re-review it? 😄

@lahdeero
Copy link
Copy Markdown
Contributor Author

@mrcasals I haven't created the instance. @oriolgual Can you redeploy please?

@mrcasals
Copy link
Copy Markdown
Contributor

Whoops, sorry about that @lahdeero.

@decidim/product I've redeployed the app with the latest changes! Give it 15min from now and you should be able to review them 😄

@carolromero
Copy link
Copy Markdown
Member

@mrcasals can't access to the admin panel of the review app. It throws a system error 🤔

@mrcasals
Copy link
Copy Markdown
Contributor

@carolromero solved now, sorry about that!

@virgile-dev
Copy link
Copy Markdown
Contributor

Hey did a little testing on my end on the link you shared.

@carolromero
Copy link
Copy Markdown
Member

@mrcasals I'm getting the server error as well

@mrcasals
Copy link
Copy Markdown
Contributor

@virgile-dev @carolromero sorry, there was an issue with the review app. Should be fixed now!

@carolromero
Copy link
Copy Markdown
Member

@mrcasals I'm still getting the server error when accessing the import from file option 😢

@mrcasals
Copy link
Copy Markdown
Contributor

@lahdeero the error we're getting is this:

ActionView::Template::Error (The asset "decidim/admin/import_guidance.js" is not present in the asset pipeline.

I think you need to either require the file in decidim-admin/app/assets/config/decidim_admin_manifest.js or add it in decidim-admin/lib/decidim/admin/engine.rb:32 😄

@mrcasals
Copy link
Copy Markdown
Contributor

Also, some conflicts appeared @lahdeero!

@lahdeero lahdeero force-pushed the feature/import_proposals_spreadsheet branch from e349dca to 4ae54e2 Compare January 27, 2021 08:43
@lahdeero
Copy link
Copy Markdown
Contributor Author

lahdeero commented Jan 27, 2021

I rebased and added import_guidance.js.es6 into decidim-admin/app/assets/config/decidim_admin_manifest.js. @mrcasals

@mrcasals
Copy link
Copy Markdown
Contributor

@carolromero can you re-check the review app, please? https://decidim-staging-pr-264.herokuapp.com/

@carolromero
Copy link
Copy Markdown
Member

@mrcasals now it's working great, thanks!

Yep. Added guidance and updated button label.

@lahdeero thanks for adding the help on the file format!

Yes, other creators are expected. For proposals component probably not (maybe for comments), but for budgets for example, we could have separate creators for budgets and projects.

Regarding the creator field, we have discussed it with the rest of @decidim/product and we prefer to remove it for now. If in the future there is a need to add it because there are another roles we can discuss it.

@lahdeero
Copy link
Copy Markdown
Contributor Author

Regarding the creator field, we have discussed it with the rest of @decidim/product and we prefer to remove it for now. If in the future there is a need to add it because there are another roles we can discuss it.

I made it so that if there is less than 2 creators, it doesn't show creator select. Is this ok? @carolromero

@carolromero
Copy link
Copy Markdown
Member

@lahdeero sorry to bother you with this but I just don't understand the logic 😢 .
Let's recap:

  • There is a Creator field with the value "proposal creator". But this only determines the role of who imports (creates) the proposals, right?
  • And then there is a field Create imports as (maybe we could better call it "Create proposals as") where a drop-down list appears with the user and the groups to which he/she belongs.

So, for better understanding, could you give me an example of another possible value that could appear in the Creator field (bearing in mind that this option is for the proposal component only)? Thanks and sorry!

@lahdeero
Copy link
Copy Markdown
Contributor Author

lahdeero commented Jan 29, 2021

Not bothering at all 😊 Clearly there is room for making this more understandable for users.

Little bit technical background: I have tried to making this similar to export feature that we can use in all components. In every resource needs to be created differently (purpose of creator class), but the file upload view for example would look like same in every component. Now that I think more about this, maybe this is what it should look like:

creatortoresource

* There is a `Creator` field with the value "proposal creator". But this only determines the role of who imports (creates) the proposals, right?

It determines (under the hood) which class is responsible for the creating actual resource from parsed data.

* And then there is a field `Create imports as` (maybe we could better call it "Create proposals as") where a drop-down list appears with the user and the groups to which he/she belongs.

We could call it by resource, but if there is more resources (creators before) in same component we would have to change text (dynamically) when we select another resource and that might be confusing for the user as well.

So, for better understanding, could you give me an example of another possible value that could appear in the Creator field (bearing in mind that this option is for the proposal component only)? Thanks and sorry!

Another value could be Comment creator, if we want to import comments (as we can already export them). That creator we could use with other commentable resources too.

Bottom line is that before importing we need to have following information:

  • Resource
  • User or group
  • File

Hopefully this clears this at least a bit. @carolromero

@carolromero
Copy link
Copy Markdown
Member

Hi @lahdeero, thank you very much for the explanation ❤️!

It determines (under the hood) which class is responsible for the creating actual resource from parsed data.

Understood!

We could call it by resource, but if there is more resources (creators before) in same component we would have to change text (dynamically) when we select another resource and that might be confusing for the user as well.

yes, better to leave a generic text then and not the name of the specific resource. Although I am anticipating that the help text in the upload file will have to be dynamic. But we can discuss that when that option is available.

Ok, so to move forward with this PR, let's do what you proposed, if there is only one creator it is not shown to the user. It's already working like that, isn't it?

@lahdeero
Copy link
Copy Markdown
Contributor Author

lahdeero commented Feb 2, 2021

yes, better to leave a generic text then and not the name of the specific resource. Although I am anticipating that the help text in the upload file will have to be dynamic. But we can discuss that when that option is available.

Yes, help text is dynamic already (not that it really matters yet with just one creator/resource).

Ok, so to move forward with this PR, let's do what you proposed, if there is only one creator it is not shown to the user. It's already working like that, isn't it?

Yes, selection is hidden if component has just one creator.

Thanks!

def call
return broadcast(:invalid) if form.invalid?

form.context[:user_group] = user_group
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 think this should be inside the form, with a def user_group rather than modifying the form from the command

Copy link
Copy Markdown
Contributor Author

@lahdeero lahdeero Feb 3, 2021

Choose a reason for hiding this comment

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

Yep. Moved user_group assign to the form.

Comment on lines +15 to +19
importer = importer_for(form.file_path, form.mime_type)
imported_data = importer.prepare

return broadcast(:invalid_lines, importer.invalid_lines) unless importer.invalid_lines.empty?

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.

Maybe consider moving this logic also to the form and adding a validation there?

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.

Yep. Form validates invalid_lines now.

Comment on lines +7 to +8
include Decidim::ComponentPathHelper
def new
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.

Suggested change
include Decidim::ComponentPathHelper
def new
include Decidim::ComponentPathHelper
def new

include Decidim::ComponentPathHelper
def new
enforce_permission_to :import, :component_data, component: current_component
@import = form(Admin::ImportForm).from_params(
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 rename this to @form so it's easier to udnerstand

Suggested change
@import = form(Admin::ImportForm).from_params(
@form = form(Admin::ImportForm).from_params(

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.

Yep. Renamed import -> form

def create
enforce_permission_to :import, :component_data, component: current_component

@import = form(Admin::ImportForm).from_params(
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.

Same here

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.

Same here

@@ -0,0 +1 @@
,elahdenpera,THINK7,07.01.2021 11:38,file:///home/elahdenpera/.config/libreoffice/4; No newline at end of 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.

Should this file be here?

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.

No 😥

Copy link
Copy Markdown
Contributor

@mrcasals mrcasals left a comment

Choose a reason for hiding this comment

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

Looks good to me, thanks @lahdeero!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants