diff --git a/frontend/src/metabase/dashboard/components/DashCard.jsx b/frontend/src/metabase/dashboard/components/DashCard.jsx index 028f585a3a0f15ae9c19107c05ada5cdf211b25d..af04185b1d7fcf2d1256bdfdcaabf537ac90ad1b 100644 --- a/frontend/src/metabase/dashboard/components/DashCard.jsx +++ b/frontend/src/metabase/dashboard/components/DashCard.jsx @@ -60,7 +60,7 @@ export default class DashCard extends Component { isEditingParameter, onAddSeries, onRemove, - onChangeCardAndRun, + navigateToNewCard, metadata } = this.props; @@ -134,10 +134,8 @@ export default class DashCard extends Component { onUpdateVisualizationSettings={this.props.onUpdateVisualizationSettings} replacementContent={isEditingParameter && <DashCardParameterMapper dashcard={dashcard} />} metadata={metadata} - onChangeCardAndRun={(card) => { - // ensure the original card ID is included to track lineage - card = { ...card, id: series[0].card.id }; - onChangeCardAndRun(card, dashcard); + onChangeCardAndRun={(card: UnsavedCard|Card) => { + this.props.navigateToNewCard(card, dashcard) }} /> </div> diff --git a/frontend/src/metabase/dashboard/components/DashboardGrid.jsx b/frontend/src/metabase/dashboard/components/DashboardGrid.jsx index 58a54d6b55b14e3a9ae72eca2d6c5ac10c81f624..ad353f01f992ed8ef7830b96076f8ccfe3405443 100644 --- a/frontend/src/metabase/dashboard/components/DashboardGrid.jsx +++ b/frontend/src/metabase/dashboard/components/DashboardGrid.jsx @@ -197,7 +197,7 @@ export default class DashboardGrid extends Component { onAddSeries={this.onDashCardAddSeries.bind(this, dc)} onUpdateVisualizationSettings={this.props.onUpdateDashCardVisualizationSettings.bind(this, dc.id)} onReplaceAllVisualizationSettings={this.props.onReplaceAllDashCardVisualizationSettings.bind(this, dc.id)} - onChangeCardAndRun={this.props.onChangeCardAndRun} + navigateToNewCard={this.props.navigateToNewCard} metadata={this.props.metadata} /> ) diff --git a/frontend/src/metabase/dashboard/dashboard.js b/frontend/src/metabase/dashboard/dashboard.js index ecd9d0fb77312da12c1d842b4ed1f4da1cb87dc4..e07872334d5349dcbbe0b56f1f773c5e65c1010f 100644 --- a/frontend/src/metabase/dashboard/dashboard.js +++ b/frontend/src/metabase/dashboard/dashboard.js @@ -14,7 +14,7 @@ import { applyParameters, questionUrlWithParameters } from "metabase/meta/Card"; import { getParametersBySlug } from "metabase/meta/Parameter"; import type { DashboardWithCards, DashCard, DashCardId } from "metabase/meta/types/Dashboard"; -import type { Card, CardId } from "metabase/meta/types/Card"; +import type { UnsavedCard, Card, CardId } from "metabase/meta/types/Card"; import Utils from "metabase/lib/utils"; import { getPositionForNewDashCard } from "metabase/lib/dashboard_grid"; @@ -55,7 +55,6 @@ export const SET_DASHCARD_ATTRIBUTES = "metabase/dashboard/SET_DASHCARD_ATTRIBUT export const UPDATE_DASHCARD_VISUALIZATION_SETTINGS = "metabase/dashboard/UPDATE_DASHCARD_VISUALIZATION_SETTINGS"; export const REPLACE_ALL_DASHCARD_VISUALIZATION_SETTINGS = "metabase/dashboard/REPLACE_ALL_DASHCARD_VISUALIZATION_SETTINGS"; export const UPDATE_DASHCARD_ID = "metabase/dashboard/UPDATE_DASHCARD_ID" -export const SAVE_DASHCARD = "metabase/dashboard/SAVE_DASHCARD"; export const FETCH_DASHBOARD_CARD_DATA = "metabase/dashboard/FETCH_DASHBOARD_CARD_DATA"; export const FETCH_CARD_DATA = "metabase/dashboard/FETCH_CARD_DATA"; @@ -67,8 +66,6 @@ export const REVERT_TO_REVISION = "metabase/dashboard/REVERT_TO_REVISION"; export const MARK_NEW_CARD_SEEN = "metabase/dashboard/MARK_NEW_CARD_SEEN"; -export const FETCH_DATABASE_METADATA = "metabase/dashboard/FETCH_DATABASE_METADATA"; - export const SET_EDITING_PARAMETER_ID = "metabase/dashboard/SET_EDITING_PARAMETER_ID"; export const ADD_PARAMETER = "metabase/dashboard/ADD_PARAMETER"; export const REMOVE_PARAMETER = "metabase/dashboard/REMOVE_PARAMETER"; @@ -496,10 +493,13 @@ export const deletePublicLink = createAction(DELETE_PUBLIC_LINK, async ({ id }) /** All navigation actions from dashboards to cards (e.x. clicking a title, drill through) * should go through this action, which merges any currently applied dashboard filters - * into the new card / URL parmeters. + * into the new card / URL parameters. */ -const CHANGE_CARD_AND_RUN = "metabase/database/CHANGE_CARD_AND_RUN"; -export const onChangeCardAndRun = createThunkAction(CHANGE_CARD_AND_RUN, (card, dashcard = null) => + +// TODO Atte Keinänen 5/2/17: This could be combined with `setCardAndRun` of query_builder/actions.js +// Having two separate actions for very similar behavior was a source of initial confusion for me +const NAVIGATE_TO_NEW_CARD = "metabase/dashboard/NAVIGATE_TO_NEW_CARD"; +export const navigateToNewCard = createThunkAction(NAVIGATE_TO_NEW_CARD, (card: UnsavedCard|Card, dashcard: DashCard) => (dispatch, getState) => { const { metadata } = getState(); const { dashboardId, dashboards, parameterValues } = getState().dashboard; diff --git a/frontend/src/metabase/meta/types/Card.js b/frontend/src/metabase/meta/types/Card.js index 9ef102d6db3011f2e7e4ccfac89184ceca1e4819..8ab071c4ad67245301abae5d1ef99f183ac29560 100644 --- a/frontend/src/metabase/meta/types/Card.js +++ b/frontend/src/metabase/meta/types/Card.js @@ -6,15 +6,20 @@ import type { Parameter, ParameterInstance } from "./Parameter"; export type CardId = number; -export type Card = { - id: CardId, - name: ?string, - description: ?string, +export type UnsavedCard = { dataset_query: DatasetQuery, display: string, visualization_settings: VisualizationSettings, parameters?: Array<Parameter> -}; +} + +export type SavedCardFields = { + id: CardId, + name: ?string, + description: ?string, +} + +export type Card = UnsavedCard & SavedCardFields; export type StructuredDatasetQuery = { type: "query", diff --git a/frontend/src/metabase/query_builder/actions.js b/frontend/src/metabase/query_builder/actions.js index 0c112e73d730fd5e897911d6b20d63bff87440d9..8e014bc1d339aa465b63768fa7629df6925a5166 100644 --- a/frontend/src/metabase/query_builder/actions.js +++ b/frontend/src/metabase/query_builder/actions.js @@ -156,6 +156,8 @@ export const initializeQB = createThunkAction(INITIALIZE_QB, (location, params) if (params.cardId || serializedCard) { // existing card being loaded try { + // TODO: Don't load a card if a card is passed in the hash? Speeds up the page load. + if (params.cardId) { card = await loadCard(params.cardId); diff --git a/frontend/src/metabase/visualizations/components/Visualization.jsx b/frontend/src/metabase/visualizations/components/Visualization.jsx index 97a67a37bc9369eb87a7569112c5510eeecbd11f..af1916b4f8a2a2d7b164de106dabf245ec3c124e 100644 --- a/frontend/src/metabase/visualizations/components/Visualization.jsx +++ b/frontend/src/metabase/visualizations/components/Visualization.jsx @@ -30,7 +30,7 @@ import cx from "classnames"; export const ERROR_MESSAGE_GENERIC = "There was a problem displaying this chart."; export const ERROR_MESSAGE_PERMISSION = "Sorry, you don't have permission to see this card." -import type { Card as CardObject, VisualizationSettings } from "metabase/meta/types/Card"; +import type {Card as CardObject, UnsavedCard, VisualizationSettings} from "metabase/meta/types/Card"; import type { HoverObject, ClickObject, Series } from "metabase/meta/types/Visualization"; import type { Metadata } from "metabase/meta/types/Metadata"; @@ -221,6 +221,23 @@ export default class Visualization extends Component<*, Props, State> { }, 100) } + handleOnChangeCardAndRun = (card: UnsavedCard) => { + // If the current card has a name, carry that information to the new card for showing lineage + // The card description is omitted because it isn't relevant for showing the lineage + const { series } = this.state + const currentlyInSavedCard = series[0] && series[0].card && series[0].card.id + if (currentlyInSavedCard) { + const savedCard: CardObject = { + ...card, + id: series[0].card.id, + }; + + this.props.onChangeCardAndRun(savedCard) + } else { + this.props.onChangeCardAndRun(card) + } + } + onRender = ({ yAxisSplit, warnings = [] } = {}) => { this.setState({ yAxisSplit, warnings }); } @@ -230,7 +247,7 @@ export default class Visualization extends Component<*, Props, State> { } render() { - const { actionButtons, className, showTitle, isDashboard, width, height, errorIcon, isSlow, expectedDuration, replacementContent, onChangeCardAndRun } = this.props; + const { actionButtons, className, showTitle, isDashboard, width, height, errorIcon, isSlow, expectedDuration, replacementContent } = this.props; const { series, CardVisualization } = this.state; const small = width < 330; @@ -315,7 +332,7 @@ export default class Visualization extends Component<*, Props, State> { actionButtons={extra} description={settings["card.description"]} settings={settings} - onChangeCardAndRun={onChangeCardAndRun} + onChangeCardAndRun={this.handleOnChangeCardAndRun} /> </div> : null @@ -384,7 +401,7 @@ export default class Visualization extends Component<*, Props, State> { onRenderError={this.onRenderError} onRender={this.onRender} gridSize={gridSize} - onChangeCardAndRun={onChangeCardAndRun} + onChangeCardAndRun={this.handleOnChangeCardAndRun} /> } <ChartTooltip @@ -394,7 +411,7 @@ export default class Visualization extends Component<*, Props, State> { <ChartClickActions clicked={clicked} clickActions={clickActions} - onChangeCardAndRun={this.props.onChangeCardAndRun} + onChangeCardAndRun={this.handleOnChangeCardAndRun} onClose={() => this.setState({ clicked: null })} /> </div>