Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds workflow approval list and details #8375

Merged

Conversation

mabashian
Copy link
Member

SUMMARY

Meta issue #8273
Addresses #8373
Sort of addresses #7112 (the rest of it captured in #8374)
Does not include #8372

This PR adds a new list /workflow_approvals along with a details view for items in that list.

The entry point for this list is here:

Screen Shot 2020-10-12 at 2 36 43 PM

Since this list does not exist in the old UI I figured this was as good a spot as any. We can move it if we need to.

The list itself is pretty straightforward but here's an explanation of the columns:

Screen Shot 2020-10-12 at 2 45 12 PM

Screen Shot 2020-10-12 at 2 47 18 PM

Screen Shot 2020-10-12 at 2 50 26 PM

Some examples of tooltip on status:

Screen Shot 2020-10-12 at 2 51 00 PM

Screen Shot 2020-10-12 at 2 51 06 PM

Screen Shot 2020-10-12 at 2 54 38 PM

Here's a look at the details view for a pending approval:

Screen Shot 2020-10-12 at 2 55 15 PM

a lot of the same information from the list row is shown here.

Here's a look at the details view for an approved approval:

Screen Shot 2020-10-12 at 2 56 11 PM

The action buttons/rbac should be the same on the details view as they are on the list.

Websockets

OK so here's how websockets work on this list. This list is subscribed to the jobs -> status_changed channel just like the jobs list. We're only interested in jobs with the type: workflow_approval though. The response to events that match our criteria is pretty straightforward: we refresh the list contents. This is throttled but that throttle is currently set to just 1 second. Unlike the jobs list, I'm not anticipating a tremendous amount of activity on this list in a short amount of time but if we need to increase that throttle threshold then we can. Here's when we refresh the list:

  1. When the job in question is not in our list and it's status is pending.
  2. When the job in question is in our list and it's status is not in ['new', 'pending', 'waiting', 'running'] (i.e. the job finished).

^^ Scenario 2 creates an interesting challenge when the user that's viewing the list is also the user that is acting on the row. When the user clicks approve/deny and the API responds with a 204 there's a bit of a delay before the socket message comes through and tells us that the job has moved to a completed status. During that time, I hide the action buttons via a boolean on the list row state.

Websockets are where I spent a majority of my time on this feature and I'm still not sure that it's quite right. I'm definitely open to alternative approaches to keeping this list up to date using the data that we get from the job status channel.

Unfortunately, we have to hit the API to retrieve the row data as the socket message doesn't have much more than the status and the job id. There could be a solution where we fetch specific rows instead of refetching all of them.

ISSUE TYPE
  • Feature Pull Request
COMPONENT NAME
  • UI

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@wenottingham
Copy link
Contributor

Looks generally good. I do think we need to move the list - workflow approvals are the same conceptual things as job runs, and so should be in that area.

@unlikelyzero unlikelyzero added the type:feature prioritized on a feature board label Oct 13, 2020
@unlikelyzero
Copy link

@tiagodread note: This is net new and not absolutely critical for this week.

@mabashian
Copy link
Member Author

OK, made the following updates based on feedback from Taufique and Bill.

  1. Moved Workflow Approvals out of Administration and in to Views
  2. Moved approve/deny buttons from the individual list row items up to the list action level (alongside delete). This means multiple rows can be approved/denied at the same time.
  3. Updated the UX on the status labels to match the mockups: https://tower-mockups.testing.ansible.com/patternfly/workflow-approvals/wf-approvals/

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

Copy link
Contributor

@jakemcdermott jakemcdermott left a comment

Choose a reason for hiding this comment

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

  • List item, approval button, new view, and tests, etc. LGTM
  • let's double-check w/ @keithjgrant on the websocket hook usage

import { WorkflowApproval } from '../../../types';
import { formatDateString } from '../../../util/dates';

function WorkflowApprovalStatus({ workflowApproval, i18n }) {
Copy link
Member

Choose a reason for hiding this comment

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

We have a generic status label component at components/StatusLabel. Do you think it could meet your needs here instead of a new component?

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 will check that out

Copy link
Member Author

@mabashian mabashian Nov 13, 2020

Choose a reason for hiding this comment

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

Yea there's definitely some overlap here. If we want to keep the same UX then I'd have to refactor this component quite a bit with several conditionals. I'm a little reluctant to do that given how clean this component (StatusLabel) is.

<ErrorDetail error={deleteError} />
</AlertModal>
)}
{approveError && (
Copy link
Member

@AlexSCorey AlexSCorey Oct 22, 2020

Choose a reason for hiding this comment

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

You could combine these 2 AlertModals, and would you also only need to have 1 useDismissableError above, which would be something like
const {error, dismissError} = useDismissableError(approveError || denyError)
and then the alertModals would be

          isOpen={error}
          variant="error"
          title={i18n._(t`Error!`)}
          onClose={dismissError}
        >
         approveError ?  {i18n._(t`Failed to approve workflow approval.`)} 
            : {i18n._(t`Failed to deny workflow approval.`)}
          <ErrorDetail error={approveError} />
        </AlertModal>

fetchWorkflowApprovals();
}, [fetchWorkflowApprovals]);

// TODO: update QS_CONFIG to be safe for deps array
Copy link
Member

Choose a reason for hiding this comment

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

Is this a note for your current work that you forgot to remove, or is this future work?

Copy link
Member

Choose a reason for hiding this comment

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

that's an old TODO of mine, copied over from somewhere else I think


jest.mock('../../../api');

const mockWorkflowApprovals = [
Copy link
Member

Choose a reason for hiding this comment

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

Might consider putting this inside of a data.json file to reduce the # of lines of code in this file

Copy link
Member Author

Choose a reason for hiding this comment

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

👍

@@ -0,0 +1,61 @@
import { useState, useEffect } from 'react';
Copy link
Member

Choose a reason for hiding this comment

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

was does the Ws in useWsWorkflowApprovals stand for?

Copy link
Member Author

Choose a reason for hiding this comment

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

That's the naming pattern we have for all of our websocket hooks. They all start with useWs and then we concat the resource on the end.

@tiagodread
Copy link
Contributor

tiagodread commented Oct 23, 2020

Hey @mabashian !

  • I tried to delete a workflow approval before approving or deny and I got this result (on the list or details):

approval

  • The simple search using name doesn’t work:
    search

  • If i delete the job the workflow approval associated with that job show undefined for the job name and if I click on it I got 404:

deleted

<div>
<Button
isDisabled={isDisabled}
aria-label={i18n._(t`Approve`)}

Choose a reason for hiding this comment

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

do aria-labels need to be translated?

@unlikelyzero
Copy link

We have tests pending the merge of this PR. Please let us know when it's ready for final merge

@tiagodread
Copy link
Contributor

@mabashian can you add some uniques ids for the data on datails tab specially for the status

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@tiagodread
Copy link
Contributor

@mabashian awesome job!!!

Tests covered by a mix of manual and automated test cases in here https://github.com/ansible/tower-qa/pull/5656

@mabashian
Copy link
Member Author

@keithjgrant @jakemcdermott @AlexSCorey any other thoughts on this one before merge?

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded (gate pipeline).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:feature prioritized on a feature board
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants