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

[Cases] Refactor UI user actions #121962

Merged
merged 16 commits into from
Jan 14, 2022
Merged

Conversation

cnasikas
Copy link
Member

@cnasikas cnasikas commented Dec 23, 2021

Summary

When a user views a single case all user actions are being shown. A user action can be the edit of a title, a new comment, the addition or deletion of a tag, and etc. To visualize the user actions we use the EuiCommentList. The UserActions component is responsible for showing all user actions to the user. This component iterates the user actions and a big if/else is responsible for checking which user action to render. This PR refactors the component to use the factory pattern to render user actions. Each user action has a builder which is responsible for returning a EuiComment. The UserActions component, uses a map and calls the builder of each user action to accumulate all needed user actions.

Related issue: #115730

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@cnasikas cnasikas added release_note:skip Skip the PR/issue when compiling release notes v8.1.0 Team:Threat Hunting:Cases labels Dec 23, 2021
@cnasikas cnasikas self-assigned this Dec 23, 2021
@cnasikas cnasikas changed the title [Cases][skip-ci] Refactor UI user actions [Cases] Refactor UI user actions Jan 5, 2022
@cnasikas cnasikas added Feature:Cases Cases feature Team:ResponseOps Label for the ResponseOps team (formerly the Cases and Alerting teams) and removed Team:Threat Hunting:Cases labels Jan 10, 2022
@cnasikas cnasikas force-pushed the user_actions_ui_ref branch from b427d59 to a3bd04f Compare January 11, 2022 18:58
@cnasikas cnasikas marked this pull request as ready for review January 11, 2022 18:58
@elasticmachine
Copy link
Contributor

Pinging @elastic/response-ops (Team:ResponseOps)

@elasticmachine
Copy link
Contributor

Pinging @elastic/response-ops-cases (Feature:Cases)

@cnasikas cnasikas force-pushed the user_actions_ui_ref branch from 9e94b82 to 657c847 Compare January 11, 2022 20:15
@cnasikas
Copy link
Member Author

@elasticmachine merge upstream


it('renders correctly when editing a description', async () => {
const userAction = getUserAction('description', Actions.update);
// @ts-ignore no need to pass all the arguments
Copy link
Contributor

Choose a reason for hiding this comment

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

I keep seeing this same @ts-ignore comment in many other tests and I am not a big fan of using them when we can avoid them. Could you perhaps create a common test helper builder that handles this and call it in these cases? that way we don't put so many @ts-ignore across the code.

Copy link
Contributor

@academo academo left a comment

Choose a reason for hiding this comment

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

My main concern on the current pattern is the typescript types for the builders. Could you create specific types for the builders?

return (
<>
<MyEuiCommentList comments={comments} data-test-subj="user-actions" />
{(isLoadingUserActions || loadingCommentIds.includes(NEW_COMMENT_ID)) && (
Copy link
Contributor

Choose a reason for hiding this comment

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

could you turn this into a ternary? It makes it easier to read.

Copy link
Member Author

@cnasikas cnasikas Jan 13, 2022

Choose a reason for hiding this comment

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

I like better this pattern, to be honest. With a ternary, I have to return null and I found it more difficult to read.

Copy link
Contributor

Choose a reason for hiding this comment

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

@cnasikas I understand that but keep in mind it is more common for react to have ternaries returning null than having expressions like this. I won't push for the change but I find it better to follow code conventions like that one.

@academo
Copy link
Contributor

academo commented Jan 12, 2022

I'll go ahead and approve the PR though keep in mind my actual knowledge of the code is limited and I just ran a basic sanity check.

My main concern is the lack of types for the action builders, if you could add those would make the PR better.

Copy link
Contributor

@jonathan-buttner jonathan-buttner left a comment

Choose a reason for hiding this comment

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

Nice work, left a few questions

};

export const createCommentUserActionBuilder: UserActionBuilder = ({
caseData,
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure of the best practice here but that seems like a lot of parameters haha. If we used classes on the frontend we could group these fields into classes but I'm not sure what the equivalent is. Do you think grouping these by sub objects would be helpful? That way common fields are grouped together.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think in the front-end, or better in the React ecosystem (hooks, etc), the functional paradigm is more appropriate. Any proposal on the grouping of sub-objects?

Copy link
Contributor

@jonathan-buttner jonathan-buttner Jan 13, 2022

Choose a reason for hiding this comment

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

Gotcha, makes sense, hmm maybe grouping the comment stuff together, something like this

export interface UserActionBuilderArgs {
  comments: {
    data: Comment[];
    refs: React.MutableRefObject<
      Record<string, AddCommentRefObject | UserActionMarkdownRefObject | null | undefined>
    >;
    loadingIds: string[];
    selectedOutlineId: string;
    handleOutline: (id: string) => void;
    handleSave: ({ id, version }: { id: string; version: string }, content: string) => void;
  };
  navigation: {
    onShowAlertDetails: (alertId: string, index: string) => void;
    actionsNavigation?: ActionsNavigation;
    getRuleDetailsHref?: RuleDetailsNavigation['href'];
    onRuleDetailsClick?: RuleDetailsNavigation['onClick'];
  };
  alerts: {
    loading: boolean;
    data: Record<string, Ecs>;
  };
  markdown: {
    manageEditIds: string[];
    handleManageEditId: (id: string) => void;
  };
  caseData: Case;
  userAction: CaseUserActions;
  caseServices: CaseServices;
  index: number;
  userCanCrud: boolean;
  handleManageQuote: (quote: string) => void;
}

We could probably pull the definition of each object out into their own interface. This puts the burden of grouping the objects on the caller, so maybe that's not helpful 🤷‍♂️

Copy link
Contributor

@jonathan-buttner jonathan-buttner left a comment

Choose a reason for hiding this comment

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

Thanks for the changes! I tested it locally and the user actions look good!

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
cases 376 389 +13

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
cases 310.0KB 311.0KB +1.0KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
cases 81.7KB 81.7KB -43.0B
Unknown metric groups

ESLint disabled line counts

id before after diff
cases 72 71 -1

Total ESLint disabled count

id before after diff
cases 90 89 -1

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @cnasikas

@cnasikas cnasikas merged commit 5a77714 into elastic:main Jan 14, 2022
@cnasikas cnasikas deleted the user_actions_ui_ref branch January 14, 2022 09:38
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Jan 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:Cases Cases feature release_note:skip Skip the PR/issue when compiling release notes Team:ResponseOps Label for the ResponseOps team (formerly the Cases and Alerting teams) v8.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants