Skip to content

Commit

Permalink
feat: support filter
Browse files Browse the repository at this point in the history
  • Loading branch information
Sky-FE committed Apr 18, 2023
1 parent 85d6bb3 commit 63a4c81
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
.idea

dist/*/*.map
dist
.doc
.build.env
/blueprint-templates
Expand Down
2 changes: 0 additions & 2 deletions dist/packed/widget_bundle.min.js

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.1.7",
"version": "0.1.8",
"description": "a apitable widget",
"engines": {
"node": ">=8.x"
Expand Down
9 changes: 5 additions & 4 deletions src/components/chart/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ const getRecordIndex = (allRecords, selection, individualSelection, freeze) => {

export const View: React.FC<IViewProps> = (props) => {
const { config, setConfig, editable } = props;
const { viewId, dimensionFieldIds, selection, freeze } = config;
const { viewId, filter, dimensionFieldIds, selection, freeze } = config;
const { runtimeEnv } = useMeta();
const { isFullscreen } = useViewport();
const currSelection = useSelection();
const allRecords = useRecords(viewId);
const recordQuery = useMemo(() => ({ filter }), [filter]);
const allRecords = useRecords(viewId, recordQuery);
const [isMulti, _setIsMulti] = useCloudStorage("isMulti", false);


const setIsMulti = useCallback(
(isMulti) => {
if (!editable) return;
Expand Down Expand Up @@ -113,7 +113,7 @@ export const View: React.FC<IViewProps> = (props) => {
if (allRecords.length > 0) {
setCurrentRecordIndex(newRecordIndex);
}
}, [recordIdsInSelectionStr, freeze, allRecords]);
}, [recordIdsInSelectionStr, freeze]);

const changeCurrentRecordIndex = () => {
if (
Expand Down Expand Up @@ -143,6 +143,7 @@ export const View: React.FC<IViewProps> = (props) => {

const multiRecords = useRecords(viewId, {
ids: individualSelection?.recordIds,
filter
});

const singleRecord = allRecords.length
Expand Down
3 changes: 1 addition & 2 deletions src/components/setting/fieldItem/fieldItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IconButton, Select, useThemeColors } from "@apitable/components";
import { DeleteOutlined } from "@apitable/icons";
import { useFields, useRecords, useSettingsButton } from "@apitable/widget-sdk";
import { useSettingsButton } from "@apitable/widget-sdk";
import { getNumFields } from "../../utils";
import { IConfig } from "index";
import React from "react";
Expand All @@ -17,7 +17,6 @@ export const FieldItem: React.FC<IFieldItem> = (props) => {
const [isSettingOpened] = useSettingsButton();
const { i, v, config, setConfig } = props; // The "i" is an index in dimensionFieldids, the "v" is the value of dimensionFieldids
const { dimensionFieldIds, viewId } = config;
const allFields = useFields(viewId);
const colors = useThemeColors()
const number_fields = getNumFields(viewId);

Expand Down
119 changes: 119 additions & 0 deletions src/components/setting/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, t } from "@apitable/widget-sdk"
import styled from 'styled-components';
import { Strings } from '../utils';

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 style={{ marginTop: 8 }}>
{
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/components/setting/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./setting";
export * from "./filter_select";
19 changes: 12 additions & 7 deletions src/components/setting/setting.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import { IConfig } from "index";
import React, { useEffect, useMemo, useState } from "react";
import React, { useEffect, useMemo } from "react";
import {
useActiveViewId,
useFields,
useMeta,
useSettingsButton,
useViewIds,
t,
RuntimeEnv
} from "@apitable/widget-sdk";

import { Box, Typography, Button, Alert, Tooltip, useThemeColors } from "@apitable/components";
import { Typography, Button, Alert, Tooltip, useThemeColors } from "@apitable/components";
import { AddOutlined, InformationSmallOutlined } from "@apitable/icons";
import { FieldItem } from "./fieldItem/fieldItem";
import { SettingPanel } from "./styled";
import { getNumFields, Strings } from "../utils";
import { FilterSelect } from "./filter_select";



const FormItem = ({ label, colors, children }) => {
return (
<Box>
<div style={{ marginBottom: 16 }}>
<Typography style={{ fontSize: "12px", color: colors.fc3 }}>
{label}
</Typography>
<div style={{ width: "100%" }}>{children}</div>
</Box>
</div>
);
};

Expand All @@ -45,10 +45,8 @@ export const Setting: React.FC<ISettingProps> = (props) => {
const { installPosition, runtimeEnv } = useMeta(); // Get the installation location and operating environment of the widget
const colors = useThemeColors()


const activeViewId =
installPosition === "WidgetPanel" ? useActiveViewId() : useViewIds()[0];
const allFields = useFields(viewId);
const number_fields = getNumFields(viewId);
const number_fieldIds = number_fields.map((field) => field.id);
// When create/update/delete the number field, modify the demensionFieldIds synchronous modification
Expand Down Expand Up @@ -116,6 +114,13 @@ export const Setting: React.FC<ISettingProps> = (props) => {
<Typography style={{ fontSize: "14px" }}>{t(Strings.function_settings)}</Typography>
</div>

<FormItem label={`${t(Strings.filter)}`} colors={colors}>
<FilterSelect
value={config.filter}
onChange={(filter) => setConfig({ ...config, filter })}
/>
</FormItem>

<FormItem label={`${t(Strings.select_dimensions)}(${dimensionFieldIds.length}/10)`} colors={colors}>
{Array.from(dimensionFieldIds, (v: string, i) => {
return (
Expand Down
5 changes: 2 additions & 3 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ import {
useSelection,
useCloudStorage,
useActiveViewId,
useFields,
useMeta,
useViewIds,
useDatasheet,
FieldType,
useSettingsButton,
} from "@apitable/widget-sdk";
import { ThemeProvider, useThemeColors } from "@apitable/components";
Expand All @@ -25,6 +22,7 @@ export enum SortType {

export interface IConfig {
viewId: string | undefined;
filter: string | null;
freeze: boolean;
dimensionFieldIds: string[];
sortType: SortType;
Expand All @@ -50,6 +48,7 @@ export const useGetDefaultConfig = () => {
return useCallback(() => {
return {
viewId: defaultViewId, // View ID
filter: null,
freeze: false, // whether to lock
dimensionFieldIds: defaultDimensionFieldIds, // The selected field's ID
sortType: SortType.None, // Sorting mode, default is None
Expand Down
24 changes: 24 additions & 0 deletions src/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,30 @@
"add_a_dimension": {
"zh_CN": "添加维度",
"en_US": "Add"
},
"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"
},
"filter": {
"zh_CN": "筛选",
"en_US": "Filter"
}
}
}
6 changes: 3 additions & 3 deletions widget.config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"packageId": "",
"spaceId": "",
"packageId": "wpkwnbexhiWDq",
"spaceId": "spcKJspLmm8E6",
"entry": "./src/index.tsx",
"name": {
"zh-CN": "漏斗图",
Expand All @@ -13,7 +13,7 @@
"zh-CN": "比较各环节业务数据,发现问题,进而做出决策。常用于短信/邮件/电商销售的活动监控,或者在复盘汇报中可视化展示。",
"en-US": "Analyze the data for different sections within the procedure, reveal the issue and help making the well-informed decision. Often used in SMS/email/online retailing campaigns as well as data visualization in summary reports."
},
"globalPackageId": "",
"globalPackageId": "wpkZV0RkAD90t",
"sandbox": true,
"authorName": "APITbale",
"authorLink": "https://apitable.com",
Expand Down

0 comments on commit 63a4c81

Please sign in to comment.