QueryEditorRows.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import React, { PureComponent } from 'react';
  2. import { DragDropContext, DragStart, Droppable, DropResult } from 'react-beautiful-dnd';
  3. import {
  4. CoreApp,
  5. DataQuery,
  6. DataSourceInstanceSettings,
  7. DataSourceRef,
  8. EventBusExtended,
  9. HistoryItem,
  10. PanelData,
  11. } from '@grafana/data';
  12. import { getDataSourceSrv, reportInteraction } from '@grafana/runtime';
  13. import { QueryEditorRow } from './QueryEditorRow';
  14. interface Props {
  15. // The query configuration
  16. queries: DataQuery[];
  17. dsSettings: DataSourceInstanceSettings;
  18. // Query editing
  19. onQueriesChange: (queries: DataQuery[]) => void;
  20. onAddQuery: (query: DataQuery) => void;
  21. onRunQueries: () => void;
  22. // Query Response Data
  23. data: PanelData;
  24. // Misc
  25. app?: CoreApp;
  26. history?: Array<HistoryItem<DataQuery>>;
  27. eventBus?: EventBusExtended;
  28. }
  29. export class QueryEditorRows extends PureComponent<Props> {
  30. onRemoveQuery = (query: DataQuery) => {
  31. this.props.onQueriesChange(this.props.queries.filter((item) => item !== query));
  32. };
  33. onChangeQuery(query: DataQuery, index: number) {
  34. const { queries, onQueriesChange } = this.props;
  35. // update query in array
  36. onQueriesChange(
  37. queries.map((item, itemIndex) => {
  38. if (itemIndex === index) {
  39. return query;
  40. }
  41. return item;
  42. })
  43. );
  44. }
  45. onDataSourceChange(dataSource: DataSourceInstanceSettings, index: number) {
  46. const { queries, onQueriesChange } = this.props;
  47. onQueriesChange(
  48. queries.map((item, itemIndex) => {
  49. if (itemIndex !== index) {
  50. return item;
  51. }
  52. const dataSourceRef: DataSourceRef = {
  53. type: dataSource.type,
  54. uid: dataSource.uid,
  55. };
  56. if (item.datasource) {
  57. const previous = getDataSourceSrv().getInstanceSettings(item.datasource);
  58. if (previous?.type === dataSource.type) {
  59. return {
  60. ...item,
  61. datasource: dataSourceRef,
  62. };
  63. }
  64. }
  65. return {
  66. refId: item.refId,
  67. hide: item.hide,
  68. datasource: dataSourceRef,
  69. };
  70. })
  71. );
  72. }
  73. onDragStart = (result: DragStart) => {
  74. const { queries, dsSettings } = this.props;
  75. reportInteraction('query_row_reorder_started', {
  76. startIndex: result.source.index,
  77. numberOfQueries: queries.length,
  78. datasourceType: dsSettings.type,
  79. });
  80. };
  81. onDragEnd = (result: DropResult) => {
  82. const { queries, onQueriesChange, dsSettings } = this.props;
  83. if (!result || !result.destination) {
  84. return;
  85. }
  86. const startIndex = result.source.index;
  87. const endIndex = result.destination.index;
  88. if (startIndex === endIndex) {
  89. reportInteraction('query_row_reorder_canceled', {
  90. startIndex,
  91. endIndex,
  92. numberOfQueries: queries.length,
  93. datasourceType: dsSettings.type,
  94. });
  95. return;
  96. }
  97. const update = Array.from(queries);
  98. const [removed] = update.splice(startIndex, 1);
  99. update.splice(endIndex, 0, removed);
  100. onQueriesChange(update);
  101. reportInteraction('query_row_reorder_ended', {
  102. startIndex,
  103. endIndex,
  104. numberOfQueries: queries.length,
  105. datasourceType: dsSettings.type,
  106. });
  107. };
  108. render() {
  109. const { dsSettings, data, queries, app, history, eventBus } = this.props;
  110. return (
  111. <DragDropContext onDragStart={this.onDragStart} onDragEnd={this.onDragEnd}>
  112. <Droppable droppableId="transformations-list" direction="vertical">
  113. {(provided) => {
  114. return (
  115. <div ref={provided.innerRef} {...provided.droppableProps}>
  116. {queries.map((query, index) => {
  117. const dataSourceSettings = getDataSourceSettings(query, dsSettings);
  118. const onChangeDataSourceSettings = dsSettings.meta.mixed
  119. ? (settings: DataSourceInstanceSettings) => this.onDataSourceChange(settings, index)
  120. : undefined;
  121. return (
  122. <QueryEditorRow
  123. id={query.refId}
  124. index={index}
  125. key={query.refId}
  126. data={data}
  127. query={query}
  128. dataSource={dataSourceSettings}
  129. onChangeDataSource={onChangeDataSourceSettings}
  130. onChange={(query) => this.onChangeQuery(query, index)}
  131. onRemoveQuery={this.onRemoveQuery}
  132. onAddQuery={this.props.onAddQuery}
  133. onRunQuery={this.props.onRunQueries}
  134. queries={queries}
  135. app={app}
  136. history={history}
  137. eventBus={eventBus}
  138. />
  139. );
  140. })}
  141. {provided.placeholder}
  142. </div>
  143. );
  144. }}
  145. </Droppable>
  146. </DragDropContext>
  147. );
  148. }
  149. }
  150. const getDataSourceSettings = (
  151. query: DataQuery,
  152. groupSettings: DataSourceInstanceSettings
  153. ): DataSourceInstanceSettings => {
  154. if (!query.datasource) {
  155. return groupSettings;
  156. }
  157. const querySettings = getDataSourceSrv().getInstanceSettings(query.datasource);
  158. return querySettings || groupSettings;
  159. };