Skip to content
Snippets Groups Projects
Commit 29aa1fb2 authored by Tom Robinson's avatar Tom Robinson
Browse files

Merge branch 'master' of github.com:metabase/metabase into multiseries_charts_v1

parents ddfa8465 1ca2accd
No related branches found
No related tags found
No related merge requests found
......@@ -56,12 +56,12 @@ export default class Dashboard extends Component {
<LoadingAndErrorWrapper className="Dashboard full-height" loading={!dashboard} error={error}>
{() =>
<div className="full">
<header className="bg-white border-bottom">
<header className="bg-white border-bottom relative z2">
<DashboardHeader {...this.props} />
</header>
<div className="Dash-wrapper wrapper">
{ dashboard.ordered_cards.length === 0 ?
<div className="absolute top bottom left right flex flex-column layout-centered">
<div className="absolute z1 top bottom left right flex flex-column layout-centered">
<span className="QuestionCircle">?</span>
<div className="text-normal mt3 mb1">This dashboard is looking empty.</div>
<div className="text-normal text-grey-2">Add a question to start making it useful!</div>
......
......@@ -147,7 +147,7 @@ export default class DashboardHeader extends Component {
ref="addQuestionModal"
triggerElement={
<a data-metabase-event="Dashboard;Add Card Modal" title="Add a question to this dashboard">
<Icon className={cx("text-brand-hover", { "Icon--pulse": isEmpty })} name="add" width="16px" height="16px" />
<Icon className={cx("text-brand-hover cursor-pointer", { "Icon--pulse": isEmpty })} name="add" width="16px" height="16px" />
</a>
}
>
......
......@@ -22,8 +22,7 @@ export default class QueryVisualization extends Component {
this.runQuery = this.runQuery.bind(this);
this.state = {
lastRunCard: props.card,
lastRunQuery: JSON.stringify(props.card.dataset_query)
lastRunDatasetQuery: props.card.dataset_query
};
}
......@@ -53,15 +52,14 @@ export default class QueryVisualization extends Component {
// whenever we are told that we are running a query lets update our understanding of the "current" query
if (nextProps.isRunning) {
this.setState({
lastRunCard: nextProps.card,
lastRunQuery: JSON.stringify(nextProps.card.dataset_query)
lastRunDatasetQuery: nextProps.card.dataset_query
});
}
}
queryIsDirty() {
// a query is considered dirty if ANY part of it has been changed
return (JSON.stringify(this.props.card.dataset_query) !== this.state.lastRunQuery);
return JSON.stringify(this.props.card.dataset_query) !== JSON.stringify(this.state.lastRunDatasetQuery);
}
isChartDisplay(display) {
......@@ -313,11 +311,17 @@ export default class QueryVisualization extends Component {
);
} else {
// we want to provide the visualization with a card containing the latest
// "display", "visualization_settings", etc, (to ensure the correct visualization is shown)
// BUT the last executed "dataset_query" (to ensure data matches the query)
let card = {
...this.props.card,
dataset_query: this.state.lastRunDatasetQuery
};
viz = (
<Visualization
card={this.state.lastRunCard}
card={card}
data={this.props.result.data}
// Table:
setSortFn={this.props.setSortFn}
cellIsClickableFn={this.props.cellIsClickableFn}
......
......@@ -7,6 +7,7 @@
(metabase.models [activity :refer [Activity]]
[card :refer [Card]]
[database :refer [Database]]
[foreign-key :refer [ForeignKey]]
[table :refer [Table]]
[setting :as setting])
[metabase.sample-data :as sample-data]
......@@ -96,3 +97,14 @@
(when-not (contains? activity-feed-topics :database-sync-begin)
(k/delete Activity
(k/where {:topic "database-sync"}))))
;; Clean up duplicate FK entries
(defmigration remove-duplicate-fk-entries
(let [existing-fks (db/sel :many ForeignKey)
grouped-fks (group-by #(str (:origin_id %) "_" (:destination_id %)) existing-fks)]
(doseq [[k fks] grouped-fks]
(when (< 1 (count fks))
(log/debug "Removing duplicate FK entries for" k)
(doseq [duplicate-fk (drop-last fks)]
(db/del ForeignKey :id (:id duplicate-fk)))))))
......@@ -476,18 +476,19 @@ infer-field-special-type
(every? :dest-column-name fks))
"table-fks should return a set of maps with keys :fk-column-name, :dest-table, and :dest-column-name.")
(when (seq fks)
(let [fk-name->id (sel :many :field->id [Field :name], :table_id (:id table), :name [in (map :fk-column-name fks)], :parent_id nil)]
(let [fk-name->id (sel :many :field->id [Field :name], :table_id (:id table), :name [in (map :fk-column-name fks)], :parent_id nil)]
(doseq [{:keys [fk-column-name dest-column-name dest-table]} fks]
(when-let [fk-column-id (fk-name->id fk-column-name)]
(when-let [dest-table-id (sel :one :field [Table :id], :db_id (:db_id table) :name (:name dest-table) :schema (:schema dest-table))]
(when-let [dest-column-id (sel :one :id Field, :table_id dest-table-id, :name dest-column-name, :parent_id nil)]
(log/debug (u/format-color 'green "Marking foreign key '%s.%s' -> '%s.%s'." (:name table) fk-column-name (:name dest-table) dest-column-name))
(ins ForeignKey
:origin_id fk-column-id
:destination_id dest-column-id
;; TODO: do we even care about this?
;:relationship (determine-fk-type {:id fk-column-id, :table (delay table)}) ; fake a Field instance
:relationship :Mt1)
(when-not (exists? ForeignKey :origin_id fk-column-id, :destination_id dest-column-id)
(ins ForeignKey
:origin_id fk-column-id
:destination_id dest-column-id
;; TODO: do we even care about this?
;:relationship (determine-fk-type {:id fk-column-id, :table (delay table)}) ; fake a Field instance
:relationship :Mt1))
(upd Field fk-column-id :special_type :fk))))))))))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment