Skip to content

[72383] Workflow UX improvement: Apply workflow setting from one role to another role#22441

Open
dfriquet wants to merge 33 commits intodevfrom
feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role
Open

[72383] Workflow UX improvement: Apply workflow setting from one role to another role#22441
dfriquet wants to merge 33 commits intodevfrom
feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role

Conversation

@dfriquet
Copy link
Copy Markdown
Contributor

@dfriquet dfriquet commented Mar 20, 2026

Ticket

https://community.openproject.org/wp/72383

What are you trying to accomplish?

  • No more global advanced legacy Copy feature for workflow;
  • Two separate features:
    • Copy from type to type, on a new type creation for example;
    • Copy from a type’s role to other roles of this same type.

Screenshots

Workflows Administration OpenProject - Copy dialog

What approach did you choose and why?

  1. The first commit builds solid foundations for lighter controllers, starting with the new Workflows::Copies::FromTypesController — and extracting the Workflows::CopiesController for good measure;
  2. The second commit adds the other feature, to copy workflows from a role;
  3. The third commit removes the legacy Copy feature completely;
  4. The fourth commit is an optional refactoring of the summary route to match the namespaced lighter controllers scheme ;
  5. The fifth commit change the way actions are shown on the index page (see screenshots above), to be more explicit while sticking to the AC.
  6. The eleventh commit change the way actions are shown on the index page (see screenshots above), to be consistent with other enumerations like Priorities;
  7. The I-lost-count-falling-into-the-rabbit-holish commit merges the forms into a unified dialog for both actions;
  8. The last commits plug this dialog into the "unsaved changes" warning dialog…

Merge checklist

  • Added/updated tests
  • Added/updated documentation in Lookbook (patterns, previews, etc)
  • Tested major browsers (Chrome, Firefox, Edge, ...)

@dfriquet dfriquet force-pushed the feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role branch 8 times, most recently from 23fd062 to c3ee143 Compare March 24, 2026 09:40
@dfriquet dfriquet force-pushed the feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role branch from c3ee143 to 6d435d7 Compare March 24, 2026 09:48
@dfriquet dfriquet force-pushed the feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role branch from 51f8201 to 5ebe35a Compare March 24, 2026 14:40
Comment thread app/forms/workflows/copies/from_role_form.rb Outdated
Comment thread config/routes.rb Outdated
Comment thread spec/models/workflow_spec.rb
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 24, 2026

Deploying openproject with PullPreview

Field Value
Latest commit 85c7849
Job deploy
Status ✅ Deploy successful
Preview URL https://pr-22441-72383-workflows-ux-ip-49-12-32-87.my.opf.run:443

View logs

@dfriquet dfriquet marked this pull request as ready for review March 24, 2026 15:48
Base automatically changed from epic/workflows-ux-quick-wins to dev March 24, 2026 16:15
@lindenthal
Copy link
Copy Markdown
Member

Hi @dfriquet,
Sorry for this maybe stupid question. I didn’t read all the history.
Is there a specific reason you removed the link to the details page? Why is there an edit button?
Best
Niels

@dfriquet
Copy link
Copy Markdown
Contributor Author

Hi @lindenthal,

Is there a specific reason you removed the link to the details page? Why is there an edit button?

I turned the link into an Edit button because the More button felt unnoticed at the end of the row, and an Edit button is more explicit and appealing than a link — I expect navigation to content behind a link, not action.

But obviously that’s not the case in OpenProject’s UX patterns. I walked my way around the admin settings and I see that Priorities or Statuses names links to edit pages, with a More menu at the end of the row for Priorities for instance… My bad, I’ll fix it 👌

@dfriquet dfriquet force-pushed the feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role branch from 7d55a67 to 6e2efe8 Compare April 9, 2026 07:42
@dfriquet dfriquet force-pushed the feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role branch from 63c6154 to 4612050 Compare April 10, 2026 06:10
@dfriquet dfriquet force-pushed the feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role branch 2 times, most recently from bb88b2d to 56fe369 Compare April 13, 2026 15:36
…s-ux-improvement-apply-workflow-setting-from-role-to-role
@dfriquet dfriquet force-pushed the feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role branch from 56fe369 to 32831e0 Compare April 13, 2026 15:41
dfriquet and others added 2 commits April 14, 2026 09:28
Copy link
Copy Markdown
Contributor

@mrmir mrmir left a comment

Choose a reason for hiding this comment

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

Functionality wise, nice job, especially with all the dialog/state management. I did notice a few things that need changes however, before a deeper code review:

  1. Opening the page for a type does a very obvious two-part load, with the rest of the page coming in first and then the matrix being loaded. If this is something that you touched, is there a way to prevent that? Or is it just a factor of the size of the matrix and something we have to live with for types/roles with many check boxes?
  2. I think the copy dialog needs to be taller to prevent it from scrolling/prevent the 'target roles' dropdown from being cut off and hiding the buttons of the dialog:
Image
  1. I expected to be redirected to the selected role when only one role is selected for copying, but I know being able to multi select them complicates the expected behaviour so it's fine to redirect to the first available role. However, can the flash messages be more descriptive? Maybe something like "Successfully copied to 'Anonymous' role." or "Successfully copied to 3 roles." or "Successfully copied to role: Anonymous". And while we're at it, also for when copying types?

