-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Component templates] Table view #68031
[Component templates] Table view #68031
Conversation
Pinging @elastic/es-ui (Team:Elasticsearch UI) |
...n/components/component_templates/__jest__/client_integration/component_template_list.test.ts
Outdated
Show resolved
Hide resolved
…nent_templates_list_view
…nent_templates_list_view
@elasticmachine merge upstream |
Great job @alisonelizabeth ! I will review the code now but leaving here a comment about UX. I am not sure about repeating in each cell "index template" under the "Used by" column. I wonder if by just having the number (e.g. Also, the cross icon looks like there is an error. What do you think about not having the icon, and setting the text in italic with lighter text color like this? In a following iteration, as an enhancement, I can see that the current "in use/not in use" filter is replaced by a dropdown select with those 2 options + 3 others
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code LGTM overall. I left a few comments, none are really blockers so I approve but would like the performance once to be looked at 👍
|
||
const hasEntries = (data: object = {}) => Object.entries(data).length > 0; | ||
|
||
const getAssociatedIndexTemplates = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the deserializeComponenTemplateList
is called inside a map, and here we have 2 loops, that's a total of 3 nested loops. Depending on the size of the arrays this could be a performance issue.
It would be better to first (once) convert the array of index template to a flat map with this function
/**
* Normalize a list of component templates to a map where each key
* is a component template name, and the value is an array of index templates name using it
*
* @example
*
{
"comp-1": [
"template-1",
"template-2"
],
"comp2": [
"template-1",
"template-2"
]
}
*
* @param indexTemplatesEs List of component templates
*/
export const indexTemplatesToUsedBy = (indexTemplatesEs: TemplateV2Es[]) => {
return indexTemplatesEs.reduce((acc, item) => {
if (item.index_template.composed_of) {
item.index_template.composed_of.forEach((component) => {
acc[component] = acc[component] ? [...acc[component], item.name] : [item.name];
});
}
return acc;
}, {} as { [key: string]: string[] });
};
then it is direct access to the index templates used by a component template
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great point. I went ahead and addressed this.
@@ -49,6 +49,11 @@ export interface TemplateDeserialized { | |||
}; | |||
} | |||
|
|||
export interface TemplateV2Es { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed all references to "V1" and "V2", can we rename this interface TemplateListItemES
?
Also, there is no more "name" prop so it can be
index_template: TemplateSerialized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I forgot to update this when pulling your changes.
.then(({ data: { itemsDeleted, errors }, error }) => { | ||
const hasDeletedComponentTemplates = itemsDeleted && itemsDeleted.length; | ||
|
||
if (hasDeletedComponentTemplates) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this is the typical example where I prefer to have an i18nTexts
object declared on top of the component and use it in the JSX. It makes things much clearer to understand IMO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I'll keep this in mind. I'm going to leave as is for now, since I am not following this pattern elsewhere.
onSelectionChange: setSelection, | ||
selectable: ({ usedBy }) => usedBy.length === 0, | ||
selectableMessage: (selectable) => | ||
!selectable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I prefer to use the affirmative in ternary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed
const { field } = column as EuiTableFieldDataColumnType<ComponentTemplateListItem>; | ||
|
||
return { | ||
'data-test-subj': `componentTemplateTableRow-${field}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is all the logic in cellProps
necessary? Do we need those specific test subject or can we test the table without them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows the name of the cell to be part of the data-test-subj
. I see I'm not currently using this in any of the tests though, so I removed for now.
const docsBase = `${ELASTIC_WEBSITE_URL}guide/en`; | ||
const esDocsBase = `${docsBase}/elasticsearch/reference/${DOC_LINK_VERSION}`; | ||
|
||
function getComponentTemplatesLink() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use an object instead of declaring methods? Do we expect parameters to be passed?
export const getDocumentation = ({ ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }: DocLinksSetup) => {
const docsBase = `${ELASTIC_WEBSITE_URL}guide/en`;
const esDocsBase = `${docsBase}/elasticsearch/reference/${DOC_LINK_VERSION}`;
return {
componentTemplates: `${esDocsBase}/indices-component-template.html`,
};
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great point. Fixed.
httpClient: services.httpService.httpClient, | ||
apiBasePath: API_BASE_PATH, | ||
appBasePath: BASE_PATH, | ||
trackMetric: services.uiMetricService.trackMetric.bind(services.uiMetricService), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! 👍
@@ -60,4 +61,14 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) | |||
], | |||
method: 'DELETE', | |||
}); | |||
|
|||
// Index templates v2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Can we update the comment // Composable templates
?
…nent_templates_list_view
Thanks for the review @sebelga! I believe I addressed all of your feedback.
Thanks for bringing this up. I was thinking the same thing after seeing CJ's changes. I went ahead and followed your suggestions. I changed the column title from "Used by" to "Index templates" to make it a little more clear what the number represents. There might still be some better copy we can use here; I'll follow up on this during copy review. |
💚 Build SucceededHistory
To update your PR or re-run it, just comment with: |
Co-authored-by: Elastic Machine <[email protected]>
* master: (22 commits) Partial revert of "Sync Kerberos + Anonymous access tests with the latest `security/_authenticate` API (user roles now include roles of anonymous user)." (elastic#68624) adapt some snapshot test (elastic#68489) [APM] Service maps - Fix missing ML status for services with jobs but no anomalies (elastic#68486) [skip test] apis Kerberos security Kerberos authentication finishing SPNEGO should properly set cookie and authenticate user [SIEM][Exceptions] - ExceptionsViewer UI component part 2 (elastic#68294) Surface data streams in Index Management. (elastic#67806) Fix edit datasource not working following changes in elastic#67234 (elastic#68583) [Logs + Metrics UI] Clean up async plugin initialization (elastic#67654) APM Storybook fixes (elastic#68671) Upgrade EUI to v24.1.0 (elastic#68141) [ML] DF Analytics: Creation wizard part 2 (elastic#68462) [Uptime] Fix race on overview page query (elastic#67843) Prefer using npm_execpath when spawning Yarn (elastic#68673) [Security] [Cases] Attach timeline to existing case (elastic#68580) Use Search API in Vega (elastic#68257) [Component templates] Table view (elastic#68031) [Uptime] Added relative date info in cert status column (elastic#67612) [Endpoint] Re-enable Functional test case for Endpoint related pages (elastic#68445) run page_load_metrics tests in visual regresssion jobs (elastic#68570) Enable exhaustive-deps; correct any lint warnings (elastic#68453) ...
This PR adds the "Component templates" tab with table view. It also includes the ability to delete a component template.
Create/edit/clone actions and the details flyout will come in subsequent PRs.
Note to reviewer: All client code is contained within a new
component_templates
directory undercomponents
, including associated jest tests.How to test
Create >1 component templates and associate one or more with an index template.
For example:
Test cases:
Screenshots