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

[App Search] Create Curation view/functionality #92560

Merged
merged 9 commits into from
Feb 25, 2021

Conversation

cee-chen
Copy link
Contributor

@cee-chen cee-chen commented Feb 24, 2021

Summary

This adds the "Create new curation" view to the curations section. It also essentially adds the "Manage queries" modal that will be used on the individual curation view, as the CurationQueries component is shared between these two views.

QA

createcurations

  • Go to http://localhost:5601/xyz/app/enterprise_search/app_search/engines/national-parks-demo/curations
  • Confirm clicking the "Create new curation" button takes you to the correct page
  • Confirm the "continue" button is disabled if there no query fields are filled out, and enabled if there are any fields with content
  • Confirm clicking the "Add query" button adds a new row
  • Confirm the trash icon button is disabled if there's only 1 row remaining, and enabled once more rows are added
  • Confirm that attempting to add a query that already has a curation (e.g. mountains) displays an error
  • Confirm that creating a new curation query works and takes you to a curation page that works on the standalone UI
  • Confirm that creating a new query with an empty row correctly filters out the blank query

Checklist

- to match createCuration

- IMO, this language isn't necessary if we're splitting up Curations and CurationLogic - the context is fairly evident within a smaller and more modular logic file
@cee-chen cee-chen added Feature:Plugins release_note:skip Skip the PR/issue when compiling release notes v7.13.0 auto-backport Deprecated - use backport:version if exact versions are needed labels Feb 24, 2021
@cee-chen cee-chen requested review from JasonStoltz, byronhulcher and a team February 24, 2021 03:37
+ accompanying CurationQueriesLogic & CurationQuery row
@cee-chen cee-chen force-pushed the curations-creation branch 2 times, most recently from 241f31b to 0ce2645 Compare February 24, 2021 04:00
* 2.0.
*/

export { CurationQueries } from './curation_queries';
Copy link
Contributor Author

@cee-chen cee-chen Feb 24, 2021

Choose a reason for hiding this comment

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

👋 Just want to highlight this commit (f6dc151) and note where I've made some significant differences from the Standalone UI.

<CurationQueries /> and <CurationQuery /> are almost completely different from ent-search, and require significantly less logic & branching. With @daveyholler's approval and guidance, I've simplified the UX of the curation queries component significantly which results in a massive code cleanup.

The component is used in two places: The Create New view and the Manage Queries modal

Create curation page

Before

After

Changes

  • Removed unnecessary multi-toggle - Davey agreed it does not add any significant confusion to have curation queries default to multiple
  • Allow removing rows - this was functionality present in the modal but hidden for the create view, which feels confusing/inconsistent. I strongly think the ability to control/remove rows should always be present for maximum user agency
  • Change EuiFieldSearch to EuiFieldText: this was done for semantic reasons as an input type="search" is simply not the correct field to be using in this scenario - since nothing is actually being searched. This loses us the magnifying glass icon and the ability to clear the input, but IMO the loss there is minimal

Manage queries modal

Before

After

Changes

As you can see, the main UX issue here complicating the 'before' view is the concept of "selecting" the currently active query. It forces the concept of an "editable" vs a "non-editable/selectable" query row.

Davey suggested (and I strongly agree) that it makes far more sense to create a select/dropdown on the main curation page itself for switching/selecting the current active query, and have this modal purely in charge of editing/deleting queries. This vastly simplifies & cleans up the component to be able to :

  • Always use editable form components, instead of adding any branching clickable interactivity
  • Removes the need for a "cancel" button, instead allowing us to simplify to always having the same remove row icon/functionality
  • Remove singleton "Save" buttons - instead, we can just save once, at the end of the form

Thoughts?

Let me know what y'all think! I think there's potentially some room here as well to use Byron's InlineEditableTable component that he made for Crawler, but I don't want to migrate that over right now, and I think this is a fairly straightforward compromise that is hopefully easy to review (let me know if not) and involves wayyy less code than what's currently in ent-search. I'm definitely open to investigating InlineEditableTable later post-MVP.

Copy link
Member

Choose a reason for hiding this comment

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

I think it's a great improvement.

editQuery(index: number, newQueryValue: string): { index: number; newQueryValue: string };
}

export const CurationQueriesLogic = kea<
Copy link
Contributor Author

@cee-chen cee-chen Feb 24, 2021

Choose a reason for hiding this comment

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

👋 Just want to highlight this logic file as well - this actually doesn't strictly need to be a logic file and it's very lightweight, but I thought it was kinda fun/helped separate concerns to make it one. This was my original proof of concept with just basic React state:

