mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ShareDrawer: Add confirm action (#89001)
This commit is contained in:
parent
07ec1a303e
commit
b7180c17b8
@ -23,6 +23,7 @@ import { DashboardInteractions } from 'app/features/dashboard-scene/utils/intera
|
||||
import { AccessControlAction } from 'app/types';
|
||||
|
||||
import { getDashboardSceneFor } from '../../../utils/utils';
|
||||
import { ShareDrawerConfirmAction } from '../../ShareDrawer/ShareDrawerConfirmAction';
|
||||
import { useShareDrawerContext } from '../../ShareDrawer/ShareDrawerContext';
|
||||
|
||||
import { EmailSharing } from './EmailShare/EmailSharing';
|
||||
@ -65,22 +66,62 @@ export class ShareExternally extends SceneObjectBase {
|
||||
}
|
||||
|
||||
function ShareExternallyRenderer({ model }: SceneComponentProps<ShareExternally>) {
|
||||
const dashboard = getDashboardSceneFor(model);
|
||||
const { data: publicDashboard, isLoading } = useGetPublicDashboardQuery(dashboard.state.uid!);
|
||||
const [showRevokeAccess, setShowRevokeAccess] = useState(false);
|
||||
|
||||
const styles = useStyles2(getStyles);
|
||||
const dashboard = getDashboardSceneFor(model);
|
||||
|
||||
const { data: publicDashboard, isLoading } = useGetPublicDashboardQuery(dashboard.state.uid!);
|
||||
const [deletePublicDashboard, { isLoading: isDeleteLoading }] = useDeletePublicDashboardMutation();
|
||||
|
||||
const onRevokeClick = () => {
|
||||
setShowRevokeAccess(true);
|
||||
};
|
||||
|
||||
const onDeleteClick = async () => {
|
||||
DashboardInteractions.revokePublicDashboardClicked();
|
||||
await deletePublicDashboard({
|
||||
dashboard,
|
||||
uid: publicDashboard!.uid,
|
||||
dashboardUid: dashboard.state.uid!,
|
||||
}).unwrap();
|
||||
setShowRevokeAccess(false);
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
if (showRevokeAccess) {
|
||||
return (
|
||||
<ShareDrawerConfirmAction
|
||||
title={t('public-dashboard.share-externally.revoke-access-button', 'Revoke access')}
|
||||
confirmButtonLabel={t('public-dashboard.share-externally.revoke-access-button', 'Revoke access')}
|
||||
onConfirm={onDeleteClick}
|
||||
onDismiss={() => setShowRevokeAccess(false)}
|
||||
description={t(
|
||||
'public-dashboard.share-externally.revoke-access-description',
|
||||
'Are you sure you want to revoke this access? The dashboard can no longer be shared.'
|
||||
)}
|
||||
isActionLoading={isDeleteLoading}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<ShareExternallyBase publicDashboard={publicDashboard} />
|
||||
<ShareExternallyBase publicDashboard={publicDashboard} onRevokeClick={onRevokeClick} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ShareExternallyBase({ publicDashboard }: { publicDashboard?: PublicDashboard }) {
|
||||
function ShareExternallyBase({
|
||||
publicDashboard,
|
||||
onRevokeClick,
|
||||
}: {
|
||||
publicDashboard?: PublicDashboard;
|
||||
onRevokeClick: () => void;
|
||||
}) {
|
||||
const options = getShareExternallyOptions();
|
||||
const getShareType = useMemo(() => {
|
||||
if (publicDashboard && isEmailSharingEnabled()) {
|
||||
@ -105,24 +146,21 @@ function ShareExternallyBase({ publicDashboard }: { publicDashboard?: PublicDash
|
||||
<Stack direction="column" gap={2} data-testid={selectors.container}>
|
||||
<ShareAlerts publicDashboard={publicDashboard} />
|
||||
<ShareTypeSelect setShareType={setShareType} value={shareType} options={options} />
|
||||
|
||||
{Config}
|
||||
{publicDashboard && (
|
||||
<>
|
||||
<Divider spacing={0} />
|
||||
<Actions publicDashboard={publicDashboard} />
|
||||
<Actions publicDashboard={publicDashboard} onRevokeClick={onRevokeClick} />
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
function Actions({ publicDashboard }: { publicDashboard: PublicDashboard }) {
|
||||
function Actions({ publicDashboard, onRevokeClick }: { publicDashboard: PublicDashboard; onRevokeClick: () => void }) {
|
||||
const { dashboard } = useShareDrawerContext();
|
||||
const [update, { isLoading: isUpdateLoading }] = usePauseOrResumePublicDashboardMutation();
|
||||
const [deletePublicDashboard, { isLoading: isDeleteLoading }] = useDeletePublicDashboardMutation();
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const isLoading = isUpdateLoading || isDeleteLoading;
|
||||
const hasWritePermissions = contextSrv.hasPermission(AccessControlAction.DashboardsPublicWrite);
|
||||
|
||||
function onCopyURL() {
|
||||
@ -142,15 +180,6 @@ function Actions({ publicDashboard }: { publicDashboard: PublicDashboard }) {
|
||||
});
|
||||
};
|
||||
|
||||
const onDeleteClick = () => {
|
||||
DashboardInteractions.revokePublicDashboardClicked();
|
||||
deletePublicDashboard({
|
||||
dashboard,
|
||||
uid: publicDashboard!.uid,
|
||||
dashboardUid: dashboard.state.uid!,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack alignItems="center" direction={{ xs: 'column', sm: 'row' }}>
|
||||
<div className={styles.actionsContainer}>
|
||||
@ -169,8 +198,8 @@ function Actions({ publicDashboard }: { publicDashboard: PublicDashboard }) {
|
||||
icon="trash-alt"
|
||||
variant="destructive"
|
||||
fill="outline"
|
||||
disabled={isLoading || !hasWritePermissions}
|
||||
onClick={onDeleteClick}
|
||||
disabled={isUpdateLoading || !hasWritePermissions}
|
||||
onClick={onRevokeClick}
|
||||
>
|
||||
<Trans i18nKey="public-dashboard.share-externally.revoke-access-button">Revoke access</Trans>
|
||||
</Button>
|
||||
@ -187,7 +216,7 @@ function Actions({ publicDashboard }: { publicDashboard: PublicDashboard }) {
|
||||
: ''
|
||||
}
|
||||
onClick={onPauseOrResumeClick}
|
||||
disabled={isLoading || !hasWritePermissions}
|
||||
disabled={isUpdateLoading || !hasWritePermissions}
|
||||
>
|
||||
{publicDashboard.isEnabled ? (
|
||||
<Trans i18nKey="public-dashboard.share-externally.pause-access-button">Pause access</Trans>
|
||||
@ -197,7 +226,7 @@ function Actions({ publicDashboard }: { publicDashboard: PublicDashboard }) {
|
||||
</Button>
|
||||
</Stack>
|
||||
</div>
|
||||
{isLoading && <Spinner />}
|
||||
{isUpdateLoading && <Spinner />}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Spinner, Stack, Text } from '@grafana/ui';
|
||||
import { IconButton, useStyles2 } from '@grafana/ui/';
|
||||
import { ConfirmContent, ConfirmContentProps } from '@grafana/ui/src/components/ConfirmModal/ConfirmContent';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
export function ShareDrawerConfirmAction({
|
||||
onConfirm,
|
||||
onDismiss,
|
||||
description,
|
||||
confirmButtonLabel,
|
||||
title,
|
||||
isActionLoading,
|
||||
}: { title: string; isActionLoading: boolean } & Pick<
|
||||
ConfirmContentProps,
|
||||
'description' | 'onConfirm' | 'onDismiss' | 'confirmButtonLabel'
|
||||
>) {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const ConfirmBody = () => (
|
||||
<div className={styles.bodyContainer}>
|
||||
<Stack justifyContent="space-between">
|
||||
<Stack gap={1} alignItems="center">
|
||||
<IconButton
|
||||
size="xl"
|
||||
name="angle-left"
|
||||
aria-label={t('share-drawer.confirm-action.back-arrow-button', 'Back button')}
|
||||
onClick={onDismiss}
|
||||
/>
|
||||
<Text variant="h4">{title}</Text>
|
||||
</Stack>
|
||||
{isActionLoading && <Spinner />}
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<ConfirmContent
|
||||
body={<ConfirmBody />}
|
||||
description={description}
|
||||
confirmButtonLabel={confirmButtonLabel}
|
||||
confirmButtonVariant="destructive"
|
||||
dismissButtonLabel="Cancel"
|
||||
dismissButtonVariant="secondary"
|
||||
justifyButtons="flex-start"
|
||||
onConfirm={onConfirm}
|
||||
onDismiss={onDismiss}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
bodyContainer: css({
|
||||
marginBottom: theme.spacing(2),
|
||||
}),
|
||||
});
|
@ -1487,7 +1487,8 @@
|
||||
"public-share-type-option-description": "Anyone with the link can access",
|
||||
"public-share-type-option-label": "Anyone with the link",
|
||||
"resume-access-button": "Resume access",
|
||||
"revoke-access-button": "Revoke access"
|
||||
"revoke-access-button": "Revoke access",
|
||||
"revoke-access-description": "Are you sure you want to revoke this access? The dashboard can no longer be shared."
|
||||
},
|
||||
"sharing": {
|
||||
"success-creation": "Dashboard is public!"
|
||||
@ -1654,6 +1655,11 @@
|
||||
"title": "You haven't created any service accounts yet"
|
||||
}
|
||||
},
|
||||
"share-drawer": {
|
||||
"confirm-action": {
|
||||
"back-arrow-button": "Back button"
|
||||
}
|
||||
},
|
||||
"share-modal": {
|
||||
"dashboard": {
|
||||
"title": "Share"
|
||||
|
@ -1487,7 +1487,8 @@
|
||||
"public-share-type-option-description": "Åʼnyőʼnę ŵįŧĥ ŧĥę ľįʼnĸ čäʼn äččęşş",
|
||||
"public-share-type-option-label": "Åʼnyőʼnę ŵįŧĥ ŧĥę ľįʼnĸ",
|
||||
"resume-access-button": "Ŗęşūmę äččęşş",
|
||||
"revoke-access-button": "Ŗęvőĸę äččęşş"
|
||||
"revoke-access-button": "Ŗęvőĸę äččęşş",
|
||||
"revoke-access-description": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő řęvőĸę ŧĥįş äččęşş? Ŧĥę đäşĥþőäřđ čäʼn ʼnő ľőʼnģęř þę şĥäřęđ."
|
||||
},
|
||||
"sharing": {
|
||||
"success-creation": "Đäşĥþőäřđ įş pūþľįč!"
|
||||
@ -1654,6 +1655,11 @@
|
||||
"title": "Ÿőū ĥävęʼn'ŧ čřęäŧęđ äʼny şęřvįčę äččőūʼnŧş yęŧ"
|
||||
}
|
||||
},
|
||||
"share-drawer": {
|
||||
"confirm-action": {
|
||||
"back-arrow-button": "ßäčĸ þūŧŧőʼn"
|
||||
}
|
||||
},
|
||||
"share-modal": {
|
||||
"dashboard": {
|
||||
"title": "Ŝĥäřę"
|
||||
|
Loading…
Reference in New Issue
Block a user