Copy link
Copy Markdown
Contributor

@mrmir mrmir left a comment

Choose a reason for hiding this comment

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

I-lost-count-falling-into-the-rabbit-holish

Oops, hopefully not too many more commits, but I found some more points:

  1. The AC/figma mockups show that even when copying to another type, it is possible to select multiple types at once but the implementation is single select only
  2. Can changing roles not be a full page reload easily?
  3. When making changes to the matrix, switching tabs by saving changes, and then switching back to the original tab, there is a flicker with the success banner visible for a short period before it disappears
  4. The status button is scrolling with a wide matrix again 🫠:
Image

Comment thread config/locales/en.yml
Comment thread config/locales/en.yml Outdated
Comment thread config/locales/en.yml Outdated
Comment thread config/locales/en.yml Outdated
Comment thread spec/features/workflows/copies/from_role_spec.rb Outdated
Comment thread spec/features/workflows/edit_spec.rb
Comment thread spec/features/workflows/edit_spec.rb
Co-authored-by: Mir Bhatia <mirdotbhatia@gmail.com>
Comment thread app/views/workflows/edit.html.erb
Comment on lines +45 to +46
href: helpers.edit_workflow_path(@type, role_id: available_role.id, tab: @tab),
content_arguments: { data: { "admin--workflow-checkbox-state-confirmation-trigger": "click" }, target: "_top" }
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.

Can changing roles not be a full page reload easily?

Yes, it can, with something like this:

Suggested change
href: helpers.edit_workflow_path(@type, role_id: available_role.id, tab: @tab),
content_arguments: { data: { "admin--workflow-checkbox-state-confirmation-trigger": "click" }, target: "_top" }
href: helpers.edit_workflow_tab_path(@type, @tab, role_id: available_role.id),
content_arguments: { data: { "admin--workflow-checkbox-state-confirmation-trigger": "click" } }

I made this change on purpose so that the browser address bar URL matches the data shown on the page. Without a full page reload, one could land on this page with role_id=3, select another role and now the address bar is out of sync with the role actually edited. Sharing the current URL, for example, does not land on the same view.

That’s a problem from where I sit, but:

  1. it may not be a problem, and we can prefer smoother navigation over URL synchronization;
  2. there is a mechanism I can’t think of to achieve both goals.

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.

Hmm, but then this is a regression from the previous implementation, right? That did both, but I guess with the new components and different loading/reloading, it is a bit more difficult to get those to work together now. I'm not sure which I prefer tbh, so maybe @oliverguenther has an opinion?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would not worry about that too much for now, given that when we switch to a SelectPanel, the role switches need to be different anyway. You would be able to select multiple roles then. And maybe, in this case it doesn't make sense to keep it in the URL state?

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.

Fair point with the multi role selection changes, I guess it makes sense to keep navigation smooth and forget about the param/url for 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.

Eventually, it’s not that simple: the role_id change is kept inside the turbo-frame and not reflected in the Tabs links => Clicking on User is author for instance loses the currently selected role. And that would be the same with multi-role selection.

And even if the role selector is in the tab, I guess we want to keep the current behaviour (staying on the same role selection) when switching tabs, right?

If so, I’ll broaden the turbo-frame boundary to encapsulate all dependent moving parts.

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.

And even if the role selector is in the tab, I guess we want to keep the current behaviour (staying on the same role selection) when switching tabs, right?

Yes, so I guess changes to the frame are necessary

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.

A lot of trial and error in the process, but I ended up with something satisfying. That broke some of the pristine/dirty state management — still on it.

Comment thread app/forms/workflows/copies/form.rb Outdated
Comment thread app/views/workflows/copies/new.turbo_stream.erb
tag: :div,
classes: "op-primer-flash--item",
data: {
turbo_temporary: true,
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.

When making changes to the matrix, switching tabs by saving changes, and then switching back to the original tab, there is a flicker with the success banner visible for a short period before it disappears

@mrmir I assumed this may be an OpenProject-wide expectation, therefore made the change at the generic component level. Good idea? 😬

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.

Yeah I don't see why those will ever need to be cached, so this works for me 👍🏽. Let's just hope it doesn't break something in some obscure way...

Comment thread app/controllers/workflows/copies/from_roles_controller.rb
Comment thread app/controllers/workflows/copies/from_roles_controller.rb
@dfriquet dfriquet force-pushed the feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role branch 2 times, most recently from 5be0199 to c319c1f Compare April 16, 2026 15:10
@dfriquet dfriquet force-pushed the feature/72383-workflows-ux-improvement-apply-workflow-setting-from-role-to-role branch from c319c1f to 71e4e8b Compare April 16, 2026 15:17

++#%>

<%= component_wrapper do %>
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.

The status button is scrolling with a wide matrix again 🫠:

This wrapper binds the subheader and the matrix together, and the sticky CSS rule doesn’t fix it anymore. I’m on it.

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 tried to find the right combination of sticky/scroll/visible until I shortcut it with an old trick we used to define application-wide:

// Make CSS "ignore" <turbo-frame> in DOM hierarchy.
// https://github.com/hotwired/turbo/issues/48#issuecomment-925760725
turbo-frame
  display: contents

I admit I was surprised to push the first occurrence of this display: contents with all the ViewComponents and Turbo Streams in this project.

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

Development

Successfully merging this pull request may close these issues.

5 participants