VariableEditorContainer.tsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import React, { MouseEvent, PureComponent } from 'react';
  2. import { connect, ConnectedProps } from 'react-redux';
  3. import { bindActionCreators } from 'redux';
  4. import { selectors } from '@grafana/e2e-selectors';
  5. import { Button, Icon } from '@grafana/ui';
  6. import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
  7. import { StoreState, ThunkDispatch } from '../../../types';
  8. import { VariablesDependenciesButton } from '../inspect/VariablesDependenciesButton';
  9. import { VariablesUnknownTable } from '../inspect/VariablesUnknownTable';
  10. import { toKeyedAction } from '../state/keyedVariablesReducer';
  11. import { getEditorVariables, getVariablesState } from '../state/selectors';
  12. import { changeVariableOrder, duplicateVariable, removeVariable } from '../state/sharedReducer';
  13. import { KeyedVariableIdentifier } from '../state/types';
  14. import { toKeyedVariableIdentifier, toVariablePayload } from '../utils';
  15. import { VariableEditorEditor } from './VariableEditorEditor';
  16. import { VariableEditorList } from './VariableEditorList';
  17. import { switchToEditMode, switchToListMode, switchToNewMode } from './actions';
  18. const mapStateToProps = (state: StoreState, ownProps: OwnProps) => {
  19. const { uid } = ownProps.dashboard;
  20. const templatingState = getVariablesState(uid, state);
  21. return {
  22. variables: getEditorVariables(uid, state),
  23. idInEditor: templatingState.editor.id,
  24. usagesNetwork: templatingState.inspect.usagesNetwork,
  25. usages: templatingState.inspect.usages,
  26. };
  27. };
  28. const mapDispatchToProps = (dispatch: ThunkDispatch) => {
  29. return {
  30. ...bindActionCreators({ switchToNewMode, switchToEditMode, switchToListMode }, dispatch),
  31. changeVariableOrder: (identifier: KeyedVariableIdentifier, fromIndex: number, toIndex: number) =>
  32. dispatch(
  33. toKeyedAction(
  34. identifier.rootStateKey,
  35. changeVariableOrder(toVariablePayload(identifier, { fromIndex, toIndex }))
  36. )
  37. ),
  38. duplicateVariable: (identifier: KeyedVariableIdentifier) =>
  39. dispatch(
  40. toKeyedAction(
  41. identifier.rootStateKey,
  42. duplicateVariable(toVariablePayload(identifier, { newId: undefined as unknown as string }))
  43. )
  44. ),
  45. removeVariable: (identifier: KeyedVariableIdentifier) => {
  46. dispatch(
  47. toKeyedAction(identifier.rootStateKey, removeVariable(toVariablePayload(identifier, { reIndex: true })))
  48. );
  49. },
  50. };
  51. };
  52. interface OwnProps {
  53. dashboard: DashboardModel;
  54. }
  55. const connector = connect(mapStateToProps, mapDispatchToProps);
  56. type Props = OwnProps & ConnectedProps<typeof connector>;
  57. class VariableEditorContainerUnconnected extends PureComponent<Props> {
  58. componentDidMount(): void {
  59. this.props.switchToListMode(this.props.dashboard.uid);
  60. }
  61. onChangeToListMode = (event: MouseEvent<HTMLAnchorElement>) => {
  62. event.preventDefault();
  63. this.props.switchToListMode(this.props.dashboard.uid);
  64. };
  65. onEditVariable = (identifier: KeyedVariableIdentifier) => {
  66. this.props.switchToEditMode(identifier);
  67. };
  68. onNewVariable = () => {
  69. this.props.switchToNewMode(this.props.dashboard.uid);
  70. };
  71. onChangeVariableOrder = (identifier: KeyedVariableIdentifier, fromIndex: number, toIndex: number) => {
  72. this.props.changeVariableOrder(identifier, fromIndex, toIndex);
  73. };
  74. onDuplicateVariable = (identifier: KeyedVariableIdentifier) => {
  75. this.props.duplicateVariable(identifier);
  76. };
  77. onRemoveVariable = (identifier: KeyedVariableIdentifier) => {
  78. this.props.removeVariable(identifier);
  79. };
  80. render() {
  81. const variableToEdit = this.props.variables.find((s) => s.id === this.props.idInEditor) ?? null;
  82. return (
  83. <div>
  84. <div className="page-action-bar">
  85. <h3 className="dashboard-settings__header">
  86. <a
  87. onClick={this.onChangeToListMode}
  88. aria-label={selectors.pages.Dashboard.Settings.Variables.Edit.General.headerLink}
  89. >
  90. Variables
  91. </a>
  92. {this.props.idInEditor && (
  93. <span>
  94. <Icon name="angle-right" />
  95. Edit
  96. </span>
  97. )}
  98. </h3>
  99. <div className="page-action-bar__spacer" />
  100. {this.props.variables.length > 0 && variableToEdit === null && (
  101. <>
  102. <VariablesDependenciesButton variables={this.props.variables} />
  103. <Button
  104. type="button"
  105. onClick={this.onNewVariable}
  106. aria-label={selectors.pages.Dashboard.Settings.Variables.List.newButton}
  107. >
  108. New
  109. </Button>
  110. </>
  111. )}
  112. </div>
  113. {!variableToEdit && (
  114. <VariableEditorList
  115. variables={this.props.variables}
  116. onAdd={this.onNewVariable}
  117. onEdit={this.onEditVariable}
  118. onChangeOrder={this.onChangeVariableOrder}
  119. onDuplicate={this.onDuplicateVariable}
  120. onDelete={this.onRemoveVariable}
  121. usages={this.props.usages}
  122. usagesNetwork={this.props.usagesNetwork}
  123. />
  124. )}
  125. {!variableToEdit && this.props.variables.length > 0 && (
  126. <VariablesUnknownTable variables={this.props.variables} dashboard={this.props.dashboard} />
  127. )}
  128. {variableToEdit && <VariableEditorEditor identifier={toKeyedVariableIdentifier(variableToEdit)} />}
  129. </div>
  130. );
  131. }
  132. }
  133. export const VariableEditorContainer = connector(VariableEditorContainerUnconnected);