return async function(dispatch, getState) { const isPublicLink = Utils.isUUID(dashId); if (isPublicLink) { result = await PublicApi.dashboard({ uuid: dashId }); result = { ...result, id: dashId, ordered_cards: result.ordered_cards.map(dc => ({ ...dc, dashboard_id: dashId })) }; } else { result = await DashboardApi.get({ dashId: dashId }); } dispatch(setDashboardId(dashId)); if (result.parameters) { for (const parameter of result.parameters) { if (queryParams && queryParams[parameter.slug] != null) { dispatch(setParameterValue(parameter.id, queryParams[parameter.slug])); } else if (enableDefaultParameters && parameter.default != null) { dispatch(setParameterValue(parameter.id, parameter.default)); } } } if (!isPublicLink) { // fetch database metadata for every card _.chain(result.ordered_cards) .map((dc) => [dc.card].concat(dc.series)) .flatten() .filter(card => card && card.dataset_query && card.dataset_query.database) .map(card => card.dataset_query.database) .uniq() .each((dbId) => dispatch(fetchDatabaseMetadata(dbId))); } return normalize(result, dashboard); };
return async function(dispatch, getState) { // If the dataset_query was filtered then we don't have permisison to view this card, so // shortcircuit and return a fake 403 if (!card.dataset_query) { return { dashcard_id: dashcard.id, card_id: card.id, result: { error: { status: 403 }} }; } const isPublicLink = Utils.isUUID(dashcard.dashboard_id); const { dashboardId, dashboards, parameterValues, dashcardData } = getState().dashboard; const dashboard = dashboards[dashboardId]; // if we have a parameter, apply it to the card query before we execute const datasetQuery = applyParameters(card, dashboard.parameters, parameterValues, dashcard && dashcard.parameter_mappings); if (!reload) { // if reload not set, check to see if the last result has the same query dict and return that const lastResult = getIn(dashcardData, [dashcard.id, card.id]); // "constraints" is added by the backend, remove it when comparing if (lastResult && Utils.equals(_.omit(lastResult.json_query, "constraints"), datasetQuery)) { return { dashcard_id: dashcard.id, card_id: card.id, result: lastResult }; } } if (clear) { // clears the card data to indicate the card is reloading dispatch(clearCardData(card.id, dashcard.id)); } let result = null; // start a timer that will fetch the expected card duration if the query takes too long let slowCardTimer = setTimeout(() => { if (result === null) { dispatch(fetchCardDuration(card, datasetQuery)); } }, DATASET_SLOW_TIMEOUT); // make the actual request if (isPublicLink) { result = await fetchDataOrError(PublicApi.dashboardCardQuery({ uuid: dashcard.dashboard_id, cardId: card.id, parameters: datasetQuery.parameters ? JSON.stringify(datasetQuery.parameters) : undefined })); } else { result = await fetchDataOrError(CardApi.query({cardId: card.id, parameters: datasetQuery.parameters})); } clearTimeout(slowCardTimer); return { dashcard_id: dashcard.id, card_id: card.id, result: result }; };
return async function(dispatch, getState) { const dashboardType = getDashboardType(dashId); if (dashboardType === "public") { result = await PublicApi.dashboard({ uuid: dashId }); result = { ...result, id: dashId, ordered_cards: result.ordered_cards.map(dc => ({ ...dc, dashboard_id: dashId, })), }; } else if (dashboardType === "embed") { result = await EmbedApi.dashboard({ token: dashId }); result = { ...result, id: dashId, ordered_cards: result.ordered_cards.map(dc => ({ ...dc, dashboard_id: dashId, })), }; } else if (dashboardType === "transient") { const subPath = dashId .split("/") .slice(3) .join("/"); result = await AutoApi.dashboard({ subPath }); result = { ...result, id: dashId, ordered_cards: result.ordered_cards.map(dc => ({ ...dc, dashboard_id: dashId, })), }; } else { result = await DashboardApi.get({ dashId: dashId }); } const parameterValues = {}; if (result.parameters) { for (const parameter of result.parameters) { if (queryParams && queryParams[parameter.slug] != null) { parameterValues[parameter.id] = queryParams[parameter.slug]; } else if (enableDefaultParameters && parameter.default != null) { parameterValues[parameter.id] = parameter.default; } } } if (dashboardType === "normal" || dashboardType === "transient") { // fetch database metadata for every card _.chain(result.ordered_cards) .map(dc => [dc.card].concat(dc.series)) .flatten() .filter( card => card && card.dataset_query && card.dataset_query.database, ) .map(card => card.dataset_query.database) .uniq() .each(dbId => dispatch(fetchDatabaseMetadata(dbId))); } // copy over any virtual cards from the dashcard to the underlying card/question result.ordered_cards.forEach(card => { if (card.visualization_settings.virtual_card) { card.card = Object.assign( card.card || {}, card.visualization_settings.virtual_card, ); } }); if (result.param_values) { dispatch(addParamValues(result.param_values)); } if (result.param_fields) { dispatch(addFields(result.param_fields)); } return { ...normalize(result, dashboard), // includes `result` and `entities` dashboardId: dashId, parameterValues: parameterValues, }; };