Skip to content
Snippets Groups Projects
Unverified Commit e8d1a604 authored by Alexander Polyankin's avatar Alexander Polyankin Committed by GitHub
Browse files

Remove flow from containers (#19210)

parent 001aeedc
No related branches found
No related tags found
No related merge requests found
/* eslint-disable react/prop-types */
import React from "react";
import { connect } from "react-redux";
......@@ -9,30 +10,6 @@ import { getMetadata } from "metabase/selectors/metadata";
import Question from "metabase-lib/lib/Question";
// type annotations
import type Metadata from "metabase-lib/lib/metadata/Metadata";
import type { Card } from "metabase-types/types/Card";
type ChildProps = {
loading: boolean,
error: ?any,
question: ?Question,
};
type Props = {
questionHash?: string,
children?: (props: ChildProps) => React.Element,
// provided by redux
loadMetadataForCard: (card: Card) => Promise<void>,
metadata: Metadata,
};
type State = {
// the question should be of type Question if it is set
question: ?Question,
card: ?Card,
loading: boolean,
error: ?any,
};
/*
* AdHocQuestionLoader
......@@ -64,9 +41,7 @@ type State = {
* without the redux store.
*/
export class AdHocQuestionLoader extends React.Component {
props: Props;
state: State = {
state = {
// this will store the loaded question
question: null,
// keep a reference to the card as well to help with re-creating question
......@@ -81,7 +56,7 @@ export class AdHocQuestionLoader extends React.Component {
this._loadQuestion(this.props.questionHash);
}
UNSAFE_componentWillReceiveProps(nextProps: Props) {
UNSAFE_componentWillReceiveProps(nextProps) {
// if the questionHash changes (this will most likely be the result of a
// url change) then we need to load this new question
if (nextProps.questionHash !== this.props.questionHash) {
......@@ -106,7 +81,7 @@ export class AdHocQuestionLoader extends React.Component {
* be used
* 4. Set the component state to the new Question
*/
async _loadQuestion(questionHash: ?string) {
async _loadQuestion(questionHash) {
if (!questionHash) {
this.setState({
loading: false,
......
......@@ -12,9 +12,6 @@ import DashboardPicker from "metabase/containers/DashboardPicker";
import * as Urls from "metabase/lib/urls";
import type { Dashboard as DashboardType } from "metabase-types/types/Dashboard";
import type { Card } from "metabase-types/types/Card";
function mapStateToProps(state) {
return {
dashboards: state.entities.dashboards,
......@@ -27,13 +24,6 @@ export default class AddToDashSelectDashModal extends Component {
shouldCreateDashboard: false,
};
props: {
card: Card,
onClose: () => void,
onChangeLocation: string => void,
createDashboard: DashboardType => any,
};
navigateToDashboard = dashboard => {
const { card, onChangeLocation } = this.props;
......
/* eslint-disable react/prop-types */
import React from "react";
import _ from "underscore";
import { MetabaseApi, AutoApi } from "metabase/services";
import type { DatabaseCandidates } from "metabase-types/types/Auto";
type Props = {
databaseId: number,
children: (props: RenderProps) => ?React.Element,
};
type RenderProps = {
candidates: ?DatabaseCandidates,
sampleCandidates: ?DatabaseCandidates,
isSample: ?boolean,
};
type State = {
databaseId: ?number,
isSample: ?boolean,
candidates: ?DatabaseCandidates,
sampleCandidates: ?DatabaseCandidates,
};
const CANDIDATES_POLL_INTERVAL = 2000;
// ensure this is 1 second offset from CANDIDATES_POLL_INTERVAL due to
// concurrency issue in candidates endpoint
const CANDIDATES_TIMEOUT = 11000;
class CandidateListLoader extends React.Component {
props: Props;
state: State = {
state = {
databaseId: null,
isSample: null,
candidates: null,
sampleCandidates: null,
};
_sampleTimeout: ?number;
_pollTimer: ?number;
async UNSAFE_componentWillMount() {
// If we get passed in a database id, just use that.
// Don't fall back to the sample dataset
......
/* eslint-disable react/prop-types */
import React from "react";
import Collection from "metabase/entities/collections";
......@@ -5,12 +6,7 @@ import Search from "metabase/entities/search";
const PINNED_DASHBOARDS_LOAD_LIMIT = 500;
type Props = {
collectionId: number,
children: () => void,
};
const CollectionItemsLoader = ({ collectionId, children, ...props }: Props) => (
const CollectionItemsLoader = ({ collectionId, children, ...props }) => (
<Collection.Loader {...props} id={collectionId}>
{({ object }) => (
<Search.ListLoader
......
......@@ -20,78 +20,6 @@ export {
CustomFormSection as FormSection,
} from "metabase/components/form/CustomForm";
type FormFieldName = string;
type FormFieldTitle = string;
type FormFieldDescription = string;
type FormFieldType =
| "input"
| "password"
| "select"
| "text"
| "color"
| "hidden"
| "collection"
| "snippetCollection";
type FormValue = any;
type FormError = string;
type FormValues = { [name: FormFieldName]: FormValue };
type FormErrors = { [name: FormFieldName]: FormError };
export type FormFieldDefinition = {
name: FormFieldName,
type?: FormFieldType,
title?: FormFieldTitle,
description?: FormFieldDescription,
initial?: FormValue | (() => FormValue),
normalize?: (value: FormValue) => FormValue,
validate?: (value: FormValue, props: FormProps) => ?FormError | boolean,
readOnly?: boolean,
};
export type FormDefinition = {
fields:
| ((values: FormValues) => FormFieldDefinition[])
| FormFieldDefinition[],
initial?: FormValues | (() => FormValues),
normalize?: (values: FormValues) => FormValues,
validate?: (values: FormValues, props: FormProps) => FormErrors,
};
type FormObject = {
fields: (values: FormValues) => FormFieldDefinition[],
fieldNames: (values: FormValues) => FormFieldName[],
initial: () => FormValues,
normalize: (values: FormValues) => FormValues,
validate: (values: FormValues, props: FormProps) => FormErrors,
disablePristineSubmit?: boolean,
};
type FormProps = {
values?: FormValues,
};
type Props = {
form: FormDefinition,
initialValues?: ?FormValues,
formName?: string,
onSubmit: (values: FormValues) => Promise<any>,
onSubmitSuccess: (action: any) => Promise<any>,
formComponent?: React.Component,
dispatch: Function,
values: FormValues,
};
type State = {
inlineFields: { [name: FormFieldName]: FormFieldDefinition },
};
type SubmitState = {
submitting: boolean,
failed: boolean,
result: any,
};
let FORM_ID = 0;
// use makeMapStateToProps so each component gets it's own unique formId
const makeMapStateToProps = () => {
......@@ -128,21 +56,13 @@ const ReduxFormComponent = reduxForm()(
@connect(makeMapStateToProps)
export default class Form extends React.Component {
props: Props;
state: State;
_state: SubmitState = {
_state = {
submitting: false,
failed: false,
result: undefined,
};
_getFormDefinition: () => FormDefinition;
_getFormObject: () => FormObject;
_getInitialValues: () => FormValues;
_getFieldNames: () => FormFieldName[];
constructor(props: Props) {
constructor(props) {
super(props);
this.state = {
......@@ -239,7 +159,7 @@ export default class Form extends React.Component {
fieldNames: PropTypes.array,
};
componentDidUpdate(prevProps: Props, prevState: State) {
componentDidUpdate(prevProps, prevState) {
// HACK: when new fields are added they aren't initialized with their intialValues, so we have to force it here:
const newFields = _.difference(
Object.keys(this.state.inlineFields),
......@@ -252,7 +172,7 @@ export default class Form extends React.Component {
}
}
_registerFormField = (field: FormFieldDefinition) => {
_registerFormField = field => {
if (!_.isEqual(this.state.inlineFields[field.name], field)) {
this.setState(prevState =>
assocIn(prevState, ["inlineFields", field.name], field),
......@@ -260,7 +180,7 @@ export default class Form extends React.Component {
}
};
_unregisterFormField = (field: FormFieldDefinition) => {
_unregisterFormField = field => {
if (this.state.inlineFields[field.name]) {
// this.setState(prevState =>
// dissocIn(prevState, ["inlineFields", field.name]),
......@@ -275,7 +195,7 @@ export default class Form extends React.Component {
};
}
_validate = (values: FormValues, props: any) => {
_validate = (values, props) => {
// HACK: clears failed state for global error
if (!this._state.submitting && this._state.failed) {
this._state.failed = false;
......@@ -285,7 +205,7 @@ export default class Form extends React.Component {
return formObject.validate(values, props);
};
_onSubmit = async (values: FormValues) => {
_onSubmit = async values => {
const formObject = this._getFormObject();
// HACK: clears failed state for global error
this._state.submitting = true;
......@@ -320,7 +240,7 @@ export default class Form extends React.Component {
}
};
_handleSubmitSuccess = async (action: any) => {
_handleSubmitSuccess = async action => {
if (this.props.onSubmitSuccess) {
await this.props.onSubmitSuccess(action);
}
......@@ -329,7 +249,7 @@ export default class Form extends React.Component {
);
};
_handleChangeField = (fieldName: FormFieldName, value: FormValue) => {
_handleChangeField = (fieldName, value) => {
return this.props.dispatch(change(this.props.formName, fieldName, value));
};
......@@ -370,12 +290,7 @@ export default class Form extends React.Component {
// form.fields[0] is { name: "foo", initial: "bar" }
// form.fields[0] is { name: "foo", initial: () => "bar" }
//
function makeFormMethod(
form: FormObject,
methodName: string,
defaultValues: any = {},
mergeFn,
) {
function makeFormMethod(form, methodName, defaultValues = {}, mergeFn) {
const originalMethod = form[methodName];
form[methodName] = (object, ...args) => {
// make a copy
......@@ -397,10 +312,10 @@ function makeFormMethod(
};
}
// if the first arg is a function, call it, otherwise return it.
function getValue(fnOrValue, ...args): any {
function getValue(fnOrValue, ...args) {
return typeof fnOrValue === "function" ? fnOrValue(...args) : fnOrValue;
}
function makeFormObject(formDef: FormDefinition): FormObject {
function makeFormObject(formDef) {
const form = {
...formDef,
fields: values => getValue(formDef.fields, values),
......
/* eslint-disable react/prop-types */
import React from "react";
import QuestionLoader from "metabase/containers/QuestionLoader";
import QuestionResultLoader from "metabase/containers/QuestionResultLoader";
import type { ChildProps as QuestionLoaderChildProps } from "./QuestionLoader";
import type { ChildProps as QuestionResultLoaderChildProps } from "./QuestionResultLoader";
type ChildProps = QuestionLoaderChildProps & QuestionResultLoaderChildProps;
type Props = {
questionId?: ?number,
questionHash?: ?string,
children?: (props: ChildProps) => React.Element,
};
/*
* QuestionAndResultLoader
*
......@@ -32,11 +22,7 @@ type Props = {
* </QuestionAndResultLoader>
*
*/
const QuestionAndResultLoader = ({
questionId,
questionHash,
children,
}: Props) => (
const QuestionAndResultLoader = ({ questionId, questionHash, children }) => (
<QuestionLoader questionId={questionId} questionHash={questionHash}>
{({ loading: questionLoading, error: questionError, ...questionProps }) => (
<QuestionResultLoader question={questionProps.question}>
......
/* eslint-disable react/prop-types */
import React from "react";
import renderPropToHOC from "metabase/hoc/RenderPropToHOC";
import AdHocQuestionLoader from "metabase/containers/AdHocQuestionLoader";
import SavedQuestionLoader from "metabase/containers/SavedQuestionLoader";
import Question from "metabase-lib/lib/Question";
import { serializeCardForUrl } from "metabase/lib/card";
export type ChildProps = {
loading: boolean,
error: ?any,
question: ?Question,
};
type Props = {
questionObject?: any, // FIXME: minimal card
questionId?: ?number,
questionHash?: ?string,
children?: (props: ChildProps) => React.Element,
};
/*
* QuestionLoader
*
......@@ -62,7 +49,7 @@ const QuestionLoader = ({
questionId,
questionHash,
children,
}: Props) =>
}) =>
questionObject != null ? (
<AdHocQuestionLoader questionHash={serializeCardForUrl(questionObject)}>
{children}
......
/* eslint-disable react/prop-types */
import React from "react";
import PropTypes from "prop-types";
import { defer } from "metabase/lib/promise";
import type { Dataset } from "metabase-types/types/Dataset";
import type { RawSeries } from "metabase-types/types/Visualization";
import Question from "metabase-lib/lib/Question";
export type ChildProps = {
loading: boolean,
error: ?any,
results: ?(Dataset[]),
result: ?Dataset,
rawSeries: ?RawSeries,
cancel: () => void,
reload: () => void,
};
type OnLoadCallback = (results: ?(Dataset[])) => void;
type Props = {
question: ?Question,
children?: (props: ChildProps) => React.Element,
onLoad?: OnLoadCallback,
};
type State = {
results: ?(Dataset[]),
loading: boolean,
error: ?any,
};
const propTypes = {
question: PropTypes.object,
children: PropTypes.func,
......@@ -57,15 +29,12 @@ const propTypes = {
*
*/
export class QuestionResultLoader extends React.Component {
props: Props;
state: State = {
state = {
results: null,
loading: false,
error: null,
};
_cancelDeferred: ?() => void;
UNSAFE_componentWillMount = () => {
this._reload();
};
......@@ -96,7 +65,7 @@ export class QuestionResultLoader extends React.Component {
}));
// call apiGetResults and pass our cancel to allow for cancelation
const results: Dataset[] = await question.apiGetResults({
const results = await question.apiGetResults({
cancelDeferred: this._cancelDeferred,
});
......
/* eslint-disable react/prop-types */
import React from "react";
import { connect } from "react-redux";
......@@ -9,32 +10,6 @@ import { getMetadata } from "metabase/selectors/metadata";
import Question from "metabase-lib/lib/Question";
// type annotations
import type Metadata from "metabase-lib/lib/metadata/Metadata";
import type { Card } from "metabase-types/types/Card";
type ChildProps = {
loading: boolean,
error: ?any,
question: ?Question,
};
type Props = {
questionId: ?number,
children?: (props: ChildProps) => React.Element,
// provided by redux
loadMetadataForCard: (card: Card) => Promise<void>,
metadata: Metadata,
};
type State = {
// the question should be of type Question if it is set
question: ?Question,
// keep a reference to the card as well to help with re-creating question
// objects if the underlying metadata changes
card: ?Card,
loading: boolean,
error: ?any,
};
/*
* SavedQuestionLaoder
......@@ -65,9 +40,7 @@ type State = {
* without the redux store.
*/
export class SavedQuestionLoader extends React.Component {
props: Props;
state: State = {
state = {
// this will store the loaded question
question: null,
card: null,
......@@ -80,7 +53,7 @@ export class SavedQuestionLoader extends React.Component {
this._loadQuestion(this.props.questionId);
}
UNSAFE_componentWillReceiveProps(nextProps: Props) {
UNSAFE_componentWillReceiveProps(nextProps) {
// if the questionId changes (this will most likely be the result of a
// url change) then we need to load this new question
if (nextProps.questionId !== this.props.questionId) {
......@@ -105,7 +78,7 @@ export class SavedQuestionLoader extends React.Component {
* be used
* 4. Set the component state to the new Question
*/
async _loadQuestion(questionId: ?number) {
async _loadQuestion(questionId) {
if (questionId == null) {
this.setState({
loading: false,
......
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