mirror of
https://github.com/grafana/grafana.git
synced 2024-11-21 16:38:03 -06:00
ShareExternally: Rename public dashboard section (#91928)
This commit is contained in:
parent
34ab5fe1f3
commit
07500e11be
@ -1,3 +1,4 @@
|
||||
import { config } from '@grafana/runtime';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
// Maps the ID of the nav item to a translated phrase to later pass to <Trans />
|
||||
@ -43,7 +44,9 @@ export function getNavTitle(navId: string | undefined) {
|
||||
case 'reports':
|
||||
return t('nav.reporting.title', 'Reporting');
|
||||
case 'dashboards/public':
|
||||
return t('nav.public.title', 'Public dashboards');
|
||||
return config.featureToggles.newDashboardSharingComponent
|
||||
? t('nav.shared-dashboard.title', 'Shared dashboards')
|
||||
: t('nav.public.title', 'Public dashboards');
|
||||
case 'dashboards/recently-deleted':
|
||||
return t('nav.recently-deleted.title', 'Recently deleted');
|
||||
case 'dashboards/new':
|
||||
@ -210,6 +213,10 @@ export function getNavSubTitle(navId: string | undefined) {
|
||||
'nav.snapshots.subtitle',
|
||||
'Interactive, publically available, point-in-time representations of dashboards'
|
||||
);
|
||||
case 'dashboards/public':
|
||||
return config.featureToggles.newDashboardSharingComponent
|
||||
? t('nav.shared-dashboard.subtitle', "Manage your organization's externally shared dashboards")
|
||||
: undefined;
|
||||
case 'dashboards/library-panels':
|
||||
return t('nav.library-panels.subtitle', 'Reusable panels that can be added to multiple dashboards');
|
||||
case 'dashboards/recently-deleted':
|
||||
|
@ -264,7 +264,6 @@ export function ConfigPublicDashboard({ publicDashboard, unsupportedDatasources
|
||||
onRevoke={() => {
|
||||
DashboardInteractions.revokePublicDashboardClicked();
|
||||
showModal(DeletePublicDashboardModal, {
|
||||
dashboardTitle: dashboard.title,
|
||||
onConfirm: () => onDeletePublicDashboardClick(hideModal),
|
||||
onDismiss: () => {
|
||||
showModal(ShareModal, {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Button, ModalsController, ButtonProps } from '@grafana/ui/src';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { useDeletePublicDashboardMutation } from 'app/features/dashboard/api/publicDashboardApi';
|
||||
@ -41,17 +42,15 @@ export const DeletePublicDashboardButton = ({
|
||||
return (
|
||||
<ModalsController>
|
||||
{({ showModal, hideModal }) => {
|
||||
const translatedRevocationButtonText = t(
|
||||
'public-dashboard-list.button.revoke-button-text',
|
||||
'Revoke public URL'
|
||||
);
|
||||
const translatedRevocationButtonText = config.featureToggles.newDashboardSharingComponent
|
||||
? t('shared-dashboard-list.button.revoke-button-text', 'Revoke access')
|
||||
: t('public-dashboard-list.button.revoke-button-text', 'Revoke public URL');
|
||||
return (
|
||||
<Button
|
||||
aria-label={translatedRevocationButtonText}
|
||||
title={translatedRevocationButtonText}
|
||||
onClick={() =>
|
||||
showModal(DeletePublicDashboardModal, {
|
||||
dashboardTitle: publicDashboard.title,
|
||||
onConfirm: () => onDeletePublicDashboardClick(publicDashboard, hideModal),
|
||||
onDismiss: () => {
|
||||
onDismiss ? onDismiss() : hideModal();
|
||||
|
@ -1,41 +1,42 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data/src';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { ConfirmModal, useStyles2 } from '@grafana/ui/src';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
const Body = ({ title }: { title?: string }) => {
|
||||
const Body = () => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
return (
|
||||
<p className={styles.description}>
|
||||
{title
|
||||
{config.featureToggles.newDashboardSharingComponent
|
||||
? t(
|
||||
'public-dashboard.delete-modal.revoke-nonorphaned-body-text',
|
||||
'Are you sure you want to revoke this URL? The dashboard will no longer be public.'
|
||||
'shared-dashboard.delete-modal.revoke-body-text',
|
||||
'Are you sure you want to revoke this access? The dashboard can no longer be shared.'
|
||||
)
|
||||
: t(
|
||||
'public-dashboard.delete-modal.revoke-orphaned-body-text',
|
||||
'Orphaned public dashboard will no longer be public.'
|
||||
'public-dashboard.delete-modal.revoke-body-text',
|
||||
'Are you sure you want to revoke this URL? The dashboard will no longer be public.'
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
export const DeletePublicDashboardModal = ({
|
||||
dashboardTitle,
|
||||
onConfirm,
|
||||
onDismiss,
|
||||
}: {
|
||||
dashboardTitle?: string;
|
||||
onConfirm: () => void;
|
||||
onDismiss: () => void;
|
||||
}) => {
|
||||
const translatedRevocationModalText = t('public-dashboard.delete-modal.revoke-title', 'Revoke public URL');
|
||||
const translatedRevocationModalText = config.featureToggles.newDashboardSharingComponent
|
||||
? t('shared-dashboard.delete-modal.revoke-title', 'Revoke access')
|
||||
: t('public-dashboard.delete-modal.revoke-title', 'Revoke public URL');
|
||||
return (
|
||||
<ConfirmModal
|
||||
isOpen
|
||||
body={<Body title={dashboardTitle} />}
|
||||
body={<Body />}
|
||||
onConfirm={onConfirm}
|
||||
onDismiss={onDismiss}
|
||||
title={translatedRevocationModalText}
|
||||
|
@ -32,25 +32,6 @@ const publicDashboardListResponse: PublicDashboardListResponse[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const orphanedDashboardListResponse: PublicDashboardListResponse[] = [
|
||||
{
|
||||
uid: 'SdZwuCZVz2',
|
||||
accessToken: 'beeaf92f6ab3467f80b2be922c7741ab',
|
||||
title: '',
|
||||
dashboardUid: '',
|
||||
isEnabled: false,
|
||||
slug: '',
|
||||
},
|
||||
{
|
||||
uid: 'EuiEbd3nz2',
|
||||
accessToken: '8687b0498ccf4babb2f92810d8563b33',
|
||||
title: '',
|
||||
dashboardUid: '',
|
||||
isEnabled: true,
|
||||
slug: '',
|
||||
},
|
||||
];
|
||||
|
||||
const paginationResponse: Omit<PublicDashboardListWithPaginationResponse, 'publicDashboards'> = {
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
@ -165,26 +146,6 @@ describe('Delete public dashboard', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Orphaned public dashboard', () => {
|
||||
it('renders orphaned and non orphaned public dashboards items correctly', async () => {
|
||||
const response: PublicDashboardListWithPaginationResponse = {
|
||||
...paginationResponse,
|
||||
publicDashboards: [...publicDashboardListResponse, ...orphanedDashboardListResponse],
|
||||
};
|
||||
server.use(
|
||||
http.get('/api/dashboards/public-dashboards', () => {
|
||||
return HttpResponse.json(response);
|
||||
})
|
||||
);
|
||||
jest.spyOn(contextSrv, 'hasPermission').mockReturnValue(true);
|
||||
|
||||
await renderPublicDashboardTable(true);
|
||||
response.publicDashboards.forEach((pd, idx) => {
|
||||
renderPublicDashboardItemCorrectly(pd, idx, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const renderPublicDashboardItemCorrectly = (pd: PublicDashboardListResponse, idx: number, hasWriteAccess: boolean) => {
|
||||
const isOrphaned = !pd.dashboardUid;
|
||||
|
||||
|
@ -4,23 +4,21 @@ import { useMedia } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import {
|
||||
LinkButton,
|
||||
useStyles2,
|
||||
Spinner,
|
||||
Card,
|
||||
useTheme2,
|
||||
Tooltip,
|
||||
Icon,
|
||||
Switch,
|
||||
Pagination,
|
||||
HorizontalGroup,
|
||||
EmptyState,
|
||||
HorizontalGroup,
|
||||
LinkButton,
|
||||
Pagination,
|
||||
Spinner,
|
||||
Switch,
|
||||
TextLink,
|
||||
useStyles2,
|
||||
useTheme2,
|
||||
} from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import {
|
||||
useListPublicDashboardsQuery,
|
||||
@ -45,7 +43,6 @@ const PublicDashboardCard = ({ pd }: { pd: PublicDashboardListResponse }) => {
|
||||
|
||||
const selectors = e2eSelectors.pages.PublicDashboards;
|
||||
const hasWritePermissions = contextSrv.hasPermission(AccessControlAction.DashboardsPublicWrite);
|
||||
const isOrphaned = !pd.dashboardUid;
|
||||
|
||||
const onTogglePause = (pd: PublicDashboardListResponse, isPaused: boolean) => {
|
||||
const req = {
|
||||
@ -60,29 +57,16 @@ const PublicDashboardCard = ({ pd }: { pd: PublicDashboardListResponse }) => {
|
||||
};
|
||||
|
||||
const CardActions = useMemo(() => (isMobile ? Card.Actions : Card.SecondaryActions), [isMobile]);
|
||||
const translatedPauseSharingText = t('public-dashboard-list.toggle.pause-sharing-toggle-text', 'Pause sharing');
|
||||
|
||||
const isNewSharingComponentEnabled = config.featureToggles.newDashboardSharingComponent;
|
||||
const translatedPauseSharingText = isNewSharingComponentEnabled
|
||||
? t('shared-dashboard-list.toggle.pause-sharing-toggle-text', 'Pause access')
|
||||
: t('public-dashboard-list.toggle.pause-sharing-toggle-text', 'Pause sharing');
|
||||
|
||||
return (
|
||||
<Card className={styles.card} href={!isOrphaned ? `/d/${pd.dashboardUid}` : undefined}>
|
||||
<Card className={styles.card} href={`/d/${pd.dashboardUid}`}>
|
||||
<Card.Heading className={styles.heading}>
|
||||
{!isOrphaned ? (
|
||||
<span>{pd.title}</span>
|
||||
) : (
|
||||
<Tooltip
|
||||
content={t(
|
||||
'public-dashboard-list.dashboard-title.orphaned-tooltip',
|
||||
'The linked dashboard has already been deleted'
|
||||
)}
|
||||
placement="top"
|
||||
>
|
||||
<div className={styles.orphanedTitle}>
|
||||
<Trans i18nKey="public-dashboard-list.dashboard-title.orphaned-title">
|
||||
<span>Orphaned public dashboard</span>
|
||||
</Trans>
|
||||
<Icon name="info-circle" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
<span>{pd.title}</span>
|
||||
</Card.Heading>
|
||||
<CardActions className={styles.actions}>
|
||||
<div className={styles.pauseSwitch}>
|
||||
@ -101,7 +85,6 @@ const PublicDashboardCard = ({ pd }: { pd: PublicDashboardListResponse }) => {
|
||||
<span>{translatedPauseSharingText}</span>
|
||||
</div>
|
||||
<LinkButton
|
||||
disabled={isOrphaned}
|
||||
fill="text"
|
||||
icon="external-link-alt"
|
||||
variant="secondary"
|
||||
@ -109,18 +92,25 @@ const PublicDashboardCard = ({ pd }: { pd: PublicDashboardListResponse }) => {
|
||||
color={theme.colors.warning.text}
|
||||
href={generatePublicDashboardUrl(pd.accessToken)}
|
||||
key="public-dashboard-url"
|
||||
tooltip={t('public-dashboard-list.button.view-button-tooltip', 'View public dashboard')}
|
||||
tooltip={
|
||||
isNewSharingComponentEnabled
|
||||
? t('shared-dashboard-list.button.view-button-tooltip', 'View shared dashboard')
|
||||
: t('public-dashboard-list.button.view-button-tooltip', 'View public dashboard')
|
||||
}
|
||||
data-testid={selectors.ListItem.linkButton}
|
||||
/>
|
||||
<LinkButton
|
||||
disabled={isOrphaned}
|
||||
fill="text"
|
||||
icon="cog"
|
||||
variant="secondary"
|
||||
color={theme.colors.warning.text}
|
||||
href={generatePublicDashboardConfigUrl(pd.dashboardUid, pd.slug)}
|
||||
key="public-dashboard-config-url"
|
||||
tooltip={t('public-dashboard-list.button.config-button-tooltip', 'Configure public dashboard')}
|
||||
tooltip={
|
||||
isNewSharingComponentEnabled
|
||||
? t('shared-dashboard-list.button.config-button-tooltip', 'Configure shared dashboard')
|
||||
: t('public-dashboard-list.button.config-button-tooltip', 'Configure public dashboard')
|
||||
}
|
||||
data-testid={selectors.ListItem.configButton}
|
||||
/>
|
||||
{hasWritePermissions && (
|
||||
@ -129,7 +119,11 @@ const PublicDashboardCard = ({ pd }: { pd: PublicDashboardListResponse }) => {
|
||||
icon="trash-alt"
|
||||
variant="secondary"
|
||||
publicDashboard={pd}
|
||||
tooltip={t('public-dashboard-list.button.revoke-button-tooltip', 'Revoke public dashboard URL')}
|
||||
tooltip={
|
||||
isNewSharingComponentEnabled
|
||||
? t('shared-dashboard-list.button.revoke-button-tooltip', 'Revoke access')
|
||||
: t('public-dashboard-list.button.revoke-button-tooltip', 'Revoke public dashboard URL')
|
||||
}
|
||||
loader={<Spinner />}
|
||||
data-testid={selectors.ListItem.trashcanButton}
|
||||
/>
|
||||
|
@ -1519,6 +1519,10 @@
|
||||
"subtitle": "Use service accounts to run automated workloads in Grafana",
|
||||
"title": "Service accounts"
|
||||
},
|
||||
"shared-dashboard": {
|
||||
"subtitle": "Manage your organization's externally shared dashboards",
|
||||
"title": "Shared dashboards"
|
||||
},
|
||||
"sign-out": {
|
||||
"title": "Sign out"
|
||||
},
|
||||
@ -1744,8 +1748,7 @@
|
||||
"welcome-title": "Welcome to public dashboards!"
|
||||
},
|
||||
"delete-modal": {
|
||||
"revoke-nonorphaned-body-text": "Are you sure you want to revoke this URL? The dashboard will no longer be public.",
|
||||
"revoke-orphaned-body-text": "Orphaned public dashboard will no longer be public.",
|
||||
"revoke-body-text": "Are you sure you want to revoke this URL? The dashboard will no longer be public.",
|
||||
"revoke-title": "Revoke public URL"
|
||||
},
|
||||
"email-sharing": {
|
||||
@ -1844,10 +1847,6 @@
|
||||
"revoke-button-tooltip": "Revoke public dashboard URL",
|
||||
"view-button-tooltip": "View public dashboard"
|
||||
},
|
||||
"dashboard-title": {
|
||||
"orphaned-title": "<0>Orphaned public dashboard</0>",
|
||||
"orphaned-tooltip": "The linked dashboard has already been deleted"
|
||||
},
|
||||
"empty-state": {
|
||||
"message": "You haven't created any public dashboards yet",
|
||||
"more-info": "Create a public dashboard from any existing dashboard through the <1>Share</1> modal. <4>Learn more</4>"
|
||||
@ -2160,10 +2159,25 @@
|
||||
}
|
||||
},
|
||||
"shared-dashboard": {
|
||||
"delete-modal": {
|
||||
"revoke-body-text": "Are you sure you want to revoke this access? The dashboard can no longer be shared.",
|
||||
"revoke-title": "Revoke access"
|
||||
},
|
||||
"fields": {
|
||||
"timezone-label": "Timezone"
|
||||
}
|
||||
},
|
||||
"shared-dashboard-list": {
|
||||
"button": {
|
||||
"config-button-tooltip": "Configure shared dashboard",
|
||||
"revoke-button-text": "Revoke access",
|
||||
"revoke-button-tooltip": "Revoke access",
|
||||
"view-button-tooltip": "View shared dashboard"
|
||||
},
|
||||
"toggle": {
|
||||
"pause-sharing-toggle-text": "Pause access"
|
||||
}
|
||||
},
|
||||
"shared-preferences": {
|
||||
"fields": {
|
||||
"home-dashboard-label": "Home Dashboard",
|
||||
|
@ -1519,6 +1519,10 @@
|
||||
"subtitle": "Ůşę şęřvįčę äččőūʼnŧş ŧő řūʼn äūŧőmäŧęđ ŵőřĸľőäđş įʼn Ğřäƒäʼnä",
|
||||
"title": "Ŝęřvįčę äččőūʼnŧş"
|
||||
},
|
||||
"shared-dashboard": {
|
||||
"subtitle": "Mäʼnäģę yőūř őřģäʼnįžäŧįőʼn'ş ęχŧęřʼnäľľy şĥäřęđ đäşĥþőäřđş",
|
||||
"title": "Ŝĥäřęđ đäşĥþőäřđş"
|
||||
},
|
||||
"sign-out": {
|
||||
"title": "Ŝįģʼn őūŧ"
|
||||
},
|
||||
@ -1744,8 +1748,7 @@
|
||||
"welcome-title": "Ŵęľčőmę ŧő pūþľįč đäşĥþőäřđş!"
|
||||
},
|
||||
"delete-modal": {
|
||||
"revoke-nonorphaned-body-text": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő řęvőĸę ŧĥįş ŮŖĿ? Ŧĥę đäşĥþőäřđ ŵįľľ ʼnő ľőʼnģęř þę pūþľįč.",
|
||||
"revoke-orphaned-body-text": "Øřpĥäʼnęđ pūþľįč đäşĥþőäřđ ŵįľľ ʼnő ľőʼnģęř þę pūþľįč.",
|
||||
"revoke-body-text": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő řęvőĸę ŧĥįş ŮŖĿ? Ŧĥę đäşĥþőäřđ ŵįľľ ʼnő ľőʼnģęř þę pūþľįč.",
|
||||
"revoke-title": "Ŗęvőĸę pūþľįč ŮŖĿ"
|
||||
},
|
||||
"email-sharing": {
|
||||
@ -1844,10 +1847,6 @@
|
||||
"revoke-button-tooltip": "Ŗęvőĸę pūþľįč đäşĥþőäřđ ŮŖĿ",
|
||||
"view-button-tooltip": "Vįęŵ pūþľįč đäşĥþőäřđ"
|
||||
},
|
||||
"dashboard-title": {
|
||||
"orphaned-title": "<0>Øřpĥäʼnęđ pūþľįč đäşĥþőäřđ</0>",
|
||||
"orphaned-tooltip": "Ŧĥę ľįʼnĸęđ đäşĥþőäřđ ĥäş äľřęäđy þęęʼn đęľęŧęđ"
|
||||
},
|
||||
"empty-state": {
|
||||
"message": "Ÿőū ĥävęʼn'ŧ čřęäŧęđ äʼny pūþľįč đäşĥþőäřđş yęŧ",
|
||||
"more-info": "Cřęäŧę ä pūþľįč đäşĥþőäřđ ƒřőm äʼny ęχįşŧįʼnģ đäşĥþőäřđ ŧĥřőūģĥ ŧĥę <1>Ŝĥäřę</1> mőđäľ. <4>Ŀęäřʼn mőřę</4>"
|
||||
@ -2160,10 +2159,25 @@
|
||||
}
|
||||
},
|
||||
"shared-dashboard": {
|
||||
"delete-modal": {
|
||||
"revoke-body-text": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő řęvőĸę ŧĥįş äččęşş? Ŧĥę đäşĥþőäřđ čäʼn ʼnő ľőʼnģęř þę şĥäřęđ.",
|
||||
"revoke-title": "Ŗęvőĸę äččęşş"
|
||||
},
|
||||
"fields": {
|
||||
"timezone-label": "Ŧįmęžőʼnę"
|
||||
}
|
||||
},
|
||||
"shared-dashboard-list": {
|
||||
"button": {
|
||||
"config-button-tooltip": "Cőʼnƒįģūřę şĥäřęđ đäşĥþőäřđ",
|
||||
"revoke-button-text": "Ŗęvőĸę äččęşş",
|
||||
"revoke-button-tooltip": "Ŗęvőĸę äččęşş",
|
||||
"view-button-tooltip": "Vįęŵ şĥäřęđ đäşĥþőäřđ"
|
||||
},
|
||||
"toggle": {
|
||||
"pause-sharing-toggle-text": "Päūşę äččęşş"
|
||||
}
|
||||
},
|
||||
"shared-preferences": {
|
||||
"fields": {
|
||||
"home-dashboard-label": "Ħőmę Đäşĥþőäřđ",
|
||||
|
Loading…
Reference in New Issue
Block a user