Skip to content

Commit

Permalink
feat: filter (#5)
Browse files Browse the repository at this point in the history
* feat: support filter settings

* fix: filter ui style

* perf: scroll to the corresponding position after adding the filter rules

---------

Co-authored-by: 王波 <wangbo@vikadata.com>
  • Loading branch information
Sky-FE and boris-w committed Apr 19, 2023
1 parent a8ee2d0 commit 43ec2f4
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.0.71",
"version": "1.0.72",
"description": "my apitable widget chart",
"engines": {
"node": ">=8.x"
Expand Down
7 changes: 5 additions & 2 deletions src/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const useGetDefaultFormData = (meta) => {
// Statistical indicators (only numeric fields can be used as statistical indicators).
const metrics = fields.filter(field => field.basicValueType === BasicValueType.Number);
return {
dataSource: { view: viewId },
dataSource: { view: viewId, filter: null },
...new EchartsColumn(StackType.None, meta.theme).getDefaultFormData(dimensions, metrics),
};
// Since it is only used for the first time, there is no need to update.
Expand Down Expand Up @@ -74,7 +74,7 @@ const WidgetChartBase: React.FC = () => {

const readOnly = !editable;
const viewId = formData.dataSource.view;
const records = useRecords(viewId);
const records = useRecords(viewId, { filter: formData.dataSource.filter});
const fields = useFields(viewId);
const isPartOfDataRef = useRef(false);

Expand Down Expand Up @@ -147,6 +147,9 @@ const WidgetChartBase: React.FC = () => {
enum: viewIds,
enumNames: viewNames,
},
filter: {
type: 'string',
},
},
},
chartStructure: chartStructureFormJSON,
Expand Down
119 changes: 119 additions & 0 deletions src/custom_form_components/filter_select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { LinkButton, useThemeColors, Modal, Button } from "@apitable/components"
import { AddOutlined, FilterOutlined } from "@apitable/icons"
import { Filter } from "@apitable/widget-sdk"
import styled from 'styled-components';
import { Strings, t } from '../i18n';

import React, { useEffect, useRef, useState } from "react"

interface IFilterSelect {
value: any;
onChange?: (filter: any) => void;
}

export const AddFilterButton = styled(LinkButton)`
:hover {
color: var(--textBrandHover);
svg {
fill: var(--textBrandHover);
}
}
:active {
color: var(--textBrandActive);
svg {
fill: var(--textBrandActive);
}
}
`;

const FilterModal = ({ value, visible, onCancel, onConfirm }) => {
const [filter, setFilter] = useState(value);
const listRef = useRef<HTMLDivElement>(null);

useEffect(() => {
if (visible) {
setFilter(value);
} else {
setFilter(null);
}
}, [visible, value]);

const onChange = (value) => {
const curLength = value ? (Object.values(value)[0] as [])?.length : 0;
const prevLength = filter ? (Object.values(filter)[0] as [])?.length : 0;
const isAddFilter = curLength > prevLength;
setFilter(value);
isAddFilter && setTimeout(() => {
if (!listRef.current) return;
listRef.current.scroll({ top: listRef.current.scrollHeight, behavior: 'smooth' });
});
};

return (
<Modal
title={t(Strings.filter_modal_title)}
visible={visible}
onCancel={onCancel}
onOk={() => onConfirm(filter)}
cancelText={t(Strings.cancel)}
okText={t(Strings.confirm)}
width={800}
centered
>
<div ref={listRef} style={{ maxHeight: 440, overflowY: 'auto' }}>
<Filter
filter={filter}
onChange={onChange}
/>
</div>
</Modal>
)
};

export const FilterSelect = ({ value, onChange }: IFilterSelect) => {
const colors = useThemeColors();
const [showModal, setShowModal] = useState<boolean>();

const onConfirm = (filter) => {
onChange?.(filter);
setShowModal(false);
}

const filterLen = value ? value[Object.keys(value)[0]]?.length : 0;

return (
<div>
{
filterLen ?
<Button
size={'small'}
variant="jelly"
color="primary"
prefixIcon={<FilterOutlined />}
onClick={() => setShowModal(true)}
style={{ fontSize: 13 }}
>
{filterLen}{t(Strings.filters_amount)}
</Button> :
<AddFilterButton
href="javascript:void(0)"
color={colors.textCommonPrimary}
underline={false}
prefixIcon={<AddOutlined color={colors.textCommonPrimary} size={12} />}
onClick={() => setShowModal(true)}
>
<span style={{ fontSize: 12 }}>
{t(Strings.add_filter)}
</span>
</AddFilterButton>
}
<FilterModal
visible={showModal}
onCancel={() => setShowModal(false)}
onConfirm={onConfirm}
value={value}
/>
</div>
)
};
1 change: 1 addition & 0 deletions src/custom_form_components/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './chart_select';
export * from './theme_select';
export * from './field_select';
export * from './filter_select';
12 changes: 10 additions & 2 deletions src/ui_schema.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { ChartSelect, FieldSelect, ThemeSelect } from './custom_form_components';
import { ChartSelect, FieldSelect, ThemeSelect, FilterSelect } from './custom_form_components';
import { ViewPicker } from '@apitable/widget-sdk';
import { Strings, t } from './i18n';
import settings from '../settings.json';
Expand All @@ -18,7 +18,15 @@ export const getUiSchema = (viewId: string) => {
'ui:widget': (props) => {
return <ViewPicker controlJump viewId={props.value} onChange={option => props.onChange(option.value)} />;
},
}
},
filter: {
'ui:options': {
showTitle: false,
},
'ui:widget': (props) => {
return <FilterSelect value={props.value} onChange={filter => props.onChange(filter)}/>;
},
},
},
chartStructure: {
'ui:order': ['chartType', 'dimension', 'isSplitMultipleValue', 'isFormatDatetime', 'datetimeFormatter', 'metricsType', 'metrics', 'seriesField'],
Expand Down
20 changes: 20 additions & 0 deletions strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,26 @@
"echarts_scatter_chart": {
"zh_CN": "散点图",
"en_US": "Scatter Chart"
},
"filters_amount": {
"zh_CN": " 个筛选",
"en_US": " filter(s)"
},
"filter_modal_title": {
"zh_CN": "筛选设置",
"en_US": "Filter Setting"
},
"add_filter": {
"zh_CN": "添加筛选条件",
"en_US": "Add filter"
},
"confirm": {
"zh_CN": "确认",
"en_US": "Confirm"
},
"cancel": {
"zh_CN": "取消",
"en_US": "Cancel"
}
}
}
4 changes: 2 additions & 2 deletions widget.config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"globalPackageId": "wpkCKtqGTjzM7",
"packageId": "wpkf5Ul97CY0q",
"spaceId": "spczdmQDfBAn5",
"packageId": "wpk1ZRKCsNek9",
"spaceId": "spcKJspLmm8E6",
"entry": "./src/index.ts",
"name": {
"zh-CN": "图表(Chart)",
Expand Down

0 comments on commit 43ec2f4

Please sign in to comment.