From 1f70e46680b82ea9ae0c2a68788fbe33127bab7d Mon Sep 17 00:00:00 2001 From: Samuel Stadler Date: Wed, 22 Nov 2023 18:51:32 +0100 Subject: [PATCH] improves EntityValidationPage UX Signed-off-by: Samuel Stadler --- .changeset/metal-students-drive.md | 5 + .../EntityValidationPage.test.tsx | 91 +++++++++++++++++++ .../EntityValidationPage.tsx | 81 +++++++++++------ 3 files changed, 148 insertions(+), 29 deletions(-) create mode 100644 .changeset/metal-students-drive.md create mode 100644 plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.test.tsx diff --git a/.changeset/metal-students-drive.md b/.changeset/metal-students-drive.md new file mode 100644 index 0000000000..5ba8f4ee3d --- /dev/null +++ b/.changeset/metal-students-drive.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-entity-validation': minor +--- + +Improves UX of the EntityValidationPage: Moves the validate button below the EntityTextArea which is actually validated, the location TextField can now be hidden to prevent confusion about what is validated and additional content can be added to the top of the validation page. diff --git a/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.test.tsx b/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.test.tsx new file mode 100644 index 0000000000..c8827ffc13 --- /dev/null +++ b/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.test.tsx @@ -0,0 +1,91 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { TestApiProvider, renderInTestApp } from '@backstage/test-utils'; +import { EntityValidationPage } from './EntityValidationPage'; +import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; +import { MarkdownContent } from '@backstage/core-components'; + +describe('EntityValidatorPage', () => { + const catalogApi: Partial = { + getEntities: () => + Promise.resolve({ + items: [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'API', + metadata: { + name: 'Entity1', + annotations: { + 'backstage.io/view-url': 'viewurl', + 'backstage.io/edit-url': 'editurl', + }, + }, + spec: { type: 'openapi' }, + }, + ], + }), + }; + + const contentHead = ; + + it('should show loation text field', async () => { + const { getByText, getByTestId } = await renderInTestApp( + + + , + ); + const mainGrid = getByTestId('main-grid'); + + expect(mainGrid.children.length).toBe(2); + expect(getByText('File Location')).toBeInTheDocument(); + }); + + it('should not show loation text field', async () => { + const { queryByText, getByTestId } = await renderInTestApp( + + + , + ); + const mainGrid = getByTestId('main-grid'); + + expect(mainGrid.children.length).toBe(1); + expect(queryByText('File Location')).not.toBeInTheDocument(); + }); + + it('should not show content head', async () => { + const { getByTestId } = await renderInTestApp( + + + , + ); + const mainGrid = getByTestId('main-grid'); + + expect(mainGrid.children.length).toBe(2); + }); + + it('should show content head', async () => { + const { getByTestId } = await renderInTestApp( + + + , + ); + const mainGrid = getByTestId('main-grid'); + + expect(mainGrid.children.length).toBe(3); + }); +}); diff --git a/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx b/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx index 0f0e60366b..c3e6386a37 100644 --- a/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx +++ b/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx @@ -15,9 +15,9 @@ */ import React, { useState } from 'react'; -import { Content, Header, LinkButton, Page } from '@backstage/core-components'; +import { Content, Header, Page } from '@backstage/core-components'; import { EntityTextArea } from '../EntityTextArea'; -import { Grid, TextField } from '@material-ui/core'; +import { Button, Grid, TextField } from '@material-ui/core'; import { CatalogProcessorResult } from '../../types'; import { parseEntityYaml } from '../../utils'; import { EntityValidationOutput } from '../EntityValidationOutput'; @@ -40,10 +40,14 @@ spec: export const EntityValidationPage = (props: { defaultYaml?: string; defaultLocation?: string; + hideFileLocationField?: boolean; + contentHead?: React.ReactNode; }) => { const { defaultYaml = EXAMPLE_CATALOG_INFO_YAML, defaultLocation = 'https://github.com/backstage/backstage/blob/master/catalog-info.yaml', + hideFileLocationField = false, + contentHead, } = props; const [catalogYaml, setCatalogYaml] = useState(defaultYaml); @@ -67,8 +71,16 @@ export const EntityValidationPage = (props: { subtitle="Tool to validate catalog-info.yaml files" /> - - + + {contentHead} + + {!hideFileLocationField && ( setLocationUrl(e.target.value)} /> - - - - - - Validate - + )} + + + + + + setCatalogYaml(value)} + catalogYaml={catalogYaml} + /> + + + + - - - - - setCatalogYaml(value)} - catalogYaml={catalogYaml} - /> - - - - - + + + + +