widgetBuilder.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import {useEffect, useState} from 'react';
  2. import {RouteComponentProps} from 'react-router';
  3. import Alert from 'app/components/alert';
  4. import {IconWarning} from 'app/icons';
  5. import {t} from 'app/locale';
  6. import {Organization} from 'app/types';
  7. import {defined} from 'app/utils';
  8. import {DashboardDetails, Widget} from '../types';
  9. import EventWidget from './eventWidget';
  10. import MetricWidget from './metricWidget';
  11. import {DataSet} from './utils';
  12. type RouteParams = {
  13. orgId: string;
  14. dashboardId: string;
  15. widgetId?: number;
  16. };
  17. type Props = RouteComponentProps<RouteParams, {}> & {
  18. organization: Organization;
  19. dashboard: DashboardDetails;
  20. onSave: (Widgets: Widget[]) => void;
  21. widget?: Widget;
  22. };
  23. function WidgetBuilder({
  24. dashboard,
  25. onSave,
  26. widget,
  27. params,
  28. location,
  29. router,
  30. organization,
  31. }: Props) {
  32. const [dataSet, setDataSet] = useState<DataSet | undefined>(DataSet.EVENTS);
  33. const isEditing = !!widget;
  34. const {widgetId, orgId, dashboardId} = params;
  35. const goBackLocation = {
  36. pathname: dashboardId
  37. ? `/organizations/${orgId}/dashboard/${dashboardId}/`
  38. : `/organizations/${orgId}/dashboards/new/`,
  39. query: {...location.query, dataSet: undefined},
  40. };
  41. useEffect(() => {
  42. checkDataSet();
  43. });
  44. function checkDataSet() {
  45. const {query} = location;
  46. const queryDataSet = query?.dataSet;
  47. if (!queryDataSet) {
  48. router.replace({
  49. pathname: location.pathname,
  50. query: {...location.query, dataSet: DataSet.EVENTS},
  51. });
  52. return;
  53. }
  54. if (queryDataSet !== DataSet.EVENTS && queryDataSet !== DataSet.METRICS) {
  55. setDataSet(undefined);
  56. return;
  57. }
  58. if (queryDataSet === DataSet.METRICS) {
  59. if (dataSet === DataSet.METRICS) {
  60. return;
  61. }
  62. setDataSet(DataSet.METRICS);
  63. return;
  64. }
  65. if (dataSet === DataSet.EVENTS) {
  66. return;
  67. }
  68. setDataSet(DataSet.EVENTS);
  69. }
  70. function handleDataSetChange(newDataSet: DataSet) {
  71. router.replace({
  72. pathname: location.pathname,
  73. query: {
  74. ...location.query,
  75. dataSet: newDataSet,
  76. },
  77. });
  78. }
  79. if (!dataSet) {
  80. return (
  81. <Alert type="error" icon={<IconWarning />}>
  82. {t('Data set not found.')}
  83. </Alert>
  84. );
  85. }
  86. function handleAddWidget(newWidget: Widget) {
  87. onSave([...dashboard.widgets, newWidget]);
  88. }
  89. if (
  90. (isEditing && !defined(widgetId)) ||
  91. (isEditing && defined(widgetId) && !dashboard.widgets[widgetId])
  92. ) {
  93. return (
  94. <Alert type="error" icon={<IconWarning />}>
  95. {t('Widget not found.')}
  96. </Alert>
  97. );
  98. }
  99. function handleUpdateWidget(nextWidget: Widget) {
  100. if (!widgetId) {
  101. return;
  102. }
  103. const nextList = [...dashboard.widgets];
  104. nextList[widgetId] = nextWidget;
  105. onSave(nextList);
  106. }
  107. function handleDeleteWidget() {
  108. if (!widgetId) {
  109. return;
  110. }
  111. const nextList = [...dashboard.widgets];
  112. nextList.splice(widgetId, 1);
  113. onSave(nextList);
  114. }
  115. if (dataSet === DataSet.EVENTS) {
  116. return (
  117. <EventWidget
  118. dashboardTitle={dashboard.title}
  119. widget={widget}
  120. onAdd={handleAddWidget}
  121. onUpdate={handleUpdateWidget}
  122. onDelete={handleDeleteWidget}
  123. onChangeDataSet={handleDataSetChange}
  124. goBackLocation={goBackLocation}
  125. isEditing={isEditing}
  126. />
  127. );
  128. }
  129. return (
  130. <MetricWidget
  131. organization={organization}
  132. router={router}
  133. location={location}
  134. dashboardTitle={dashboard.title}
  135. params={params}
  136. goBackLocation={goBackLocation}
  137. onChangeDataSet={handleDataSetChange}
  138. />
  139. );
  140. }
  141. export default WidgetBuilder;