@aloudata/aloudata-design 3.1.6 → 3.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ConfigProvider/getUserList.d.ts +47 -0
- package/dist/ConfigProvider/getUserList.js.map +1 -1
- package/dist/ConfigProvider/hooks/useGetUserList.d.ts +7 -0
- package/dist/ConfigProvider/hooks/useGetUserList.js +5 -1
- package/dist/ConfigProvider/hooks/useGetUserList.js.map +1 -1
- package/dist/ConfigProvider/index.d.ts +5 -1
- package/dist/ConfigProvider/index.js +6 -2
- package/dist/ConfigProvider/index.js.map +1 -1
- package/dist/Dropdown/index.d.ts +7 -2
- package/dist/Dropdown/index.js +52 -18
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/MemberPicker/components/MultipleOption.d.ts +1 -0
- package/dist/MemberPicker/components/MultipleOption.js +3 -1
- package/dist/MemberPicker/components/MultipleOption.js.map +1 -1
- package/dist/MemberPicker/components/NickLabel.d.ts +5 -0
- package/dist/MemberPicker/components/NickLabel.js +14 -4
- package/dist/MemberPicker/components/NickLabel.js.map +1 -1
- package/dist/MemberPicker/components/Panel.d.ts +6 -1
- package/dist/MemberPicker/components/Panel.js +17 -5
- package/dist/MemberPicker/components/Panel.js.map +1 -1
- package/dist/MemberPicker/components/PanelWrapper.d.ts +3 -2
- package/dist/MemberPicker/components/PanelWrapper.js +27 -25
- package/dist/MemberPicker/components/PanelWrapper.js.map +1 -1
- package/dist/MemberPicker/components/SearchFeedback.d.ts +7 -0
- package/dist/MemberPicker/components/SearchFeedback.js +27 -0
- package/dist/MemberPicker/components/SearchFeedback.js.map +1 -0
- package/dist/MemberPicker/components/SingleOption.d.ts +1 -0
- package/dist/MemberPicker/components/SingleOption.js +3 -1
- package/dist/MemberPicker/components/SingleOption.js.map +1 -1
- package/dist/MemberPicker/components/UserGroupSelection.d.ts +6 -1
- package/dist/MemberPicker/components/UserGroupSelection.js +30 -23
- package/dist/MemberPicker/components/UserGroupSelection.js.map +1 -1
- package/dist/MemberPicker/dialog/DialogColumns.d.ts +5 -0
- package/dist/MemberPicker/dialog/DialogColumns.js +59 -0
- package/dist/MemberPicker/dialog/DialogColumns.js.map +1 -0
- package/dist/MemberPicker/dialog/DialogContent.d.ts +3 -0
- package/dist/MemberPicker/dialog/DialogContent.js +109 -0
- package/dist/MemberPicker/dialog/DialogContent.js.map +1 -0
- package/dist/MemberPicker/dialog/MemberOption.d.ts +16 -0
- package/dist/MemberPicker/dialog/MemberOption.js +101 -0
- package/dist/MemberPicker/dialog/MemberOption.js.map +1 -0
- package/dist/MemberPicker/dialog/MemberPickerDialog.d.ts +11 -0
- package/dist/MemberPicker/dialog/MemberPickerDialog.js +11 -0
- package/dist/MemberPicker/dialog/MemberPickerDialog.js.map +1 -0
- package/dist/MemberPicker/dialog/SelectedMemberPanel.d.ts +12 -0
- package/dist/MemberPicker/dialog/SelectedMemberPanel.js +37 -0
- package/dist/MemberPicker/dialog/SelectedMemberPanel.js.map +1 -0
- package/dist/MemberPicker/dialog/UserCandidatePanel.d.ts +13 -0
- package/dist/MemberPicker/dialog/UserCandidatePanel.js +168 -0
- package/dist/MemberPicker/dialog/UserCandidatePanel.js.map +1 -0
- package/dist/MemberPicker/dialog/UserGroupCandidatePanel.d.ts +14 -0
- package/dist/MemberPicker/dialog/UserGroupCandidatePanel.js +134 -0
- package/dist/MemberPicker/dialog/UserGroupCandidatePanel.js.map +1 -0
- package/dist/MemberPicker/dialog/helper.d.ts +20 -0
- package/dist/MemberPicker/dialog/helper.js +61 -0
- package/dist/MemberPicker/dialog/helper.js.map +1 -0
- package/dist/MemberPicker/dialog/types.d.ts +41 -0
- package/dist/MemberPicker/dialog/types.js +7 -0
- package/dist/MemberPicker/dialog/types.js.map +1 -0
- package/dist/MemberPicker/dialog/useDialogLocale.d.ts +103 -0
- package/dist/MemberPicker/dialog/useDialogLocale.js +12 -0
- package/dist/MemberPicker/dialog/useDialogLocale.js.map +1 -0
- package/dist/MemberPicker/dialog/useMemberPickerDraft.d.ts +27 -0
- package/dist/MemberPicker/dialog/useMemberPickerDraft.js +95 -0
- package/dist/MemberPicker/dialog/useMemberPickerDraft.js.map +1 -0
- package/dist/MemberPicker/dialog/useUserGroupCandidates.d.ts +29 -0
- package/dist/MemberPicker/dialog/useUserGroupCandidates.js +443 -0
- package/dist/MemberPicker/dialog/useUserGroupCandidates.js.map +1 -0
- package/dist/MemberPicker/index.d.ts +2 -0
- package/dist/MemberPicker/index.js +61 -35
- package/dist/MemberPicker/index.js.map +1 -1
- package/dist/MemberPicker/interface.d.ts +6 -0
- package/dist/MemberPicker/interface.js.map +1 -1
- package/dist/MemberPicker/useMemberSearch.d.ts +8 -0
- package/dist/MemberPicker/useMemberSearch.js +51 -0
- package/dist/MemberPicker/useMemberSearch.js.map +1 -0
- package/dist/Menu/index.d.ts +6 -0
- package/dist/Menu/index.js +21 -9
- package/dist/Menu/index.js.map +1 -1
- package/dist/Modal/index.js +1 -1
- package/dist/Modal/index.js.map +1 -1
- package/dist/aloudata-design.css +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -2
- package/dist/locale/default.d.ts +29 -0
- package/dist/locale/en_US.d.ts +29 -0
- package/dist/locale/en_US.js +29 -0
- package/dist/locale/en_US.js.map +1 -1
- package/dist/locale/zh_CN.d.ts +29 -0
- package/dist/locale/zh_CN.js +29 -0
- package/dist/locale/zh_CN.js.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserGroupSelection.js","names":[],"sources":["../../../src/MemberPicker/components/UserGroupSelection.tsx"],"sourcesContent":["import Breadcrumb from '../../Breadcrumb';\nimport { cn } from '../../lib/utils';\nimport _ from 'lodash';\nimport React, { useContext, useEffect, useMemo, useState } from 'react';\nimport GetUserListContext, {\n IUserGroup,\n TUserGroupValue,\n TUserValue,\n} from '../../ConfigProvider/getUserList';\nimport Empty from '../../Empty';\nimport { ChevronLeftLine, SearchLine } from '../../Icon';\nimport Input from '../../Input';\nimport ScrollArea from '../../ScrollArea';\nimport Spin from '../../Spin';\nimport { LocaleContext, getTranslator } from '../../locale/default';\nimport { isUserGroup } from '../utils/getUsersWithUserId';\nimport MultipleOption from './MultipleOption';\nimport SingleOption from './SingleOption';\n\ninterface IProps {\n className?: string;\n userGroupList: IUserGroup[];\n multiple?: boolean;\n onChange: (selected: boolean, userGroup: IUserGroup) => void;\n selectedUsersGroup: IUserGroup[];\n loading: boolean;\n onSearchValueChange?: (value: string) => void;\n width: number;\n lockedIds: Array<TUserValue | TUserGroupValue>;\n filterItem?: (item: IUserGroup) => boolean;\n searchValue?: string;\n showSearch?: boolean;\n renderItem?: (\n item: IUserGroup,\n context: {\n isSelected: boolean;\n disabled: boolean;\n onClick: () => void;\n onNextLevel?: () => void;\n originNode: React.ReactNode;\n },\n ) => React.ReactNode;\n}\n\nconst UserGroupSelection = ({\n className,\n userGroupList,\n multiple,\n onChange,\n selectedUsersGroup: selectedUsersGroups,\n loading,\n onSearchValueChange,\n width,\n lockedIds,\n filterItem,\n searchValue = '',\n showSearch,\n renderItem,\n}: IProps) => {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const { getNextLevelGroup } = useContext(GetUserListContext);\n\n const isAsync = !!getNextLevelGroup;\n\n const [groupPath, setGroupPath] = useState<IUserGroup[]>([]);\n const [asyncUserGroupList, setAsyncUserGroupList] = useState<IUserGroup[]>(\n [],\n );\n const parentGroupId = _.last(groupPath)?.groupId;\n\n useEffect(() => {\n if (!getNextLevelGroup) {\n return;\n }\n\n let ignore = false;\n getNextLevelGroup({\n parentGroupId,\n keyword: searchValue,\n }).then((userGroups) => {\n if (!ignore) {\n setAsyncUserGroupList(userGroups);\n }\n });\n\n return () => {\n ignore = true;\n };\n }, [getNextLevelGroup, parentGroupId, searchValue]);\n\n const filterUserList = useMemo(() => {\n let currentLevelGroups = asyncUserGroupList;\n\n if (!isAsync) {\n currentLevelGroups = userGroupList.filter((userGroup) => {\n if (groupPath.length === 0) {\n return !userGroup.parentId;\n }\n\n return userGroup.parentId === parentGroupId;\n });\n\n const normalizedKeyword = searchValue.trim().toLowerCase();\n currentLevelGroups = currentLevelGroups.filter((group) => {\n if (!normalizedKeyword) {\n return true;\n }\n\n return group.name.toLowerCase().includes(normalizedKeyword);\n });\n }\n\n return currentLevelGroups.filter((userGroup) => {\n if (filterItem) {\n return filterItem(userGroup);\n }\n\n return true;\n });\n }, [\n asyncUserGroupList,\n filterItem,\n groupPath.length,\n isAsync,\n parentGroupId,\n searchValue,\n userGroupList,\n ]);\n\n return (\n <div className={cn(className, 'ald-member-picker-member-list-wrap')}>\n {showSearch && (\n <Input\n prefix={<SearchLine size={16} />}\n className=\"ald-member-picker-search-input\"\n aria-label={t.InputSearch.search}\n autoFocus\n value={searchValue}\n onChange={(event) => onSearchValueChange?.(event.target.value)}\n />\n )}\n {userGroupList.length === 0 && !loading && (\n <Empty\n title={t.MemberPicker.noData}\n size=\"small\"\n image={Empty.PRESENTED_IMAGE_SEARCH}\n className=\"ald-member-picker-member-list-empty\"\n />\n )}\n {groupPath.length !== 0 && (\n <ScrollArea className=\"ald-member-picker-breadcrumb-scroll\">\n <Breadcrumb className=\"ald-member-picker-breadcrumb\">\n <Breadcrumb.Item\n className=\"ald-member-picker-breadcrumb-item\"\n onClick={() => {\n setGroupPath([]);\n }}\n >\n <div className=\"ald-member-picker-breadcrumb-item-inner\">\n <ChevronLeftLine size={16} />\n {t.MemberPicker.userGroups}\n </div>\n </Breadcrumb.Item>\n {groupPath.map((group) => (\n <Breadcrumb.Item\n className=\"ald-member-picker-breadcrumb-item\"\n key={group.groupId}\n onClick={() => {\n setGroupPath((groups) => {\n const groupIndex = groups.findIndex(\n (tempGroup) => tempGroup.groupId === group.groupId,\n );\n return groups.filter(\n (tempGroup, index) => index <= groupIndex,\n );\n });\n }}\n >\n <div className=\"ald-member-picker-breadcrumb-item-inner\">\n {group.name}\n </div>\n </Breadcrumb.Item>\n ))}\n </Breadcrumb>\n </ScrollArea>\n )}\n <Spin\n tip=\"Loading\"\n spinning={loading}\n size=\"small\"\n className=\"ald-member-picker-user-list\"\n >\n <ScrollArea\n className={cn('ald-member-picker-member-list', {\n 'ald-member-picker-member-list-null':\n userGroupList.length === 0 && !loading,\n })}\n innerClassName=\"ald-member-picker-member-scroll\"\n >\n <div\n role=\"listbox\"\n aria-label=\"Groups\"\n aria-multiselectable={multiple || undefined}\n className=\"ald-member-picker-member-list-inner\"\n style={{ width: multiple ? width : undefined, overflow: 'hidden' }}\n >\n {filterUserList.map((userGroup) => {\n const isSelected = selectedUsersGroups.some(\n (selectUserGroup) =>\n selectUserGroup.groupId === userGroup.groupId,\n );\n\n const index = _.findIndex(lockedIds, {\n groupId: userGroup.groupId,\n type: userGroup.type,\n });\n const disabled = index !== -1;\n\n const hasNextLevel =\n userGroupList.some(\n (group) => group.parentId === userGroup.groupId,\n ) || isAsync;\n const onNextLevel = () => {\n setGroupPath((prev) => [...prev, userGroup]);\n onSearchValueChange?.('');\n };\n\n const originNode = multiple ? (\n <MultipleOption\n key={userGroup.groupId}\n user={userGroup}\n disabled={disabled}\n selected={isSelected}\n onChange={(selected, userGroup) => {\n if (isUserGroup(userGroup)) {\n onChange(selected, userGroup);\n }\n }}\n hasNextLevel={hasNextLevel}\n onNextLevel={onNextLevel}\n ></MultipleOption>\n ) : (\n <SingleOption\n key={userGroup.groupId}\n user={userGroup}\n disabled={disabled}\n selected={isSelected}\n onChange={(selected, userGroup) => {\n if (isUserGroup(userGroup)) {\n onChange(selected, userGroup);\n }\n }}\n hasNextLevel={hasNextLevel}\n onNextLevel={onNextLevel}\n ></SingleOption>\n );\n\n if (renderItem) {\n return (\n <div\n key={userGroup.groupId}\n role=\"option\"\n id={`ald-member-picker-option-${userGroup.groupId}`}\n aria-selected={isSelected}\n aria-disabled={disabled || undefined}\n >\n {renderItem(userGroup, {\n isSelected,\n disabled,\n onClick: () => {\n if (isUserGroup(userGroup) && !disabled) {\n onChange(!isSelected, userGroup);\n }\n },\n onNextLevel: hasNextLevel ? onNextLevel : undefined,\n originNode,\n })}\n </div>\n );\n }\n\n return originNode;\n })}\n </div>\n </ScrollArea>\n </Spin>\n </div>\n );\n};\n\nexport default UserGroupSelection;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UserGroupSelection.js","names":[],"sources":["../../../src/MemberPicker/components/UserGroupSelection.tsx"],"sourcesContent":["import type { IBaseMemberSelectorProps } from '../interface';\nimport { useCallback } from 'react';\nimport useMemberSearch from '../useMemberSearch';\nimport SearchFeedback from './SearchFeedback';\nimport Breadcrumb from '../../Breadcrumb';\nimport { cn } from '../../lib/utils';\nimport _ from 'lodash';\nimport React, { useContext, useMemo, useState } from 'react';\nimport GetUserListContext, {\n IUserGroup,\n TUserGroupValue,\n TUserValue,\n} from '../../ConfigProvider/getUserList';\nimport Empty from '../../Empty';\nimport { ChevronLeftLine, SearchLine } from '../../Icon';\nimport Input from '../../Input';\nimport ScrollArea from '../../ScrollArea';\nimport Spin from '../../Spin';\nimport { LocaleContext, getTranslator } from '../../locale/default';\nimport { isUserGroup } from '../utils/getUsersWithUserId';\nimport MultipleOption from './MultipleOption';\nimport SingleOption from './SingleOption';\n\ninterface IProps {\n active?: boolean;\n useProvidedSearch?: boolean;\n parentSearchFailed?: boolean;\n className?: string;\n userGroupList: IUserGroup[];\n multiple?: boolean;\n onChange: (selected: boolean, userGroup: IUserGroup) => void;\n selectedUsersGroup: IUserGroup[];\n loading: boolean;\n onSearchValueChange?: (value: string) => void;\n width: number;\n lockedIds: Array<TUserValue | TUserGroupValue>;\n filterItem?: (item: IUserGroup) => boolean;\n searchValue?: string;\n showSearch?: boolean;\n canEnterGroup?: IBaseMemberSelectorProps['canEnterGroup'];\n renderItem?: (\n item: IUserGroup,\n context: {\n isSelected: boolean;\n disabled: boolean;\n onClick: () => void;\n onNextLevel?: () => void;\n originNode: React.ReactNode;\n },\n ) => React.ReactNode;\n}\n\nconst UserGroupSelection = ({\n active = true,\n useProvidedSearch = false,\n parentSearchFailed = false,\n className,\n userGroupList,\n multiple,\n onChange,\n selectedUsersGroup: selectedUsersGroups,\n loading,\n onSearchValueChange,\n width,\n lockedIds,\n filterItem,\n searchValue = '',\n showSearch,\n canEnterGroup,\n renderItem,\n}: IProps) => {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const { getNextLevelGroup, getNextLevelGroupWithMeta } =\n useContext(GetUserListContext);\n\n const isAsync = !!(getNextLevelGroup || getNextLevelGroupWithMeta);\n\n const [groupPath, setGroupPath] = useState<IUserGroup[]>([]);\n const parentGroupId = _.last(groupPath)?.groupId;\n const queryGroups = useCallback(\n (keyword: string) => {\n const params = { parentGroupId, keyword };\n if (getNextLevelGroupWithMeta) return getNextLevelGroupWithMeta(params);\n return getNextLevelGroup\n ? getNextLevelGroup(params)\n : Promise.resolve([]);\n },\n [getNextLevelGroup, getNextLevelGroupWithMeta, parentGroupId],\n );\n const {\n result,\n loading: groupLoading,\n failed,\n retry,\n } = useMemberSearch<IUserGroup>(\n queryGroups,\n searchValue,\n isAsync && active && !useProvidedSearch,\n );\n const asyncUserGroupList = result.items;\n\n const filterUserList = useMemo(() => {\n let currentLevelGroups = asyncUserGroupList;\n\n if (!isAsync || useProvidedSearch) {\n currentLevelGroups = userGroupList.filter((userGroup) => {\n if (searchValue.trim()) return true;\n if (groupPath.length === 0) {\n return !userGroup.parentId;\n }\n\n return userGroup.parentId === parentGroupId;\n });\n\n const normalizedKeyword = searchValue.trim().toLowerCase();\n currentLevelGroups = currentLevelGroups.filter((group) => {\n if (!normalizedKeyword) {\n return true;\n }\n\n return group.name.toLowerCase().includes(normalizedKeyword);\n });\n }\n\n return currentLevelGroups.filter((userGroup) => {\n if (filterItem) {\n return filterItem(userGroup);\n }\n\n return true;\n });\n }, [\n asyncUserGroupList,\n filterItem,\n groupPath.length,\n isAsync,\n useProvidedSearch,\n parentGroupId,\n searchValue,\n userGroupList,\n ]);\n\n return (\n <div className={cn(className, 'ald-member-picker-member-list-wrap')}>\n {showSearch && (\n <Input\n prefix={<SearchLine size={16} />}\n className=\"ald-member-picker-search-input\"\n aria-label={t.InputSearch.search}\n autoFocus\n value={searchValue}\n onChange={(event) => onSearchValueChange?.(event.target.value)}\n />\n )}\n {filterUserList.length === 0 &&\n !loading &&\n !(useProvidedSearch ? parentSearchFailed : groupLoading || failed) && (\n <Empty\n title={t.MemberPicker.noData}\n size=\"small\"\n image={Empty.PRESENTED_IMAGE_SEARCH}\n className=\"ald-member-picker-member-list-empty\"\n />\n )}\n {groupPath.length !== 0 && (\n <ScrollArea className=\"ald-member-picker-breadcrumb-scroll\">\n <Breadcrumb className=\"ald-member-picker-breadcrumb\">\n <Breadcrumb.Item\n className=\"ald-member-picker-breadcrumb-item\"\n onClick={() => {\n setGroupPath([]);\n }}\n >\n <div className=\"ald-member-picker-breadcrumb-item-inner\">\n <ChevronLeftLine size={16} />\n {t.MemberPicker.userGroups}\n </div>\n </Breadcrumb.Item>\n {groupPath.map((group) => (\n <Breadcrumb.Item\n className=\"ald-member-picker-breadcrumb-item\"\n key={group.groupId}\n onClick={() => {\n setGroupPath((groups) => {\n const groupIndex = groups.findIndex(\n (tempGroup) => tempGroup.groupId === group.groupId,\n );\n return groups.filter(\n (tempGroup, index) => index <= groupIndex,\n );\n });\n }}\n >\n <div className=\"ald-member-picker-breadcrumb-item-inner\">\n {group.name}\n </div>\n </Breadcrumb.Item>\n ))}\n </Breadcrumb>\n </ScrollArea>\n )}\n {isAsync && !useProvidedSearch && (\n <SearchFeedback\n failed={failed}\n hasMore={result.hasMore}\n pathWarningCode={result.pathWarningCode}\n retry={retry}\n />\n )}\n <Spin\n tip=\"Loading\"\n spinning={loading || (!useProvidedSearch && groupLoading)}\n size=\"small\"\n className=\"ald-member-picker-user-list\"\n >\n <ScrollArea\n className={cn('ald-member-picker-member-list', {\n 'ald-member-picker-member-list-null':\n filterUserList.length === 0 && !loading && !groupLoading,\n })}\n innerClassName=\"ald-member-picker-member-scroll\"\n >\n <div\n role=\"listbox\"\n aria-label=\"Groups\"\n aria-multiselectable={multiple || undefined}\n className=\"ald-member-picker-member-list-inner\"\n style={{ width: multiple ? width : undefined, overflow: 'hidden' }}\n >\n {filterUserList.map((userGroup) => {\n const isSelected = selectedUsersGroups.some(\n (selectUserGroup) =>\n selectUserGroup.groupId === userGroup.groupId,\n );\n\n const index = _.findIndex(lockedIds, {\n groupId: userGroup.groupId,\n type: userGroup.type,\n });\n const disabled = index !== -1;\n\n const hasNextLevel =\n (userGroupList.some(\n (group) => group.parentId === userGroup.groupId,\n ) ||\n isAsync) &&\n canEnterGroup?.(userGroup) !== false;\n const onNextLevel = () => {\n setGroupPath((prev) => [...prev, userGroup]);\n onSearchValueChange?.('');\n };\n\n const originNode = multiple ? (\n <MultipleOption\n key={userGroup.groupId}\n searchValue={searchValue}\n user={userGroup}\n disabled={disabled}\n selected={isSelected}\n onChange={(selected, userGroup) => {\n if (isUserGroup(userGroup)) {\n onChange(selected, userGroup);\n }\n }}\n hasNextLevel={hasNextLevel}\n onNextLevel={onNextLevel}\n ></MultipleOption>\n ) : (\n <SingleOption\n key={userGroup.groupId}\n searchValue={searchValue}\n user={userGroup}\n disabled={disabled}\n selected={isSelected}\n onChange={(selected, userGroup) => {\n if (isUserGroup(userGroup)) {\n onChange(selected, userGroup);\n }\n }}\n hasNextLevel={hasNextLevel}\n onNextLevel={onNextLevel}\n ></SingleOption>\n );\n\n if (renderItem) {\n return (\n <div\n key={userGroup.groupId}\n role=\"option\"\n id={`ald-member-picker-option-${userGroup.groupId}`}\n aria-selected={isSelected}\n aria-disabled={disabled || undefined}\n >\n {renderItem(userGroup, {\n isSelected,\n disabled,\n onClick: () => {\n if (isUserGroup(userGroup) && !disabled) {\n onChange(!isSelected, userGroup);\n }\n },\n onNextLevel: hasNextLevel ? onNextLevel : undefined,\n originNode,\n })}\n </div>\n );\n }\n\n return originNode;\n })}\n </div>\n </ScrollArea>\n </Spin>\n </div>\n );\n};\n\nexport default UserGroupSelection;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import useDialogLocale from "./useDialogLocale.js";
|
|
2
|
+
import { useRef, useState } from "react";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/MemberPicker/dialog/DialogColumns.tsx
|
|
5
|
+
/** 两栏分隔器仅持有比例;指针与键盘共用边界,避免全屏切换后像素宽度失效。 */
|
|
6
|
+
function DialogColumns({ children }) {
|
|
7
|
+
const root = useRef(null);
|
|
8
|
+
const [percent, setPercent] = useState(58);
|
|
9
|
+
const t = useDialogLocale();
|
|
10
|
+
const clamp = (value) => Math.min(70, Math.max(35, value));
|
|
11
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
12
|
+
ref: root,
|
|
13
|
+
className: "tw-grid tw-h-full tw-min-h-0 tw-min-w-0",
|
|
14
|
+
style: { gridTemplateColumns: `minmax(0, ${percent}fr) 8px minmax(0, ${100 - percent}fr)` },
|
|
15
|
+
children: [
|
|
16
|
+
children[0],
|
|
17
|
+
/* @__PURE__ */ jsxs("div", {
|
|
18
|
+
role: "separator",
|
|
19
|
+
tabIndex: 0,
|
|
20
|
+
"aria-label": t.MemberPickerDialog.resizePanels,
|
|
21
|
+
"aria-orientation": "vertical",
|
|
22
|
+
"aria-valuemin": 35,
|
|
23
|
+
"aria-valuemax": 70,
|
|
24
|
+
"aria-valuenow": Math.round(percent),
|
|
25
|
+
className: "tw-group tw-relative tw-flex tw-cursor-col-resize tw-touch-none tw-items-center tw-justify-center tw-rounded-r-50 focus-visible:tw-outline focus-visible:tw-outline-2 focus-visible:tw-outline-offset-2 focus-visible:tw-outline-[var(--focus-ring)]",
|
|
26
|
+
onKeyDown: (event) => {
|
|
27
|
+
const offset = event.key === "ArrowLeft" ? -2 : event.key === "ArrowRight" ? 2 : 0;
|
|
28
|
+
if (offset || event.key === "Home" || event.key === "End") {
|
|
29
|
+
event.preventDefault();
|
|
30
|
+
setPercent((current) => event.key === "Home" ? 35 : event.key === "End" ? 70 : clamp(current + offset));
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
onPointerDown: (event) => {
|
|
34
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
35
|
+
},
|
|
36
|
+
onPointerMove: (event) => {
|
|
37
|
+
if (!event.currentTarget.hasPointerCapture(event.pointerId)) return;
|
|
38
|
+
const bounds = root.current?.getBoundingClientRect();
|
|
39
|
+
if (bounds?.width) setPercent(clamp((event.clientX - bounds.left) / bounds.width * 100));
|
|
40
|
+
},
|
|
41
|
+
onPointerUp: (event) => {
|
|
42
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
43
|
+
},
|
|
44
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
45
|
+
"aria-hidden": "true",
|
|
46
|
+
className: "tw-pointer-events-none tw-h-full tw-w-px tw-bg-border-default group-hover:tw-bg-[var(--border-brand-strong)] group-focus-visible:tw-bg-[var(--border-brand-strong)]"
|
|
47
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
48
|
+
"aria-hidden": "true",
|
|
49
|
+
className: "tw-pointer-events-none tw-absolute tw-h-sp-300 tw-w-full tw-rounded-r-50 tw-border tw-border-solid tw-border-border-default tw-bg-bg-default group-hover:tw-border-[var(--border-brand-strong)] group-focus-visible:tw-border-[var(--border-brand-strong)]"
|
|
50
|
+
})]
|
|
51
|
+
}),
|
|
52
|
+
children[1]
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { DialogColumns as default };
|
|
58
|
+
|
|
59
|
+
//# sourceMappingURL=DialogColumns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DialogColumns.js","names":[],"sources":["../../../src/MemberPicker/dialog/DialogColumns.tsx"],"sourcesContent":["import { useRef, useState, type ReactNode } from 'react';\nimport useDialogLocale from './useDialogLocale';\n\n/** 两栏分隔器仅持有比例;指针与键盘共用边界,避免全屏切换后像素宽度失效。 */\nexport default function DialogColumns({\n children,\n}: {\n children: [ReactNode, ReactNode];\n}) {\n const root = useRef<HTMLDivElement>(null);\n const [percent, setPercent] = useState(58);\n const t = useDialogLocale();\n const clamp = (value: number) => Math.min(70, Math.max(35, value));\n return (\n <div\n ref={root}\n className=\"tw-grid tw-h-full tw-min-h-0 tw-min-w-0\"\n style={{\n gridTemplateColumns: `minmax(0, ${percent}fr) 8px minmax(0, ${\n 100 - percent\n }fr)`,\n }}\n >\n {children[0]}\n <div\n role=\"separator\"\n tabIndex={0}\n aria-label={t.MemberPickerDialog.resizePanels}\n aria-orientation=\"vertical\"\n aria-valuemin={35}\n aria-valuemax={70}\n aria-valuenow={Math.round(percent)}\n className=\"tw-group tw-relative tw-flex tw-cursor-col-resize tw-touch-none tw-items-center tw-justify-center tw-rounded-r-50 focus-visible:tw-outline focus-visible:tw-outline-2 focus-visible:tw-outline-offset-2 focus-visible:tw-outline-[var(--focus-ring)]\"\n onKeyDown={(event) => {\n const offset =\n event.key === 'ArrowLeft' ? -2 : event.key === 'ArrowRight' ? 2 : 0;\n if (offset || event.key === 'Home' || event.key === 'End') {\n event.preventDefault();\n setPercent((current) =>\n event.key === 'Home'\n ? 35\n : event.key === 'End'\n ? 70\n : clamp(current + offset),\n );\n }\n }}\n onPointerDown={(event) => {\n event.currentTarget.setPointerCapture(event.pointerId);\n }}\n onPointerMove={(event) => {\n if (!event.currentTarget.hasPointerCapture(event.pointerId)) return;\n const bounds = root.current?.getBoundingClientRect();\n if (bounds?.width)\n setPercent(\n clamp(((event.clientX - bounds.left) / bounds.width) * 100),\n );\n }}\n onPointerUp={(event) => {\n if (event.currentTarget.hasPointerCapture(event.pointerId))\n event.currentTarget.releasePointerCapture(event.pointerId);\n }}\n >\n <span\n aria-hidden=\"true\"\n className=\"tw-pointer-events-none tw-h-full tw-w-px tw-bg-border-default group-hover:tw-bg-[var(--border-brand-strong)] group-focus-visible:tw-bg-[var(--border-brand-strong)]\"\n />\n <span\n aria-hidden=\"true\"\n className=\"tw-pointer-events-none tw-absolute tw-h-sp-300 tw-w-full tw-rounded-r-50 tw-border tw-border-solid tw-border-border-default tw-bg-bg-default group-hover:tw-border-[var(--border-brand-strong)] group-focus-visible:tw-border-[var(--border-brand-strong)]\"\n />\n </div>\n {children[1]}\n </div>\n );\n}\n"],"mappings":";;;;;AAIA,SAAwB,cAAc,EACpC,YAGC;CACD,MAAM,OAAO,OAAuB,KAAK;CACzC,MAAM,CAAC,SAAS,cAAc,SAAS,GAAG;CAC1C,MAAM,IAAI,iBAAiB;CAC3B,MAAM,SAAS,UAAkB,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC;AAClE,QACE,qBAAC,OAAD;EACE,KAAK;EACL,WAAU;EACV,OAAO,EACL,qBAAqB,aAAa,QAAQ,oBACxC,MAAM,QACP,MACF;YAPH;GASG,SAAS;GACV,qBAAC,OAAD;IACE,MAAK;IACL,UAAU;IACV,cAAY,EAAE,mBAAmB;IACjC,oBAAiB;IACjB,iBAAe;IACf,iBAAe;IACf,iBAAe,KAAK,MAAM,QAAQ;IAClC,WAAU;IACV,YAAY,UAAU;KACpB,MAAM,SACJ,MAAM,QAAQ,cAAc,KAAK,MAAM,QAAQ,eAAe,IAAI;AACpE,SAAI,UAAU,MAAM,QAAQ,UAAU,MAAM,QAAQ,OAAO;AACzD,YAAM,gBAAgB;AACtB,kBAAY,YACV,MAAM,QAAQ,SACV,KACA,MAAM,QAAQ,QACd,KACA,MAAM,UAAU,OAAO,CAC5B;;;IAGL,gBAAgB,UAAU;AACxB,WAAM,cAAc,kBAAkB,MAAM,UAAU;;IAExD,gBAAgB,UAAU;AACxB,SAAI,CAAC,MAAM,cAAc,kBAAkB,MAAM,UAAU,CAAE;KAC7D,MAAM,SAAS,KAAK,SAAS,uBAAuB;AACpD,SAAI,QAAQ,MACV,YACE,OAAQ,MAAM,UAAU,OAAO,QAAQ,OAAO,QAAS,IAAI,CAC5D;;IAEL,cAAc,UAAU;AACtB,SAAI,MAAM,cAAc,kBAAkB,MAAM,UAAU,CACxD,OAAM,cAAc,sBAAsB,MAAM,UAAU;;cApChE,CAuCE,oBAAC,QAAD;KACE,eAAY;KACZ,WAAU;KACV,CAAA,EACF,oBAAC,QAAD;KACE,eAAY;KACZ,WAAU;KACV,CAAA,CACE;;GACL,SAAS;GACN"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { MemberPickerDialogProps } from './MemberPickerDialog.js';
|
|
2
|
+
/** 打开期间拥有选择草稿;确认才通知业务,取消与卸载均释放请求和临时选择。 */
|
|
3
|
+
export default function DialogContent({ value, onChange, onClose, type, lockedIds, filterItem, canEnterGroup, renderItem, renderSelectedTag, zIndex, footer, onCancel, }: MemberPickerDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import IconButton from "../../IconButton/index.js";
|
|
2
|
+
import Modal from "../../Modal/index.js";
|
|
3
|
+
import Tabs from "../../Tabs/index.js";
|
|
4
|
+
import SelectorFooter from "../components/SelectorFooter.js";
|
|
5
|
+
import { EMemberPicker } from "../interface.js";
|
|
6
|
+
import useDialogLocale from "./useDialogLocale.js";
|
|
7
|
+
import DialogColumns from "./DialogColumns.js";
|
|
8
|
+
import SelectedMemberPanel from "./SelectedMemberPanel.js";
|
|
9
|
+
import UserCandidatePanel from "./UserCandidatePanel.js";
|
|
10
|
+
import UserGroupCandidatePanel from "./UserGroupCandidatePanel.js";
|
|
11
|
+
import { useMemberPickerDraft } from "./useMemberPickerDraft.js";
|
|
12
|
+
import { useState } from "react";
|
|
13
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
+
import { MaximizeLine, MinimizeLine } from "@aloudata/icons-react";
|
|
15
|
+
//#region src/MemberPicker/dialog/DialogContent.tsx
|
|
16
|
+
/** 打开期间拥有选择草稿;确认才通知业务,取消与卸载均释放请求和临时选择。 */
|
|
17
|
+
function DialogContent({ value, onChange, onClose, type = EMemberPicker.BOTH, lockedIds, filterItem, canEnterGroup, renderItem, renderSelectedTag, zIndex, footer, onCancel }) {
|
|
18
|
+
const t = useDialogLocale();
|
|
19
|
+
const [fullscreen, setFullscreen] = useState(false);
|
|
20
|
+
const draft = useMemberPickerDraft({
|
|
21
|
+
value,
|
|
22
|
+
onChange,
|
|
23
|
+
type,
|
|
24
|
+
lockedIds
|
|
25
|
+
});
|
|
26
|
+
const panelProps = {
|
|
27
|
+
selectedByKey: draft.selectedByKey,
|
|
28
|
+
onToggle: draft.toggleMember,
|
|
29
|
+
onToggleAll: draft.toggleMembers,
|
|
30
|
+
lockedIds,
|
|
31
|
+
filterItem,
|
|
32
|
+
renderItem
|
|
33
|
+
};
|
|
34
|
+
const confirm = () => {
|
|
35
|
+
if (draft.hydrating) return;
|
|
36
|
+
draft.confirm();
|
|
37
|
+
onClose();
|
|
38
|
+
};
|
|
39
|
+
const cancel = () => {
|
|
40
|
+
onCancel?.();
|
|
41
|
+
onClose();
|
|
42
|
+
};
|
|
43
|
+
const users = /* @__PURE__ */ jsx(UserCandidatePanel, { ...panelProps });
|
|
44
|
+
const groups = /* @__PURE__ */ jsx(UserGroupCandidatePanel, {
|
|
45
|
+
...panelProps,
|
|
46
|
+
canEnterGroup
|
|
47
|
+
});
|
|
48
|
+
return /* @__PURE__ */ jsx(Modal, {
|
|
49
|
+
open: true,
|
|
50
|
+
centered: true,
|
|
51
|
+
paddingLess: true,
|
|
52
|
+
zIndex,
|
|
53
|
+
width: fullscreen ? "calc(100vw - 24px)" : "min(800px, calc(100vw - 32px))",
|
|
54
|
+
title: /* @__PURE__ */ jsxs("div", {
|
|
55
|
+
className: "tw-flex tw-items-center tw-gap-sp-150",
|
|
56
|
+
children: [/* @__PURE__ */ jsx("span", { children: t.MemberPickerDialog.title }), /* @__PURE__ */ jsx(IconButton, {
|
|
57
|
+
size: "small",
|
|
58
|
+
"aria-label": fullscreen ? t.MemberPickerDialog.exitMaximize : t.MemberPickerDialog.maximize,
|
|
59
|
+
tooltip: { title: fullscreen ? t.MemberPickerDialog.exitMaximize : t.MemberPickerDialog.maximize },
|
|
60
|
+
icon: fullscreen ? /* @__PURE__ */ jsx(MinimizeLine, {}) : /* @__PURE__ */ jsx(MaximizeLine, {}),
|
|
61
|
+
onClick: () => setFullscreen((current) => !current)
|
|
62
|
+
})]
|
|
63
|
+
}),
|
|
64
|
+
okText: t.MemberPickerDialog.ok,
|
|
65
|
+
cancelText: t.MemberPickerDialog.cancel,
|
|
66
|
+
okButtonProps: { disabled: draft.hydrating },
|
|
67
|
+
onOk: confirm,
|
|
68
|
+
footer: footer ? /* @__PURE__ */ jsx(SelectorFooter, {
|
|
69
|
+
footer,
|
|
70
|
+
onOk: confirm,
|
|
71
|
+
onCancel: cancel
|
|
72
|
+
}) : void 0,
|
|
73
|
+
onCancel: cancel,
|
|
74
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
75
|
+
className: "ald-member-picker-dialog tw-min-h-0 tw-p-sp-200",
|
|
76
|
+
style: { height: fullscreen ? "calc(100dvh - 150px)" : "min(560px, calc(100dvh - 180px))" },
|
|
77
|
+
children: /* @__PURE__ */ jsxs(DialogColumns, { children: [/* @__PURE__ */ jsx("div", {
|
|
78
|
+
className: "tw-h-full tw-min-w-0 tw-overflow-hidden",
|
|
79
|
+
children: type === EMemberPicker.BOTH ? /* @__PURE__ */ jsx(Tabs, {
|
|
80
|
+
compact: true,
|
|
81
|
+
adaptHeight: true,
|
|
82
|
+
className: "tw-h-full",
|
|
83
|
+
activeKey: draft.activeTab,
|
|
84
|
+
onChange: (key) => {
|
|
85
|
+
if (key === EMemberPicker.USER || key === EMemberPicker.GROUP) draft.setActiveTab(key);
|
|
86
|
+
},
|
|
87
|
+
items: [{
|
|
88
|
+
key: EMemberPicker.USER,
|
|
89
|
+
label: t.MemberPickerDialog.user,
|
|
90
|
+
children: users
|
|
91
|
+
}, {
|
|
92
|
+
key: EMemberPicker.GROUP,
|
|
93
|
+
label: t.MemberPickerDialog.userGroup,
|
|
94
|
+
children: groups
|
|
95
|
+
}]
|
|
96
|
+
}) : type === EMemberPicker.GROUP ? groups : users
|
|
97
|
+
}), /* @__PURE__ */ jsx(SelectedMemberPanel, {
|
|
98
|
+
members: draft.selectedMembers,
|
|
99
|
+
lockedIds,
|
|
100
|
+
onRemove: draft.removeMember,
|
|
101
|
+
renderSelectedTag
|
|
102
|
+
})] })
|
|
103
|
+
})
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
107
|
+
export { DialogContent as default };
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=DialogContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DialogContent.js","names":[],"sources":["../../../src/MemberPicker/dialog/DialogContent.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { MaximizeLine, MinimizeLine } from '@aloudata/icons-react';\nimport IconButton from '../../IconButton';\nimport Modal from '../../Modal';\nimport Tabs from '../../Tabs';\nimport SelectorFooter from '../components/SelectorFooter';\nimport { EMemberPicker } from '../interface';\nimport type { MemberPickerDialogProps } from './MemberPickerDialog';\nimport DialogColumns from './DialogColumns';\nimport SelectedMemberPanel from './SelectedMemberPanel';\nimport UserCandidatePanel from './UserCandidatePanel';\nimport UserGroupCandidatePanel from './UserGroupCandidatePanel';\nimport { useMemberPickerDraft } from './useMemberPickerDraft';\nimport useDialogLocale from './useDialogLocale';\n\n/** 打开期间拥有选择草稿;确认才通知业务,取消与卸载均释放请求和临时选择。 */\nexport default function DialogContent({\n value,\n onChange,\n onClose,\n type = EMemberPicker.BOTH,\n lockedIds,\n filterItem,\n canEnterGroup,\n renderItem,\n renderSelectedTag,\n zIndex,\n footer,\n onCancel,\n}: MemberPickerDialogProps) {\n const t = useDialogLocale();\n const [fullscreen, setFullscreen] = useState(false);\n const draft = useMemberPickerDraft({ value, onChange, type, lockedIds });\n const panelProps = {\n selectedByKey: draft.selectedByKey,\n onToggle: draft.toggleMember,\n onToggleAll: draft.toggleMembers,\n lockedIds,\n filterItem,\n renderItem,\n };\n const confirm = () => {\n if (draft.hydrating) return;\n draft.confirm();\n onClose();\n };\n const cancel = () => {\n onCancel?.();\n onClose();\n };\n const users = <UserCandidatePanel {...panelProps} />;\n const groups = (\n <UserGroupCandidatePanel {...panelProps} canEnterGroup={canEnterGroup} />\n );\n return (\n <Modal\n open\n centered\n paddingLess\n zIndex={zIndex}\n width={\n fullscreen ? 'calc(100vw - 24px)' : 'min(800px, calc(100vw - 32px))'\n }\n title={\n <div className=\"tw-flex tw-items-center tw-gap-sp-150\">\n <span>{t.MemberPickerDialog.title}</span>\n <IconButton\n size=\"small\"\n aria-label={\n fullscreen\n ? t.MemberPickerDialog.exitMaximize\n : t.MemberPickerDialog.maximize\n }\n tooltip={{\n title: fullscreen\n ? t.MemberPickerDialog.exitMaximize\n : t.MemberPickerDialog.maximize,\n }}\n icon={fullscreen ? <MinimizeLine /> : <MaximizeLine />}\n onClick={() => setFullscreen((current) => !current)}\n />\n </div>\n }\n okText={t.MemberPickerDialog.ok}\n cancelText={t.MemberPickerDialog.cancel}\n okButtonProps={{ disabled: draft.hydrating }}\n onOk={confirm}\n footer={\n footer ? (\n <SelectorFooter footer={footer} onOk={confirm} onCancel={cancel} />\n ) : undefined\n }\n onCancel={cancel}\n >\n <div\n className=\"ald-member-picker-dialog tw-min-h-0 tw-p-sp-200\"\n style={{\n height: fullscreen\n ? 'calc(100dvh - 150px)'\n : 'min(560px, calc(100dvh - 180px))',\n }}\n >\n <DialogColumns>\n <div className=\"tw-h-full tw-min-w-0 tw-overflow-hidden\">\n {type === EMemberPicker.BOTH ? (\n <Tabs\n compact\n adaptHeight\n className=\"tw-h-full\"\n activeKey={draft.activeTab}\n onChange={(key) => {\n if (key === EMemberPicker.USER || key === EMemberPicker.GROUP)\n draft.setActiveTab(key);\n }}\n items={[\n {\n key: EMemberPicker.USER,\n label: t.MemberPickerDialog.user,\n children: users,\n },\n {\n key: EMemberPicker.GROUP,\n label: t.MemberPickerDialog.userGroup,\n children: groups,\n },\n ]}\n />\n ) : type === EMemberPicker.GROUP ? (\n groups\n ) : (\n users\n )}\n </div>\n <SelectedMemberPanel\n members={draft.selectedMembers}\n lockedIds={lockedIds}\n onRemove={draft.removeMember}\n renderSelectedTag={renderSelectedTag}\n />\n </DialogColumns>\n </div>\n </Modal>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,SAAwB,cAAc,EACpC,OACA,UACA,SACA,OAAO,cAAc,MACrB,WACA,YACA,eACA,YACA,mBACA,QACA,QACA,YAC0B;CAC1B,MAAM,IAAI,iBAAiB;CAC3B,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM;CACnD,MAAM,QAAQ,qBAAqB;EAAE;EAAO;EAAU;EAAM;EAAW,CAAC;CACxE,MAAM,aAAa;EACjB,eAAe,MAAM;EACrB,UAAU,MAAM;EAChB,aAAa,MAAM;EACnB;EACA;EACA;EACD;CACD,MAAM,gBAAgB;AACpB,MAAI,MAAM,UAAW;AACrB,QAAM,SAAS;AACf,WAAS;;CAEX,MAAM,eAAe;AACnB,cAAY;AACZ,WAAS;;CAEX,MAAM,QAAQ,oBAAC,oBAAD,EAAoB,GAAI,YAAc,CAAA;CACpD,MAAM,SACJ,oBAAC,yBAAD;EAAyB,GAAI;EAA2B;EAAiB,CAAA;AAE3E,QACE,oBAAC,OAAD;EACE,MAAA;EACA,UAAA;EACA,aAAA;EACQ;EACR,OACE,aAAa,uBAAuB;EAEtC,OACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,QAAD,EAAA,UAAO,EAAE,mBAAmB,OAAa,CAAA,EACzC,oBAAC,YAAD;IACE,MAAK;IACL,cACE,aACI,EAAE,mBAAmB,eACrB,EAAE,mBAAmB;IAE3B,SAAS,EACP,OAAO,aACH,EAAE,mBAAmB,eACrB,EAAE,mBAAmB,UAC1B;IACD,MAAM,aAAa,oBAAC,cAAD,EAAgB,CAAA,GAAG,oBAAC,cAAD,EAAgB,CAAA;IACtD,eAAe,eAAe,YAAY,CAAC,QAAQ;IACnD,CAAA,CACE;;EAER,QAAQ,EAAE,mBAAmB;EAC7B,YAAY,EAAE,mBAAmB;EACjC,eAAe,EAAE,UAAU,MAAM,WAAW;EAC5C,MAAM;EACN,QACE,SACE,oBAAC,gBAAD;GAAwB;GAAQ,MAAM;GAAS,UAAU;GAAU,CAAA,GACjE;EAEN,UAAU;YAEV,oBAAC,OAAD;GACE,WAAU;GACV,OAAO,EACL,QAAQ,aACJ,yBACA,oCACL;aAED,qBAAC,eAAD,EAAA,UAAA,CACE,oBAAC,OAAD;IAAK,WAAU;cACZ,SAAS,cAAc,OACtB,oBAAC,MAAD;KACE,SAAA;KACA,aAAA;KACA,WAAU;KACV,WAAW,MAAM;KACjB,WAAW,QAAQ;AACjB,UAAI,QAAQ,cAAc,QAAQ,QAAQ,cAAc,MACtD,OAAM,aAAa,IAAI;;KAE3B,OAAO,CACL;MACE,KAAK,cAAc;MACnB,OAAO,EAAE,mBAAmB;MAC5B,UAAU;MACX,EACD;MACE,KAAK,cAAc;MACnB,OAAO,EAAE,mBAAmB;MAC5B,UAAU;MACX,CACF;KACD,CAAA,GACA,SAAS,cAAc,QACzB,SAEA;IAEE,CAAA,EACN,oBAAC,qBAAD;IACE,SAAS,MAAM;IACJ;IACX,UAAU,MAAM;IACG;IACnB,CAAA,CACY,EAAA,CAAA;GACZ,CAAA;EACA,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IMemberPickerProps as MemberPickerProps } from '../interface';
|
|
2
|
+
import { TMember } from './types.js';
|
|
3
|
+
interface IProps {
|
|
4
|
+
member: TMember;
|
|
5
|
+
selected: boolean;
|
|
6
|
+
locked: boolean;
|
|
7
|
+
onToggle?: (member: TMember) => void;
|
|
8
|
+
onRemove?: (member: TMember) => void;
|
|
9
|
+
onOpenGroup?: () => void;
|
|
10
|
+
renderItem?: MemberPickerProps['renderItem'];
|
|
11
|
+
searchValue?: string;
|
|
12
|
+
renderSelectedTag?: MemberPickerProps['renderSelectedTag'];
|
|
13
|
+
}
|
|
14
|
+
/** 候选项统一用名称切换选择;用户组仅通过右侧独立入口进入下级。 */
|
|
15
|
+
export default function MemberOption({ member, selected, locked, onToggle, onRemove, onOpenGroup, renderItem, renderSelectedTag, searchValue, }: IProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import Avatar from "../../Avatar/index.js";
|
|
3
|
+
import Button_default from "../../Button/index.js";
|
|
4
|
+
import Checkbox from "../../Checkbox/index.js";
|
|
5
|
+
import Tooltip from "../../Tooltip/index.js";
|
|
6
|
+
import Tag from "../../Tag/index.js";
|
|
7
|
+
import { EUserType } from "../../ConfigProvider/getUserList.js";
|
|
8
|
+
import HighlightText from "../../HighlightText/index.js";
|
|
9
|
+
import useDialogLocale from "./useDialogLocale.js";
|
|
10
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
//#region src/MemberPicker/dialog/MemberOption.tsx
|
|
12
|
+
/** 候选项统一用名称切换选择;用户组仅通过右侧独立入口进入下级。 */
|
|
13
|
+
function MemberOption({ member, selected, locked, onToggle, onRemove, onOpenGroup, renderItem, renderSelectedTag, searchValue }) {
|
|
14
|
+
const t = useDialogLocale();
|
|
15
|
+
const toggle = () => onToggle?.(member);
|
|
16
|
+
const displayName = member.type === EUserType.USER_GROUP && searchValue?.trim() && member.path?.length ? member.path.map((node) => node.name).join(" / ") : member.name;
|
|
17
|
+
const ancestors = member.type === EUserType.USER_GROUP && searchValue?.trim() ? member.path?.slice(0, -1).map((node) => node.name).join(" / ") : void 0;
|
|
18
|
+
const nameNode = /* @__PURE__ */ jsx(Tooltip, {
|
|
19
|
+
title: displayName,
|
|
20
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
21
|
+
title: displayName,
|
|
22
|
+
className: cn("tw-min-w-0 tw-flex-1 tw-truncate tw-text-typography-body-dense", locked ? "tw-text-content-disabled" : "tw-text-content-primary"),
|
|
23
|
+
children: [ancestors && /* @__PURE__ */ jsxs("span", {
|
|
24
|
+
className: "tw-text-content-secondary",
|
|
25
|
+
children: [ancestors, " / "]
|
|
26
|
+
}), /* @__PURE__ */ jsx(HighlightText, {
|
|
27
|
+
keyword: searchValue?.trim() ?? "",
|
|
28
|
+
children: member.name ?? ""
|
|
29
|
+
})]
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
const renderedCandidate = renderItem?.(member, {
|
|
33
|
+
isSelected: selected,
|
|
34
|
+
disabled: locked,
|
|
35
|
+
onClick: toggle,
|
|
36
|
+
onNextLevel: onOpenGroup,
|
|
37
|
+
originNode: nameNode
|
|
38
|
+
});
|
|
39
|
+
const content = (onRemove ? renderSelectedTag?.(member, nameNode) : void 0) ?? renderedCandidate ?? nameNode;
|
|
40
|
+
if (onRemove) return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Tag, {
|
|
41
|
+
closable: true,
|
|
42
|
+
disabled: locked,
|
|
43
|
+
status: "default",
|
|
44
|
+
mode: "border",
|
|
45
|
+
title: member.name,
|
|
46
|
+
className: "tw-min-w-0 tw-max-w-full",
|
|
47
|
+
onClose: (event) => {
|
|
48
|
+
event.stopPropagation();
|
|
49
|
+
onRemove(member);
|
|
50
|
+
},
|
|
51
|
+
children: content
|
|
52
|
+
}) });
|
|
53
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
54
|
+
className: "tw-flex tw-min-w-0 tw-items-center tw-gap-sp-100 tw-rounded-r-50 tw-px-sp-150 tw-py-sp-100 hover:tw-bg-bg-subtle",
|
|
55
|
+
onClick: locked ? void 0 : toggle,
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ jsx("span", {
|
|
58
|
+
onClick: (event) => event.stopPropagation(),
|
|
59
|
+
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
60
|
+
checked: selected,
|
|
61
|
+
disabled: locked,
|
|
62
|
+
"aria-label": member.name,
|
|
63
|
+
onChange: toggle
|
|
64
|
+
})
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ jsx("span", {
|
|
67
|
+
"aria-hidden": "true",
|
|
68
|
+
className: "tw-flex tw-shrink-0",
|
|
69
|
+
children: /* @__PURE__ */ jsx(Avatar, {
|
|
70
|
+
size: 20,
|
|
71
|
+
type: member.type === EUserType.USER ? "user" : "team"
|
|
72
|
+
})
|
|
73
|
+
}),
|
|
74
|
+
/* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("button", {
|
|
75
|
+
type: "button",
|
|
76
|
+
disabled: locked,
|
|
77
|
+
className: "tw-flex tw-min-w-0 tw-flex-1 tw-items-center tw-border-0 tw-bg-transparent tw-p-0 tw-text-left focus-visible:tw-outline focus-visible:tw-outline-2 focus-visible:tw-outline-offset-2 focus-visible:tw-outline-[var(--focus-ring)]",
|
|
78
|
+
onClick: (event) => {
|
|
79
|
+
event.stopPropagation();
|
|
80
|
+
toggle();
|
|
81
|
+
},
|
|
82
|
+
children: content
|
|
83
|
+
}) }),
|
|
84
|
+
onOpenGroup ? /* @__PURE__ */ jsx(Button_default, {
|
|
85
|
+
type: "link",
|
|
86
|
+
size: "small",
|
|
87
|
+
className: "tw-ml-auto tw-shrink-0",
|
|
88
|
+
disabled: locked,
|
|
89
|
+
onClick: (event) => {
|
|
90
|
+
event.stopPropagation();
|
|
91
|
+
onOpenGroup();
|
|
92
|
+
},
|
|
93
|
+
children: t.MemberPickerDialog.subLevel
|
|
94
|
+
}) : null
|
|
95
|
+
]
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
export { MemberOption as default };
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=MemberOption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemberOption.js","names":[],"sources":["../../../src/MemberPicker/dialog/MemberOption.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport Button from '../../Button';\nimport Avatar from '../../Avatar';\nimport { cn } from '../../lib/utils';\nimport Checkbox from '../../Checkbox';\nimport { EUserType } from '../../ConfigProvider/getUserList';\nimport Tag from '../../Tag';\nimport Tooltip from '../../Tooltip';\nimport HighlightText from '../../HighlightText';\nimport type { IMemberPickerProps as MemberPickerProps } from '../interface';\nimport useDialogLocale from './useDialogLocale';\nimport type { TMember } from './types';\n\ninterface IProps {\n member: TMember;\n selected: boolean;\n locked: boolean;\n onToggle?: (member: TMember) => void;\n onRemove?: (member: TMember) => void;\n onOpenGroup?: () => void;\n renderItem?: MemberPickerProps['renderItem'];\n searchValue?: string;\n renderSelectedTag?: MemberPickerProps['renderSelectedTag'];\n}\n\n/** 候选项统一用名称切换选择;用户组仅通过右侧独立入口进入下级。 */\nexport default function MemberOption({\n member,\n selected,\n locked,\n onToggle,\n onRemove,\n onOpenGroup,\n renderItem,\n renderSelectedTag,\n searchValue,\n}: IProps) {\n const t = useDialogLocale();\n const toggle = () => onToggle?.(member);\n const displayName =\n member.type === EUserType.USER_GROUP &&\n searchValue?.trim() &&\n member.path?.length\n ? member.path.map((node) => node.name).join(' / ')\n : member.name;\n // 祖先路径提供定位上下文,命中名称仍使用正文层级;标签保持原名称。\n const ancestors =\n member.type === EUserType.USER_GROUP && searchValue?.trim()\n ? member.path\n ?.slice(0, -1)\n .map((node) => node.name)\n .join(' / ')\n : undefined;\n const nameTextNode = (\n <span\n title={displayName}\n className={cn(\n 'tw-min-w-0 tw-flex-1 tw-truncate tw-text-typography-body-dense',\n locked ? 'tw-text-content-disabled' : 'tw-text-content-primary',\n )}\n >\n {ancestors && (\n <span className=\"tw-text-content-secondary\">{ancestors} / </span>\n )}\n <HighlightText keyword={searchValue?.trim() ?? ''}>\n {member.name ?? ''}\n </HighlightText>\n </span>\n );\n const nameNode = <Tooltip title={displayName}>{nameTextNode}</Tooltip>;\n const renderedCandidate = renderItem?.(member, {\n isSelected: selected,\n disabled: locked,\n onClick: toggle,\n onNextLevel: onOpenGroup,\n originNode: nameNode,\n });\n const renderedSelected = onRemove\n ? renderSelectedTag?.(member, nameNode)\n : undefined;\n const content: ReactNode = renderedSelected ?? renderedCandidate ?? nameNode;\n\n if (onRemove) {\n return (\n <>\n <Tag\n closable\n disabled={locked}\n status=\"default\"\n mode=\"border\"\n title={member.name}\n className=\"tw-min-w-0 tw-max-w-full\"\n onClose={(event) => {\n event.stopPropagation();\n onRemove(member);\n }}\n >\n {content}\n </Tag>\n </>\n );\n }\n\n return (\n <div\n className=\"tw-flex tw-min-w-0 tw-items-center tw-gap-sp-100 tw-rounded-r-50 tw-px-sp-150 tw-py-sp-100 hover:tw-bg-bg-subtle\"\n onClick={locked ? undefined : toggle}\n >\n <span onClick={(event) => event.stopPropagation()}>\n <Checkbox\n checked={selected}\n disabled={locked}\n aria-label={member.name}\n onChange={toggle}\n />\n </span>\n <span aria-hidden=\"true\" className=\"tw-flex tw-shrink-0\">\n <Avatar\n size={20}\n type={member.type === EUserType.USER ? 'user' : 'team'}\n />\n </span>\n <>\n <button\n type=\"button\"\n disabled={locked}\n className=\"tw-flex tw-min-w-0 tw-flex-1 tw-items-center tw-border-0 tw-bg-transparent tw-p-0 tw-text-left focus-visible:tw-outline focus-visible:tw-outline-2 focus-visible:tw-outline-offset-2 focus-visible:tw-outline-[var(--focus-ring)]\"\n onClick={(event) => {\n event.stopPropagation();\n toggle();\n }}\n >\n {content}\n </button>\n </>\n {onOpenGroup ? (\n <Button\n type=\"link\"\n size=\"small\"\n className=\"tw-ml-auto tw-shrink-0\"\n disabled={locked}\n onClick={(event) => {\n event.stopPropagation();\n onOpenGroup();\n }}\n >\n {t.MemberPickerDialog.subLevel}\n </Button>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AA0BA,SAAwB,aAAa,EACnC,QACA,UACA,QACA,UACA,UACA,aACA,YACA,mBACA,eACS;CACT,MAAM,IAAI,iBAAiB;CAC3B,MAAM,eAAe,WAAW,OAAO;CACvC,MAAM,cACJ,OAAO,SAAS,UAAU,cAC1B,aAAa,MAAM,IACnB,OAAO,MAAM,SACT,OAAO,KAAK,KAAK,SAAS,KAAK,KAAK,CAAC,KAAK,MAAM,GAChD,OAAO;CAEb,MAAM,YACJ,OAAO,SAAS,UAAU,cAAc,aAAa,MAAM,GACvD,OAAO,MACH,MAAM,GAAG,GAAG,CACb,KAAK,SAAS,KAAK,KAAK,CACxB,KAAK,MAAM,GACd;CAiBN,MAAM,WAAW,oBAAC,SAAD;EAAS,OAAO;YAf/B,qBAAC,QAAD;GACE,OAAO;GACP,WAAW,GACT,kEACA,SAAS,6BAA6B,0BACvC;aALH,CAOG,aACC,qBAAC,QAAD;IAAM,WAAU;cAAhB,CAA6C,WAAU,MAAU;OAEnE,oBAAC,eAAD;IAAe,SAAS,aAAa,MAAM,IAAI;cAC5C,OAAO,QAAQ;IACF,CAAA,CACX;;EAE6D,CAAA;CACtE,MAAM,oBAAoB,aAAa,QAAQ;EAC7C,YAAY;EACZ,UAAU;EACV,SAAS;EACT,aAAa;EACb,YAAY;EACb,CAAC;CAIF,MAAM,WAHmB,WACrB,oBAAoB,QAAQ,SAAS,GACrC,WAC2C,qBAAqB;AAEpE,KAAI,SACF,QACE,oBAAA,UAAA,EAAA,UACE,oBAAC,KAAD;EACE,UAAA;EACA,UAAU;EACV,QAAO;EACP,MAAK;EACL,OAAO,OAAO;EACd,WAAU;EACV,UAAU,UAAU;AAClB,SAAM,iBAAiB;AACvB,YAAS,OAAO;;YAGjB;EACG,CAAA,EACL,CAAA;AAIP,QACE,qBAAC,OAAD;EACE,WAAU;EACV,SAAS,SAAS,SAAY;YAFhC;GAIE,oBAAC,QAAD;IAAM,UAAU,UAAU,MAAM,iBAAiB;cAC/C,oBAAC,UAAD;KACE,SAAS;KACT,UAAU;KACV,cAAY,OAAO;KACnB,UAAU;KACV,CAAA;IACG,CAAA;GACP,oBAAC,QAAD;IAAM,eAAY;IAAO,WAAU;cACjC,oBAAC,QAAD;KACE,MAAM;KACN,MAAM,OAAO,SAAS,UAAU,OAAO,SAAS;KAChD,CAAA;IACG,CAAA;GACP,oBAAA,UAAA,EAAA,UACE,oBAAC,UAAD;IACE,MAAK;IACL,UAAU;IACV,WAAU;IACV,UAAU,UAAU;AAClB,WAAM,iBAAiB;AACvB,aAAQ;;cAGT;IACM,CAAA,EACR,CAAA;GACF,cACC,oBAAC,gBAAD;IACE,MAAK;IACL,MAAK;IACL,WAAU;IACV,UAAU;IACV,UAAU,UAAU;AAClB,WAAM,iBAAiB;AACvB,kBAAa;;cAGd,EAAE,mBAAmB;IACf,CAAA,GACP;GACA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TUser } from '../../ConfigProvider/getUserList';
|
|
2
|
+
import { IBaseMemberSelectorProps } from '../interface';
|
|
3
|
+
/** 独立弹窗公开契约,数据从最近的 ConfigProvider 读取。 */
|
|
4
|
+
export interface MemberPickerDialogProps extends Pick<IBaseMemberSelectorProps, 'value' | 'type' | 'lockedIds' | 'filterItem' | 'canEnterGroup' | 'renderItem' | 'renderSelectedTag' | 'footer' | 'onCancel'> {
|
|
5
|
+
open: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
onChange?: (members: TUser) => void;
|
|
8
|
+
zIndex?: number;
|
|
9
|
+
}
|
|
10
|
+
/** 关闭时不挂载内容,避免关闭态请求和选择草稿串入下次打开。 */
|
|
11
|
+
export default function MemberPickerDialog(props: MemberPickerDialogProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import DialogContent from "./DialogContent.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
//#region src/MemberPicker/dialog/MemberPickerDialog.tsx
|
|
4
|
+
/** 关闭时不挂载内容,避免关闭态请求和选择草稿串入下次打开。 */
|
|
5
|
+
function MemberPickerDialog(props) {
|
|
6
|
+
return props.open ? /* @__PURE__ */ jsx(DialogContent, { ...props }) : null;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { MemberPickerDialog as default };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=MemberPickerDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemberPickerDialog.js","names":[],"sources":["../../../src/MemberPicker/dialog/MemberPickerDialog.tsx"],"sourcesContent":["import type { TUser } from '../../ConfigProvider/getUserList';\nimport type { IBaseMemberSelectorProps } from '../interface';\nimport DialogContent from './DialogContent';\n\n/** 独立弹窗公开契约,数据从最近的 ConfigProvider 读取。 */\nexport interface MemberPickerDialogProps\n extends Pick<\n IBaseMemberSelectorProps,\n | 'value'\n | 'type'\n | 'lockedIds'\n | 'filterItem'\n | 'canEnterGroup'\n | 'renderItem'\n | 'renderSelectedTag'\n | 'footer'\n | 'onCancel'\n > {\n open: boolean;\n onClose: () => void;\n onChange?: (members: TUser) => void;\n zIndex?: number;\n}\n\n/** 关闭时不挂载内容,避免关闭态请求和选择草稿串入下次打开。 */\nexport default function MemberPickerDialog(props: MemberPickerDialogProps) {\n return props.open ? <DialogContent {...props} /> : null;\n}\n"],"mappings":";;;;AAyBA,SAAwB,mBAAmB,OAAgC;AACzE,QAAO,MAAM,OAAO,oBAAC,eAAD,EAAe,GAAI,OAAS,CAAA,GAAG"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IMemberPickerProps as MemberPickerProps } from '../interface';
|
|
2
|
+
import { TUserGroupValue, TUserValue, TUser } from '../../ConfigProvider/getUserList';
|
|
3
|
+
import { TMember } from './types.js';
|
|
4
|
+
interface IProps {
|
|
5
|
+
members: TUser;
|
|
6
|
+
lockedIds?: Array<TUserValue | TUserGroupValue>;
|
|
7
|
+
onRemove: (member: TMember) => void;
|
|
8
|
+
renderSelectedTag?: MemberPickerProps['renderSelectedTag'];
|
|
9
|
+
}
|
|
10
|
+
/** 用户和用户组共享一个已选区,顺序直接来自不可变选择 Map。 */
|
|
11
|
+
export default function SelectedMemberPanel({ members, lockedIds, onRemove, renderSelectedTag, }: IProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Empty from "../../Empty/index.js";
|
|
2
|
+
import useDialogLocale from "./useDialogLocale.js";
|
|
3
|
+
import { getMemberKey, isMemberLocked } from "./helper.js";
|
|
4
|
+
import MemberOption from "./MemberOption.js";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/MemberPicker/dialog/SelectedMemberPanel.tsx
|
|
7
|
+
/** 用户和用户组共享一个已选区,顺序直接来自不可变选择 Map。 */
|
|
8
|
+
function SelectedMemberPanel({ members, lockedIds = [], onRemove, renderSelectedTag }) {
|
|
9
|
+
const t = useDialogLocale();
|
|
10
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
11
|
+
className: "tw-flex tw-h-full tw-min-h-0 tw-flex-col tw-overflow-hidden",
|
|
12
|
+
"data-testid": "selected-member-panel",
|
|
13
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
14
|
+
className: "tw-flex tw-h-10 tw-shrink-0 tw-items-center tw-gap-sp-100 tw-border-b tw-border-solid tw-border-border-default tw-px-sp-150 tw-text-content-primary tw-text-typography-label",
|
|
15
|
+
children: [t.MemberPickerDialog.selected, /* @__PURE__ */ jsx("span", {
|
|
16
|
+
className: "tw-text-content-secondary tw-text-typography-caption",
|
|
17
|
+
children: members.length
|
|
18
|
+
})]
|
|
19
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
20
|
+
className: "tw-min-h-0 tw-flex-1 tw-overflow-auto tw-p-sp-150",
|
|
21
|
+
children: !members.length ? /* @__PURE__ */ jsx(Empty, { description: t.MemberPickerDialog.emptySelected }) : /* @__PURE__ */ jsx("div", {
|
|
22
|
+
className: "tw-flex tw-flex-wrap tw-content-start tw-gap-sp-100",
|
|
23
|
+
children: members.map((member) => /* @__PURE__ */ jsx(MemberOption, {
|
|
24
|
+
member,
|
|
25
|
+
selected: true,
|
|
26
|
+
locked: isMemberLocked(member, lockedIds),
|
|
27
|
+
onRemove,
|
|
28
|
+
renderSelectedTag
|
|
29
|
+
}, getMemberKey(member)))
|
|
30
|
+
})
|
|
31
|
+
})]
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { SelectedMemberPanel as default };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=SelectedMemberPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectedMemberPanel.js","names":[],"sources":["../../../src/MemberPicker/dialog/SelectedMemberPanel.tsx"],"sourcesContent":["import Empty from '../../Empty';\nimport type { IMemberPickerProps as MemberPickerProps } from '../interface';\nimport type {\n TUserGroupValue,\n TUserValue,\n} from '../../ConfigProvider/getUserList';\nimport type { TUser } from '../../ConfigProvider/getUserList';\nimport useDialogLocale from './useDialogLocale';\nimport { getMemberKey, isMemberLocked } from './helper';\nimport MemberOption from './MemberOption';\nimport type { TMember } from './types';\n\ninterface IProps {\n members: TUser;\n lockedIds?: Array<TUserValue | TUserGroupValue>;\n onRemove: (member: TMember) => void;\n renderSelectedTag?: MemberPickerProps['renderSelectedTag'];\n}\n\n/** 用户和用户组共享一个已选区,顺序直接来自不可变选择 Map。 */\nexport default function SelectedMemberPanel({\n members,\n lockedIds = [],\n onRemove,\n renderSelectedTag,\n}: IProps) {\n const t = useDialogLocale();\n return (\n <section\n className=\"tw-flex tw-h-full tw-min-h-0 tw-flex-col tw-overflow-hidden\"\n data-testid=\"selected-member-panel\"\n >\n <div className=\"tw-flex tw-h-10 tw-shrink-0 tw-items-center tw-gap-sp-100 tw-border-b tw-border-solid tw-border-border-default tw-px-sp-150 tw-text-content-primary tw-text-typography-label\">\n {t.MemberPickerDialog.selected}\n <span className=\"tw-text-content-secondary tw-text-typography-caption\">\n {members.length}\n </span>\n </div>\n <div className=\"tw-min-h-0 tw-flex-1 tw-overflow-auto tw-p-sp-150\">\n {!members.length ? (\n <Empty description={t.MemberPickerDialog.emptySelected} />\n ) : (\n <div className=\"tw-flex tw-flex-wrap tw-content-start tw-gap-sp-100\">\n {members.map((member) => (\n <MemberOption\n key={getMemberKey(member)}\n member={member}\n selected\n locked={isMemberLocked(member, lockedIds)}\n onRemove={onRemove}\n renderSelectedTag={renderSelectedTag}\n />\n ))}\n </div>\n )}\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;;;AAoBA,SAAwB,oBAAoB,EAC1C,SACA,YAAY,EAAE,EACd,UACA,qBACS;CACT,MAAM,IAAI,iBAAiB;AAC3B,QACE,qBAAC,WAAD;EACE,WAAU;EACV,eAAY;YAFd,CAIE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAE,mBAAmB,UACtB,oBAAC,QAAD;IAAM,WAAU;cACb,QAAQ;IACJ,CAAA,CACH;MACN,oBAAC,OAAD;GAAK,WAAU;aACZ,CAAC,QAAQ,SACR,oBAAC,OAAD,EAAO,aAAa,EAAE,mBAAmB,eAAiB,CAAA,GAE1D,oBAAC,OAAD;IAAK,WAAU;cACZ,QAAQ,KAAK,WACZ,oBAAC,cAAD;KAEU;KACR,UAAA;KACA,QAAQ,eAAe,QAAQ,UAAU;KAC/B;KACS;KACnB,EANK,aAAa,OAAO,CAMzB,CACF;IACE,CAAA;GAEJ,CAAA,CACE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IMemberPickerProps as MemberPickerProps } from '../interface';
|
|
2
|
+
import { TMember, TMemberKey } from './types.js';
|
|
3
|
+
interface IProps {
|
|
4
|
+
selectedByKey: ReadonlyMap<TMemberKey, TMember>;
|
|
5
|
+
onToggle: (member: TMember) => void;
|
|
6
|
+
onToggleAll: (members: readonly TMember[], selected: boolean) => void;
|
|
7
|
+
lockedIds?: MemberPickerProps['lockedIds'];
|
|
8
|
+
filterItem?: MemberPickerProps['filterItem'];
|
|
9
|
+
renderItem?: MemberPickerProps['renderItem'];
|
|
10
|
+
}
|
|
11
|
+
/** 用户候选继续使用设计系统既有查询语义,并在前端只接受 USER。 */
|
|
12
|
+
export default function UserCandidatePanel({ selectedByKey, onToggle, onToggleAll, lockedIds, filterItem, renderItem, }: IProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export {};
|