From 569953f6059b76d9292c3f824b1851a2e2bd847c Mon Sep 17 00:00:00 2001 From: mintsweet <0x1304570@gmail.com> Date: Fri, 27 Sep 2024 18:32:52 +1200 Subject: [PATCH] feat: simplify the miller columns --- config-ui/package.json | 4 +- .../data-scope-remote/search-local.tsx | 129 ++++++----------- .../data-scope-remote/search-remote.tsx | 135 ++++++++---------- .../components/data-scope-select/index.tsx | 95 +++++++----- .../webhook/components/selector-dialog.tsx | 19 +-- config-ui/yarn.lock | 20 +-- 6 files changed, 189 insertions(+), 213 deletions(-) diff --git a/config-ui/package.json b/config-ui/package.json index 6bf07198852..7e1305d7240 100644 --- a/config-ui/package.json +++ b/config-ui/package.json @@ -24,8 +24,8 @@ "dependencies": { "@ant-design/icons": "^5.4.0", "@fontsource/roboto": "^5.0.14", - "@mints/hooks": "^1.0.0-beta.2", - "@mints/miller-columns": "^2.0.0-beta.5", + "@mints/hooks": "^1.0.0-beta.9", + "@mints/miller-columns": "^2.0.0-beta.10", "@mui/icons-material": "^5.16.7", "@mui/material": "^5.16.7", "@mui/styled-engine-sc": "^6.0.0-alpha.18", diff --git a/config-ui/src/plugins/components/data-scope-remote/search-local.tsx b/config-ui/src/plugins/components/data-scope-remote/search-local.tsx index 67b8f4a7f16..961ca68e918 100644 --- a/config-ui/src/plugins/components/data-scope-remote/search-local.tsx +++ b/config-ui/src/plugins/components/data-scope-remote/search-local.tsx @@ -16,11 +16,12 @@ * */ -import { useState, useReducer, useCallback } from 'react'; +import { useState, useReducer } from 'react'; import { CheckCircleFilled, SearchOutlined } from '@ant-design/icons'; import { Space, Tag, Button, Input, Modal } from 'antd'; -import { MillerColumns } from '@mints/miller-columns'; import { useDebounce } from '@mints/hooks'; +import type { IDType } from '@mints/miller-columns'; +import { MillerColumns } from '@mints/miller-columns'; import API from '@/api'; import { Block, Loading, Message } from '@/components'; @@ -76,43 +77,26 @@ export const SearchLocal = ({ mode, plugin, connectionId, config, disabledScope, const searchDebounce = useDebounce(search, { wait: 500 }); - const request = useCallback( - async (groupId?: string | number, params?: any) => { - const res = await API.scope.remote(plugin, connectionId, { - groupId: groupId ?? null, - pageToken: params?.nextPageToken, - }); - - return { - data: res.children.map((it) => ({ - parentId: it.parentId, - id: it.id, - title: it.name ?? it.fullName, - canExpand: it.type === 'group', - original: it, - })), - hasMore: !!res.nextPageToken, - params: { - nextPageToken: res.nextPageToken, - }, - }; - }, - [plugin, connectionId, scope, searchDebounce], - ); + const request = async (groupId?: string | number, params?: any) => { + const res = await API.scope.remote(plugin, connectionId, { + groupId: groupId ?? null, + pageToken: params?.nextPageToken, + }); - const requestAll = useCallback( - async (groupId?: string | number) => { - return { - data: searchDebounce - ? scope - .filter((it) => it.title.includes(searchDebounce) && !it.canExpand) - .map((it) => ({ ...it, parentId: null })) - : scope.filter((it) => it.parentId === (groupId ?? null)), - hasMore: false, - }; - }, - [scope, searchDebounce], - ); + return { + data: res.children.map((it) => ({ + parentId: it.parentId, + id: it.id, + title: it.name ?? it.fullName, + canExpand: it.type === 'group', + original: it, + })), + hasMore: !!res.nextPageToken, + params: { + nextPageToken: res.nextPageToken, + }, + }; + }; const handleRequestAll = async () => { setOpen(false); @@ -145,6 +129,24 @@ export const SearchLocal = ({ mode, plugin, connectionId, config, disabledScope, dispatch({ type: 'DONE' }); }; + const millerColumnsProps = { + bordered: true, + theme: { + colorPrimary: '#7497f7', + borderColor: '#dbe4fd', + }, + columnHeight: 300, + mode, + renderTitle: (id?: IDType) => + !id && + config.millerColumn?.firstColumnTitle && {config.millerColumn.firstColumnTitle}, + renderLoading: () => , + selectable: true, + disabledIds: disabledScope.map((it) => it.id), + selectedIds: selectedScope.map((it) => it.id), + onSelectedIds: (_: IDType[], data?: any) => onChange(data ?? []), + }; + return ( <> @@ -189,56 +191,19 @@ export const SearchLocal = ({ mode, plugin, connectionId, config, disabledScope, )} - {status === 'idle' && ( + {status === 'idle' ? ( - !id && - config.millerColumn?.firstColumnTitle && ( - {config.millerColumn.firstColumnTitle} - ) - } - renderLoading={() => } - renderError={() => Something Error} - selectable - disabledIds={(disabledScope ?? []).map((it) => it.id)} - selectedIds={selectedScope.map((it) => it.id)} - onSelectedIds={(_, data) => onChange(data ?? [])} + columnCount={config.millerColumn?.columnCount ?? 1} /> - )} - {status === 'done' && ( + ) : ( <> } value={search} onChange={(e) => setSearch(e.target.value)} /> - !id && - config.millerColumn?.firstColumnTitle && ( - {config.millerColumn.firstColumnTitle} - ) - } - renderLoading={() => } - renderError={() => Something Error} - selectable - disabledIds={(disabledScope ?? []).map((it) => it.id)} - selectedIds={selectedScope.map((it) => it.id)} - onSelectedIds={(_, data) => onChange(data ?? [])} + {...millerColumnsProps} + loading={status === 'loading'} + items={searchDebounce ? scope.filter((it) => it.title.includes(searchDebounce) && !it.canExpand) : scope} /> )} diff --git a/config-ui/src/plugins/components/data-scope-remote/search-remote.tsx b/config-ui/src/plugins/components/data-scope-remote/search-remote.tsx index 0510ad29a88..1841d3403b4 100644 --- a/config-ui/src/plugins/components/data-scope-remote/search-remote.tsx +++ b/config-ui/src/plugins/components/data-scope-remote/search-remote.tsx @@ -16,11 +16,13 @@ * */ -import { useState, useCallback } from 'react'; +import { useState } from 'react'; import { SearchOutlined } from '@ant-design/icons'; import { Space, Tag, Input } from 'antd'; -import { MillerColumns } from '@mints/miller-columns'; +import { useRequest } from '@mints/hooks'; import { useDebounce } from '@mints/hooks'; +import type { IDType } from '@mints/miller-columns'; +import { MillerColumns } from '@mints/miller-columns'; import API from '@/api'; import { Block, Loading } from '@/components'; @@ -43,60 +45,62 @@ export const SearchRemote = ({ mode, plugin, connectionId, config, disabledScope const searchDebounce = useDebounce(search, { wait: 500 }); - const request = useCallback( - async (groupId?: string | number, params?: any) => { - let data = []; - let hasMore = false; - let newParams = {}; - - if (!searchDebounce) { - const res = await API.scope.remote(plugin, connectionId, { - groupId: groupId ?? null, - pageToken: params?.pageToken, - }); - - data = res.children.map((it) => ({ - parentId: it.parentId, - id: it.id, - title: it.name ?? it.fullName, - canExpand: it.type === 'group', - original: it, - })); + const { loading, data } = useRequest(async () => { + if (!searchDebounce) { + return []; + } + const res = await API.scope.searchRemote(plugin, connectionId, { + search: searchDebounce, + page: 1, + pageSize: 50, + }); + return res.children.map((it) => ({ + parentId: it.parentId, + id: it.id, + title: it.fullName ?? it.name, + canExpand: it.type === 'group', + original: it, + })); + }, [plugin, connectionId, searchDebounce]); - hasMore = !!res.nextPageToken; - newParams = { - pageToken: res.nextPageToken, - }; - } else { - const res = await API.scope.searchRemote(plugin, connectionId, { - search: searchDebounce, - page: params?.page ?? 1, - pageSize: 20, - }); + const request = async (groupId?: string | number, params?: any) => { + const res = await API.scope.remote(plugin, connectionId, { + groupId: groupId ?? null, + pageToken: params?.pageToken, + }); - data = res.children.map((it) => ({ - parentId: it.parentId, - id: it.id, - title: it.fullName ?? it.name, - canExpand: it.type === 'group', - original: it, - })); + return { + data: res.children.map((it) => ({ + parentId: it.parentId, + id: it.id, + title: it.name ?? it.fullName, + canExpand: it.type === 'group', + original: it, + })), + hasMore: !!res.nextPageToken, + params: { + pageToken: res.nextPageToken, + }, + }; + }; - hasMore = res.children.length === res.pageSize; - newParams = { - page: (params?.page ?? 0) + 1, - count: (params?.count ?? 0) + res.children.length, - }; - } - - return { - data, - hasMore, - params: newParams, - }; + const millerColumnsProps = { + bordered: true, + theme: { + colorPrimary: '#7497f7', + borderColor: '#dbe4fd', }, - [plugin, connectionId, searchDebounce], - ); + columnHeight: 300, + mode, + renderTitle: (id?: IDType) => + !id && + config.millerColumn?.firstColumnTitle && {config.millerColumn.firstColumnTitle}, + renderLoading: () => , + selectable: true, + disabledIds: disabledScope.map((it) => it.id), + selectedIds: selectedScope.map((it) => it.id), + onSelectedIds: (_: IDType[], data?: any) => onChange(data ?? []), + }; return ( <> @@ -125,28 +129,11 @@ export const SearchRemote = ({ mode, plugin, connectionId, config, disabledScope value={search} onChange={(e) => setSearch(e.target.value)} /> - - !id && - config.millerColumn?.firstColumnTitle && ( - {config.millerColumn.firstColumnTitle} - ) - } - renderLoading={() => } - selectable - disabledIds={disabledScope.map((it) => it.id)} - selectedIds={selectedScope.map((it) => it.id)} - onSelectedIds={(_, data) => onChange(data ?? [])} - /> + {searchDebounce ? ( + + ) : ( + + )} ); diff --git a/config-ui/src/plugins/components/data-scope-select/index.tsx b/config-ui/src/plugins/components/data-scope-select/index.tsx index d6913cee0a8..6bee1af1e61 100644 --- a/config-ui/src/plugins/components/data-scope-select/index.tsx +++ b/config-ui/src/plugins/components/data-scope-select/index.tsx @@ -19,12 +19,15 @@ import { useState, useEffect, useCallback } from 'react'; import { RedoOutlined, PlusOutlined } from '@ant-design/icons'; import { Flex, Button, Input, Space, Tag } from 'antd'; +import { useRequest } from '@mints/hooks'; +import type { IDType } from '@mints/miller-columns'; import { MillerColumns } from '@mints/miller-columns'; import { useDebounce } from '@mints/hooks'; import API from '@/api'; import { Loading, Block, ExternalLink, Message } from '@/components'; import { getPluginScopeId } from '@/plugins'; +import type { IDataScope } from '@/types'; interface Props { plugin: string; @@ -65,6 +68,25 @@ export const DataScopeSelect = ({ ); }, []); + const { loading, data } = useRequest(async () => { + if (!searchDebounce) { + return []; + } + const res = await API.scope.list(plugin, connectionId, { + page: 1, + pageSize: 50, + searchTerm: searchDebounce, + }); + + return res.scopes.map((it) => ({ + parentId: null, + id: getPluginScopeId(plugin, it.scope), + title: it.scope.fullName ?? it.scope.name, + canExpand: false, + original: it, + })); + }, [plugin, connectionId, searchDebounce, version]); + const request = useCallback( async (_?: string | number, params?: any) => { const res = await API.scope.list(plugin, connectionId, { @@ -87,11 +109,46 @@ export const DataScopeSelect = ({ }, }; }, - [plugin, connectionId, searchDebounce, version], + [plugin, connectionId], ); const handleSubmit = () => onSubmit?.(selectedIds); + const millerColumnsProps = { + bordered: true, + theme: { + colorPrimary: '#7497f7', + borderColor: '#dbe4fd', + }, + columnHeight: 200, + renderLoading: () => , + renderNoData: () => ( + + + + + + ), + selectable: true, + selectedIds, + onSelectedIds: ( + ids: IDType[], + data?: Array<{ + scope: IDataScope; + }>, + ) => { + setSelectedIds(ids); + setSelectedScope( + (data ?? []).map((it) => ({ + id: getPluginScopeId(plugin, it.scope), + name: it.scope.fullName ?? it.scope.name, + })), + ); + }, + }; + return (
setSearch(e.target.value)} /> - } - renderError={() => Something Error} - renderNoData={() => ( - - - - - - )} - selectable - selectedIds={selectedIds} - onSelectedIds={(ids, data) => { - setSelectedIds(ids); - setSelectedScope( - (data ?? []).map((it) => ({ - id: it.scope.id, - name: it.scope.name, - })), - ); - }} - /> + {searchDebounce ? ( + + ) : ( + + )}
diff --git a/config-ui/src/plugins/register/webhook/components/selector-dialog.tsx b/config-ui/src/plugins/register/webhook/components/selector-dialog.tsx index a0c972dee37..516298572a9 100644 --- a/config-ui/src/plugins/register/webhook/components/selector-dialog.tsx +++ b/config-ui/src/plugins/register/webhook/components/selector-dialog.tsx @@ -16,7 +16,7 @@ * */ -import { useCallback, useState } from 'react'; +import { useState } from 'react'; import { Modal } from 'antd'; import { MillerColumns } from '@mints/miller-columns'; @@ -39,17 +39,6 @@ export const SelectorDialog = ({ open, saving, onCancel, onSubmit }: Props) => { const webhooks = useAppSelector(selectWebhooks); - const request = useCallback(async () => { - return { - data: webhooks.map((it) => ({ - parentId: null, - id: it.id, - title: it.name, - })), - hasMore: false, - }; - }, [webhooks]); - const handleSubmit = () => onSubmit(webhooks.filter((it) => selectedIds.includes(it.id))); return ( @@ -74,7 +63,11 @@ export const SelectorDialog = ({ open, saving, onCancel, onSubmit }: Props) => { colorPrimary: '#7497f7', borderColor: '#dbe4fd', }} - request={request} + items={webhooks.map((it) => ({ + parentId: null, + id: it.id, + title: it.name, + }))} columnHeight={160} renderLoading={() => } selectable diff --git a/config-ui/yarn.lock b/config-ui/yarn.lock index 9e36a73e38c..c7db434e486 100644 --- a/config-ui/yarn.lock +++ b/config-ui/yarn.lock @@ -2073,9 +2073,9 @@ __metadata: languageName: node linkType: hard -"@mints/hooks@npm:^1.0.0-beta.2": - version: 1.0.0-beta.2 - resolution: "@mints/hooks@npm:1.0.0-beta.2" +"@mints/hooks@npm:^1.0.0-beta.9": + version: 1.0.0-beta.9 + resolution: "@mints/hooks@npm:1.0.0-beta.9" dependencies: lodash: ^4.17.21 react: ^18.3.1 @@ -2083,13 +2083,13 @@ __metadata: peerDependencies: react: ^18.3.1 react-dom: ^18.3.1 - checksum: b11707b70aca8c931d247e18065046d7f5bbef4eee7e17bbae1ff1c85a4f90e830d6af0d3397bd8bec63fa81b5f44055363184b162b4cd90edc0316d4d53251b + checksum: 03f146f2e1881dee18383502dc7631f630c7b99fd7da67d54d37a7b3abac6518e0a302e34b968c72d27cb21ae0c45c39e34d668930881d3e1fd2fbb7dac34b85 languageName: node linkType: hard -"@mints/miller-columns@npm:^2.0.0-beta.5": - version: 2.0.0-beta.5 - resolution: "@mints/miller-columns@npm:2.0.0-beta.5" +"@mints/miller-columns@npm:^2.0.0-beta.10": + version: 2.0.0-beta.10 + resolution: "@mints/miller-columns@npm:2.0.0-beta.10" dependencies: "@fontsource/roboto": ^5.0.14 "@mui/material": ^5.16.7 @@ -2108,7 +2108,7 @@ __metadata: react-dom: ^18.2.0 react-infinite-scroll-component: ^6.1.0 styled-components: ^6.1.12 - checksum: 2ff5e7e942a1f5e592d7fe53d5522a59d72075604e80cfcf816d70d67ad33d3982b699770cdab01065bff19a219117b51017ea878ce5f015f120fb6623431839 + checksum: 94c3ba41210f2ccbddc413ef6c26e5615f11c5a3aac7954484d838d1b05713543def70b6714e79cfc396efea522f553b2d648b36af994bf66456a440836a1386 languageName: node linkType: hard @@ -3910,8 +3910,8 @@ __metadata: dependencies: "@ant-design/icons": ^5.4.0 "@fontsource/roboto": ^5.0.14 - "@mints/hooks": ^1.0.0-beta.2 - "@mints/miller-columns": ^2.0.0-beta.5 + "@mints/hooks": ^1.0.0-beta.9 + "@mints/miller-columns": ^2.0.0-beta.10 "@mui/icons-material": ^5.16.7 "@mui/material": ^5.16.7 "@mui/styled-engine-sc": ^6.0.0-alpha.18