tachybase_todo/packages/plugins/charts/src/client/ChartBlockEngineDesigner.tsx
Frozen FIsh b276ce1258
feat: add chart plugin (#1477)
* feat: add pie schema template

* chore: refactor

* chore: update

* chore: init server

* feat: add pie schema template

* chore: add chart utils

* chore: update

* chore: update

* chore: update

* chore: update

* feat: mvp

* chore: update

* chore: test

* feat: example

* fix: templates map error

* chore: update

* feat: add ChartBlockEngineDesigner.tsx

* chore: clean code

* chore: update templates

* chore: init bat template

* chore: update chart block engine

* feat: add chart block engine designer

* chore: update chart block initializer

* chore: update pie template

* chore: update

* feat: split sql

* chore: update

* chore: clean

* feat: support bar

* chore: add bar template

* chore: clean code

* chore: clean code

* fix: chart block initializer title

* chore: update

* fix: use title

* chore: update

* fix: bugs

* chore: clean code

* chore: update pie template

* chore: update ChartBlockInitializer.tsx

* chore: update

* feat: support chart config

* chore: add local plugin

* feat: add column template

* feat: add column chart action

* feat: add line chart template

* feat: add line action

* feat: add area template

* feat: add area action

* chore: update pie template

* chore: update

* chore: update dep

* fix: export missing utils

* chore: update dep

* chore: update dep

* chore: update pie template

* fix(charts): sql table capitalization

* fix(charts): improve sql compatibility

* fix: support choices type

* chore: update

* chore: clean code

* chore: get collection fields in chart engine

* feat(demo): chart block initializer

* fix: hello block

* chore: init data analyse plugin

* chore: add data-analyse plugin

* chore: init plugin

* chore: update

* chore: export schema initializers

* feat: add data analyse block

* chore: update data analyse block initializer

* chore: rename plugin name

* chore: update

* chore: update enum

* chore: update add block

* feat: add pie schema template

* chore: refactor

* chore: update

* chore: init server

* feat: add pie schema template

* chore: add chart utils

* chore: update

* chore: update

* chore: update

* chore: update

* feat: mvp

* chore: update

* chore: test

* feat: example

* fix: templates map error

* chore: update

* feat: add ChartBlockEngineDesigner.tsx

* chore: clean code

* chore: update templates

* chore: init bat template

* chore: update chart block engine

* feat: add chart block engine designer

* chore: update chart block initializer

* chore: update pie template

* chore: update

* feat: split sql

* chore: update

* chore: clean

* feat: support bar

* chore: add bar template

* chore: clean code

* chore: clean code

* fix: chart block initializer title

* chore: update

* fix: use title

* chore: update

* fix: bugs

* chore: clean code

* chore: update pie template

* chore: update ChartBlockInitializer.tsx

* chore: update

* feat: support chart config

* chore: add local plugin

* feat: add column template

* feat: add column chart action

* feat: add line chart template

* feat: add line action

* feat: add area template

* feat: add area action

* chore: update pie template

* chore: update

* chore: update dep

* fix: export missing utils

* chore: update dep

* chore: update dep

* chore: update pie template

* fix(charts): sql table capitalization

* fix(charts): improve sql compatibility

* fix: support choices type

* chore: update

* chore: clean code

* chore: get collection fields in chart engine

* chore: init dataset plugin

* chore: init dataset designer

* chore: init dataset block initializer

* chore: update

* chore: update

* chore: update deps

* chore: add tests

* chore: update utils

* chore: init plugin

* feat: add datasets client

* chore: update tests

* chore: update datastructures

* chore: update

* feat: add DataSetBlockInitializer

* chore: use dataset initializer

* chore: update deps

* chore: update

* chore: update pie template

* chore: update ChartBlockInitializer

* chore: update ChartBlockEngine

* chore: remove mdg file

* chore: update ChartBlockEngine

* chore: update

* chore: update g2plot

* chore: update template

* chore: update pie handler

* chore: update DataSetPreviewTable

* chore: update ChartBlockEngine

* chore: update ChartBlockEngineDesigner

* chore: remove useless files

* chore: update ChartBlockInitializer

* chore: update template

* chore: feat area template

* chore: update tests

* chore: update local plugins

* chore: update deps

* chore: update templates

* chore: update template

* feat: add CustomSelect

* chore: update select component

* fix: seriesField color error

* chore: update template

* chore: update

* fix: bar

* chore: update templates & clean code

* chore: update templates

* feat: add FunnelTemplate

* feat: charts queries

* fix: data shift

* feat: add ChartQueryMetadataProvider

* chore: update

* chore: remove dataset

* chore: update

* chore: update

* chore: clean code

* fix: delete query query list wrong behavior

* fix: delete all queries query list behavior

* chore: add empty occupancy

* chore: update description

* chore: update chart icon

* chore: update funnel template

* chore: update template title

* chore: add references

* chore: update dialog height

* fix: scatter template

* chore: update popup description

* refactor: schema level

* refactor: charts schema

* chore: remove console

* chore: remove console

* fix: error message

* chore: remove console

* chore: update DataSetPreviewTable

* feat: chart icons

* feat: update i18n

* feat: update i18n

* chore: update i18n

* chore: update i18n

* chore: update i18n

* feat: add tittle

* chore: update icons

* chore: update i18n

* chore: update i18n

* chore: update i18n

* chore: update i18n

* chore: update i18n

* fix: improve code

* chore: update i18n

* chore: update i18n

* fix: chart icon

* feat: quick add query (#1527)

* feat: quick add query

* feat: query

* chore: remove useless files

* fix: json5 validator error

* chore: update

* chore: update style

* chore: lint

* feat: improve code

* feat: sql validation

* refactor: clean code

* Update utils.ts

* chore: format code

* chore: remove useless file

* chore: update

---------

Co-authored-by: chenos <chenlinxh@gmail.com>
2023-03-04 19:36:58 +08:00

239 lines
8.3 KiB
TypeScript

import { css } from '@emotion/css';
import { FormDialog, FormLayout } from '@formily/antd';
import { SchemaOptionsContext, useField, useFieldSchema } from '@formily/react';
import {
APIClientProvider,
GeneralSchemaDesigner,
i18n,
SchemaComponent,
SchemaComponentOptions,
SchemaSettings,
useAPIClient,
useCompile,
useDesignable,
} from '@nocobase/client';
import { Card } from 'antd';
import JSON5 from 'json5';
import React, { useContext, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ChartBlockEngineMetaData } from './ChartBlockEngine';
import { Options } from './ChartBlockInitializer';
import DataSetPreviewTable from './DataSetPreviewTable';
import { useFieldsById } from './hooks';
import { lang } from './locale';
import { templates } from './templates';
export const jsonConfigDesc = (title: string, link: string) => {
return (
<span>
{lang('Json config references: ')}
<a href={link} target="_blank">
{lang(title)}
</a>
</span>
);
};
const validateJSON = {
validator: `{{(value, rule)=> {
if (!value) {
return '';
}
try {
const val = JSON.parse(value);
if(!isNaN(val)) {
return false;
}
return true;
} catch(error) {
console.error(error);
return false;
}
}}}`,
message: '{{t("Invalid JSON format",{ ns: "charts" })}}',
};
export const ChartBlockEngineDesigner = () => {
const fieldSchema = useFieldSchema();
const { chartBlockEngineMetaData } = fieldSchema?.['x-component-props'];
return (
<GeneralSchemaDesigner>
<ChartBlockEngineDesignerInitializer chartBlockEngineMetaData={chartBlockEngineMetaData} />
<SchemaSettings.Divider />
<SchemaSettings.Remove
removeParentsIfNoChildren
breakRemoveOn={{
'x-component': 'Grid',
}}
/>
</GeneralSchemaDesigner>
);
};
export const ChartBlockEngineDesignerInitializer = (props) => {
const { chartBlockEngineMetaData }: { chartBlockEngineMetaData: ChartBlockEngineMetaData } = props;
const { t } = useTranslation();
const options = useContext(SchemaOptionsContext);
const { dn } = useDesignable();
const fieldSchema = useFieldSchema();
const api = useAPIClient();
const field = useField();
const compile = useCompile();
const { chart, query } = chartBlockEngineMetaData;
const { fields } = useFieldsById(query.id);
const dataSource = fields.map((field) => {
return {
label: field.name,
value: field.name,
};
});
return (
<SchemaSettings.Item
onClick={async () => {
FormDialog(
{
okText: compile('{{t("Submit")}}'),
title: lang('Edit chart block'),
width: 1200,
bodyStyle: { background: '#f0f2f5', maxHeight: '65vh', overflow: 'auto' },
},
(form) => {
const [chartBlockEngineMetaData, setChartBlockEngineMetaData] = useState<ChartBlockEngineMetaData>(null);
useEffect(() => {
const chartBlockEngineMetaData = {
query: {
id: query?.id,
},
chart: form.values, //TODO
};
setChartBlockEngineMetaData(chartBlockEngineMetaData);
}, [form.values.type]);
return (
<APIClientProvider apiClient={api}>
<SchemaComponentOptions scope={options.scope} components={{ ...options.components }}>
<section
className={css`
display: flex;
gap: 24px;
`}
>
{/* left*/}
<Card
bordered={false}
title={i18n.t('Chart config')}
size={'default'}
className={css`
flex: 1;
`}
>
<FormLayout layout={'vertical'}>
<SchemaComponent
scope={{ dataSource, JSON5, jsonConfigDesc }}
components={{ Options }}
schema={{
properties: {
// title: {
// title: lang('Chart title'),
// 'x-component': 'Input',
// 'x-decorator': 'FormItem',
// },
type: {
title: t('Chart type'),
required: true,
'x-component': 'CustomSelect',
'x-decorator': 'FormItem',
enum: [...templates.values()].map((template) => {
return {
title: template.title,
key: template.type,
description: template.description,
group: template.group,
iconId: template.iconId,
};
}),
},
options: {
type: 'void',
'x-component': 'Options',
},
},
}}
/>
</FormLayout>
</Card>
{/* right*/}
<div
className={css`
flex: 1;
min-width: 600px;
`}
>
<Card size={'default'} title={lang('Chart preview')}>
{/* Chart Preview*/}
{chartBlockEngineMetaData && (
<>
<SchemaComponent
schema={{
properties: {
chartPreview: {
type: 'void',
'x-decorator': 'CardItem',
'x-component': 'ChartBlockEngine',
'x-component-props': {
chartBlockEngineMetaData: chartBlockEngineMetaData,
},
},
},
}}
/>
</>
)}
</Card>
<Card
size={'default'}
title={lang('Data preview')}
className={css`
margin-top: 24px;
overflow: scroll;
`}
>
{/*Data preview*/}
{chartBlockEngineMetaData?.query?.id && (
<DataSetPreviewTable queryId={chartBlockEngineMetaData?.query?.id} fields={fields} />
)}
</Card>
</div>
</section>
</SchemaComponentOptions>
</APIClientProvider>
);
},
)
.open({
initialValues: { ...chart }, //reset before chartBlockMetaData
})
.then((values) => {
//patch updates
values = {
query,
chart: values,
};
field.title = values.chart.title;
fieldSchema['title'] = values.chart.title;
field.componentProps.chartBlockEngineMetaData = values;
fieldSchema['x-component-props'].chartBlockEngineMetaData = values;
dn.emit('patch', {
schema: {
'x-uid': fieldSchema['x-uid'],
'x-component-props': fieldSchema['x-component-props'],
},
});
dn.refresh();
});
}}
>
{props.children || props.title || lang('Edit chart block')}
</SchemaSettings.Item>
);
};