Settings: Consistent footer actions across edit views (#82048)

This commit is contained in:
Ivan Ortega Alba 2024-02-08 10:50:53 +01:00 committed by GitHub
parent ea96c83a2c
commit 35e96d6b04
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 61 additions and 53 deletions

View File

@ -25,12 +25,14 @@ describe('Variables - Datasource', () => {
e2e.pages.Dashboard.Settings.Variables.Edit.DatasourceVariable.datasourceSelect().within(() => { e2e.pages.Dashboard.Settings.Variables.Edit.DatasourceVariable.datasourceSelect().within(() => {
cy.get('input').type('Prometheus{enter}'); cy.get('input').type('Prometheus{enter}');
}); });
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption() e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().should(
.eq(0) 'contain.text',
.should('have.text', 'gdev-prometheus'); 'gdev-prometheus'
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption() );
.eq(1) e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().should(
.should('have.text', 'gdev-slow-prometheus'); 'contain.text',
'gdev-slow-prometheus'
);
// Navigate back to the homepage and change the selected variable value // Navigate back to the homepage and change the selected variable value
e2e.pages.Dashboard.Settings.Variables.Edit.General.submitButton().click(); e2e.pages.Dashboard.Settings.Variables.Edit.General.submitButton().click();

View File

@ -158,41 +158,20 @@ export const Permissions = ({
return ( return (
<div> <div>
{canSetPermissions && ( {canSetPermissions && resource === 'folders' && (
<> <>
{resource === 'folders' && ( <Trans i18nKey="access-control.permissions.permissions-change-warning">
<> This will change permissions for this folder and all its descendants. In total, this will affect:
<Trans i18nKey="access-control.permissions.permissions-change-warning"> </Trans>
This will change permissions for this folder and all its descendants. In total, this will affect: <DescendantCount
</Trans> selectedItems={{
<DescendantCount folder: { [resourceId]: true },
selectedItems={{ dashboard: {},
folder: { [resourceId]: true }, panel: {},
dashboard: {}, $all: false,
panel: {}, }}
$all: false, />
}} <Space v={2} />
/>
<Space v={2} />
</>
)}
<Button
className={styles.addPermissionButton}
variant={'primary'}
key="add-permission"
onClick={() => setIsAdding(true)}
>
{buttonLabel}
</Button>
<SlideDown in={isAdding}>
<AddPermission
title={addPermissionTitle}
onAdd={onAdd}
permissions={desc.permissions}
assignments={desc.assignments}
onCancel={() => setIsAdding(false)}
/>
</SlideDown>
</> </>
)} )}
{items.length === 0 && ( {items.length === 0 && (
@ -227,7 +206,6 @@ export const Permissions = ({
onRemove={onRemove} onRemove={onRemove}
canSet={canSetPermissions} canSet={canSetPermissions}
/> />
<PermissionList <PermissionList
title={titleTeam} title={titleTeam}
items={teams} items={teams}
@ -237,6 +215,28 @@ export const Permissions = ({
onRemove={onRemove} onRemove={onRemove}
canSet={canSetPermissions} canSet={canSetPermissions}
/> />
{canSetPermissions && (
<>
<Button
className={styles.addPermissionButton}
variant={'primary'}
key="add-permission"
onClick={() => setIsAdding(true)}
icon="plus"
>
{buttonLabel}
</Button>
<SlideDown in={isAdding}>
<AddPermission
title={addPermissionTitle}
onAdd={onAdd}
permissions={desc.permissions}
assignments={desc.assignments}
onCancel={() => setIsAdding(false)}
/>
</SlideDown>
</>
)}
</div> </div>
); );
}; };

View File

@ -215,7 +215,7 @@ describe('DashboardLinksEditView', () => {
const { getByText } = render(<settings.Component model={settings} />); const { getByText } = render(<settings.Component model={settings} />);
expect(getByText('Edit link')).toBeInTheDocument(); expect(getByText('Edit link')).toBeInTheDocument();
expect(getByText('Apply')).toBeInTheDocument(); expect(getByText('Back to list')).toBeInTheDocument();
}); });
}); });
}); });

View File

@ -101,7 +101,9 @@ export function DashboardLinkForm({ link, onUpdate, onGoBack }: DashboardLinkFor
<Checkbox label="Open link in new tab" name="targetBlank" value={link.targetBlank} onChange={onChange} /> <Checkbox label="Open link in new tab" name="targetBlank" value={link.targetBlank} onChange={onChange} />
</Field> </Field>
</CollapsableSection> </CollapsableSection>
<Button onClick={onGoBack}>Apply</Button> <Button variant="secondary" onClick={onGoBack}>
Back to list
</Button>
</div> </div>
); );
} }

View File

