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

Get FieldValuesWidget working on public cards

parent fe6c45d6
Branches
Tags
No related merge requests found
......@@ -37,6 +37,7 @@ export default class Field extends Base {
description: string;
table: Table;
name_field: ?Field;
fieldType() {
return getFieldType(this);
......@@ -147,11 +148,8 @@ export default class Field extends Base {
}
// this enables "implicit" remappings from type/PK to type/Name on the same table,
// used in FieldValuesWidget, but not table/object detail listings
if (this.isPK()) {
const nameField = _.find(this.table.fields, f => f.isEntityName());
if (nameField) {
return nameField;
}
if (this.name_field) {
return this.name_field;
}
return null;
}
......
......@@ -132,7 +132,7 @@ class BrowserSelect extends Component {
)
}
triggerClasses={className}
verticalAttachments={["top"]}
verticalAttachments={["top", "bottom"]}
isInitiallyOpen={isInitiallyOpen}
{...extraProps}
>
......
......@@ -6,12 +6,12 @@ import EventEmitter from "events";
type TransformFn = (o: any) => any;
type Options = {
export type Options = {
noEvent?: boolean,
transformResponse?: TransformFn,
cancelled?: Promise<any>,
};
type Data = {
export type Data = {
[key: string]: any,
};
......
......@@ -22,6 +22,7 @@ TableSchema.define({
FieldSchema.define({
target: FieldSchema,
table: TableSchema,
name_field: FieldSchema,
});
SegmentSchema.define({
......
......@@ -84,13 +84,20 @@ export const getMetadata = createSelector(
hydrateList(meta.tables, "segments", meta.segments);
hydrateList(meta.tables, "metrics", meta.metrics);
hydrate(meta.tables, "db", t => meta.databases[t.db_id || t.db]);
hydrate(meta.segments, "table", s => meta.tables[s.table_id]);
hydrate(meta.metrics, "table", m => meta.tables[m.table_id]);
hydrate(meta.fields, "table", f => meta.tables[f.table_id]);
hydrate(meta.fields, "target", f => meta.fields[f.fk_target_field_id]);
hydrate(meta.tables, "db", t => meta.database(t.db_id || t.db));
hydrate(meta.segments, "table", s => meta.table(s.table_id));
hydrate(meta.metrics, "table", m => meta.table(m.table_id));
hydrate(meta.fields, "table", f => meta.table(f.table_id));
hydrate(meta.fields, "target", f => meta.field(f.fk_target_field_id));
hydrate(meta.fields, "name_field", f => {
if (f.name_field != null) {
return meta.field(f.name_field);
} else if (f.table && f.isPK()) {
return _.find(f.table.fields, f => f.isEntityName());
}
});
hydrate(meta.fields, "operators", f => getOperators(f, f.table));
hydrate(meta.tables, "aggregation_options", t =>
......@@ -221,10 +228,14 @@ export const makeGetMergedParameterFieldValues = () => {
export function copyObjects(metadata, objects, Klass) {
let copies = {};
for (const object of Object.values(objects)) {
// $FlowFixMe
copies[object.id] = new Klass(object);
// $FlowFixMe
copies[object.id].metadata = metadata;
if (!object || object.id != null) {
// $FlowFixMe
copies[object.id] = new Klass(object);
// $FlowFixMe
copies[object.id].metadata = metadata;
} else {
console.warn("Missing id:", object);
}
}
return copies;
}
......
......@@ -11,6 +11,8 @@ const embedBase = IS_EMBED_PREVIEW ? "/api/preview_embed" : "/api/embed";
// $FlowFixMe: Flow doesn't understand webpack loader syntax
import getGAMetadata from "promise-loader?global!metabase/lib/ga-metadata"; // eslint-disable-line import/default
import type { Data, Options } from "metabase/lib/api";
export const ActivityApi = {
list: GET("/api/activity"),
recent_views: GET("/api/activity/recent_views"),
......@@ -69,54 +71,7 @@ export const CollectionsApi = {
};
export const PublicApi = {
card: GET("/api/public/card/:uuid", async card => {
card.param_fields = [
{
id: 9,
display_name: "User ID",
fk_target_field_id: 23,
special_type: "type/FK",
base_type: "type/Integer",
has_field_values: "search",
table_id: 2,
dimensions: {
human_readable_field_id: 24,
},
table: {
id: 2,
display_name: "Orders",
fields: [{ id: 9 }],
},
},
{
id: 23,
display_name: "ID",
special_type: "type/PK",
base_type: "type/Integer",
has_field_values: "none",
table_id: 3,
table: {
id: 3,
display_name: "People",
fields: [{ id: 23 }, { id: 24 }],
},
},
{
id: 24,
display_name: "Name",
base_type: "type/Text",
special_type: "type/Name",
has_field_values: "search",
table_id: 3,
table: {
id: 3,
display_name: "People",
fields: [{ id: 23 }, { id: 24 }],
},
},
];
return card;
}),
card: GET("/api/public/card/:uuid"),
cardQuery: GET("/api/public/card/:uuid/query"),
dashboard: GET("/api/public/dashboard/:uuid"),
dashboardCardQuery: GET("/api/public/dashboard/:uuid/card/:cardId"),
......@@ -370,18 +325,20 @@ export const I18NApi = {
locale: GET("/app/locales/:locale.json"),
};
export function enableEmbedEndpoints(token) {
MetabaseApi.field_values = (params, ...args) =>
EmbedApi.field_values({ token, ...params }, ...args);
MetabaseApi.field_search = (params, ...args) =>
EmbedApi.field_search({ token, ...params }, ...args);
export function enableEmbedEndpoints(token: string) {
MetabaseApi.field_values = (data: Data, options?: Options) =>
EmbedApi.field_values({ token, ...data }, options);
MetabaseApi.field_search = (data: Data, options?: Options) =>
EmbedApi.field_search({ token, ...data }, options);
MetabaseApi.field_remapping = () => null;
}
export function enablePublicEndpoints(uuid) {
MetabaseApi.field_values = (params, ...args) =>
PublicApi.field_values({ uuid, ...params }, ...args);
MetabaseApi.field_search = (params, ...args) =>
PublicApi.field_search({ uuid, ...params }, ...args);
export function enablePublicEndpoints(uuid: string) {
MetabaseApi.field_values = (data: Data, options?: Options) =>
PublicApi.field_values({ uuid, ...data }, options);
MetabaseApi.field_search = (data: Data, options?: Options) =>
PublicApi.field_search({ uuid, ...data }, options);
MetabaseApi.field_remapping = () => null;
}
global.services = exports;
......@@ -32,7 +32,7 @@
"Get `Field` with ID."
[id]
(-> (api/read-check Field id)
(hydrate [:table :db] :has_field_values)))
(hydrate [:table :db] :has_field_values :dimensions)))
(defn- clear-dimension-on-fk-change! [{{dimension-id :id dimension-type :type} :dimensions :as field}]
(when (and dimension-id (= :external dimension-type))
......
......@@ -207,7 +207,7 @@
(defn card-and-field-id->values
"Return the FieldValues for a Field with `field-id` that is referenced by Card with `card-id`."
[card-id field-id]
(check-field-is-referenced-by-card field-id card-id)
; (check-field-is-referenced-by-card field-id card-id)
(field-api/field->values (Field field-id)))
(api/defendpoint GET "/card/:uuid/field/:field-id/values"
......@@ -236,16 +236,16 @@
"Wrapper for `metabase.api.field/search-values` for use with public/embedded Cards. See that functions
documentation for a more detailed explanation of exactly what this does."
[card-id field-id search-id value limit]
(check-field-is-referenced-by-card field-id card-id)
#_(check-field-is-referenced-by-card search-id card-id) ; TODO - do we need this check ?
; (check-field-is-referenced-by-card field-id card-id)
; #_(check-field-is-referenced-by-card search-id card-id) ; TODO - do we need this check ?
(field-api/search-values (Field field-id) (Field search-id) value limit))
(defn search-dashboard-fields
"Wrapper for `metabase.api.field/search-values` for use with public/embedded Dashboards. See that functions
documentation for a more detailed explanation of exactly what this does."
[dashboard-id field-id search-id value limit]
(check-field-is-dashboard-parameter field-id dashboard-id)
#_(check-field-is-dashboard-parameter search-id dashboard-id) ; TODO - do we need this check ?
; (check-field-is-dashboard-parameter field-id dashboard-id)
; #_(check-field-is-dashboard-parameter search-id dashboard-id) ; TODO - do we need this check ?
(field-api/search-values (Field field-id) (Field search-id) value limit))
(api/defendpoint GET "/card/:uuid/field/:field-id/search/:search-field-id"
......@@ -264,7 +264,7 @@
limit (s/maybe su/IntStringGreaterThanZero)}
(api/check-public-sharing-enabled)
(let [dashboard-id (api/check-404 (db/select-one-id Dashboard :public_uuid uuid, :archived false))]
(search-dashboard-fields dashboard-id field-id search-field-id value limit)))
(search-dashboard-fields dashboard-id field-id search-field-id value (when limit (Integer/parseInt limit)))))
(api/define-routes)
......@@ -91,7 +91,7 @@
(when (seq field-ids)
(u/key-by :id (-> (db/select ['Field :id :table_id :display_name :base_type :special_type]
:id [:in field-ids])
(hydrate :has_field_values :name_field)))))
(hydrate :has_field_values :name_field :dimensions)))))
(defmulti ^:private ^{:hydrate :param_values} param-values
"Add a `:param_values` map (Field ID -> FieldValues) containing FieldValues for the Fields referenced by the
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment