ShareExport.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import { saveAs } from 'file-saver';
  2. import React, { PureComponent } from 'react';
  3. import { config } from '@grafana/runtime';
  4. import { Button, Field, Modal, Switch } from '@grafana/ui';
  5. import { appEvents } from 'app/core/core';
  6. import { getBackendSrv } from 'app/core/services/backend_srv';
  7. import { DashboardExporter } from 'app/features/dashboard/components/DashExportModal';
  8. import { ShowModalReactEvent } from 'app/types/events';
  9. import { ViewJsonModal } from './ViewJsonModal';
  10. import { ShareModalTabProps } from './types';
  11. interface Props extends ShareModalTabProps {}
  12. interface State {
  13. shareExternally: boolean;
  14. trimDefaults: boolean;
  15. }
  16. export class ShareExport extends PureComponent<Props, State> {
  17. private exporter: DashboardExporter;
  18. constructor(props: Props) {
  19. super(props);
  20. this.state = {
  21. shareExternally: false,
  22. trimDefaults: false,
  23. };
  24. this.exporter = new DashboardExporter();
  25. }
  26. onShareExternallyChange = () => {
  27. this.setState({
  28. shareExternally: !this.state.shareExternally,
  29. });
  30. };
  31. onTrimDefaultsChange = () => {
  32. this.setState({
  33. trimDefaults: !this.state.trimDefaults,
  34. });
  35. };
  36. onSaveAsFile = () => {
  37. const { dashboard } = this.props;
  38. const { shareExternally } = this.state;
  39. const { trimDefaults } = this.state;
  40. if (shareExternally) {
  41. this.exporter.makeExportable(dashboard).then((dashboardJson: any) => {
  42. if (trimDefaults) {
  43. getBackendSrv()
  44. .post('/api/dashboards/trim', { dashboard: dashboardJson })
  45. .then((resp: any) => {
  46. this.openSaveAsDialog(resp.dashboard);
  47. });
  48. } else {
  49. this.openSaveAsDialog(dashboardJson);
  50. }
  51. });
  52. } else {
  53. if (trimDefaults) {
  54. getBackendSrv()
  55. .post('/api/dashboards/trim', { dashboard: dashboard.getSaveModelClone() })
  56. .then((resp: any) => {
  57. this.openSaveAsDialog(resp.dashboard);
  58. });
  59. } else {
  60. this.openSaveAsDialog(dashboard.getSaveModelClone());
  61. }
  62. }
  63. };
  64. onViewJson = () => {
  65. const { dashboard } = this.props;
  66. const { shareExternally } = this.state;
  67. const { trimDefaults } = this.state;
  68. if (shareExternally) {
  69. this.exporter.makeExportable(dashboard).then((dashboardJson: any) => {
  70. if (trimDefaults) {
  71. getBackendSrv()
  72. .post('/api/dashboards/trim', { dashboard: dashboardJson })
  73. .then((resp: any) => {
  74. this.openJsonModal(resp.dashboard);
  75. });
  76. } else {
  77. this.openJsonModal(dashboardJson);
  78. }
  79. });
  80. } else {
  81. if (trimDefaults) {
  82. getBackendSrv()
  83. .post('/api/dashboards/trim', { dashboard: dashboard.getSaveModelClone() })
  84. .then((resp: any) => {
  85. this.openJsonModal(resp.dashboard);
  86. });
  87. } else {
  88. this.openJsonModal(dashboard.getSaveModelClone());
  89. }
  90. }
  91. };
  92. openSaveAsDialog = (dash: any) => {
  93. const dashboardJsonPretty = JSON.stringify(dash, null, 2);
  94. const blob = new Blob([dashboardJsonPretty], {
  95. type: 'application/json;charset=utf-8',
  96. });
  97. const time = new Date().getTime();
  98. saveAs(blob, `${dash.title}-${time}.json`);
  99. };
  100. openJsonModal = (clone: object) => {
  101. appEvents.publish(
  102. new ShowModalReactEvent({
  103. props: {
  104. json: JSON.stringify(clone, null, 2),
  105. },
  106. component: ViewJsonModal,
  107. })
  108. );
  109. this.props.onDismiss?.();
  110. };
  111. render() {
  112. const { onDismiss } = this.props;
  113. const { shareExternally } = this.state;
  114. const { trimDefaults } = this.state;
  115. return (
  116. <>
  117. <p className="share-modal-info-text">Export this dashboard.</p>
  118. <Field label="Export for sharing externally">
  119. <Switch id="share-externally-toggle" value={shareExternally} onChange={this.onShareExternallyChange} />
  120. </Field>
  121. {config.featureToggles.trimDefaults && (
  122. <Field label="Export with default values removed">
  123. <Switch id="trim-defaults-toggle" value={trimDefaults} onChange={this.onTrimDefaultsChange} />
  124. </Field>
  125. )}
  126. <Modal.ButtonRow>
  127. <Button variant="secondary" onClick={onDismiss} fill="outline">
  128. Cancel
  129. </Button>
  130. <Button variant="secondary" onClick={this.onViewJson}>
  131. View JSON
  132. </Button>
  133. <Button variant="primary" onClick={this.onSaveAsFile}>
  134. Save to file
  135. </Button>
  136. </Modal.ButtonRow>
  137. </>
  138. );
  139. }
  140. }