mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
publicdashboards: split create/update api paths (#57940)
This PR splits the create and update paths for public dashboards and includes assorted refactors toward a proper REST API. Additionally, we removed the concept of a "public dashboard config" in favor of "public dashboard" Co-authored-by: juanicabanas <juan.cabanas@grafana.com> Co-authored-by: Ezequiel Victorero <ezequiel.victorero@grafana.com>
This commit is contained in:
@@ -17,20 +17,7 @@ import { configureStore } from 'app/store/configureStore';
|
||||
|
||||
import { ShareModal } from '../ShareModal';
|
||||
|
||||
const server = setupServer(
|
||||
rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (_, res, ctx) => {
|
||||
return res(
|
||||
ctx.status(200),
|
||||
ctx.json({
|
||||
isEnabled: false,
|
||||
annotationsEnabled: false,
|
||||
uid: undefined,
|
||||
dashboardUid: undefined,
|
||||
accessToken: 'an-access-token',
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
const server = setupServer();
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
...(jest.requireActual('@grafana/runtime') as unknown as object),
|
||||
@@ -147,6 +134,7 @@ describe('SharePublic', () => {
|
||||
expect(screen.getByText('2022-08-30 00:00:00 to 2022-09-04 01:59:59')).toBeInTheDocument();
|
||||
});
|
||||
it('when modal is opened, then loader spinner appears and inputs are disabled', async () => {
|
||||
mockDashboard.meta.hasPublicDashboard = true;
|
||||
await renderSharePublicDashboard({ panel: mockPanel, dashboard: mockDashboard, onDismiss: () => {} });
|
||||
|
||||
expect(await screen.findByTestId('Spinner')).toBeInTheDocument();
|
||||
@@ -158,6 +146,7 @@ describe('SharePublic', () => {
|
||||
expect(screen.getByTestId(selectors.SaveConfigButton)).toBeDisabled();
|
||||
});
|
||||
it('when fetch errors happen, then all inputs remain disabled', async () => {
|
||||
mockDashboard.meta.hasPublicDashboard = true;
|
||||
server.use(
|
||||
rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
|
||||
return res(ctx.status(500));
|
||||
@@ -165,7 +154,7 @@ describe('SharePublic', () => {
|
||||
);
|
||||
|
||||
await renderSharePublicDashboard({ panel: mockPanel, dashboard: mockDashboard, onDismiss: () => {} });
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'), { timeout: 7000 });
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
|
||||
expect(screen.getByTestId(selectors.WillBePublicCheckbox)).toBeDisabled();
|
||||
expect(screen.getByTestId(selectors.LimitedDSCheckbox)).toBeDisabled();
|
||||
@@ -178,13 +167,16 @@ describe('SharePublic', () => {
|
||||
});
|
||||
|
||||
describe('SharePublic - New config setup', () => {
|
||||
beforeEach(() => {
|
||||
mockDashboard.meta.hasPublicDashboard = false;
|
||||
});
|
||||
it('when modal is opened, then save button is disabled', async () => {
|
||||
await renderSharePublicDashboard({ panel: mockPanel, dashboard: mockDashboard, onDismiss: () => {} });
|
||||
expect(screen.getByTestId(selectors.SaveConfigButton)).toBeDisabled();
|
||||
});
|
||||
it('when fetch is done, then loader spinner is gone, inputs are enabled and save button is disabled', async () => {
|
||||
it('when fetch is done, then no loader spinner appears, inputs are enabled and save button is disabled', async () => {
|
||||
await renderSharePublicDashboard({ panel: mockPanel, dashboard: mockDashboard, onDismiss: () => {} });
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
expect(screen.queryByTestId('Spinner')).not.toBeInTheDocument();
|
||||
|
||||
expect(screen.getByTestId(selectors.WillBePublicCheckbox)).toBeEnabled();
|
||||
expect(screen.getByTestId(selectors.LimitedDSCheckbox)).toBeEnabled();
|
||||
@@ -196,7 +188,7 @@ describe('SharePublic - New config setup', () => {
|
||||
});
|
||||
it('when checkboxes are filled, then save button remains disabled', async () => {
|
||||
await renderSharePublicDashboard({ panel: mockPanel, dashboard: mockDashboard, onDismiss: () => {} });
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
expect(screen.queryByTestId('Spinner')).not.toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByTestId(selectors.WillBePublicCheckbox));
|
||||
fireEvent.click(screen.getByTestId(selectors.LimitedDSCheckbox));
|
||||
@@ -206,7 +198,7 @@ describe('SharePublic - New config setup', () => {
|
||||
});
|
||||
it('when checkboxes and switch are filled, then save button is enabled', async () => {
|
||||
await renderSharePublicDashboard({ panel: mockPanel, dashboard: mockDashboard, onDismiss: () => {} });
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
expect(screen.queryByTestId('Spinner')).not.toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByTestId(selectors.WillBePublicCheckbox));
|
||||
fireEvent.click(screen.getByTestId(selectors.LimitedDSCheckbox));
|
||||
@@ -219,6 +211,7 @@ describe('SharePublic - New config setup', () => {
|
||||
|
||||
describe('SharePublic - Already persisted', () => {
|
||||
beforeEach(() => {
|
||||
mockDashboard.meta.hasPublicDashboard = true;
|
||||
server.use(
|
||||
rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
|
||||
return res(
|
||||
|
||||
@@ -6,7 +6,11 @@ import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
|
||||
import { reportInteraction } from '@grafana/runtime/src';
|
||||
import { Alert, Button, ClipboardButton, Field, HorizontalGroup, Input, useStyles2, Spinner } from '@grafana/ui/src';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { useGetConfigQuery, useSaveConfigMutation } from 'app/features/dashboard/api/publicDashboardApi';
|
||||
import {
|
||||
useGetPublicDashboardQuery,
|
||||
useCreatePublicDashboardMutation,
|
||||
useUpdatePublicDashboardMutation,
|
||||
} from 'app/features/dashboard/api/publicDashboardApi';
|
||||
import { AcknowledgeCheckboxes } from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/AcknowledgeCheckboxes';
|
||||
import { Configuration } from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/Configuration';
|
||||
import { Description } from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/Description';
|
||||
@@ -27,13 +31,19 @@ export const SharePublicDashboard = (props: Props) => {
|
||||
const selectors = e2eSelectors.pages.ShareDashboardModal.PublicDashboard;
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const [hasPublicDashboard, setHasPublicDashboard] = useState(props.dashboard.meta.hasPublicDashboard);
|
||||
|
||||
const {
|
||||
isLoading: isFetchingLoading,
|
||||
data: publicDashboard,
|
||||
isError: isFetchingError,
|
||||
} = useGetConfigQuery(props.dashboard.uid);
|
||||
} = useGetPublicDashboardQuery(props.dashboard.uid, {
|
||||
// if we don't have a public dashboard, don't try to load public dashboard
|
||||
skip: !hasPublicDashboard,
|
||||
});
|
||||
|
||||
const [saveConfig, { isLoading: isSaveLoading }] = useSaveConfigMutation();
|
||||
const [createPublicDashboard, { isLoading: isSaveLoading }] = useCreatePublicDashboardMutation();
|
||||
const [updatePublicDashboard, { isLoading: isUpdateLoading }] = useUpdatePublicDashboardMutation();
|
||||
|
||||
const [acknowledgements, setAcknowledgements] = useState<Acknowledgements>({
|
||||
public: false,
|
||||
@@ -63,7 +73,7 @@ export const SharePublicDashboard = (props: Props) => {
|
||||
setEnabledSwitch((prevState) => ({ ...prevState, isEnabled: !!publicDashboard?.isEnabled }));
|
||||
}, [publicDashboard]);
|
||||
|
||||
const isLoading = isFetchingLoading || isSaveLoading;
|
||||
const isLoading = isFetchingLoading || isSaveLoading || isUpdateLoading;
|
||||
const hasWritePermissions = contextSrv.hasAccess(AccessControlAction.DashboardsPublicWrite, isOrgAdmin());
|
||||
const acknowledged = acknowledgements.public && acknowledgements.datasources && acknowledgements.usage;
|
||||
const isSaveEnabled = useMemo(
|
||||
@@ -77,13 +87,23 @@ export const SharePublicDashboard = (props: Props) => {
|
||||
[hasWritePermissions, acknowledged, props.dashboard, isLoading, isFetchingError, enabledSwitch, publicDashboard]
|
||||
);
|
||||
|
||||
const onSavePublicConfig = () => {
|
||||
const onSavePublicConfig = async () => {
|
||||
reportInteraction('grafana_dashboards_public_create_clicked');
|
||||
|
||||
saveConfig({
|
||||
const req = {
|
||||
dashboard: props.dashboard,
|
||||
payload: { ...publicDashboard!, isEnabled: enabledSwitch.isEnabled, annotationsEnabled },
|
||||
});
|
||||
};
|
||||
|
||||
// create or update based on whether we have existing uid
|
||||
|
||||
if (hasPublicDashboard) {
|
||||
await updatePublicDashboard(req).unwrap();
|
||||
setHasPublicDashboard(true);
|
||||
} else {
|
||||
await createPublicDashboard(req).unwrap();
|
||||
setHasPublicDashboard(true);
|
||||
}
|
||||
};
|
||||
|
||||
const onAcknowledge = (field: string, checked: boolean) => {
|
||||
|
||||
Reference in New Issue
Block a user