export const CurationQueries: React.FC = (props) => {
  // TODO: logic file rather than state??
  const [queries, setQueries] = useState(props.queries || ['']);

  const addQuery = () => {
    setQueries([...queries, '']);
  };
  const deleteQuery = (index: number) => {
    const newArray = [...queries];
    newArray.splice(index, 1);
    setQueries(newArray);
  };
  const changeQuery = (index: number, newQueryValue: string) => {
    const newArray = [...queries];
    newArray[index] = newQueryValue;
    setQueries(newArray);
  };

  const hasEmptyQueries = queries.indexOf('') >= 0;
  const hasOnlyOneQuery = queries.length <= 1;

Would be interested in hearing thoughts on what you do/don't prefer 🤷 I do think having it as logic makes it way easier to unit test.

Another thing I played around with was keying this logic file with an id, but it actually made testing kind of a pain (since you have to store that keyed logic file reference in a var and can't just refer back to the plain imported CurationQueriesLogic), and I also decided I didn't really need it since the component fully unmounts/mounts between page visits/modal closures.

Copy link
Member

Choose a reason for hiding this comment

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

I like this quite a bit constance. +1 for separation of concerns and easier unit testing.

@JasonStoltz JasonStoltz self-assigned this Feb 25, 2021
@JasonStoltz
Copy link
Member

Quick testing note ... after I create a curation, I don't see the button to launch a modal as seen in your gif

latest

@JasonStoltz
Copy link
Member

Also, amazing work on the simplification. Seriously commendable, I really like this new experience.

@cee-chen
Copy link
Contributor Author

Oh yeah sorry, the modal is not in this PR, just in my local. It's in the gifs to show to Davey & get his approval for its future use/UI/UX, and give context as to why this piece of logic is out in its own component vs only living on the creation page, and also why we need the ability to pass it a pre-defined set of queries. Hope that makes sense!

BTW, I also realized after QAing your recent relevance tuning PR that it's super similar to the value boosts rows, which I really like - more consistent UI/UX = happier users, just IMO! 😁

@JasonStoltz
Copy link
Member

@constancecchen I was waiting to say anything until I dug into your code a bit more, but I like your UI better, it's cleaner and does stuff like disables the trash cans, etc. It'd be cool to retrofit some of that to Relevance Tuning, or even create a shared component. Not sure if there's other places we'd use that or not.

@daveyholler
Copy link
Contributor

This is great work @constancecchen. I think this is a great example of improving the experience while porting stuff over. This is gonna make future improvements so much easier.

Copy link
Member

@JasonStoltz JasonStoltz left a comment

Choose a reason for hiding this comment

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

This is fantastic. I have some questions and comments, but nothing big. Let me know once you've responded and I'll approve.


return (
<>
<EuiPageHeader>
Copy link
Member

Choose a reason for hiding this comment

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

I saw in the latest EUI update email that EuiPageHeader now has props for various header elements, pageTitle, description, rightSideItems, etc.

This will be good to use as it's A) Less code and B) more consistently enforcing the same size / style on every page.

I think it would be good to update all of our pages to use these options. It's up to you whether you update this here, now, or if we wait to do a separate PR and do them all at once.

I did use these in my PR as I needed all three of those properties: https://github.com/elastic/kibana/pull/92644/files#diff-fe1fd9bb49e0518f49db2e6b5888c1f628a8314fb7c3d17353a35d07ab64d128R64-R73

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yo this is awesome!!!!!!!! I totally missed this in the EUI newsletter somehow, I LOVE it. I'll make the change in this PR now but we should most definitely do a product-wide update (I probably have some time during my SDH week next week).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

size="s"
iconType="plusInCircle"
onClick={addQuery}
isDisabled={hasEmptyQueries}
Copy link
Member

Choose a reason for hiding this comment

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

Did you consider adding a test for this being disabled? I don't think it's required for code coverage, but it might be good to document this behavior via a test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great call, thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

import { CurationQueriesLogic } from './curation_queries_logic';
import { CurationQuery } from './curation_query';
import { filterEmptyQueries } from './utils';
import './curation_queries.scss';
Copy link
Member

Choose a reason for hiding this comment

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

You include this in 2 different components.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Doh, awesome catch

Copy link
Contributor Author

Choose a reason for hiding this comment

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

editQuery(index: number, newQueryValue: string): { index: number; newQueryValue: string };
}

export const CurationQueriesLogic = kea<
Copy link
Member

Choose a reason for hiding this comment

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

I like this quite a bit constance. +1 for separation of concerns and easier unit testing.

color="danger"
onClick={onDelete}
isDisabled={disableDelete}
aria-label={i18n.translate('xpack.enterpriseSearch.actions.delete', {
Copy link
Member

Choose a reason for hiding this comment

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

This is a pretty generic name, is there a risk of collision with other places where this is used?

xpack.enterpriseSearch.actions.delete

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was intentional, at some point (maybe next week if I have time?) I'd like to DRY out these really small actions/button labels like "Edit", "Delete", "Save", "Cancel", "Continue" etc. strings so we just reuse the same const/string and don't make localizers translate them repeatedly.

* 2.0.
*/

export { CurationQueries } from './curation_queries';
Copy link
Member

Choose a reason for hiding this comment

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

I think it's a great improvement.

@cee-chen cee-chen requested a review from JasonStoltz February 25, 2021 18:43
Copy link
Member

@JasonStoltz JasonStoltz left a comment

Choose a reason for hiding this comment

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

LGTM!

@cee-chen cee-chen enabled auto-merge (squash) February 25, 2021 20:10
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
enterpriseSearch 1265 1281 +16

Async chunks

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

id before after diff
enterpriseSearch 1.9MB 1.9MB +8.3KB

History

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

cc @JasonStoltz

@cee-chen cee-chen merged commit 0198607 into elastic:master Feb 25, 2021
kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Feb 25, 2021
* Add server route and logic listener

* [Misc] Remove 'Set' from 'deleteCurationSet'
- to match createCuration

- IMO, this language isn't necessary if we're splitting up Curations and CurationLogic - the context is fairly evident within a smaller and more modular logic file

* Add CurationQueries component

+ accompanying CurationQueriesLogic & CurationQuery row

* Add CurationCreation view
@kibanamachine
Copy link
Contributor

💚 Backport successful

7.x / #92923

Successful backport PRs will be merged automatically after passing CI.

@cee-chen cee-chen deleted the curations-creation branch February 25, 2021 22:12
kibanamachine added a commit that referenced this pull request Feb 26, 2021
* Add server route and logic listener

* [Misc] Remove 'Set' from 'deleteCurationSet'
- to match createCuration

- IMO, this language isn't necessary if we're splitting up Curations and CurationLogic - the context is fairly evident within a smaller and more modular logic file

* Add CurationQueries component

+ accompanying CurationQueriesLogic & CurationQuery row

* Add CurationCreation view

Co-authored-by: Constance <constancecchen@users.noreply.github.com>
gmmorris added a commit to gmmorris/kibana that referenced this pull request Feb 26, 2021
…bana into task-manager/docs-monitoring

* 'task-manager/docs-monitoring' of github.com:gmmorris/kibana: (40 commits)
  [Security Solution][Case][Bug] Improve case logging (elastic#91924)
  [Alerts][Doc] Added README documentation for alerts plugin status and framework health checks configuration options. (elastic#92761)
  Add warning for EQL and Threshold rules if exception list contains value list items (elastic#92914)
  [Security Solution][Case] Fix subcases bugs on detections and case view (elastic#91836)
  [APM] Always allow access to Profiling via URL (elastic#92889)
  [Vega] Allow image loading without CORS policy by changing the default to crossOrigin=null (elastic#91991)
  skip flaky suite (elastic#92114)
  [APM] Fix for default fields in correlations view (elastic#91868) (elastic#92090)
  chore(NA): bump bazelisk to v1.7.5 (elastic#92905)
  [Maps] fix selecting EMS basemap does not populate input (elastic#92711)
  API docs (elastic#92827)
  [kbn/test] add import/export support to KbnClient (elastic#92526)
  Test fix management scripted field filter functional test and unskip it  (elastic#92756)
  [App Search] Create Curation view/functionality (elastic#92560)
  [Reporting/Discover] include the document's entire set of fields (elastic#92730)
  [Fleet] Add new index to fleet for artifacts being served out of fleet-server (elastic#92860)
  [Alerts][Doc] Added README documentation for API key invalidation configuration options. (elastic#92757)
  [Discover][docs] Add search for relevance (elastic#90611)
  [Alerts][Docs] Extended README.md and the user docs with the licensing information. (elastic#92564)
  [7.12][Telemetry] Security telemetry allowlist fix. (elastic#92850)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed Feature:Plugins release_note:skip Skip the PR/issue when compiling release notes v7.13.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants