import { RightSquareOutlined } from '@ant-design/icons';
import { ArrayItems, Editable, FormCollapse, FormItem, FormLayout, Switch } from '@formily/antd-v5';
import { Form as FormType, ObjectField, createForm, onFieldChange, onFormInit } from '@formily/core';
import { FormConsumer, ISchema, Schema } from '@formily/react';
import {
AutoComplete,
FormProvider,
SchemaComponent,
gridRowColWrap,
useCollectionFieldsOptions,
useCollectionFilterOptions,
useDesignable,
} from '@nocobase/client';
import { Alert, App, Button, Card, Col, Modal, Row, Space, Table, Tabs, Typography } from 'antd';
import { cloneDeep, isEqual } from 'lodash';
import React, { createContext, useContext, useEffect, useMemo, useRef } from 'react';
import {
useChartFields,
useCollectionOptions,
useData,
useFieldTypes,
useFieldsWithAssociation,
useFormatters,
useOrderFieldsOptions,
useOrderReaction,
useTransformers,
useTransformersDecimal,
} from '../hooks';
import { useChartsTranslation } from '../locale';
import { ChartRenderer, ChartRendererContext } from '../renderer';
import { createRendererSchema, getField, getSelectedFields } from '../utils';
import { getConfigSchema, querySchema, transformSchema } from './schemas/configure';
import { useChartTypes, useCharts, useDefaultChartType } from '../chart/group';
import { FilterDynamicComponent } from './FilterDynamicComponent';
import { ChartConfigContext } from './ChartConfigProvider';
const { Paragraph, Text } = Typography;
export type SelectedField = {
field: string | string[];
alias?: string;
};
export const ChartConfigure: React.FC<{
insert: (
s: ISchema,
options: {
onSuccess: () => void;
wrap?: (schema: ISchema) => ISchema;
},
) => void;
}> & {
Renderer: React.FC;
Config: React.FC;
Query: React.FC;
Transform: React.FC;
Data: React.FC;
} = (props) => {
const { t } = useChartsTranslation();
const { service } = useContext(ChartRendererContext);
const { visible, setVisible, current } = useContext(ChartConfigContext);
const { schema, field, collection, initialValues } = current || {};
const { dn } = useDesignable();
const { modal } = App.useApp();
const { insert } = props;
const charts = useCharts();
const fields = useFieldsWithAssociation(collection);
const initChart = (overwrite = false) => {
if (!form.modified) {
return;
}
const chartType = form.values.config?.chartType;
if (!chartType) {
return;
}
const chart = charts[chartType];
const init = chart?.init;
if (!init) {
if (overwrite) {
form.values.config.general = {};
form.values.config.advanced = {};
}
return;
}
const query = form.values.query;
const selectedFields = getSelectedFields(fields, query);
const { general, advanced } = chart.init(selectedFields, query);
if (general || overwrite) {
form.values.config.general = general;
}
if (advanced || overwrite) {
form.values.config.advanced = advanced || {};
}
};
const [measures, setMeasures] = React.useState([]);
const [dimensions, setDimensions] = React.useState([]);
const queryReact = (form: FormType, reaction?: () => void) => {
const currentMeasures = form.values.query?.measures.filter((item) => item.field) || [];
const currentDimensions = form.values.query?.dimensions.filter((item) => item.field) || [];
if (isEqual(currentMeasures, measures) && isEqual(currentDimensions, dimensions)) {
return;
}
reaction?.();
setMeasures(cloneDeep(currentMeasures));
setDimensions(cloneDeep(currentDimensions));
};
const chartType = useDefaultChartType();
const form = useMemo(
() =>
createForm({
values: { config: { chartType }, ...(initialValues || field?.decoratorProps), collection },
effects: (form) => {
onFieldChange('config.chartType', () => initChart(true));
onFormInit(() => queryReact(form));
},
}),
// visible, collection added here to re-initialize form when visible, collection change
// eslint-disable-next-line react-hooks/exhaustive-deps
[field, visible, collection],
);
const RunButton: React.FC = () => (
}
onClick={async () => {
const queryField = form.query('query').take() as ObjectField;
try {
await queryField?.validate();
} catch (e) {
return;
}
try {
await service.runAsync(collection, form.values.query, true);
} catch (e) {
console.log(e);
}
queryReact(form, initChart);
}}
>
{t('Run query')}
);
const queryRef = useRef(null);
const configRef = useRef(null);
useEffect(() => {
if (!visible) {
return;
}
service.run(collection, field?.decoratorProps?.query, 'configure');
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [visible]);
return (