GeneralSettings.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import React, { useState } from 'react';
  2. import { connect, ConnectedProps } from 'react-redux';
  3. import { TimeZone } from '@grafana/data';
  4. import { selectors } from '@grafana/e2e-selectors';
  5. import { config } from '@grafana/runtime';
  6. import { CollapsableSection, Field, Input, RadioButtonGroup, TagsInput } from '@grafana/ui';
  7. import { FolderPicker } from 'app/core/components/Select/FolderPicker';
  8. import { updateTimeZoneDashboard, updateWeekStartDashboard } from 'app/features/dashboard/state/actions';
  9. import { DashboardModel } from '../../state/DashboardModel';
  10. import { DeleteDashboardButton } from '../DeleteDashboard/DeleteDashboardButton';
  11. import { PreviewSettings } from './PreviewSettings';
  12. import { TimePickerSettings } from './TimePickerSettings';
  13. interface OwnProps {
  14. dashboard: DashboardModel;
  15. }
  16. export type Props = OwnProps & ConnectedProps<typeof connector>;
  17. const GRAPH_TOOLTIP_OPTIONS = [
  18. { value: 0, label: 'Default' },
  19. { value: 1, label: 'Shared crosshair' },
  20. { value: 2, label: 'Shared Tooltip' },
  21. ];
  22. export function GeneralSettingsUnconnected({ dashboard, updateTimeZone, updateWeekStart }: Props): JSX.Element {
  23. const [renderCounter, setRenderCounter] = useState(0);
  24. const onFolderChange = (folder: { id: number; title: string }) => {
  25. dashboard.meta.folderId = folder.id;
  26. dashboard.meta.folderTitle = folder.title;
  27. dashboard.meta.hasUnsavedFolderChange = true;
  28. };
  29. const onBlur = (event: React.FocusEvent<HTMLInputElement>) => {
  30. dashboard[event.currentTarget.name as 'title' | 'description'] = event.currentTarget.value;
  31. };
  32. const onTooltipChange = (graphTooltip: number) => {
  33. dashboard.graphTooltip = graphTooltip;
  34. setRenderCounter(renderCounter + 1);
  35. };
  36. const onRefreshIntervalChange = (intervals: string[]) => {
  37. dashboard.timepicker.refresh_intervals = intervals.filter((i) => i.trim() !== '');
  38. };
  39. const onNowDelayChange = (nowDelay: string) => {
  40. dashboard.timepicker.nowDelay = nowDelay;
  41. };
  42. const onHideTimePickerChange = (hide: boolean) => {
  43. dashboard.timepicker.hidden = hide;
  44. setRenderCounter(renderCounter + 1);
  45. };
  46. const onLiveNowChange = (v: boolean) => {
  47. dashboard.liveNow = v;
  48. setRenderCounter(renderCounter + 1);
  49. };
  50. const onTimeZoneChange = (timeZone: TimeZone) => {
  51. dashboard.timezone = timeZone;
  52. setRenderCounter(renderCounter + 1);
  53. updateTimeZone(timeZone);
  54. };
  55. const onWeekStartChange = (weekStart: string) => {
  56. dashboard.weekStart = weekStart;
  57. setRenderCounter(renderCounter + 1);
  58. updateWeekStart(weekStart);
  59. };
  60. const onTagsChange = (tags: string[]) => {
  61. dashboard.tags = tags;
  62. setRenderCounter(renderCounter + 1);
  63. };
  64. const onEditableChange = (value: boolean) => {
  65. dashboard.editable = value;
  66. setRenderCounter(renderCounter + 1);
  67. };
  68. const editableOptions = [
  69. { label: 'Editable', value: true },
  70. { label: 'Read-only', value: false },
  71. ];
  72. return (
  73. <div style={{ maxWidth: '600px' }}>
  74. <h3 className="dashboard-settings__header" aria-label={selectors.pages.Dashboard.Settings.General.title}>
  75. General
  76. </h3>
  77. <div className="gf-form-group">
  78. <Field label="Name">
  79. <Input id="title-input" name="title" onBlur={onBlur} defaultValue={dashboard.title} />
  80. </Field>
  81. <Field label="Description">
  82. <Input id="description-input" name="description" onBlur={onBlur} defaultValue={dashboard.description} />
  83. </Field>
  84. <Field label="Tags">
  85. <TagsInput id="tags-input" tags={dashboard.tags} onChange={onTagsChange} />
  86. </Field>
  87. <Field label="Folder">
  88. <FolderPicker
  89. inputId="dashboard-folder-input"
  90. initialTitle={dashboard.meta.folderTitle}
  91. initialFolderId={dashboard.meta.folderId}
  92. onChange={onFolderChange}
  93. enableCreateNew={true}
  94. dashboardId={dashboard.id}
  95. skipInitialLoad={true}
  96. />
  97. </Field>
  98. <Field
  99. label="Editable"
  100. description="Set to read-only to disable all editing. Reload the dashboard for changes to take effect"
  101. >
  102. <RadioButtonGroup value={dashboard.editable} options={editableOptions} onChange={onEditableChange} />
  103. </Field>
  104. </div>
  105. {config.featureToggles.dashboardPreviews && config.featureToggles.dashboardPreviewsAdmin && (
  106. <PreviewSettings uid={dashboard.uid} />
  107. )}
  108. <TimePickerSettings
  109. onTimeZoneChange={onTimeZoneChange}
  110. onWeekStartChange={onWeekStartChange}
  111. onRefreshIntervalChange={onRefreshIntervalChange}
  112. onNowDelayChange={onNowDelayChange}
  113. onHideTimePickerChange={onHideTimePickerChange}
  114. onLiveNowChange={onLiveNowChange}
  115. refreshIntervals={dashboard.timepicker.refresh_intervals}
  116. timePickerHidden={dashboard.timepicker.hidden}
  117. nowDelay={dashboard.timepicker.nowDelay}
  118. timezone={dashboard.timezone}
  119. weekStart={dashboard.weekStart}
  120. liveNow={dashboard.liveNow}
  121. />
  122. <CollapsableSection label="Panel options" isOpen={true}>
  123. <Field
  124. label="Graph tooltip"
  125. description="Controls tooltip and hover highlight behavior across different panels"
  126. >
  127. <RadioButtonGroup onChange={onTooltipChange} options={GRAPH_TOOLTIP_OPTIONS} value={dashboard.graphTooltip} />
  128. </Field>
  129. </CollapsableSection>
  130. <div className="gf-form-button-row">
  131. {dashboard.meta.canDelete && <DeleteDashboardButton dashboard={dashboard} />}
  132. </div>
  133. </div>
  134. );
  135. }
  136. const mapDispatchToProps = {
  137. updateTimeZone: updateTimeZoneDashboard,
  138. updateWeekStart: updateWeekStartDashboard,
  139. };
  140. const connector = connect(null, mapDispatchToProps);
  141. export const GeneralSettings = connector(GeneralSettingsUnconnected);