@ -1,12 +1,11 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React from 'react'; import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { DashboardLink } from '@grafana/schema'; import { DashboardLink } from '@grafana/schema';
import { DeleteButton, HorizontalGroup, Icon, IconButton, TagList, useStyles2 } from '@grafana/ui'; import { Button, DeleteButton, HorizontalGroup, Icon, IconButton, TagList, useStyles2 } from '@grafana/ui';
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import { ListNewButton } from '../../../dashboard/components/DashboardSettings/ListNewButton';
interface DashboardLinkListProps { interface DashboardLinkListProps {
links: DashboardLink[]; links: DashboardLink[];
onNew: () => void; onNew: () => void;
@ -92,12 +91,14 @@ export function DashboardLinkList({
))} ))}
</tbody> </tbody>
</table> </table>
<ListNewButton onClick={onNew}>New link</ListNewButton> <Button className={styles.newLinkButton} icon="plus" onClick={onNew}>
New link
</Button>
</> </>
); );
} }
const getStyles = () => ({ const getStyles = (theme: GrafanaTheme2) => ({
titleWrapper: css({ titleWrapper: css({
width: '20vw', width: '20vw',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
@ -108,4 +109,7 @@ const getStyles = () => ({
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
overflow: 'hidden', overflow: 'hidden',
}), }),
newLinkButton: css({
marginTop: theme.spacing(3),
}),
}); });

View File

@ -42,7 +42,7 @@ export function VariableEditorList({
{variables.length === 0 && <EmptyVariablesList onAdd={onAdd} />} {variables.length === 0 && <EmptyVariablesList onAdd={onAdd} />}
{variables.length > 0 && ( {variables.length > 0 && (
<Stack direction="column" gap={4}> <Stack direction="column" gap={3}>
<div className={styles.tableContainer}> <div className={styles.tableContainer}>
<table <table
className="filter-table filter-table--hover" className="filter-table filter-table--hover"

View File

@ -175,7 +175,7 @@ describe('LinksSettings', () => {
expect(screen.queryByText('Type')).toBeInTheDocument(); expect(screen.queryByText('Type')).toBeInTheDocument();
expect(screen.queryByText('Title')).toBeInTheDocument(); expect(screen.queryByText('Title')).toBeInTheDocument();
expect(screen.queryByText('With tags')).toBeInTheDocument(); expect(screen.queryByText('With tags')).toBeInTheDocument();
expect(screen.queryByText('Apply')).toBeInTheDocument(); expect(screen.queryByText('Back to list')).toBeInTheDocument();
expect(screen.queryByText('Url')).not.toBeInTheDocument(); expect(screen.queryByText('Url')).not.toBeInTheDocument();
expect(screen.queryByText('Tooltip')).not.toBeInTheDocument(); expect(screen.queryByText('Tooltip')).not.toBeInTheDocument();
@ -194,7 +194,7 @@ describe('LinksSettings', () => {
await userEvent.clear(screen.getByRole('textbox', { name: /title/i })); await userEvent.clear(screen.getByRole('textbox', { name: /title/i }));
await userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'New Dashboard Link'); await userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'New Dashboard Link');
await userEvent.click(screen.getByRole('button', { name: /Apply/i })); await userEvent.click(screen.getByRole('button', { name: /Back to list/i }));
expect(getTableBodyRows().length).toBe(4); expect(getTableBodyRows().length).toBe(4);
expect(within(getTableBody()).queryByText('New Dashboard Link')).toBeInTheDocument(); expect(within(getTableBody()).queryByText('New Dashboard Link')).toBeInTheDocument();
@ -203,7 +203,7 @@ describe('LinksSettings', () => {
await userEvent.clear(screen.getByRole('textbox', { name: /title/i })); await userEvent.clear(screen.getByRole('textbox', { name: /title/i }));
await userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'The first dashboard link'); await userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'The first dashboard link');
await userEvent.click(screen.getByRole('button', { name: /Apply/i })); await userEvent.click(screen.getByRole('button', { name: /Back to list/i }));
expect(within(getTableBody()).queryByText(originalLinks[0].title)).not.toBeInTheDocument(); expect(within(getTableBody()).queryByText(originalLinks[0].title)).not.toBeInTheDocument();
expect(within(getTableBody()).queryByText('The first dashboard link')).toBeInTheDocument(); expect(within(getTableBody()).queryByText('The first dashboard link')).toBeInTheDocument();

View File

@ -10,7 +10,7 @@ export const ListNewButton = ({ children, ...restProps }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return ( return (
<div className={styles.buttonWrapper}> <div className={styles.buttonWrapper}>
<Button icon="plus" variant="secondary" {...restProps}> <Button icon="plus" {...restProps}>
{children} {children}
</Button> </Button>
</div> </div>