2023-07-25 13:17:39 +03:00
|
|
|
import { css } from '@emotion/css';
|
2020-03-04 12:59:30 +03:00
|
|
|
import React from 'react';
|
2022-04-22 14:33:13 +01:00
|
|
|
|
2023-07-25 13:17:39 +03:00
|
|
|
import { GrafanaTheme2 } from '@grafana/data';
|
|
|
|
|
import { Modal, ModalTabsHeader, TabContent, Themeable2, withTheme2 } from '@grafana/ui';
|
2022-05-17 14:11:55 -08:00
|
|
|
import { config } from 'app/core/config';
|
2022-04-22 14:33:13 +01:00
|
|
|
import { contextSrv } from 'app/core/core';
|
2022-10-06 16:34:04 +01:00
|
|
|
import { t } from 'app/core/internationalization';
|
2022-09-22 09:35:04 -03:00
|
|
|
import { SharePublicDashboard } from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard';
|
2020-03-03 15:04:28 +03:00
|
|
|
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
2021-04-15 08:29:34 +01:00
|
|
|
import { isPanelModelLibraryPanel } from 'app/features/library-panels/guard';
|
2022-04-22 14:33:13 +01:00
|
|
|
|
|
|
|
|
import { ShareEmbed } from './ShareEmbed';
|
|
|
|
|
import { ShareExport } from './ShareExport';
|
|
|
|
|
import { ShareLibraryPanel } from './ShareLibraryPanel';
|
2020-03-03 15:04:28 +03:00
|
|
|
import { ShareLink } from './ShareLink';
|
|
|
|
|
import { ShareSnapshot } from './ShareSnapshot';
|
2023-08-03 16:41:26 +03:00
|
|
|
import { trackDashboardSharingTypeOpen } from './analytics';
|
2020-03-04 12:59:30 +03:00
|
|
|
import { ShareModalTabModel } from './types';
|
2023-08-03 16:41:26 +03:00
|
|
|
import { shareDashboardType } from './utils';
|
2020-03-04 12:59:30 +03:00
|
|
|
|
|
|
|
|
const customDashboardTabs: ShareModalTabModel[] = [];
|
|
|
|
|
const customPanelTabs: ShareModalTabModel[] = [];
|
|
|
|
|
|
|
|
|
|
export function addDashboardShareTab(tab: ShareModalTabModel) {
|
|
|
|
|
customDashboardTabs.push(tab);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function addPanelShareTab(tab: ShareModalTabModel) {
|
|
|
|
|
customPanelTabs.push(tab);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-26 10:28:11 -03:00
|
|
|
function getTabs(panel?: PanelModel, activeTab?: string) {
|
2022-10-06 16:34:04 +01:00
|
|
|
const linkLabel = t('share-modal.tab-title.link', 'Link');
|
2023-08-03 16:41:26 +03:00
|
|
|
const tabs: ShareModalTabModel[] = [{ label: linkLabel, value: shareDashboardType.link, component: ShareLink }];
|
2021-02-17 09:51:50 +01:00
|
|
|
|
2023-01-26 10:28:11 -03:00
|
|
|
if (contextSrv.isSignedIn && config.snapshotEnabled) {
|
2022-10-06 16:34:04 +01:00
|
|
|
const snapshotLabel = t('share-modal.tab-title.snapshot', 'Snapshot');
|
2023-08-03 16:41:26 +03:00
|
|
|
tabs.push({ label: snapshotLabel, value: shareDashboardType.snapshot, component: ShareSnapshot });
|
2021-02-17 09:51:50 +01:00
|
|
|
}
|
2020-03-04 12:59:30 +03:00
|
|
|
|
|
|
|
|
if (panel) {
|
2022-10-06 16:34:04 +01:00
|
|
|
const embedLabel = t('share-modal.tab-title.embed', 'Embed');
|
2023-08-03 16:41:26 +03:00
|
|
|
tabs.push({ label: embedLabel, value: shareDashboardType.embed, component: ShareEmbed });
|
2021-04-15 08:29:34 +01:00
|
|
|
|
|
|
|
|
if (!isPanelModelLibraryPanel(panel)) {
|
2022-10-06 16:34:04 +01:00
|
|
|
const libraryPanelLabel = t('share-modal.tab-title.library-panel', 'Library panel');
|
2023-08-03 16:41:26 +03:00
|
|
|
tabs.push({ label: libraryPanelLabel, value: shareDashboardType.libraryPanel, component: ShareLibraryPanel });
|
2021-04-15 08:29:34 +01:00
|
|
|
}
|
2020-03-04 12:59:30 +03:00
|
|
|
tabs.push(...customPanelTabs);
|
|
|
|
|
} else {
|
2022-10-06 16:34:04 +01:00
|
|
|
const exportLabel = t('share-modal.tab-title.export', 'Export');
|
2023-08-03 16:41:26 +03:00
|
|
|
tabs.push({
|
|
|
|
|
label: exportLabel,
|
|
|
|
|
value: shareDashboardType.export,
|
|
|
|
|
component: ShareExport,
|
|
|
|
|
});
|
2020-03-04 12:59:30 +03:00
|
|
|
tabs.push(...customDashboardTabs);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-17 14:11:55 -08:00
|
|
|
if (Boolean(config.featureToggles['publicDashboards'])) {
|
2023-08-03 16:41:26 +03:00
|
|
|
tabs.push({
|
|
|
|
|
label: 'Public dashboard',
|
|
|
|
|
value: shareDashboardType.publicDashboard,
|
|
|
|
|
component: SharePublicDashboard,
|
|
|
|
|
});
|
2022-05-17 14:11:55 -08:00
|
|
|
}
|
|
|
|
|
|
2022-10-12 21:36:05 -08:00
|
|
|
const at = tabs.find((t) => t.value === activeTab);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
tabs,
|
|
|
|
|
activeTab: at?.value ?? tabs[0].value,
|
|
|
|
|
};
|
2020-03-04 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
|
2023-07-25 13:17:39 +03:00
|
|
|
interface Props extends Themeable2 {
|
2020-03-03 15:04:28 +03:00
|
|
|
dashboard: DashboardModel;
|
|
|
|
|
panel?: PanelModel;
|
2022-10-12 21:36:05 -08:00
|
|
|
activeTab?: string;
|
2020-03-03 15:04:28 +03:00
|
|
|
|
|
|
|
|
onDismiss(): void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface State {
|
2020-03-04 12:59:30 +03:00
|
|
|
tabs: ShareModalTabModel[];
|
|
|
|
|
activeTab: string;
|
2020-03-03 15:04:28 +03:00
|
|
|
}
|
|
|
|
|
|
2023-01-26 10:28:11 -03:00
|
|
|
function getInitialState(props: Props): State {
|
|
|
|
|
const { tabs, activeTab } = getTabs(props.panel, props.activeTab);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
tabs,
|
|
|
|
|
activeTab,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-25 13:17:39 +03:00
|
|
|
class UnthemedShareModal extends React.Component<Props, State> {
|
2020-03-03 15:04:28 +03:00
|
|
|
constructor(props: Props) {
|
|
|
|
|
super(props);
|
2020-03-04 12:59:30 +03:00
|
|
|
this.state = getInitialState(props);
|
2020-03-03 15:04:28 +03:00
|
|
|
}
|
|
|
|
|
|
2023-03-14 09:51:44 +00:00
|
|
|
onSelectTab: React.ComponentProps<typeof ModalTabsHeader>['onChangeTab'] = (t) => {
|
2023-01-26 10:28:11 -03:00
|
|
|
this.setState((prevState) => ({ ...prevState, activeTab: t.value }));
|
2023-08-03 16:41:26 +03:00
|
|
|
trackDashboardSharingTypeOpen(t.value);
|
2020-03-03 15:04:28 +03:00
|
|
|
};
|
|
|
|
|
|
2020-03-04 12:59:30 +03:00
|
|
|
getActiveTab() {
|
|
|
|
|
const { tabs, activeTab } = this.state;
|
2021-01-20 07:59:48 +01:00
|
|
|
return tabs.find((t) => t.value === activeTab)!;
|
2020-03-03 15:04:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renderTitle() {
|
|
|
|
|
const { panel } = this.props;
|
2020-03-04 12:59:30 +03:00
|
|
|
const { activeTab } = this.state;
|
2022-10-06 16:34:04 +01:00
|
|
|
const title = panel ? t('share-modal.panel.title', 'Share Panel') : t('share-modal.dashboard.title', 'Share');
|
2023-01-26 10:28:11 -03:00
|
|
|
const tabs = getTabs(this.props.panel, this.state.activeTab).tabs;
|
2020-03-03 15:04:28 +03:00
|
|
|
|
|
|
|
|
return (
|
2020-03-04 12:59:30 +03:00
|
|
|
<ModalTabsHeader
|
|
|
|
|
title={title}
|
@grafana/ui: Create Icon component and replace part of the icons (#23402)
* Part1: Unicons implementation (#23197)
* Create a new Icon component
* Update icons in main sidebar
* Update icons in Useful links and in react components on main site
* Update icons in Useful links and in main top navigation
* Adjust sizing
* Update panel navigation and timepicker
* Update icons in Panel menu
* NewPanelEditor: Fixed so that test alert rule works in new edit mode (#23179)
* Update icons in add panel widget
* Resolve merge conflict
* Fix part of the test errors and type errors
* Fix storybook errors
* Update getAvailableIcons import in storybook knobs
* Fix import path
* Fix SyntaxError: Cannot use import statement outside a module in test environment error
* Remove dynamic imports
* Remove types as using @ts-ignore
* Update snapshot test
* Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax
* Remove color prop from icon, remove color implemetation in mono icons
* Update navbar styling
* Move toPascalCase to utils/string
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
* Resolve type errors resulted from merge
* Part2: Unicons implementation (#23266)
* Create a new Icon component
* Update icons in main sidebar
* Update icons in Useful links and in react components on main site
* Update icons in Useful links and in main top navigation
* Adjust sizing
* Update panel navigation and timepicker
* Update icons in Panel menu
* Update icons in add panel widget
* Resolve merge conflict
* Fix part of the test errors and type errors
* Fix storybook errors
* Update getAvailableIcons import in storybook knobs
* Fix import path
* Fix SyntaxError: Cannot use import statement outside a module in test environment error
* Remove dynamic imports
* Remove types as using @ts-ignore
* Update snapshot test
* Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax
* Implment icons in Tabs
* Implement icons in search items and empty list
* Update buttons
* Update button-related snapshot tests
* Update icons in modals and page headers
* Create anfular wrapper and update all icons on search screen
* Update sizing, remove colors, update snapshot tests
* Remove color prop from icon, remove color implemetation in mono icons
* Remove color props from monochrome icons
* Complete update of icons for search screen
* Update icons for infor tooltips, playlist, permissions
* Support temporarly font awesome icons used in enterprise grafana
* Part1: Unicons implementation (#23197)
* Create a new Icon component
* Update icons in main sidebar
* Update icons in Useful links and in react components on main site
* Update icons in Useful links and in main top navigation
* Adjust sizing
* Update panel navigation and timepicker
* Update icons in Panel menu
* NewPanelEditor: Fixed so that test alert rule works in new edit mode (#23179)
* Update icons in add panel widget
* Resolve merge conflict
* Fix part of the test errors and type errors
* Fix storybook errors
* Update getAvailableIcons import in storybook knobs
* Fix import path
* Fix SyntaxError: Cannot use import statement outside a module in test environment error
* Remove dynamic imports
* Remove types as using @ts-ignore
* Update snapshot test
* Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax
* Remove color prop from icon, remove color implemetation in mono icons
* Update navbar styling
* Move toPascalCase to utils/string
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
* Icons update
* Add optional chaining to for isFontAwesome variable
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
* Part3: Unicons implementation (#23356)
* Create a new Icon component
* Update icons in main sidebar
* Update icons in Useful links and in react components on main site
* Update icons in Useful links and in main top navigation
* Adjust sizing
* Update panel navigation and timepicker
* Update icons in Panel menu
* Update icons in add panel widget
* Resolve merge conflict
* Fix part of the test errors and type errors
* Fix storybook errors
* Update getAvailableIcons import in storybook knobs
* Fix import path
* Fix SyntaxError: Cannot use import statement outside a module in test environment error
* Remove dynamic imports
* Remove types as using @ts-ignore
* Update snapshot test
* Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax
* Implment icons in Tabs
* Implement icons in search items and empty list
* Update buttons
* Update button-related snapshot tests
* Update icons in modals and page headers
* Create anfular wrapper and update all icons on search screen
* Update sizing, remove colors, update snapshot tests
* Remove color prop from icon, remove color implemetation in mono icons
* Remove color props from monochrome icons
* Complete update of icons for search screen
* Update icons for infor tooltips, playlist, permissions
* Support temporarly font awesome icons used in enterprise grafana
* Part1: Unicons implementation (#23197)
* Create a new Icon component
* Update icons in main sidebar
* Update icons in Useful links and in react components on main site
* Update icons in Useful links and in main top navigation
* Adjust sizing
* Update panel navigation and timepicker
* Update icons in Panel menu
* NewPanelEditor: Fixed so that test alert rule works in new edit mode (#23179)
* Update icons in add panel widget
* Resolve merge conflict
* Fix part of the test errors and type errors
* Fix storybook errors
* Update getAvailableIcons import in storybook knobs
* Fix import path
* Fix SyntaxError: Cannot use import statement outside a module in test environment error
* Remove dynamic imports
* Remove types as using @ts-ignore
* Update snapshot test
* Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax
* Remove color prop from icon, remove color implemetation in mono icons
* Update navbar styling
* Move toPascalCase to utils/string
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
* Update icons in Explore
* Update icons in alerting
* Update + and x buttons
* Update icons in configurations and settings
* Update close icons
* Update icons in rich history
* Update alert messages
* Add optional chaining to for isFontAwesome variable
* Remove icon mock, set up jest.config
* Fix navbar plus icon
* Fir enable-bacground to enableBackgournd
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
* Merge remote branch origin master to icons-unicons
* Revert "Merge remote branch origin master to icons-unicons"
This reverts commit 3f25d50a39a940883fefe73ce51219139c1ed37f.
* Size-up dashnav icons
* Fix alerting icons, panel headers, update tests
* Fix typecheck error
* Adjustments - add panel icon, spacing
* Set TerserPlugin sourceMap to false to prevent running out of memory when publishing storybook
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
2020-04-08 14:33:31 +02:00
|
|
|
icon="share-alt"
|
2023-01-26 10:28:11 -03:00
|
|
|
tabs={tabs}
|
2020-03-04 12:59:30 +03:00
|
|
|
activeTab={activeTab}
|
|
|
|
|
onChangeTab={this.onSelectTab}
|
|
|
|
|
/>
|
2020-03-03 15:04:28 +03:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
render() {
|
2023-07-25 13:17:39 +03:00
|
|
|
const { dashboard, panel, theme } = this.props;
|
|
|
|
|
const styles = getStyles(theme);
|
2020-03-04 12:59:30 +03:00
|
|
|
const activeTabModel = this.getActiveTab();
|
Chore: Fix all Typescript strict null errors (#26204)
* Chore: Fix typescript strict null errors
* Added new limit
* Fixed ts issue
* fixed tests
* trying to fix type inference
* Fixing more ts errors
* Revert tsconfig option
* Fix
* Fixed code
* More fixes
* fix tests
* Updated snapshot
* Chore: More ts strict null fixes
* More fixes in some really messed up azure config components
* More fixes, current count: 441
* 419
* More fixes
* Fixed invalid initial state in explore
* Fixing tests
* Fixed tests
* Explore fix
* More fixes
* Progress
* Sub 300
* Now at 218
* Progress
* Update
* Progress
* Updated tests
* at 159
* fixed tests
* Progress
* YAy blow 100! at 94
* 10,9,8,7,6,5,4,3,2,1... lift off
* Fixed tests
* Fixed more type errors
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2020-07-10 12:46:59 +02:00
|
|
|
const ActiveTab = activeTabModel.component;
|
2020-03-03 15:04:28 +03:00
|
|
|
|
|
|
|
|
return (
|
2023-07-25 13:17:39 +03:00
|
|
|
<Modal
|
|
|
|
|
isOpen={true}
|
|
|
|
|
title={this.renderTitle()}
|
|
|
|
|
onDismiss={this.props.onDismiss}
|
|
|
|
|
className={styles.container}
|
|
|
|
|
contentClassName={styles.content}
|
|
|
|
|
>
|
2020-03-03 15:04:28 +03:00
|
|
|
<TabContent>
|
2021-05-05 10:36:42 +02:00
|
|
|
<ActiveTab dashboard={dashboard} panel={panel} onDismiss={this.props.onDismiss} />
|
2020-03-03 15:04:28 +03:00
|
|
|
</TabContent>
|
|
|
|
|
</Modal>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-07-25 13:17:39 +03:00
|
|
|
|
|
|
|
|
export const ShareModal = withTheme2(UnthemedShareModal);
|
|
|
|
|
|
|
|
|
|
const getStyles = (theme: GrafanaTheme2) => {
|
|
|
|
|
return {
|
|
|
|
|
container: css({
|
|
|
|
|
label: 'shareModalContainer',
|
|
|
|
|
paddingTop: theme.spacing(1),
|
|
|
|
|
}),
|
|
|
|
|
content: css({
|
|
|
|
|
label: 'shareModalContent',
|
|
|
|
|
padding: theme.spacing(3, 2, 2, 2),
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
};
|