From f37183e919a3c41ea0e05dabfe46eacee56dc71a Mon Sep 17 00:00:00 2001 From: Alexander Polyankin <alexander.polyankin@metabase.com> Date: Mon, 6 Dec 2021 20:13:05 +0300 Subject: [PATCH] Remove flow from lib (#19215) --- frontend/src/metabase/lib/api.js | 53 +---- frontend/src/metabase/lib/dashboard_grid.js | 21 +- frontend/src/metabase/lib/dataset.js | 46 +--- frontend/src/metabase/lib/entities.js | 173 +-------------- .../src/metabase/lib/expressions/format.js | 11 +- frontend/src/metabase/lib/formatting.js | 153 +++---------- frontend/src/metabase/lib/formatting/date.js | 63 +----- frontend/src/metabase/lib/permissions.js | 207 ++++++------------ .../src/metabase/lib/query/aggregation.js | 79 +++---- frontend/src/metabase/lib/query/breakout.js | 24 +- frontend/src/metabase/lib/query/expression.js | 36 +-- frontend/src/metabase/lib/query/field.js | 38 +--- frontend/src/metabase/lib/query/field_ref.js | 9 +- frontend/src/metabase/lib/query/filter.js | 53 ++--- frontend/src/metabase/lib/query/join.js | 18 +- frontend/src/metabase/lib/query/limit.js | 8 +- frontend/src/metabase/lib/query/order_by.js | 24 +- frontend/src/metabase/lib/query/query.js | 155 +++++-------- frontend/src/metabase/lib/query/util.js | 17 +- frontend/src/metabase/lib/urls.js | 2 +- 20 files changed, 287 insertions(+), 903 deletions(-) diff --git a/frontend/src/metabase/lib/api.js b/frontend/src/metabase/lib/api.js index c3dc6353c62..5a70bb3e4a3 100644 --- a/frontend/src/metabase/lib/api.js +++ b/frontend/src/metabase/lib/api.js @@ -5,22 +5,6 @@ import EventEmitter from "events"; import { delay } from "metabase/lib/promise"; import { IFRAMED } from "metabase/lib/dom"; -type TransformFn = (o: any) => any; - -export type Options = { - noEvent?: boolean, - json?: boolean, - retry?: boolean, - retryCount?: number, - retryDelayIntervals?: number[], - transformResponse?: TransformFn, - cancelled?: Promise<any>, - raw?: { [key: string]: boolean }, - headers?: { [key: string]: string }, - hasBody?: boolean, - bodyParamName?: string, -}; - const ONE_SECOND = 1000; const MAX_RETRIES = 10; @@ -28,11 +12,7 @@ const ANTI_CSRF_HEADER = "X-Metabase-Anti-CSRF-Token"; let ANTI_CSRF_TOKEN = null; -export type Data = { - [key: string]: any, -}; - -const DEFAULT_OPTIONS: Options = { +const DEFAULT_OPTIONS = { json: true, hasBody: false, noEvent: false, @@ -48,16 +28,13 @@ const DEFAULT_OPTIONS: Options = { .reverse(), }; -export type APIMethod = (d?: Data, o?: Options) => Promise<any>; -export type APICreator = (t: string, o?: Options | TransformFn) => APIMethod; - export class Api extends EventEmitter { basename = ""; - GET: APICreator; - POST: APICreator; - PUT: APICreator; - DELETE: APICreator; + GET; + POST; + PUT; + DELETE; constructor() { super(); @@ -67,11 +44,8 @@ export class Api extends EventEmitter { this.PUT = this._makeMethod("PUT", { hasBody: true }); } - _makeMethod(method: string, creatorOptions?: Options = {}): APICreator { - return ( - urlTemplate: string, - methodOptions?: Options | TransformFn = {}, - ) => { + _makeMethod(method, creatorOptions = {}) { + return (urlTemplate, methodOptions = {}) => { if (typeof methodOptions === "function") { methodOptions = { transformResponse: methodOptions }; } @@ -82,11 +56,8 @@ export class Api extends EventEmitter { ...methodOptions, }; - return async ( - data?: Data, - invocationOptions?: Options = {}, - ): Promise<any> => { - const options: Options = { ...defaultOptions, ...invocationOptions }; + return async (data, invocationOptions = {}) => { + const options = { ...defaultOptions, ...invocationOptions }; let url = urlTemplate; data = { ...data }; for (const tag of url.match(/:\w+/g) || []) { @@ -109,7 +80,7 @@ export class Api extends EventEmitter { } } - const headers: { [key: string]: string } = options.json + const headers = options.json ? { Accept: "application/json", "Content-Type": "application/json" } : {}; @@ -154,9 +125,9 @@ export class Api extends EventEmitter { async _makeRequestWithRetries(method, url, headers, body, data, options) { // Get a copy of the delay intervals that we can remove items from as we retry const retryDelays = options.retryDelayIntervals.slice(); - let retryCount: number = 0; + let retryCount = 0; // maxAttempts is the first attempt followed by the number of retries - const maxAttempts: number = options.retryCount + 1; + const maxAttempts = options.retryCount + 1; // Make the first attempt for the request, then loop incrementing the retryCount do { try { diff --git a/frontend/src/metabase/lib/dashboard_grid.js b/frontend/src/metabase/lib/dashboard_grid.js index e0257632d1e..87a5396cfc0 100644 --- a/frontend/src/metabase/lib/dashboard_grid.js +++ b/frontend/src/metabase/lib/dashboard_grid.js @@ -1,5 +1,3 @@ -import type { DashCard } from "metabase-types/types/Dashboard"; - export const GRID_WIDTH = 18; export const GRID_ASPECT_RATIO = 4 / 3; @@ -19,21 +17,14 @@ export const DEFAULT_CARD_SIZE = { width: 4, height: 4 }; export const MIN_ROW_HEIGHT = 54; -type DashCardPosition = { - col: number, - row: number, - sizeY: number, - sizeX: number, -}; - // returns the first available position from left to right, top to bottom, // based on the existing cards, item size, and grid width export function getPositionForNewDashCard( - cards: Array<DashCard>, - sizeX: number = DEFAULT_CARD_SIZE.width, - sizeY: number = DEFAULT_CARD_SIZE.height, - width: number = GRID_WIDTH, -): DashCardPosition { + cards, + sizeX = DEFAULT_CARD_SIZE.width, + sizeY = DEFAULT_CARD_SIZE.height, + width = GRID_WIDTH, +) { let row = 0; let col = 0; while (row < 1000) { @@ -58,7 +49,7 @@ export function getPositionForNewDashCard( return { col, row, sizeX, sizeY }; } -function intersects(a: DashCardPosition, b: DashCardPosition): boolean { +function intersects(a, b) { return !( b.col >= a.col + a.sizeX || b.col + b.sizeX <= a.col || diff --git a/frontend/src/metabase/lib/dataset.js b/frontend/src/metabase/lib/dataset.js index cdd6d9e293e..d5e2e84d7b2 100644 --- a/frontend/src/metabase/lib/dataset.js +++ b/frontend/src/metabase/lib/dataset.js @@ -1,36 +1,18 @@ import _ from "underscore"; -import type { - Value, - Column, - ColumnName, - DatasetData, -} from "metabase-types/types/Dataset"; -import type { Field as FieldReference } from "metabase-types/types/Query"; - import StructuredQuery from "metabase-lib/lib/queries/StructuredQuery"; import Dimension, { AggregationDimension, FieldDimension, } from "metabase-lib/lib/Dimension"; -import type Question from "metabase-lib/lib/Question"; - -type ColumnSetting = { - name: ColumnName, - fieldRef?: FieldReference, - enabled: boolean, -}; -export const datasetContainsNoResults = (data: DatasetData): boolean => +export const datasetContainsNoResults = data => data.rows == null || data.rows.length === 0; /** * @returns min and max for a value in a column */ -export const rangeForValue = ( - value: Value, - column: ?Column, -): ?[number, number] => { +export const rangeForValue = (value, column) => { if (typeof value === "number" && column?.binning_info?.bin_width) { return [value, value + column.binning_info.bin_width]; } @@ -42,7 +24,7 @@ export const rangeForValue = ( * @param {Column} column Dataset result column * @return {?FieldReference} MBQL field reference */ -export function fieldRefForColumn(column: Column): ?FieldReference { +export function fieldRefForColumn(column) { // NOTE: matching existing behavior of returning the unwrapped base dimension until we understand the implications of changing this return ( column.field_ref && @@ -52,16 +34,12 @@ export function fieldRefForColumn(column: Column): ?FieldReference { ); } -export function fieldRefWithOption( - fieldRef: any, - key: string, - value: any, -): FieldReference { +export function fieldRefWithOption(fieldRef, key, value) { const dimension = FieldDimension.parseMBQLOrWarn(fieldRef); return dimension && dimension.withOption(key, value).mbql(); } -export const keyForColumn = (column: Column): string => { +export const keyForColumn = column => { let fieldRef = column.field_ref; if (!fieldRef) { console.error("column is missing field_ref", column); @@ -97,10 +75,7 @@ export const keyForColumn = (column: Column): string => { * @param {ColumnSetting} columnSetting A "column setting" from the `table.columns` settings * @return {?Column} A result column */ -export function findColumnForColumnSetting( - columns: Column[], - columnSetting: ColumnSetting, -): ?Column { +export function findColumnForColumnSetting(columns, columnSetting) { const index = findColumnIndexForColumnSetting(columns, columnSetting); if (index >= 0) { return columns[index]; @@ -109,15 +84,12 @@ export function findColumnForColumnSetting( } } -export function normalizeFieldRef(fieldRef: ?FieldReference): ?FieldReference { +export function normalizeFieldRef(fieldRef) { const dimension = Dimension.parseMBQL(fieldRef); return dimension && dimension.mbql(); } -export function findColumnIndexForColumnSetting( - columns: Column[], - columnSetting: ColumnSetting, -): number { +export function findColumnIndexForColumnSetting(columns, columnSetting) { // NOTE: need to normalize field refs because they may be old style [fk->, 1, 2] const fieldRef = normalizeFieldRef(columnSetting.fieldRef); // first try to find by fieldRef @@ -146,7 +118,7 @@ export function findColumnSettingIndexForColumn(columnSettings, column) { return index; } -export function syncTableColumnsToQuery(question: Question): Question { +export function syncTableColumnsToQuery(question) { let query = question.query(); const columnSettings = question.settings()["table.columns"]; if (columnSettings && query instanceof StructuredQuery) { diff --git a/frontend/src/metabase/lib/entities.js b/frontend/src/metabase/lib/entities.js index c9e84b6c4bf..94b3256dbdf 100644 --- a/frontend/src/metabase/lib/entities.js +++ b/frontend/src/metabase/lib/entities.js @@ -30,160 +30,10 @@ import _ from "underscore"; // schema: normalizr schema, defaults to `new schema.Entity(entity.name)` // -import type { APIMethod } from "metabase/lib/api"; -import type { FormDefinition } from "metabase/containers/Form"; - -type EntityName = string; - -type ActionType = string; -type ActionCreator = Function; -type ObjectActionCreator = Function; -type ObjectSelector = Function; - -type Action = any; -export type Reducer = (state: any, action: Action) => any; - -type EntityDefinition = { - name: EntityName, - - nameOne?: string, - nameMany?: string, - - form?: FormDefinition, - forms?: { [key: string]: FormDefinition }, - - displayNameOne?: string, - displayNameMany?: string, - - schema?: schema.Entity, - path?: string, - api?: { [method: string]: APIMethod }, - actions?: { - [name: string]: ActionCreator, - }, - selectors?: { - [name: string]: Function, - }, - createSelectors?: ({ [name: string]: Function }) => { - [name: string]: Function, - }, - objectActions?: { - [name: string]: ObjectActionCreator, - }, - objectSelectors?: { - [name: string]: ObjectSelector, - }, - reducer?: Reducer, - wrapEntity?: (object: EntityObject) => any, - actionShouldInvalidateLists?: (action: Action) => boolean, - - // list of properties for this object which should be persisted - writableProperties?: string[], -}; - -type EntityObject = any; - -type EntityQuery = { - [name: string]: string | number | boolean | null, -}; - -type FetchOptions = { - reload?: boolean, -}; -type UpdateOptions = { - notify?: - | { verb?: string, subject?: string, undo?: boolean, message?: any } - | false, -}; - -type Result = any; // FIXME - -export type Entity = { - name: EntityName, - - nameOne: string, - nameMany: string, - - displayNameOne: string, - displayNameMany: string, - - form?: FormDefinition, - forms?: { [key: string]: FormDefinition }, - - path?: string, - api: { - list: APIMethod, - create: APIMethod, - get: APIMethod, - update: APIMethod, - delete: APIMethod, - [method: string]: APIMethod, - }, - schema: schema.Entity, - actionTypes: { - [name: string]: ActionType, - CREATE: ActionType, - FETCH: ActionType, - UPDATE: ActionType, - DELETE: ActionType, - FETCH_LIST: ActionType, - }, - actionDecorators: { - [name: string]: Function, // TODO: better type - }, - actions: { - [name: string]: ActionCreator, - fetchList: ( - entityQuery?: EntityQuery, - options?: FetchOptions, - ) => Promise<Result>, - }, - reducers: { [name: string]: Reducer }, - selectors: { - getList: Function, - getObject: Function, - getLoading: Function, - getLoaded: Function, - getFetched: Function, - getError: Function, - [name: string]: Function, - }, - objectActions: { - [name: string]: ObjectActionCreator, - create: (entityObject: EntityObject) => Promise<Result>, - fetch: ( - entityObject: EntityObject, - options?: FetchOptions, - ) => Promise<Result>, - update: ( - entityObject: EntityObject, - updatedObject: EntityObject, - options?: UpdateOptions, - ) => Promise<Result>, - delete: (entityObject: EntityObject) => Promise<Result>, - }, - objectSelectors: { - [name: string]: ObjectSelector, - }, - wrapEntity: (object: EntityObject) => any, - - requestsReducer: Reducer, - actionShouldInvalidateLists: (action: Action) => boolean, - - writableProperties?: string[], - getAnalyticsMetadata?: () => any, - - normalize: (object: EntityObject, schema?: schema.Entity) => any, // FIXME: return type - normalizeList: (list: EntityObject[], schema?: schema.Entity) => any, // FIXME: return type - - getObjectStatePath: Function, - getListStatePath: Function, - - HACK_getObjectFromAction: (action: Action) => any, -}; - -export function createEntity(def: EntityDefinition): Entity { - const entity: Entity = { ...def }; +// FIXME + +export function createEntity(def) { + const entity = { ...def }; if (!entity.nameOne) { entity.nameOne = inflection.singularize(entity.name); @@ -660,7 +510,7 @@ export function createEntity(def: EntityDefinition): Entity { // dispatched using it, otherwise the actions will be returned // class EntityWrapper { - _dispatch: ?(action: any) => any; + _dispatch; constructor(object, dispatch = null) { Object.assign(this, object); @@ -700,14 +550,7 @@ export function createEntity(def: EntityDefinition): Entity { return entity; } -type CombinedEntities = { - entities: { [key: EntityName]: Entity }, - reducers: { [name: string]: Reducer }, - reducer: Reducer, - requestsReducer: Reducer, -}; - -export function combineEntities(entities: Entity[]): CombinedEntities { +export function combineEntities(entities) { const entitiesMap = {}; const reducersMap = {}; @@ -739,10 +582,10 @@ export function combineEntities(entities: Entity[]): CombinedEntities { // OBJECT ACTION DECORATORS -export const notify = (opts: any = {}, subject: string, verb: string) => +export const notify = (opts = {}, subject, verb) => merge({ notify: { subject, verb, undo: false } }, opts || {}); -export const undo = (opts: any = {}, subject: string, verb: string) => +export const undo = (opts = {}, subject, verb) => merge({ notify: { subject, verb, undo: true } }, opts || {}); // decorator versions disabled due to incompatibility with current version of flow diff --git a/frontend/src/metabase/lib/expressions/format.js b/frontend/src/metabase/lib/expressions/format.js index 9e39a9b649d..35267ead535 100644 --- a/frontend/src/metabase/lib/expressions/format.js +++ b/frontend/src/metabase/lib/expressions/format.js @@ -18,20 +18,11 @@ import { formatStringLiteral, hasOptions, } from "."; -import type StructuredQuery from "metabase-lib/lib/queries/StructuredQuery"; export { DISPLAY_QUOTES, EDITOR_QUOTES } from "./config"; -type QuotesConfig = {}; - -type FormatterOptions = { - query: StructuredQuery, - quotes: QuotesConfig, - parens: Boolean, -}; - // convert a MBQL expression back into an expression string -export function format(mbql: any, options: FormatterOptions = {}) { +export function format(mbql, options = {}) { if (mbql == null || _.isEqual(mbql, [])) { return ""; } else if (isNumberLiteral(mbql)) { diff --git a/frontend/src/metabase/lib/formatting.js b/frontend/src/metabase/lib/formatting.js index 6e9c2dafcf1..a7205a1dd3b 100644 --- a/frontend/src/metabase/lib/formatting.js +++ b/frontend/src/metabase/lib/formatting.js @@ -32,11 +32,6 @@ import { getDataFromClicked, } from "metabase/lib/click-behavior"; -import type { - DateStyle, - TimeEnabled, - TimeStyle, -} from "metabase/lib/formatting/date"; import { DEFAULT_DATE_STYLE, DEFAULT_TIME_STYLE, @@ -50,69 +45,13 @@ import { } from "metabase/lib/formatting/link"; import { NULL_DISPLAY_VALUE, NULL_NUMERIC_VALUE } from "metabase/lib/constants"; -import type Field from "metabase-lib/lib/metadata/Field"; -import type { Column, Value } from "metabase-types/types/Dataset"; -import type { DatetimeUnit } from "metabase-types/types/Query"; -import type { Moment } from "metabase-types/types"; -import type { ClickObject } from "metabase-types/types/Visualization"; - // a one or two character string specifying the decimal and grouping separator characters -export type NumberSeparators = ".," | ", " | ",." | "." | ".’"; // single character string specifying date separators -export type DateSeparator = "/" | "-" | "."; - -export type FormattingOptions = { - // GENERIC - column?: Column | Field, - majorWidth?: number, - type?: "axis" | "cell" | "tooltip", - jsx?: boolean, - remap?: boolean, - // render links for type/URLs, type/Email, etc - rich?: boolean, - compact?: boolean, - // always format as the start value rather than the range, e.x. for bar histogram - noRange?: boolean, - // NUMBER - // TODO: docoument these: - number_style?: null | "decimal" | "percent" | "scientific" | "currency", - prefix?: string, - suffix?: string, - scale?: number, - negativeInParentheses?: boolean, - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString - scale?: number, - number_separators?: NumberSeparators, - minimumFractionDigits?: number, - maximumFractionDigits?: number, - // decimals sets both minimumFractionDigits and maximumFractionDigits - decimals?: number, - // STRING - view_as?: null | "link" | "email_link" | "image" | "auto", - link_text?: string, - link_template?: string, - clicked?: ClickObject, - // DATE/TIME - // date/timeout style string that is used to derive a date_format or time_format for different units, see metabase/lib/formatting/date - date_style?: DateStyle, - date_separator?: DateSeparator, - date_abbreviate?: boolean, - date_format?: string, - time_style?: TimeStyle, - time_enabled?: TimeEnabled, - time_format?: string, - // display in local timezone or parsed timezone - local?: boolean, - // markdown template - markdown_template?: string, -}; - -type FormattedString = string | React.Element; export const FK_SYMBOL = "→"; -const DEFAULT_NUMBER_OPTIONS: FormattingOptions = { +const DEFAULT_NUMBER_OPTIONS = { compact: false, maximumFractionDigits: 2, }; @@ -151,7 +90,7 @@ const NUMBER_REGEX = /([\+\-])?[^0-9]*([0-9\., ]+)/; const DEFAULT_NUMBER_SEPARATORS = ".,"; -export function numberFormatterForOptions(options: FormattingOptions) { +export function numberFormatterForOptions(options) { options = { ...getDefaultNumberOptions(options), ...options }; // always use "en" locale so we have known number separators we can replace depending on number_separators option // TODO: if we do that how can we get localized currency names? @@ -169,7 +108,7 @@ export function numberFormatterForOptions(options: FormattingOptions) { }); } -export function formatNumber(number: number, options: FormattingOptions = {}) { +export function formatNumber(number, options = {}) { options = { ...getDefaultNumberOptions(options), ...options }; if (typeof options.scale === "number" && !isNaN(options.scale)) { @@ -243,10 +182,7 @@ export function formatNumber(number: number, options: FormattingOptions = {}) { } // replaces the decimale and grouping separators with those specified by a NumberSeparators option -function replaceNumberSeparators( - formatted: string, - separators: NumberSeparators, -) { +function replaceNumberSeparators(formatted, separators) { const [decimalSeparator, groupingSeparator] = (separators || ".,").split(""); const separatorMap = { @@ -257,10 +193,7 @@ function replaceNumberSeparators( return formatted.replace(/,|\./g, separator => separatorMap[separator]); } -function formatNumberScientific( - value: number, - options: FormattingOptions, -): FormattedString { +function formatNumberScientific(value, options) { if (options.maximumFractionDigits) { value = d3.round(value, options.maximumFractionDigits); } @@ -286,7 +219,7 @@ export const COMPACT_CURRENCY_OPTIONS = { currency_style: "symbol", }; -function formatNumberCompact(value: number, options: FormattingOptions) { +function formatNumberCompact(value, options) { if (options.number_style === "percent") { return formatNumberCompactWithoutOptions(value * 100) + "%"; } @@ -320,7 +253,7 @@ function formatNumberCompact(value: number, options: FormattingOptions) { return formatNumberCompactWithoutOptions(value); } -function formatNumberCompactWithoutOptions(value: number) { +function formatNumberCompactWithoutOptions(value) { if (value === 0) { // 0 => 0 return "0"; @@ -334,10 +267,7 @@ function formatNumberCompactWithoutOptions(value: number) { } } -export function formatCoordinate( - value: number, - options: FormattingOptions = {}, -) { +export function formatCoordinate(value, options = {}) { const binWidth = options.column && options.column.binning_info && @@ -359,11 +289,7 @@ export function formatCoordinate( return formattedValue + "°" + direction; } -export function formatRange( - range: [number, number], - formatter: (value: number) => any, - options: FormattingOptions = {}, -) { +export function formatRange(range, formatter, options = {}) { const [start, end] = range.map(value => formatter(value, options)); if ((options.jsx && typeof start !== "string") || typeof end !== "string") { return ( @@ -401,11 +327,7 @@ function formatMajorMinor(major, minor, options = {}) { } /** This formats a time with unit as a date range */ -export function formatDateTimeRangeWithUnit( - value: Value, - unit: DatetimeUnit, - options: FormattingOptions = {}, -) { +export function formatDateTimeRangeWithUnit(value, unit, options = {}) { const m = parseTimestamp(value, unit, options.local); if (!m.isValid()) { return String(value); @@ -452,7 +374,7 @@ export function formatDateTimeRangeWithUnit( } } -function formatWeek(m: Moment, options: FormattingOptions = {}) { +function formatWeek(m, options = {}) { return formatMajorMinor(m.format("wo"), m.format("gggg"), options); } @@ -490,11 +412,7 @@ function formatDateTime(value, options) { return formatDateTimeWithUnit(value, "minute", options); } -export function formatDateTimeWithUnit( - value: Value, - unit: DatetimeUnit, - options: FormattingOptions = {}, -) { +export function formatDateTimeWithUnit(value, unit, options = {}) { const m = parseTimestamp(value, unit, options.local); if (!m.isValid()) { return String(value); @@ -540,7 +458,7 @@ export function formatDateTimeWithUnit( return formatDateTimeWithFormats(m, dateFormat, timeFormat, options); } -export function formatTime(value: Value) { +export function formatTime(value) { const m = parseTime(value); if (!m.isValid()) { return String(value); @@ -549,11 +467,7 @@ export function formatTime(value: Value) { } } -export function formatTimeWithUnit( - value: Value, - unit: DatetimeUnit, - options: FormattingOptions = {}, -) { +export function formatTimeWithUnit(value, unit, options = {}) { const m = parseTimestamp(value, unit, options.local); if (!m.isValid()) { return String(value); @@ -580,8 +494,8 @@ export function formatTimeWithUnit( const EMAIL_ALLOW_LIST_REGEX = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/; export function formatEmail( - value: Value, - { jsx, rich, view_as = "auto", link_text, clicked }: FormattingOptions = {}, + value, + { jsx, rich, view_as = "auto", link_text, clicked } = {}, ) { const email = String(value); const label = @@ -691,8 +605,8 @@ export function formatUrl(value, options = {}) { } export function formatImage( - value: Value, - { jsx, rich, view_as = "auto", link_text }: FormattingOptions = {}, + value, + { jsx, rich, view_as = "auto", link_text } = {}, ) { const url = String(value); const protocol = getUrlProtocol(url); @@ -705,7 +619,7 @@ export function formatImage( } // fallback for formatting a string without a column semantic_type -function formatStringFallback(value: Value, options: FormattingOptions = {}) { +function formatStringFallback(value, options = {}) { if (options.view_as !== null) { value = formatUrl(value, options); if (typeof value === "string") { @@ -725,7 +639,7 @@ const MARKDOWN_RENDERERS = { ), }; -export function formatValue(value: Value, options: FormattingOptions = {}) { +export function formatValue(value, options = {}) { // avoid rendering <ExternalLink> if we have click_behavior set if ( options.click_behavior && @@ -782,10 +696,7 @@ export function formatValue(value: Value, options: FormattingOptions = {}) { } } -export function getRemappedValue( - value: Value, - { remap, column }: FormattingOptions = {}, -): ?string { +export function getRemappedValue(value, { remap, column } = {}) { if (remap && column) { if (column.hasRemappedValue && column.hasRemappedValue(value)) { return column.remappedValue(value); @@ -798,7 +709,7 @@ export function getRemappedValue( } } -export function formatValueRaw(value: Value, options: FormattingOptions = {}) { +export function formatValueRaw(value, options = {}) { options = { jsx: false, remap: true, @@ -883,7 +794,7 @@ export function formatValueRaw(value: Value, options: FormattingOptions = {}) { } } -export function formatColumn(column: Column): string { +export function formatColumn(column) { if (!column) { return ""; } else if (column.remapped_to_column != null) { @@ -898,7 +809,7 @@ export function formatColumn(column: Column): string { } } -export function formatField(field: Field): string { +export function formatField(field) { if (!field) { return ""; } else if (field.dimensions && field.dimensions.name) { @@ -937,7 +848,7 @@ export function humanize(...args) { return inflection.humanize(...args); } -export function conjunct(list: string[], conjunction: string) { +export function conjunct(list, conjunction) { return ( list.slice(0, -1).join(`, `) + (list.length > 2 ? `,` : ``) + @@ -946,7 +857,7 @@ export function conjunct(list: string[], conjunction: string) { ); } -export function duration(milliseconds: number) { +export function duration(milliseconds) { const SECOND = 1000; const MINUTE = 60 * SECOND; const HOUR = 60 * MINUTE; @@ -964,18 +875,18 @@ export function duration(milliseconds: number) { } // Removes trailing "id" from field names -export function stripId(name: string) { +export function stripId(name) { return name && name.replace(/ id$/i, "").trim(); } -export function slugify(name: string) { +export function slugify(name) { return name && encodeURIComponent(name.toLowerCase().replace(/\s/g, "_")); } export function assignUserColors( - userIds: number[], - currentUserId: number, - colorClasses: string[] = [ + userIds, + currentUserId, + colorClasses = [ "bg-brand", "bg-purple", "bg-error", @@ -1004,7 +915,7 @@ export function assignUserColors( return assignments; } -export function formatSQL(sql: string) { +export function formatSQL(sql) { if (typeof sql === "string") { sql = sql.replace(/\sFROM/, "\nFROM"); sql = sql.replace(/\sLEFT JOIN/, "\nLEFT JOIN"); diff --git a/frontend/src/metabase/lib/formatting/date.js b/frontend/src/metabase/lib/formatting/date.js index b4601aaab3f..d3f103062d3 100644 --- a/frontend/src/metabase/lib/formatting/date.js +++ b/frontend/src/metabase/lib/formatting/date.js @@ -1,26 +1,8 @@ import { parseTimestamp } from "metabase/lib/time"; -import type { DateSeparator } from "metabase/lib/formatting"; -import type { DatetimeUnit } from "metabase-types/types/Query"; +// moment.js format strings -export type DateStyle = - | "M/D/YYYY" - | "D/M/YYYY" - | "YYYY/M/D" - | "MMMM D, YYYY" - | "MMMM D, YYYY" - | "D MMMM, YYYY" - | "dddd, MMMM D, YYYY"; - -export type TimeStyle = "h:mm A" | "HH:mm" | "h A"; - -export type MomentFormat = string; // moment.js format strings -export type DateFormat = MomentFormat; -export type TimeFormat = MomentFormat; - -export type TimeEnabled = null | "minutes" | "seconds" | "milliseconds"; - -const DEFAULT_DATE_FORMATS: { [unit: DatetimeUnit]: MomentFormat } = { +const DEFAULT_DATE_FORMATS = { year: "YYYY", quarter: "[Q]Q - YYYY", "minute-of-hour": "m", @@ -33,9 +15,7 @@ const DEFAULT_DATE_FORMATS: { [unit: DatetimeUnit]: MomentFormat } = { }; // a "date style" is essentially a "day" format with overrides for larger units -const DATE_STYLE_TO_FORMAT: { - [style: DateStyle]: { [unit: DatetimeUnit]: MomentFormat }, -} = { +const DATE_STYLE_TO_FORMAT = { "M/D/YYYY": { month: "M/YYYY", }, @@ -58,13 +38,9 @@ const DATE_STYLE_TO_FORMAT: { }, }; -export const DEFAULT_DATE_STYLE: DateStyle = "MMMM D, YYYY"; +export const DEFAULT_DATE_STYLE = "MMMM D, YYYY"; -export function getDateFormatFromStyle( - style: DateStyle, - unit: ?DatetimeUnit, - separator?: DateSeparator, -): DateFormat { +export function getDateFormatFromStyle(style, unit, separator) { const replaceSeparators = format => separator && format ? format.replace(/\//g, separator) : format; @@ -84,35 +60,18 @@ export function getDateFormatFromStyle( return replaceSeparators(style); } -const UNITS_WITH_HOUR: DatetimeUnit[] = [ - "default", - "minute", - "hour", - "hour-of-day", -]; -const UNITS_WITH_DAY: DatetimeUnit[] = [ - "default", - "minute", - "hour", - "day", - "week", -]; +const UNITS_WITH_HOUR = ["default", "minute", "hour", "hour-of-day"]; +const UNITS_WITH_DAY = ["default", "minute", "hour", "day", "week"]; const UNITS_WITH_HOUR_SET = new Set(UNITS_WITH_HOUR); const UNITS_WITH_DAY_SET = new Set(UNITS_WITH_DAY); -export const hasHour = (unit: ?DatetimeUnit) => - unit == null || UNITS_WITH_HOUR_SET.has(unit); -export const hasDay = (unit: ?DatetimeUnit) => - unit == null || UNITS_WITH_DAY_SET.has(unit); +export const hasHour = unit => unit == null || UNITS_WITH_HOUR_SET.has(unit); +export const hasDay = unit => unit == null || UNITS_WITH_DAY_SET.has(unit); -export const DEFAULT_TIME_STYLE: TimeStyle = "h:mm A"; +export const DEFAULT_TIME_STYLE = "h:mm A"; -export function getTimeFormatFromStyle( - style: TimeStyle, - unit: DatetimeUnit, - timeEnabled: ?TimeEnabled, -): TimeFormat { +export function getTimeFormatFromStyle(style, unit, timeEnabled) { const format = style; if (!timeEnabled || timeEnabled === "milliseconds") { return format.replace(/mm/, "mm:ss.SSS"); diff --git a/frontend/src/metabase/lib/permissions.js b/frontend/src/metabase/lib/permissions.js index 24eb3c97250..3ada8b92ce5 100644 --- a/frontend/src/metabase/lib/permissions.js +++ b/frontend/src/metabase/lib/permissions.js @@ -1,13 +1,6 @@ import { getIn, setIn } from "icepick"; import _ from "underscore"; -import type { DatabaseId } from "metabase-types/types/Database"; -import type { SchemaName, TableId } from "metabase-types/types/Table"; - -import Metadata from "metabase-lib/lib/metadata/Metadata"; -import Database from "metabase-lib/lib/metadata/Database"; -import Table from "metabase-lib/lib/metadata/Table"; - import { PLUGIN_ADMIN_PERMISSIONS_TABLE_FIELDS_PERMISSION_VALUE, PLUGIN_ADVANCED_PERMISSIONS, @@ -16,27 +9,12 @@ import { export const isRestrictivePermission = value => PLUGIN_ADVANCED_PERMISSIONS.isBlockPermission(value) || value === "none"; -import type { - Group, - GroupId, - GroupsPermissions, -} from "metabase-types/types/Permissions"; - -type TableEntityId = { - databaseId: DatabaseId, - schemaName: SchemaName, - tableId: TableId, -}; -type SchemaEntityId = { databaseId: DatabaseId, schemaName: SchemaName }; -type DatabaseEntityId = { databaseId: DatabaseId }; -type EntityId = TableEntityId | SchemaEntityId | DatabaseEntityId; - export function getPermission( - permissions: GroupsPermissions, - groupId: GroupId, - path: Array<string | number>, - isControlledType: boolean = false, -): string { + permissions, + groupId, + path, + isControlledType = false, +) { const value = getIn(permissions, [groupId].concat(path)); if (isControlledType) { if (!value) { @@ -53,13 +31,7 @@ export function getPermission( } } -export function updatePermission( - permissions: GroupsPermissions, - groupId: GroupId, - path: Array<string | number>, - value: string, - entityIds: ?(Array<string> | Array<number>), -): GroupsPermissions { +export function updatePermission(permissions, groupId, path, value, entityIds) { const fullPath = [groupId].concat(path); const current = getIn(permissions, fullPath); if ( @@ -87,27 +59,19 @@ export function updatePermission( return setIn(permissions, fullPath, newValue); } -export const getSchemasPermission = ( - permissions: GroupsPermissions, - groupId: GroupId, - { databaseId }: DatabaseEntityId, -): string => { +export const getSchemasPermission = (permissions, groupId, { databaseId }) => { return getPermission(permissions, groupId, [databaseId, "schemas"], true); }; -export const getNativePermission = ( - permissions: GroupsPermissions, - groupId: GroupId, - { databaseId }: DatabaseEntityId, -): string => { +export const getNativePermission = (permissions, groupId, { databaseId }) => { return getPermission(permissions, groupId, [databaseId, "native"]); }; export const getTablesPermission = ( - permissions: GroupsPermissions, - groupId: GroupId, - { databaseId, schemaName }: SchemaEntityId, -): string => { + permissions, + groupId, + { databaseId, schemaName }, +) => { const schemas = getSchemasPermission(permissions, groupId, { databaseId }); if (schemas === "controlled") { return getPermission( @@ -122,10 +86,10 @@ export const getTablesPermission = ( }; export const getFieldsPermission = ( - permissions: GroupsPermissions, - groupId: GroupId, - { databaseId, schemaName, tableId }: TableEntityId, -): string => { + permissions, + groupId, + { databaseId, schemaName, tableId }, +) => { const tables = getTablesPermission(permissions, groupId, { databaseId, schemaName, @@ -143,12 +107,12 @@ export const getFieldsPermission = ( }; export function downgradeNativePermissionsIfNeeded( - permissions: GroupsPermissions, - groupId: GroupId, - { databaseId }: DatabaseEntityId, - value: string, - metadata: Metadata, -): GroupsPermissions { + permissions, + groupId, + { databaseId }, + value, + metadata, +) { const currentSchemas = getSchemasPermission(permissions, groupId, { databaseId, }); @@ -183,14 +147,14 @@ export function downgradeNativePermissionsIfNeeded( } } -const metadataTableToTableEntityId = (table: Table): TableEntityId => ({ +const metadataTableToTableEntityId = table => ({ databaseId: table.db_id, schemaName: table.schema_name || "", tableId: table.id, }); // TODO Atte Keinänen 6/24/17 See if this method could be simplified -const entityIdToMetadataTableFields = (entityId: EntityId) => ({ +const entityIdToMetadataTableFields = entityId => ({ ...(entityId.databaseId ? { db_id: entityId.databaseId } : {}), // Because schema name can be an empty string, which means an empty schema, this check becomes a little nasty ...(entityId.schemaName !== undefined @@ -200,15 +164,15 @@ const entityIdToMetadataTableFields = (entityId: EntityId) => ({ }); function inferEntityPermissionValueFromChildTables( - permissions: GroupsPermissions, - groupId: GroupId, - entityId: DatabaseEntityId | SchemaEntityId, - metadata: Metadata, + permissions, + groupId, + entityId, + metadata, ) { const { databaseId } = entityId; const database = metadata && metadata.database(databaseId); - const entityIdsForDescendantTables: TableEntityId[] = _.chain(database.tables) + const entityIdsForDescendantTables = _.chain(database.tables) .filter(t => _.isMatch(t, entityIdToMetadataTableFields(entityId))) .map(metadataTableToTableEntityId) .value(); @@ -232,10 +196,10 @@ function inferEntityPermissionValueFromChildTables( // Checks the child tables of a given entityId and updates the shared table and/or schema permission values according to table permissions // This method was added for keeping the UI in sync when modifying child permissions export function inferAndUpdateEntityPermissions( - permissions: GroupsPermissions, - groupId: GroupId, - entityId: DatabaseEntityId | SchemaEntityId, - metadata: Metadata, + permissions, + groupId, + entityId, + metadata, ) { const { databaseId } = entityId; const schemaName = entityId.schemaName || ""; @@ -285,12 +249,12 @@ export function inferAndUpdateEntityPermissions( } export function updateFieldsPermission( - permissions: GroupsPermissions, - groupId: GroupId, - entityId: TableEntityId, - value: string, - metadata: Metadata, -): GroupsPermissions { + permissions, + groupId, + entityId, + value, + metadata, +) { const { databaseId, tableId } = entityId; const schemaName = entityId.schemaName || ""; @@ -312,12 +276,12 @@ export function updateFieldsPermission( } export function updateTablesPermission( - permissions: GroupsPermissions, - groupId: GroupId, - { databaseId, schemaName }: SchemaEntityId, - value: string, - metadata: Metadata, -): GroupsPermissions { + permissions, + groupId, + { databaseId, schemaName }, + value, + metadata, +) { const schema = metadata && metadata.database(databaseId).schema(schemaName); const tableIds = schema && schema.tables.map(t => t.id); @@ -340,12 +304,12 @@ export function updateTablesPermission( } export function updateSchemasPermission( - permissions: GroupsPermissions, - groupId: GroupId, - { databaseId }: DatabaseEntityId, - value: string, - metadata: Metadata, -): GroupsPermissions { + permissions, + groupId, + { databaseId }, + value, + metadata, +) { const database = metadata.database(databaseId); const schemaNames = database && database.schemaNames(); const schemaNamesOrNoSchema = @@ -372,12 +336,12 @@ export function updateSchemasPermission( } export function updateNativePermission( - permissions: GroupsPermissions, - groupId: GroupId, - { databaseId }: DatabaseEntityId, - value: string, - metadata: Metadata, -): GroupsPermissions { + permissions, + groupId, + { databaseId }, + value, + metadata, +) { // if enabling native query write access, give access to all schemas since they are equivalent if (value === "write") { permissions = updateSchemasPermission( @@ -391,47 +355,14 @@ export function updateNativePermission( return updatePermission(permissions, groupId, [databaseId, "native"], value); } -type PermissionsDiff = { - groups: { - [key: GroupId]: GroupPermissionsDiff, - }, -}; - -type GroupPermissionsDiff = { - name?: string, - databases: { - [key: DatabaseId]: DatabasePermissionsDiff, - }, -}; - -type DatabasePermissionsDiff = { - name?: string, - native?: string, - revokedTables: { - [key: TableId]: TablePermissionsDiff, - }, - grantedTables: { - [key: TableId]: TablePermissionsDiff, - }, -}; - -type TablePermissionsDiff = { - name?: string, -}; - -function deleteIfEmpty(object: { [key: any]: any }, key: any) { +function deleteIfEmpty(object, key) { if (Object.keys(object[key]).length === 0) { delete object[key]; } } -function diffDatabasePermissions( - newPerms: GroupsPermissions, - oldPerms: GroupsPermissions, - groupId: GroupId, - database: Database, -): DatabasePermissionsDiff { - const databaseDiff: DatabasePermissionsDiff = { +function diffDatabasePermissions(newPerms, oldPerms, groupId, database) { + const databaseDiff = { grantedTables: {}, revokedTables: {}, }; @@ -472,13 +403,8 @@ function diffDatabasePermissions( return databaseDiff; } -function diffGroupPermissions( - newPerms: GroupsPermissions, - oldPerms: GroupsPermissions, - groupId: GroupId, - databases: Array<Object>, -): GroupPermissionsDiff { - const groupDiff: GroupPermissionsDiff = { databases: {} }; +function diffGroupPermissions(newPerms, oldPerms, groupId, databases) { + const groupDiff = { databases: {} }; for (const database of databases) { groupDiff.databases[database.id] = diffDatabasePermissions( newPerms, @@ -495,13 +421,8 @@ function diffGroupPermissions( return groupDiff; } -export function diffDataPermissions( - newPerms: GroupsPermissions, - oldPerms: GroupsPermissions, - groups: Array<Group>, - databases: Array<Object>, -): PermissionsDiff { - const permissionsDiff: PermissionsDiff = { groups: {} }; +export function diffDataPermissions(newPerms, oldPerms, groups, databases) { + const permissionsDiff = { groups: {} }; if (newPerms && oldPerms && databases) { for (const group of groups) { permissionsDiff.groups[group.id] = diffGroupPermissions( diff --git a/frontend/src/metabase/lib/query/aggregation.js b/frontend/src/metabase/lib/query/aggregation.js index 3bfaae4d033..1a2551d12cc 100644 --- a/frontend/src/metabase/lib/query/aggregation.js +++ b/frontend/src/metabase/lib/query/aggregation.js @@ -4,25 +4,14 @@ import { STANDARD_AGGREGATIONS } from "metabase/lib/expressions"; import _ from "underscore"; -import type { - AggregationClause, - Aggregation, - AggregationWithOptions, - AggregationOptions, - ConcreteField, -} from "metabase-types/types/Query"; -import type { MetricId } from "metabase-types/types/Metric"; - // returns canonical list of Aggregations, i.e. with deprecated "rows" removed -export function getAggregations( - aggregation: ?AggregationClause, -): Aggregation[] { - let aggregations: Aggregation[]; +export function getAggregations(aggregation) { + let aggregations; if (Array.isArray(aggregation) && Array.isArray(aggregation[0])) { - aggregations = (aggregation: any); + aggregations = aggregation; } else if (Array.isArray(aggregation) && typeof aggregation[0] === "string") { // legacy - aggregations = [(aggregation: any)]; + aggregations = [aggregation]; } else { aggregations = []; } @@ -30,7 +19,7 @@ export function getAggregations( } // turns a list of Aggregations into the canonical AggregationClause -function getAggregationClause(aggregations: Aggregation[]): ?AggregationClause { +function getAggregationClause(aggregations) { aggregations = getAggregations(aggregations); if (aggregations.length === 0) { return undefined; @@ -39,44 +28,34 @@ function getAggregationClause(aggregations: Aggregation[]): ?AggregationClause { } } -export function addAggregation( - aggregation: ?AggregationClause, - newAggregation: Aggregation, -): ?AggregationClause { +export function addAggregation(aggregation, newAggregation) { return getAggregationClause( add(getAggregations(aggregation), newAggregation), ); } -export function updateAggregation( - aggregation: ?AggregationClause, - index: number, - updatedAggregation: Aggregation, -): ?AggregationClause { +export function updateAggregation(aggregation, index, updatedAggregation) { return getAggregationClause( update(getAggregations(aggregation), index, updatedAggregation), ); } -export function removeAggregation( - aggregation: ?AggregationClause, - index: number, -): ?AggregationClause { +export function removeAggregation(aggregation, index) { return getAggregationClause(remove(getAggregations(aggregation), index)); } -export function clearAggregations(ac: ?AggregationClause): ?AggregationClause { +export function clearAggregations(ac) { return getAggregationClause(clear()); } // MISC -export function isBareRows(ac: ?AggregationClause) { +export function isBareRows(ac) { return getAggregations(ac).length === 0; } -export function hasEmptyAggregation(ac: ?AggregationClause): boolean { +export function hasEmptyAggregation(ac) { return _.any(getAggregations(ac), aggregation => !noNullValues(aggregation)); } -export function hasValidAggregation(ac: ?AggregationClause): boolean { +export function hasValidAggregation(ac) { return _.all(getAggregations(ac), aggregation => noNullValues(aggregation)); } @@ -84,7 +63,7 @@ export function hasValidAggregation(ac: ?AggregationClause): boolean { // NOTE: these only differentiate between "standard", "metric", and "custom", but do not validate the aggregation -export function isStandard(aggregation: any): boolean { +export function isStandard(aggregation) { return ( Array.isArray(aggregation) && STANDARD_AGGREGATIONS.has(aggregation[0]) && @@ -94,50 +73,44 @@ export function isStandard(aggregation: any): boolean { ); } -export function isMetric(aggregation: any): boolean { +export function isMetric(aggregation) { return Array.isArray(aggregation) && aggregation[0] === "metric"; } -export function isCustom(aggregation: any): boolean { +export function isCustom(aggregation) { return !isStandard(aggregation) && !isMetric(aggregation); } // AGGREGATION OPTIONS / NAMED AGGREGATIONS -export function hasOptions(aggregation: any): boolean { +export function hasOptions(aggregation) { return Array.isArray(aggregation) && aggregation[0] === "aggregation-options"; } -export function getOptions(aggregation: any): AggregationOptions { +export function getOptions(aggregation) { return hasOptions(aggregation) && aggregation[2] ? aggregation[2] : {}; } -export function getContent(aggregation: any): Aggregation { +export function getContent(aggregation) { return hasOptions(aggregation) ? aggregation[1] : aggregation; } -export function isNamed(aggregation: any): boolean { +export function isNamed(aggregation) { return !!getName(aggregation); } -export function getName(aggregation: any): ?string { +export function getName(aggregation) { return getOptions(aggregation)["display-name"]; } -export function setName( - aggregation: any, - name: string, -): AggregationWithOptions { +export function setName(aggregation, name) { return [ "aggregation-options", getContent(aggregation), { name, "display-name": name, ...getOptions(aggregation) }, ]; } -export function setContent( - aggregation: any, - content: Aggregation, -): AggregationWithOptions { +export function setContent(aggregation, content) { return ["aggregation-options", content, getOptions(aggregation)]; } // METRIC -export function getMetric(aggregation: any): ?MetricId { +export function getMetric(aggregation) { if (isMetric(aggregation)) { return aggregation[1]; } else { @@ -148,7 +121,7 @@ export function getMetric(aggregation: any): ?MetricId { // STANDARD // get the operator from a standard aggregation clause -export function getOperator(aggregation: any) { +export function getOperator(aggregation) { if (isStandard(aggregation)) { return aggregation[0]; } else { @@ -157,7 +130,7 @@ export function getOperator(aggregation: any) { } // get the fieldId from a standard aggregation clause -export function getField(aggregation: any): ?ConcreteField { +export function getField(aggregation) { if (isStandard(aggregation)) { return aggregation[1]; } else { @@ -166,7 +139,7 @@ export function getField(aggregation: any): ?ConcreteField { } // set the fieldId on a standard aggregation clause -export function setField(aggregation: any, fieldRef: ConcreteField) { +export function setField(aggregation, fieldRef) { if (isStandard(aggregation)) { return [aggregation[0], fieldRef]; } else { diff --git a/frontend/src/metabase/lib/query/breakout.js b/frontend/src/metabase/lib/query/breakout.js index e7342b225fa..7696830b97b 100644 --- a/frontend/src/metabase/lib/query/breakout.js +++ b/frontend/src/metabase/lib/query/breakout.js @@ -1,14 +1,12 @@ -import type { Breakout, BreakoutClause } from "metabase-types/types/Query"; - import { add, update, remove, clear } from "./util"; // returns canonical list of Breakouts, with nulls removed -export function getBreakouts(breakouts: ?BreakoutClause): Breakout[] { +export function getBreakouts(breakouts) { return (breakouts || []).filter(b => b != null); } // turns a list of Breakouts into the canonical BreakoutClause -export function getBreakoutClause(breakouts: Breakout[]): ?BreakoutClause { +export function getBreakoutClause(breakouts) { breakouts = getBreakouts(breakouts); if (breakouts.length === 0) { return undefined; @@ -17,27 +15,17 @@ export function getBreakoutClause(breakouts: Breakout[]): ?BreakoutClause { } } -export function addBreakout( - breakout: ?BreakoutClause, - newBreakout: Breakout, -): ?BreakoutClause { +export function addBreakout(breakout, newBreakout) { return getBreakoutClause(add(getBreakouts(breakout), newBreakout)); } -export function updateBreakout( - breakout: ?BreakoutClause, - index: number, - updatedBreakout: Breakout, -): ?BreakoutClause { +export function updateBreakout(breakout, index, updatedBreakout) { return getBreakoutClause( update(getBreakouts(breakout), index, updatedBreakout), ); } -export function removeBreakout( - breakout: ?BreakoutClause, - index: number, -): ?BreakoutClause { +export function removeBreakout(breakout, index) { return getBreakoutClause(remove(getBreakouts(breakout), index)); } -export function clearBreakouts(breakout: ?BreakoutClause): ?BreakoutClause { +export function clearBreakouts(breakout) { return getBreakoutClause(clear()); } diff --git a/frontend/src/metabase/lib/query/expression.js b/frontend/src/metabase/lib/query/expression.js index a4f21c0fb3e..bef06e27d3a 100644 --- a/frontend/src/metabase/lib/query/expression.js +++ b/frontend/src/metabase/lib/query/expression.js @@ -1,53 +1,29 @@ import _ from "underscore"; -import type { - ExpressionName, - ExpressionClause, - Expression, -} from "metabase-types/types/Query"; - -export function getExpressions( - expressions: ?ExpressionClause = {}, -): ExpressionClause { +export function getExpressions(expressions = {}) { return expressions; } -export function getExpressionsList( - expressions: ?ExpressionClause = {}, -): Array<{ name: ExpressionName, expression: Expression }> { +export function getExpressionsList(expressions = {}) { return Object.entries(expressions).map(([name, expression]) => ({ name, expression, })); } -export function addExpression( - expressions: ?ExpressionClause = {}, - name: ExpressionName, - expression: Expression, -): ?ExpressionClause { +export function addExpression(expressions = {}, name, expression) { return { ...expressions, [name]: expression }; } -export function updateExpression( - expressions: ?ExpressionClause = {}, - name: ExpressionName, - expression: Expression, - oldName?: ExpressionName, -): ?ExpressionClause { +export function updateExpression(expressions = {}, name, expression, oldName) { if (oldName != null) { expressions = removeExpression(expressions, oldName); } return addExpression(expressions, name, expression); } -export function removeExpression( - expressions: ?ExpressionClause = {}, - name: ExpressionName, -): ?ExpressionClause { +export function removeExpression(expressions = {}, name) { return _.omit(expressions, name); } -export function clearExpressions( - expressions: ?ExpressionClause, -): ?ExpressionClause { +export function clearExpressions(expressions) { return {}; } diff --git a/frontend/src/metabase/lib/query/field.js b/frontend/src/metabase/lib/query/field.js index 661cd05ae22..cd4befc74bc 100644 --- a/frontend/src/metabase/lib/query/field.js +++ b/frontend/src/metabase/lib/query/field.js @@ -1,21 +1,14 @@ import _ from "underscore"; -import type { - Field as FieldReference, - FieldsClause, -} from "metabase-types/types/Query"; -import type { Field, FieldValues } from "metabase-types/types/Field"; -import type { Value } from "metabase-types/types/Dataset"; - import { add, update, remove, clear } from "./util"; // returns canonical list of Fields, with nulls removed -export function getFields(fields: ?FieldsClause): FieldReference[] { +export function getFields(fields) { return (fields || []).filter(b => b != null); } // turns a list of Fields into the canonical FieldClause -export function getFieldClause(fields: FieldReference[]): ?FieldsClause { +export function getFieldClause(fields) { fields = getFields(fields); if (fields.length === 0) { return undefined; @@ -24,32 +17,22 @@ export function getFieldClause(fields: FieldReference[]): ?FieldsClause { } } -export function addField( - fields: ?FieldsClause, - newField: FieldReference, -): ?FieldsClause { +export function addField(fields, newField) { return getFieldClause(add(getFields(fields), newField)); } -export function updateField( - fields: ?FieldsClause, - index: number, - updatedField: FieldReference, -): ?FieldsClause { +export function updateField(fields, index, updatedField) { return getFieldClause(update(getFields(fields), index, updatedField)); } -export function removeField( - fields: ?FieldsClause, - index: number, -): ?FieldsClause { +export function removeField(fields, index) { return getFieldClause(remove(getFields(fields), index)); } -export function clearFields(fields: ?FieldsClause): ?FieldsClause { +export function clearFields(fields) { return getFieldClause(clear()); } // Metadata field "values" type is inconsistent // https://github.com/metabase/metabase/issues/3417 -export function getFieldValues(field: ?Field): FieldValues { +export function getFieldValues(field) { const values = field && field.values; if (Array.isArray(values)) { if (values.length === 0 || Array.isArray(values[0])) { @@ -77,16 +60,13 @@ export function getFieldValues(field: ?Field): FieldValues { } // merge field values and remappings -export function getRemappings(field: ?Field) { +export function getRemappings(field) { const remappings = (field && field.remappings) || []; const fieldValues = getFieldValues(field); return [...fieldValues, ...remappings]; } -export function getHumanReadableValue( - value: Value, - fieldValues?: FieldValues = [], -) { +export function getHumanReadableValue(value, fieldValues = []) { const fieldValue = _.findWhere(fieldValues, { [0]: value }); return fieldValue && fieldValue.length === 2 ? fieldValue[1] : String(value); } diff --git a/frontend/src/metabase/lib/query/field_ref.js b/frontend/src/metabase/lib/query/field_ref.js index 18308e65975..0ddb786be73 100644 --- a/frontend/src/metabase/lib/query/field_ref.js +++ b/frontend/src/metabase/lib/query/field_ref.js @@ -5,17 +5,16 @@ import { FieldDimension } from "metabase-lib/lib/Dimension"; import * as Table from "./table"; import { TYPE } from "metabase/lib/types"; -import type { FieldId, FieldReference } from "metabase-types/types/Query"; -export function isLocalField(field: FieldReference): boolean { +export function isLocalField(field) { return Array.isArray(field) && field[0] === "field"; } -export function isExpressionField(field: FieldReference): boolean { +export function isExpressionField(field) { return Array.isArray(field) && field[0] === "expression"; } -export function isAggregateField(field: FieldReference): boolean { +export function isAggregateField(field) { return Array.isArray(field) && field[0] === "aggregation"; } @@ -39,7 +38,7 @@ export function isSameField(fieldA, fieldB, exact = false) { * Get the target field ID (recursively) from a Field clause. For Field clauses that use string Field names, this * returns the Field clause directly. FIXME !!! */ -export function getFieldTargetId(field: FieldReference): ?FieldId { +export function getFieldTargetId(field) { if (isLocalField(field)) { const type = typeof field[1]; return type === "number" || type === "string" ? field[1] : field; diff --git a/frontend/src/metabase/lib/query/filter.js b/frontend/src/metabase/lib/query/filter.js index daebd551dec..af6f1d871d1 100644 --- a/frontend/src/metabase/lib/query/filter.js +++ b/frontend/src/metabase/lib/query/filter.js @@ -10,14 +10,8 @@ import { STRING, getOperatorByTypeAndName } from "metabase/lib/schema_metadata"; import _ from "underscore"; -import type { - FilterClause, - Filter, - FilterOptions, -} from "metabase-types/types/Query"; - // returns canonical list of Filters -export function getFilters(filter: ?FilterClause): Filter[] { +export function getFilters(filter) { if (!filter || (Array.isArray(filter) && filter.length === 0)) { return []; } else if (op(filter) === "and") { @@ -28,42 +22,32 @@ export function getFilters(filter: ?FilterClause): Filter[] { } // turns a list of Filters into the canonical FilterClause, either `undefined`, `filter`, or `["and", filter...]` -function getFilterClause(filters: Filter[]): ?FilterClause { +function getFilterClause(filters) { if (filters.length === 0) { return undefined; } else if (filters.length === 1) { return filters[0]; } else { - return (["and", ...filters]: any); + return ["and", ...filters]; } } -export function addFilter( - filter: ?FilterClause, - newFilter: FilterClause, -): ?FilterClause { +export function addFilter(filter, newFilter) { return getFilterClause(add(getFilters(filter), newFilter)); } -export function updateFilter( - filter: ?FilterClause, - index: number, - updatedFilter: FilterClause, -): ?FilterClause { +export function updateFilter(filter, index, updatedFilter) { return getFilterClause(update(getFilters(filter), index, updatedFilter)); } -export function removeFilter( - filter: ?FilterClause, - index: number, -): ?FilterClause { +export function removeFilter(filter, index) { return getFilterClause(remove(getFilters(filter), index)); } -export function clearFilters(filter: ?FilterClause): ?FilterClause { +export function clearFilters(filter) { return getFilterClause(clear()); } // MISC -export function canAddFilter(filter: ?FilterClause): boolean { +export function canAddFilter(filter) { const filters = getFilters(filter); if (filters.length > 0) { return noNullValues(filters[filters.length - 1]); @@ -73,7 +57,7 @@ export function canAddFilter(filter: ?FilterClause): boolean { // FILTER TYPES -export function isStandard(filter: FilterClause): boolean { +export function isStandard(filter) { if (!Array.isArray(filter)) { return false; } @@ -106,29 +90,29 @@ export function isStandard(filter: FilterClause): boolean { ); } -export function isSegment(filter: FilterClause): boolean { +export function isSegment(filter) { return Array.isArray(filter) && filter[0] === "segment"; } -export function isCustom(filter: FilterClause): boolean { +export function isCustom(filter) { return !isStandard(filter) && !isSegment(filter); } -export function isFieldFilter(filter: FilterClause): boolean { +export function isFieldFilter(filter) { return !isSegment(filter) && isValidField(filter[1]); } // FILTER OPTIONS // TODO: is it safe to assume if the last item is an object then it's options? -export function hasFilterOptions(filter: Filter): boolean { +export function hasFilterOptions(filter) { const o = filter[filter.length - 1]; return !!o && typeof o == "object" && o.constructor === Object; } -export function getFilterOptions(filter: Filter): FilterOptions { +export function getFilterOptions(filter) { // NOTE: just make a new "any" variable since getting flow to type checking this is a nightmare - const _filter: any = filter; + const _filter = filter; if (hasFilterOptions(filter)) { return _filter[_filter.length - 1]; } else { @@ -136,12 +120,9 @@ export function getFilterOptions(filter: Filter): FilterOptions { } } -export function setFilterOptions<T: Filter>( - filter: T, - options: FilterOptions, -): T { +export function setFilterOptions(filter, options) { // NOTE: just make a new "any" variable since getting flow to type checking this is a nightmare - let _filter: any = filter; + let _filter = filter; // if we have option, strip it off for now if (hasFilterOptions(filter)) { _filter = _filter.slice(0, -1); diff --git a/frontend/src/metabase/lib/query/join.js b/frontend/src/metabase/lib/query/join.js index 15e86f419c5..5cc7dc88c03 100644 --- a/frontend/src/metabase/lib/query/join.js +++ b/frontend/src/metabase/lib/query/join.js @@ -1,14 +1,12 @@ -import type { Join, JoinClause } from "metabase-types/types/Query"; - import { add, update, remove, clear } from "./util"; // returns canonical list of Joins, with nulls removed -export function getJoins(joins: ?JoinClause): Join[] { +export function getJoins(joins) { return (joins || []).filter(b => b != null); } // turns a list of Joins into the canonical JoinClause -export function getJoinClause(joins: Join[]): ?JoinClause { +export function getJoinClause(joins) { joins = getJoins(joins); if (joins.length === 0) { return undefined; @@ -17,19 +15,15 @@ export function getJoinClause(joins: Join[]): ?JoinClause { } } -export function addJoin(join: ?JoinClause, newJoin: Join): ?JoinClause { +export function addJoin(join, newJoin) { return getJoinClause(add(getJoins(join), newJoin)); } -export function updateJoin( - join: ?JoinClause, - index: number, - updatedJoin: Join, -): ?JoinClause { +export function updateJoin(join, index, updatedJoin) { return getJoinClause(update(getJoins(join), index, updatedJoin)); } -export function removeJoin(join: ?JoinClause, index: number): ?JoinClause { +export function removeJoin(join, index) { return getJoinClause(remove(getJoins(join), index)); } -export function clearJoins(join: ?JoinClause): ?JoinClause { +export function clearJoins(join) { return getJoinClause(clear()); } diff --git a/frontend/src/metabase/lib/query/limit.js b/frontend/src/metabase/lib/query/limit.js index fc34c45d02a..cc1409d6127 100644 --- a/frontend/src/metabase/lib/query/limit.js +++ b/frontend/src/metabase/lib/query/limit.js @@ -1,13 +1,11 @@ -import type { LimitClause } from "metabase-types/types/Query"; - -export function getLimit(lc: ?LimitClause): ?number { +export function getLimit(lc) { return lc; } -export function updateLimit(lc: ?LimitClause, limit: ?number): ?LimitClause { +export function updateLimit(lc, limit) { return limit; } -export function clearLimit(lc: ?LimitClause): ?LimitClause { +export function clearLimit(lc) { return undefined; } diff --git a/frontend/src/metabase/lib/query/order_by.js b/frontend/src/metabase/lib/query/order_by.js index fbf9d0ed008..309ede2ba25 100644 --- a/frontend/src/metabase/lib/query/order_by.js +++ b/frontend/src/metabase/lib/query/order_by.js @@ -1,14 +1,12 @@ -import type { OrderBy, OrderByClause } from "metabase-types/types/Query"; - import { add, update, remove, clear } from "./util"; // returns canonical list of OrderBys, with nulls removed -export function getOrderBys(breakout: ?OrderByClause): OrderBy[] { +export function getOrderBys(breakout) { return (breakout || []).filter(b => b != null); } // turns a list of OrderBys into the canonical OrderByClause -export function getOrderByClause(breakouts: OrderBy[]): ?OrderByClause { +export function getOrderByClause(breakouts) { breakouts = getOrderBys(breakouts); if (breakouts.length === 0) { return undefined; @@ -17,25 +15,15 @@ export function getOrderByClause(breakouts: OrderBy[]): ?OrderByClause { } } -export function addOrderBy( - breakout: ?OrderByClause, - newOrderBy: OrderBy, -): ?OrderByClause { +export function addOrderBy(breakout, newOrderBy) { return getOrderByClause(add(getOrderBys(breakout), newOrderBy)); } -export function updateOrderBy( - breakout: ?OrderByClause, - index: number, - updatedOrderBy: OrderBy, -): ?OrderByClause { +export function updateOrderBy(breakout, index, updatedOrderBy) { return getOrderByClause(update(getOrderBys(breakout), index, updatedOrderBy)); } -export function removeOrderBy( - breakout: ?OrderByClause, - index: number, -): ?OrderByClause { +export function removeOrderBy(breakout, index) { return getOrderByClause(remove(getOrderBys(breakout), index)); } -export function clearOrderBy(breakout: ?OrderByClause): ?OrderByClause { +export function clearOrderBy(breakout) { return getOrderByClause(clear()); } diff --git a/frontend/src/metabase/lib/query/query.js b/frontend/src/metabase/lib/query/query.js index 3fa567e0db1..85931dae778 100644 --- a/frontend/src/metabase/lib/query/query.js +++ b/frontend/src/metabase/lib/query/query.js @@ -1,23 +1,3 @@ -import type { - StructuredQuery as SQ, - Aggregation, - AggregationClause, - Breakout, - BreakoutClause, - Filter, - FilterClause, - LimitClause, - OrderBy, - OrderByClause, - JoinClause, - Join, - ExpressionClause, - ExpressionName, - Expression, - Field, - FieldsClause, -} from "metabase-types/types/Query"; - import * as A from "./aggregation"; import * as B from "./breakout"; import * as F from "./filter"; @@ -30,135 +10,117 @@ import * as FIELD_REF from "./field_ref"; // AGGREGATION -export const getAggregations = (query: SQ) => - A.getAggregations(query.aggregation); -export const addAggregation = (query: SQ, aggregation: Aggregation) => +export const getAggregations = query => A.getAggregations(query.aggregation); +export const addAggregation = (query, aggregation) => setAggregationClause(query, A.addAggregation(query.aggregation, aggregation)); -export const updateAggregation = ( - query: SQ, - index: number, - aggregation: Aggregation, -) => +export const updateAggregation = (query, index, aggregation) => setAggregationClause( query, A.updateAggregation(query.aggregation, index, aggregation), ); -export const removeAggregation = (query: SQ, index: number) => +export const removeAggregation = (query, index) => setAggregationClause(query, A.removeAggregation(query.aggregation, index)); -export const clearAggregations = (query: SQ) => +export const clearAggregations = query => setAggregationClause(query, A.clearAggregations(query.aggregation)); -export const isBareRows = (query: SQ) => A.isBareRows(query.aggregation); -export const hasEmptyAggregation = (query: SQ) => +export const isBareRows = query => A.isBareRows(query.aggregation); +export const hasEmptyAggregation = query => A.hasEmptyAggregation(query.aggregation); -export const hasValidAggregation = (query: SQ) => +export const hasValidAggregation = query => A.hasValidAggregation(query.aggregation); // BREAKOUT -export const getBreakouts = (query: SQ) => B.getBreakouts(query.breakout); -export const addBreakout = (query: SQ, breakout: Breakout) => +export const getBreakouts = query => B.getBreakouts(query.breakout); +export const addBreakout = (query, breakout) => setBreakoutClause(query, B.addBreakout(query.breakout, breakout)); -export const updateBreakout = (query: SQ, index: number, breakout: Breakout) => +export const updateBreakout = (query, index, breakout) => setBreakoutClause(query, B.updateBreakout(query.breakout, index, breakout)); -export const removeBreakout = (query: SQ, index: number) => +export const removeBreakout = (query, index) => setBreakoutClause(query, B.removeBreakout(query.breakout, index)); -export const clearBreakouts = (query: SQ) => +export const clearBreakouts = query => setBreakoutClause(query, B.clearBreakouts(query.breakout)); // FILTER -export const getFilters = (query: SQ) => F.getFilters(query.filter); -export const addFilter = (query: SQ, filter: Filter) => +export const getFilters = query => F.getFilters(query.filter); +export const addFilter = (query, filter) => setFilterClause(query, F.addFilter(query.filter, filter)); -export const updateFilter = (query: SQ, index: number, filter: Filter) => +export const updateFilter = (query, index, filter) => setFilterClause(query, F.updateFilter(query.filter, index, filter)); -export const removeFilter = (query: SQ, index: number) => +export const removeFilter = (query, index) => setFilterClause(query, F.removeFilter(query.filter, index)); -export const clearFilters = (query: SQ) => +export const clearFilters = query => setFilterClause(query, F.clearFilters(query.filter)); -export const canAddFilter = (query: SQ) => F.canAddFilter(query.filter); +export const canAddFilter = query => F.canAddFilter(query.filter); // JOIN -export const getJoins = (query: SQ) => J.getJoins(query.joins); -export const addJoin = (query: SQ, join: Join) => +export const getJoins = query => J.getJoins(query.joins); +export const addJoin = (query, join) => setJoinClause(query, J.addJoin(query.joins, join)); -export const updateJoin = (query: SQ, index: number, join: Join) => +export const updateJoin = (query, index, join) => setJoinClause(query, J.updateJoin(query.joins, index, join)); -export const removeJoin = (query: SQ, index: number) => +export const removeJoin = (query, index) => setJoinClause(query, J.removeJoin(query.joins, index)); -export const clearJoins = (query: SQ) => +export const clearJoins = query => setJoinClause(query, J.clearJoins(query.joins)); // ORDER_BY -export const getOrderBys = (query: SQ) => O.getOrderBys(query["order-by"]); -export const addOrderBy = (query: SQ, orderBy: OrderBy) => +export const getOrderBys = query => O.getOrderBys(query["order-by"]); +export const addOrderBy = (query, orderBy) => setOrderByClause(query, O.addOrderBy(query["order-by"], orderBy)); -export const updateOrderBy = (query: SQ, index: number, orderBy: OrderBy) => +export const updateOrderBy = (query, index, orderBy) => setOrderByClause(query, O.updateOrderBy(query["order-by"], index, orderBy)); -export const removeOrderBy = (query: SQ, index: number) => +export const removeOrderBy = (query, index) => setOrderByClause(query, O.removeOrderBy(query["order-by"], index)); -export const clearOrderBy = (query: SQ) => +export const clearOrderBy = query => setOrderByClause(query, O.clearOrderBy(query["order-by"])); // FIELD -export const getFields = (query: SQ) => FIELD.getFields(query.fields); -export const addField = (query: SQ, field: Field) => +export const getFields = query => FIELD.getFields(query.fields); +export const addField = (query, field) => setFieldsClause(query, FIELD.addField(query.fields, field)); -export const updateField = (query: SQ, index: number, field: Field) => +export const updateField = (query, index, field) => setFieldsClause(query, FIELD.updateField(query.fields, index, field)); -export const removeField = (query: SQ, index: number) => +export const removeField = (query, index) => setFieldsClause(query, FIELD.removeField(query.fields, index)); -export const clearFields = (query: SQ) => +export const clearFields = query => setFieldsClause(query, FIELD.clearFields(query.fields)); // LIMIT -export const getLimit = (query: SQ) => L.getLimit(query.limit); -export const updateLimit = (query: SQ, limit: LimitClause) => +export const getLimit = query => L.getLimit(query.limit); +export const updateLimit = (query, limit) => setLimitClause(query, L.updateLimit(query.limit, limit)); -export const clearLimit = (query: SQ) => +export const clearLimit = query => setLimitClause(query, L.clearLimit(query.limit)); // EXPRESSIONS -export const getExpressions = (query: SQ) => - E.getExpressions(query.expressions); -export const getExpressionsList = (query: SQ) => +export const getExpressions = query => E.getExpressions(query.expressions); +export const getExpressionsList = query => E.getExpressionsList(query.expressions); -export const addExpression = ( - query: SQ, - name: ExpressionName, - expression: Expression, -) => +export const addExpression = (query, name, expression) => setExpressionClause( query, E.addExpression(query.expressions, name, expression), ); -export const updateExpression = ( - query: SQ, - name: ExpressionName, - expression: Expression, - oldName: ExpressionName, -) => +export const updateExpression = (query, name, expression, oldName) => setExpressionClause( query, E.updateExpression(query.expressions, name, expression, oldName), ); -export const removeExpression = (query: SQ, name: ExpressionName) => +export const removeExpression = (query, name) => setExpressionClause(query, E.removeExpression(query.expressions, name)); -export const clearExpressions = (query: SQ) => +export const clearExpressions = query => setExpressionClause(query, E.clearExpressions(query.expressions)); // we can enforce various constraints in these functions: -function setAggregationClause( - query: SQ, - aggregationClause: ?AggregationClause, -): SQ { +function setAggregationClause(query, aggregationClause) { const wasBareRows = A.isBareRows(query.aggregation); const isBareRows = A.isBareRows(aggregationClause); // when switching to or from bare rows clear out any sorting and fields clauses @@ -172,7 +134,7 @@ function setAggregationClause( } return setClause("aggregation", query, aggregationClause); } -function setBreakoutClause(query: SQ, breakoutClause: ?BreakoutClause): SQ { +function setBreakoutClause(query, breakoutClause) { // NOTE: this doesn't handle complex cases const breakoutIds = B.getBreakouts(breakoutClause) .map(b => FIELD_REF.getFieldTargetId(b)) @@ -201,42 +163,29 @@ function setBreakoutClause(query: SQ, breakoutClause: ?BreakoutClause): SQ { query = clearFields(query); return setClause("breakout", query, breakoutClause); } -function setFilterClause(query: SQ, filterClause: ?FilterClause): SQ { +function setFilterClause(query, filterClause) { return setClause("filter", query, filterClause); } -function setJoinClause(query: SQ, joinClause: ?JoinClause): SQ { +function setJoinClause(query, joinClause) { return setClause("joins", query, joinClause); } -function setOrderByClause(query: SQ, orderByClause: ?OrderByClause): SQ { +function setOrderByClause(query, orderByClause) { return setClause("order-by", query, orderByClause); } -function setFieldsClause(query: SQ, fieldsClause: ?FieldsClause): SQ { +function setFieldsClause(query, fieldsClause) { return setClause("fields", query, fieldsClause); } -function setLimitClause(query: SQ, limitClause: ?LimitClause): SQ { +function setLimitClause(query, limitClause) { return setClause("limit", query, limitClause); } -function setExpressionClause( - query: SQ, - expressionClause: ?ExpressionClause, -): SQ { +function setExpressionClause(query, expressionClause) { if (expressionClause && Object.keys(expressionClause).length === 0) { expressionClause = null; } return setClause("expressions", query, expressionClause); } -type FilterClauseName = - | "filter" - | "aggregation" - | "breakout" - | "order-by" - | "limit" - | "expressions" - | "fields" - | "joins"; - -function setClause(clauseName: FilterClauseName, query: SQ, clause: ?any): SQ { +function setClause(clauseName, query, clause) { query = { ...query }; if (clause == null) { delete query[clauseName]; diff --git a/frontend/src/metabase/lib/query/util.js b/frontend/src/metabase/lib/query/util.js index 92f02c6d7be..91148030f8f 100644 --- a/frontend/src/metabase/lib/query/util.js +++ b/frontend/src/metabase/lib/query/util.js @@ -3,7 +3,7 @@ import _ from "underscore"; // determines whether 2 field IDs are equal. This is needed rather than // doing a simple comparison because field IDs are not guaranteed to be numeric: // the might be FieldLiterals, e.g. [field-literal <name> <unit>], instead. -export const fieldIdsEq = (a: any, b: any): boolean => { +export const fieldIdsEq = (a, b) => { if (typeof a !== typeof b) { return false; } @@ -32,21 +32,20 @@ export const fieldIdsEq = (a: any, b: any): boolean => { return false; }; -export const noNullValues = (clause: any[]): boolean => - _.all(clause, c => c != null); +export const noNullValues = clause => _.all(clause, c => c != null); // these are mostly to circumvent Flow type checking :-/ -export const op = (clause: any): string => clause[0]; -export const args = (clause: any[]): any[] => clause.slice(1); +export const op = clause => clause[0]; +export const args = clause => clause.slice(1); -export const add = <T>(items: T[], item: T): T[] => [...items, item]; -export const update = <T>(items: T[], index: number, newItem: T): T[] => [ +export const add = (items, item) => [...items, item]; +export const update = (items, index, newItem) => [ ...items.slice(0, index), newItem, ...items.slice(index + 1), ]; -export const remove = <T>(items: T[], index: number): T[] => [ +export const remove = (items, index) => [ ...items.slice(0, index), ...items.slice(index + 1), ]; -export const clear = <T>(): T[] => []; +export const clear = () => []; diff --git a/frontend/src/metabase/lib/urls.js b/frontend/src/metabase/lib/urls.js index c5639691f05..82c8dbe650f 100644 --- a/frontend/src/metabase/lib/urls.js +++ b/frontend/src/metabase/lib/urls.js @@ -79,7 +79,7 @@ export function serializedQuestion(card) { return question(null, card); } -export const extractQueryParams = (query: Object): Array => { +export const extractQueryParams = query => { return [].concat(...Object.entries(query).map(flattenParam)); }; -- GitLab