|
@@ -235,10 +235,13 @@ function WidgetBuilder({
|
|
|
const [state, setState] = useState<State>(() => {
|
|
|
const defaultState: State = {
|
|
|
title: defaultTitle ?? t('Custom Widget'),
|
|
|
- displayType: displayType ?? DisplayType.TABLE,
|
|
|
+ displayType:
|
|
|
+ (widgetBuilderNewDesign && displayType === DisplayType.TOP_N
|
|
|
+ ? DisplayType.AREA
|
|
|
+ : displayType) ?? DisplayType.TABLE,
|
|
|
interval: '5m',
|
|
|
queries: [],
|
|
|
- limit,
|
|
|
+ limit: limit ? Number(limit) : undefined,
|
|
|
errors: undefined,
|
|
|
loading: !!notDashboardsOrigin,
|
|
|
dashboards: [],
|
|
@@ -265,7 +268,13 @@ function WidgetBuilder({
|
|
|
defaultState.queries = [{...defaultWidgetQuery}];
|
|
|
}
|
|
|
|
|
|
- if (![DisplayType.TABLE, DisplayType.TOP_N].includes(defaultState.displayType)) {
|
|
|
+ if (
|
|
|
+ ![DisplayType.TABLE, DisplayType.TOP_N].includes(defaultState.displayType) &&
|
|
|
+ !(
|
|
|
+ getIsTimeseriesChart(defaultState.displayType) &&
|
|
|
+ defaultState.queries[0].columns.length
|
|
|
+ )
|
|
|
+ ) {
|
|
|
defaultState.queries[0].orderby = '';
|
|
|
}
|
|
|
} else {
|
|
@@ -291,16 +300,40 @@ function WidgetBuilder({
|
|
|
|
|
|
if (isEditing && isValidWidgetIndex) {
|
|
|
const widgetFromDashboard = filteredDashboardWidgets[widgetIndexNum];
|
|
|
- setState({
|
|
|
- title: widgetFromDashboard.title,
|
|
|
- displayType: widgetFromDashboard.displayType,
|
|
|
- interval: widgetFromDashboard.interval,
|
|
|
- queries: normalizeQueries({
|
|
|
- displayType: widgetFromDashboard.displayType,
|
|
|
+
|
|
|
+ let queries;
|
|
|
+ let newDisplayType = widgetFromDashboard.displayType;
|
|
|
+ let newLimit = widgetFromDashboard.limit;
|
|
|
+ if (widgetFromDashboard.displayType === DisplayType.TOP_N) {
|
|
|
+ newLimit = DEFAULT_RESULTS_LIMIT;
|
|
|
+ newDisplayType = DisplayType.AREA;
|
|
|
+
|
|
|
+ queries = normalizeQueries({
|
|
|
+ displayType: newDisplayType,
|
|
|
queries: widgetFromDashboard.queries,
|
|
|
widgetType: widgetFromDashboard.widgetType ?? WidgetType.DISCOVER,
|
|
|
widgetBuilderNewDesign,
|
|
|
- }),
|
|
|
+ }).map(query => ({
|
|
|
+ ...query,
|
|
|
+ // Use the last aggregate because that's where the y-axis is stored
|
|
|
+ aggregates: query.aggregates.length
|
|
|
+ ? [query.aggregates[query.aggregates.length - 1]]
|
|
|
+ : [],
|
|
|
+ }));
|
|
|
+ } else {
|
|
|
+ queries = normalizeQueries({
|
|
|
+ displayType: newDisplayType,
|
|
|
+ queries: widgetFromDashboard.queries,
|
|
|
+ widgetType: widgetFromDashboard.widgetType ?? WidgetType.DISCOVER,
|
|
|
+ widgetBuilderNewDesign,
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ setState({
|
|
|
+ title: widgetFromDashboard.title,
|
|
|
+ displayType: newDisplayType,
|
|
|
+ interval: widgetFromDashboard.interval,
|
|
|
+ queries,
|
|
|
errors: undefined,
|
|
|
loading: false,
|
|
|
dashboards: [],
|
|
@@ -308,13 +341,35 @@ function WidgetBuilder({
|
|
|
dataSet: widgetFromDashboard.widgetType
|
|
|
? WIDGET_TYPE_TO_DATA_SET[widgetFromDashboard.widgetType]
|
|
|
: DataSet.EVENTS,
|
|
|
- limit: widgetFromDashboard.limit,
|
|
|
+ limit: newLimit,
|
|
|
});
|
|
|
setWidgetToBeUpdated(widgetFromDashboard);
|
|
|
}
|
|
|
+ // This should only run once on mount
|
|
|
+ // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
}, []);
|
|
|
|
|
|
useEffect(() => {
|
|
|
+ async function fetchDashboards() {
|
|
|
+ const promise: Promise<DashboardListItem[]> = api.requestPromise(
|
|
|
+ `/organizations/${organization.slug}/dashboards/`,
|
|
|
+ {
|
|
|
+ method: 'GET',
|
|
|
+ query: {sort: 'myDashboardsAndRecentlyViewed'},
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ try {
|
|
|
+ const dashboards = await promise;
|
|
|
+ setState(prevState => ({...prevState, dashboards, loading: false}));
|
|
|
+ } catch (error) {
|
|
|
+ const errorMessage = t('Unable to fetch dashboards');
|
|
|
+ addErrorMessage(errorMessage);
|
|
|
+ handleXhrErrorResponse(errorMessage)(error);
|
|
|
+ setState(prevState => ({...prevState, loading: false}));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (notDashboardsOrigin) {
|
|
|
fetchDashboards();
|
|
|
}
|
|
@@ -328,11 +383,19 @@ function WidgetBuilder({
|
|
|
},
|
|
|
}));
|
|
|
}
|
|
|
- }, [source]);
|
|
|
+ }, [
|
|
|
+ api,
|
|
|
+ dashboard.id,
|
|
|
+ dashboard.title,
|
|
|
+ notDashboardsOrigin,
|
|
|
+ organization.slug,
|
|
|
+ source,
|
|
|
+ widgetBuilderNewDesign,
|
|
|
+ ]);
|
|
|
|
|
|
useEffect(() => {
|
|
|
fetchOrgMembers(api, organization.slug, selection.projects?.map(String));
|
|
|
- }, [selection.projects]);
|
|
|
+ }, [selection.projects, api, organization.slug]);
|
|
|
|
|
|
const widgetType =
|
|
|
state.dataSet === DataSet.EVENTS
|
|
@@ -897,26 +960,6 @@ function WidgetBuilder({
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async function fetchDashboards() {
|
|
|
- const promise: Promise<DashboardListItem[]> = api.requestPromise(
|
|
|
- `/organizations/${organization.slug}/dashboards/`,
|
|
|
- {
|
|
|
- method: 'GET',
|
|
|
- query: {sort: 'myDashboardsAndRecentlyViewed'},
|
|
|
- }
|
|
|
- );
|
|
|
-
|
|
|
- try {
|
|
|
- const dashboards = await promise;
|
|
|
- setState(prevState => ({...prevState, dashboards, loading: false}));
|
|
|
- } catch (error) {
|
|
|
- const errorMessage = t('Unable to fetch dashboards');
|
|
|
- addErrorMessage(errorMessage);
|
|
|
- handleXhrErrorResponse(errorMessage)(error);
|
|
|
- setState(prevState => ({...prevState, loading: false}));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
function submitFromSelectedDashboard(widgetData: Widget) {
|
|
|
if (!state.selectedDashboard) {
|
|
|
return;
|