Skip to content

DT-458: Add ability for admins to export stories regardless of status#333

Merged
JuanVqz merged 14 commits into
mainfrom
feature/DT-458-admin-export-stories
Jul 21, 2026
Merged

DT-458: Add ability for admins to export stories regardless of status#333
JuanVqz merged 14 commits into
mainfrom
feature/DT-458-admin-export-stories

Conversation

@torresga

@torresga torresga commented Oct 23, 2024

Copy link
Copy Markdown
Contributor

Jira Ticket

https://ombulabs.atlassian.net/browse/DT-458

Motivation / Context

Currently, stories are only exported to CSV if they have an accepted status. This feature allows admin users to export stories regardless of their status. Non-admins should only be able to export approved stories.

I also refactored the export method because Code Climate was complaining.

Additional changes from review

Follow-up improvements made while reviewing the PR:

  • Admin gate enforced server-side. "Export all" is no longer trusted from the request params alone (the checkbox was only hidden in the view). The controller now honors export_all only when current_user.admin?, so a non-admin cannot forge ?export_all=1 to download non-approved stories. Added a spec for that forged-param case.
  • Fixed the admin spec. It previously built user.admin = true without signing in as that user, so it never actually exercised admin behavior. It now signs in as an admin.
  • Simplified export. Replaced the four-way conditional with two booleans (with_comments, export_all) and a single call to generate_csv, and moved generate_csv to private.
  • Removed an N+1. With comments, the export now eager-loads comment authors (includes(comments: :user)), instead of firing one query per comment for display_name.
  • Uniform CSV rows. A story's comments are now written into a single comments cell (newline-separated) instead of spilling into a variable number of unlabeled trailing columns, so every row has the same width.
  • Added a status column. Since we can now export every status, the CSV includes each story's status so an all-statuses export is actually readable. Columns are ordered id, position, status, title, description, comments. Import matches columns by name, so the new column and ordering don't affect it.
  • Added a spec covering an admin exporting all stories with comments (comments are included for non-approved stories too).

QA / Testing Instructions

As an admin:

  1. Go to a project with stories in different statuses.
  2. Click CSV Import/Export.
  3. Check Export all stories and click Export — the CSV includes stories of every status.
  4. Also check Export with comments — the CSV has a comments column, populated for non-approved stories as well.

As a non-admin:
5. The Export all stories checkbox is not shown; export returns approved stories only.
6. Even hitting …/stories/export?export_all=1 directly returns approved stories only.

Screenshots:

Screenshot 2024-10-23 at 10 31 50 AM ___

I will abide by the code of conduct.

@torresga
torresga marked this pull request as ready for review October 23, 2024 14:42
@JuanVqz
JuanVqz force-pushed the feature/DT-458-admin-export-stories branch from a341873 to 2f8ca29 Compare July 21, 2026 00:02
JuanVqz added a commit that referenced this pull request Jul 21, 2026
- Only render the Select All checkbox when the project is unlocked, matching
  Add a Story and the bulk-delete control (addresses the review question about
  the unlocked check). Add a spec that it is hidden on a locked project.
- Make updateSelectAllStatus null-safe so toggling a row checkbox on a locked
  project (where Select All is absent) no longer throws.
- Clean up the extracted updateBulkDeleteStatus indentation and file newline.
- De-flake the madmin projects spec via CGI.escapeHTML (same fix as PR #333).
@JuanVqz
JuanVqz force-pushed the feature/DT-458-admin-export-stories branch from 2f8ca29 to 94e5952 Compare July 21, 2026 18:08
torresga and others added 13 commits July 21, 2026 13:26
- Only honor export_all when current_user is an admin, so the param can't be
  forged by a non-admin to export non-approved stories (the view-only guard
  was not enough). Add a non-admin guard spec and sign in as an admin in the
  admin spec, which previously never actually authenticated as one.
- Simplify export: drop the 4-way branch and the unused export_all argument,
  and move generate_csv under private.
- Fix a flaky madmin projects spec by comparing against the HTML-escaped title
  (Faker names with apostrophes were escaped in the page and failed the match).
- Eager-load comment authors (includes(comments: :user)) so generate_csv does
  not fire one query per comment for display_name.
- Collapse all of a story's comments into a single quoted cell instead of
  spilling into a variable number of unlabeled trailing columns, so every row
  has a uniform width. Header renamed to "comments".
- Add a spec for an admin exporting all stories with comments, covering that
  comments on non-approved stories are included.
@JuanVqz
JuanVqz force-pushed the feature/DT-458-admin-export-stories branch from 94e5952 to cb15a91 Compare July 21, 2026 19:27
@JuanVqz

JuanVqz commented Jul 21, 2026

Copy link
Copy Markdown
Member

QA Passed, but it is missing the status column; otherwise, we won't know what has been rejected, approved or pending, so, adding the column now.

Screenshot 2026-07-21 at 13 39 35

Include each story's status in the export so an all-statuses export is
readable (previously there was no way to tell approved from pending/rejected).
Order the columns id, position, status, title, description, comments. Import
matches columns by name, so the new column and ordering do not affect it.
@JuanVqz

JuanVqz commented Jul 21, 2026

Copy link
Copy Markdown
Member

Now include the status, approved, and as soon as it's green, I'll merge it.

Screenshot 2026-07-21 at 13 53 18

@JuanVqz
JuanVqz merged commit a6623a1 into main Jul 21, 2026
2 checks passed
@JuanVqz
JuanVqz deleted the feature/DT-458-admin-export-stories branch July 21, 2026 19:57
JuanVqz added a commit that referenced this pull request Jul 21, 2026
- Only render the Select All checkbox when the project is unlocked, matching
  Add a Story and the bulk-delete control (addresses the review question about
  the unlocked check). Add a spec that it is hidden on a locked project.
- Make updateSelectAllStatus null-safe so toggling a row checkbox on a locked
  project (where Select All is absent) no longer throws.
- Clean up the extracted updateBulkDeleteStatus indentation and file newline.
- De-flake the madmin projects spec via CGI.escapeHTML (same fix as PR #333).
JuanVqz added a commit that referenced this pull request Jul 21, 2026
* Adds Select All checkbox and functionality

* Adds indeterminate state if not all checkboxes are selected

* Adds specs to test Select All checkbox

* Gate Select All on unlocked projects and harden select-all JS

- Only render the Select All checkbox when the project is unlocked, matching
  Add a Story and the bulk-delete control (addresses the review question about
  the unlocked check). Add a spec that it is hidden on a locked project.
- Make updateSelectAllStatus null-safe so toggling a row checkbox on a locked
  project (where Select All is absent) no longer throws.
- Clean up the extracted updateBulkDeleteStatus indentation and file newline.
- De-flake the madmin projects spec via CGI.escapeHTML (same fix as PR #333).

* Assert Bulk Delete stays disabled on a locked project when a story is selected

Documents that updateBulkDeleteStatus's unlocked guard is load-bearing: story
checkboxes still render on locked projects, so without the guard, selecting a
story would enable Bulk Delete.

* Move Select All into a dedicated leftmost checkbox column

Give the checkboxes their own column with a bold 'Select All' header, instead
of tucking the control into the right-hand actions cell where it was hard to
find. Add the sixth grid track for the new column and shift the story-title
filter and estimate-position helper to account for it.

---------

Co-authored-by: Juan Vásquez <juan@ombulabs.com>
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.

2 participants