@giteeteam/apps-team-components 1.11.16-alpha.2 → 1.11.17

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.
@@ -5,7 +5,6 @@ interface UserAvatarProps {
5
5
  avatar?: {
6
6
  url?: string;
7
7
  };
8
- bosKey?: string;
9
8
  username?: string;
10
9
  name?: string;
11
10
  nickname?: string;
@@ -1,22 +1,11 @@
1
1
  import { jsx } from '@emotion/react/jsx-runtime';
2
2
  import React__default, { useMemo } from 'react';
3
3
  import { ClassNames } from '@emotion/react';
4
- import useCurrentWorkspace from '../../../lib/hooks/useCurrentWorkspace.js';
5
4
  import { getNameBadge, getBackgroundColor } from '../utils.js';
6
5
  import { avatarItemStyle, avatarStyle, defaultAvatarStyle } from './style/index.js';
7
6
 
8
7
  const UserAvatar = React__default.memo(({ user, className }) => {
9
- const { workspaceKey } = useCurrentWorkspace();
10
- const avatarUrl = useMemo(() => {
11
- var _a, _b, _c, _d;
12
- const url = (_a = user === null || user === void 0 ? void 0 : user.avatar) === null || _a === void 0 ? void 0 : _a.url;
13
- if (url)
14
- return url;
15
- const bosKey = (_d = (_c = (_b = user === null || user === void 0 ? void 0 : user.bosKey) === null || _b === void 0 ? void 0 : _b.trim) === null || _c === void 0 ? void 0 : _c.call(_b)) !== null && _d !== void 0 ? _d : user === null || user === void 0 ? void 0 : user.bosKey;
16
- if (!workspaceKey || !bosKey)
17
- return undefined;
18
- return `/api/one/${workspaceKey}/rest/v1/companies/${workspaceKey}/users/logo/picture?url=${encodeURIComponent(bosKey)}`;
19
- }, [user, workspaceKey]);
8
+ const avatarUrl = useMemo(() => { var _a; return (_a = user === null || user === void 0 ? void 0 : user.avatar) === null || _a === void 0 ? void 0 : _a.url; }, [user]);
20
9
  const displayName = useMemo(() => (user === null || user === void 0 ? void 0 : user.name) || (user === null || user === void 0 ? void 0 : user.nickname) || (user === null || user === void 0 ? void 0 : user.username), [user]);
21
10
  const userBadge = useMemo(() => getNameBadge(displayName), [displayName]);
22
11
  return (jsx(ClassNames, { children: ({ cx, css }) => {
@@ -1,10 +1,11 @@
1
1
  import { jsx, jsxs, Fragment } from '@emotion/react/jsx-runtime';
2
- import { useMemo, useState, useRef, useEffect, useCallback } from 'react';
2
+ import React__default, { useMemo, useState, useRef, useEffect, useCallback } from 'react';
3
3
  import { Overlay } from 'react-overlays';
4
4
  import { DownOutlined } from '@ant-design/icons';
5
5
  import { ClassNames } from '@emotion/react';
6
6
  import { Checkbox, Divider, Spin, Select, Col } from 'antd';
7
7
  import debug from 'debug';
8
+ import { useAtomValue } from 'jotai';
8
9
  import { isNil, isObject, noop, isPlainObject, xorWith } from 'lodash-es';
9
10
  import { emptyIconWrapper } from '../../../style/global.js';
10
11
  import useSWR from 'swr';
@@ -20,13 +21,23 @@ import { getRealValueByIqlTo } from '../../filters/filter-search/utils.js';
20
21
  import { REMOTE_DATA_QUOTE_FIELD_TYPE } from '../../../lib/constants/field.js';
21
22
  import { BASE_FIELD_WIDTH, FIELD_CONTAINERS_PAGE, CURRENT_WORKSPACE, FIELD_TYPE_KEY_MAPPINGS } from '../../../lib/global.js';
22
23
  import useAntdConfig from '../../../lib/hooks/useAntdConfig.js';
24
+ import { useDropdownOptionsFetching } from '../../../lib/hooks/useFetchDropdownOptionsStore.js';
23
25
  import useI18n from '../../../lib/hooks/useI18n.js';
26
+ import { dropDownOptionsState, createDropDownOptionsStoreKey } from '../../../lib/store/dropDownOptionsStore.js';
24
27
  import { API_KEY } from '../../../lib/swr/constants.js';
25
28
  import useViewClass from '../hooks/useViewClass.js';
26
29
  import { EMPTY_OPTIONS, useCommonProps } from './hook.js';
27
30
  import { dropdownSelectDisabled, onlyWorkspaceStyle, onlyWorkspaceDividerStyle, dropdownSelectStyle, optionDisplayWrapClass, dropdownSelectOptionClass, disabledClass, workspaceClass, dropdownStyle, hiddenHoverClass, displayWrapClass, cellWrapperStyle, valueOptionContentClass, valueOptionClass, valueOptionIconClass, valueOptionLabelClass, hoverIconClass } from './style.js';
28
31
 
29
32
  const loggers = debug('dropdown:BaseField');
33
+ const mergeStoreOptions = (baseOptions, storeOptions) => {
34
+ if (!(storeOptions === null || storeOptions === void 0 ? void 0 : storeOptions.length))
35
+ return baseOptions || [];
36
+ const base = baseOptions || [];
37
+ const existingValues = new Set(base.map(o => o.value));
38
+ const additional = storeOptions.filter(o => !existingValues.has(o.value));
39
+ return additional.length ? [...base, ...additional] : base;
40
+ };
30
41
  const isNilFilter = function (value) {
31
42
  var _a;
32
43
  return (_a = value === null || value === void 0 ? void 0 : value.filter) === null || _a === void 0 ? void 0 : _a.call(value, val => !isNil(val));
@@ -83,6 +94,9 @@ const Dropdown = props => {
83
94
  ? propsValue
84
95
  : options;
85
96
  }, [dataQuoteInit, options, propsValue, userData === null || userData === void 0 ? void 0 : userData.display, value]);
97
+ const dropDownOptionsMap = useAtomValue(dropDownOptionsState);
98
+ const storeOptions = dropDownOptionsMap[createDropDownOptionsStoreKey(objectId)];
99
+ const isDropdownOptionsFetching = useDropdownOptionsFetching();
86
100
  const _options = useMemo(() => ((options === null || options === void 0 ? void 0 : options.length) > 0 ? options : finallyOptions) || [], [finallyOptions, options]);
87
101
  async function fetcher() {
88
102
  return await fetchOptions('');
@@ -181,6 +195,7 @@ const Dropdown = props => {
181
195
  var _a;
182
196
  loggers('loadMoreRef', loadMoreRef.current);
183
197
  if (canAsyncFetchOption &&
198
+ !isDropdownOptionsFetching &&
184
199
  Array.isArray(value) &&
185
200
  optionLoadedRef.current === true &&
186
201
  loadMoreRef.current === false &&
@@ -203,11 +218,12 @@ const Dropdown = props => {
203
218
  const options = cacheSelectOptions(typeof dataQuoteInit === 'function'
204
219
  ? dataQuoteInit(appendOptions, value, userData === null || userData === void 0 ? void 0 : userData.display)
205
220
  : appendOptions);
206
- setOptions(options);
221
+ const mergedOptions = mergeStoreOptions(options, storeOptions);
222
+ setOptions(mergedOptions);
207
223
  setLoading(false);
208
224
  const res = valueRef.current.filter(val => {
209
225
  const value = typeof val === 'object' ? val.value : val;
210
- const index = options === null || options === void 0 ? void 0 : options.findIndex((o) => {
226
+ const index = mergedOptions === null || mergedOptions === void 0 ? void 0 : mergedOptions.findIndex((o) => {
211
227
  return o.value === value;
212
228
  });
213
229
  if (index !== -1 || value === 'NULL' || value === CURRENT_WORKSPACE) {
@@ -261,6 +277,8 @@ const Dropdown = props => {
261
277
  cachedOptionsRef,
262
278
  setLoading,
263
279
  setOptions,
280
+ storeOptions,
281
+ isDropdownOptionsFetching,
264
282
  ]);
265
283
  useEffect(() => {
266
284
  onOptionsChange && onOptionsChange(options);
@@ -283,7 +301,8 @@ const Dropdown = props => {
283
301
  const showValue = useCallback(({ cx, css }) => {
284
302
  var _a, _b, _c, _d;
285
303
  let showValue = null;
286
- const _options = isCascaded ? _propsOptions : noClickEditing ? finallyOptions : options;
304
+ const _baseOptions = isCascaded ? _propsOptions : noClickEditing ? finallyOptions : options;
305
+ const _options = mergeStoreOptions(_baseOptions, storeOptions);
287
306
  const _optionsMap = {};
288
307
  if (Array.isArray(_options)) {
289
308
  _options.forEach(item => {
@@ -300,7 +319,7 @@ const Dropdown = props => {
300
319
  return null;
301
320
  showValue = valueArr.map((item, index) => {
302
321
  const content = _optionsMap[item] ? getFormattedLabel(_optionsMap[item]) : item;
303
- return index === value.length - 1 ? content : jsxs(Fragment, { children: [content, ","] });
322
+ return (jsxs(React__default.Fragment, { children: [content, index === value.length - 1 ? '' : ','] }, `${String(item)}-${index}`));
304
323
  });
305
324
  }
306
325
  }
@@ -316,7 +335,7 @@ const Dropdown = props => {
316
335
  }
317
336
  }
318
337
  return showValue;
319
- }, [isCascaded, _propsOptions, noClickEditing, finallyOptions, options, isMultiple, value, screenMode]);
338
+ }, [isCascaded, _propsOptions, noClickEditing, finallyOptions, options, isMultiple, value, screenMode, storeOptions]);
320
339
  const valueOptions = useMemo(() => {
321
340
  if ((Array.isArray(options) && (options === null || options === void 0 ? void 0 : options.length) >= 1 && value && Array.isArray(value)) ||
322
341
  (noClickEditing && Array.isArray(_options) && _options.length > 0)) {
@@ -565,10 +584,11 @@ const Dropdown = props => {
565
584
  selectValue,
566
585
  t,
567
586
  ]);
587
+ const mergedValueOptions = useMemo(() => mergeStoreOptions(valueOptions, storeOptions), [valueOptions, storeOptions]);
568
588
  return (jsx(ClassNames, { children: ({ cx, css }) => {
569
589
  const cxShowValue = showValue({ cx, css });
570
590
  return (jsx(Col, { style: style, ref: containerRef, className: cx(css(dropdownStyle(antPrefix)), 'field-value', viewClassNames, { [hiddenHoverClass]: hiddenHover }, { [displayWrapClass]: valueDisplayWrap }, { [css(dropdownSelectStyle(antPrefix))]: disabledLineThrough || displayValueHidden }), onClick: handleClick, children: jsxs("div", { css: css(cellWrapperStyle), children: [(readonly || (!editMode && !editing)) &&
571
- (cxShowValue ? (!valueDisplayWrap ? (isView && isMultiple ? (jsx(Expand, { readonly: readonly, editing: editing, expandType: EXPAND_TYPE_ENUM.TAG, children: valueOptions.map(item => (jsx("span", { className: "field-common-view-tag", children: jsx(BaseOverflowTooltip, { title: item.label, children: item.label }) }, item.value))) })) : (jsx(OverflowTooltip, { title: cxShowValue, children: cxShowValue }))) : (jsx("div", { className: cx(valueOptionContentClass), children: valueOptions.map(ele => {
591
+ (cxShowValue ? (!valueDisplayWrap ? (isView && isMultiple ? (jsx(Expand, { readonly: readonly, editing: editing, expandType: EXPAND_TYPE_ENUM.TAG, children: mergedValueOptions.map(item => (jsx("span", { className: "field-common-view-tag", children: jsx(BaseOverflowTooltip, { title: item.label, children: item.label }) }, item.value))) })) : (jsx(OverflowTooltip, { title: cxShowValue, children: cxShowValue }))) : (jsx("div", { className: cx(valueOptionContentClass), children: mergedValueOptions.map(ele => {
572
592
  return (jsxs("div", { className: cx(valueOptionClass), title: ele.label, children: [jsx(ItemIcon, { className: cx(valueOptionIconClass), icon: ele.icon }), jsx("span", { className: cx(valueOptionLabelClass), children: ele.label })] }, ele.value));
573
593
  }) }))) : (jsx(EmptyField, { readonly: readonly }))), !readonly && (editMode || editing) && containerRef && (jsx(Overlay, { show: true, rootClose: true, container: containerRef, target: containerRef, onHide: noop, children: () => overlayRender })), jsx(DownOutlined, { className: cx(hoverIconClass) })] }) }));
574
594
  } }));
package/dist/index.d.ts CHANGED
@@ -48,3 +48,4 @@ export { TableCell } from './components/table-components';
48
48
  export { getAllReadComponents, getStandardEditComponents, getStandardReadComponents, } from './components/table-components/utils';
49
49
  export { LibraryProvider } from './lib/contexts';
50
50
  export { useDataQuoteStore } from './lib/hooks/useDataQuoteStore';
51
+ export { useDropdownOptionsFetching, useFetchDropdownOptionsStore } from './lib/hooks/useFetchDropdownOptionsStore';
package/dist/index.js CHANGED
@@ -48,3 +48,4 @@ export { TableCell } from './components/table-components/index.js';
48
48
  export { getAllReadComponents, getStandardEditComponents, getStandardReadComponents } from './components/table-components/utils.js';
49
49
  export { LibraryProvider } from './lib/contexts/index.js';
50
50
  export { useDataQuoteStore } from './lib/hooks/useDataQuoteStore.js';
51
+ export { useDropdownOptionsFetching, useFetchDropdownOptionsStore } from './lib/hooks/useFetchDropdownOptionsStore.js';
@@ -0,0 +1,13 @@
1
+ interface CustomField {
2
+ key: string;
3
+ name: string;
4
+ objectId: string;
5
+ fieldType: Record<string, any>;
6
+ }
7
+ interface DataSourceItem {
8
+ values?: Record<string, any>;
9
+ [key: string]: any;
10
+ }
11
+ export declare const useDropdownOptionsFetching: () => boolean;
12
+ export declare const useFetchDropdownOptionsStore: (dataSource?: DataSourceItem[], customFields?: CustomField[], workspaceId?: string) => void;
13
+ export {};
@@ -0,0 +1,114 @@
1
+ import { useRef, useCallback, useMemo, useEffect } from 'react';
2
+ import { useAtomValue, useSetAtom } from 'jotai';
3
+ import useFetch from '../fetch.js';
4
+ import { FIELD_TYPE_KEY_MAPPINGS } from '../global.js';
5
+ import { dropDownOptionsFetchingState, dropDownOptionsState, createDropDownOptionsStoreKey } from '../store/dropDownOptionsStore.js';
6
+
7
+ const mergeDropDownOptions = (currentOptions, newOptions) => {
8
+ const seen = new Map();
9
+ for (const option of currentOptions) {
10
+ if (option)
11
+ seen.set(option.value, option);
12
+ }
13
+ for (const option of newOptions) {
14
+ if (option && !seen.has(option.value)) {
15
+ seen.set(option.value, option);
16
+ }
17
+ }
18
+ return Array.from(seen.values());
19
+ };
20
+ const getRequestCacheKey = (storeKey, workspaceId) => {
21
+ return `${workspaceId || 'default'}:${storeKey}`;
22
+ };
23
+ const useDropdownOptionsFetching = () => {
24
+ return useAtomValue(dropDownOptionsFetchingState);
25
+ };
26
+ const useFetchDropdownOptionsStore = (dataSource, customFields, workspaceId) => {
27
+ const fetch = useFetch();
28
+ const setDropDownOptionsMap = useSetAtom(dropDownOptionsState);
29
+ const setFetching = useSetAtom(dropDownOptionsFetchingState);
30
+ const activeRequestCountRef = useRef(0);
31
+ const fetchedValuesRef = useRef({});
32
+ const pendingRequestRef = useRef({});
33
+ const prevWorkspaceIdRef = useRef(workspaceId);
34
+ const updateFetchingState = useCallback((delta) => {
35
+ activeRequestCountRef.current += delta;
36
+ setFetching(activeRequestCountRef.current > 0);
37
+ }, [setFetching]);
38
+ const dropdownFields = useMemo(() => {
39
+ if (!(customFields === null || customFields === void 0 ? void 0 : customFields.length))
40
+ return [];
41
+ return customFields.filter(field => { var _a; return ((_a = field.fieldType) === null || _a === void 0 ? void 0 : _a.key) === FIELD_TYPE_KEY_MAPPINGS.Dropdown; });
42
+ }, [customFields]);
43
+ useEffect(() => {
44
+ if (prevWorkspaceIdRef.current !== workspaceId) {
45
+ fetchedValuesRef.current = {};
46
+ pendingRequestRef.current = {};
47
+ prevWorkspaceIdRef.current = workspaceId;
48
+ }
49
+ if (!dropdownFields.length || !(dataSource === null || dataSource === void 0 ? void 0 : dataSource.length))
50
+ return;
51
+ const fetchFieldOptions = async (field) => {
52
+ var _a;
53
+ const storeKey = createDropDownOptionsStoreKey(field.objectId);
54
+ if (!storeKey)
55
+ return;
56
+ const requestCacheKey = getRequestCacheKey(storeKey, workspaceId);
57
+ const values = new Set();
58
+ for (const item of dataSource) {
59
+ const fieldValues = (_a = item.values) === null || _a === void 0 ? void 0 : _a[field.key];
60
+ if (Array.isArray(fieldValues)) {
61
+ fieldValues.forEach(v => {
62
+ if (v != null)
63
+ values.add(String(v));
64
+ });
65
+ }
66
+ }
67
+ if (!values.size)
68
+ return;
69
+ const fetchedValues = fetchedValuesRef.current[requestCacheKey] || new Set();
70
+ fetchedValuesRef.current[requestCacheKey] = fetchedValues;
71
+ const missingValues = Array.from(values).filter(v => !fetchedValues.has(v));
72
+ if (!missingValues.length)
73
+ return;
74
+ const requestSignature = JSON.stringify(missingValues.slice().sort());
75
+ if (pendingRequestRef.current[requestCacheKey] === requestSignature) {
76
+ return;
77
+ }
78
+ pendingRequestRef.current[requestCacheKey] = requestSignature;
79
+ updateFetchingState(1);
80
+ try {
81
+ const { data } = await fetch.get(`/dropdown/data/${field.objectId}`, {
82
+ params: { propsValue: JSON.stringify(missingValues), workspaceId },
83
+ });
84
+ const options = (data === null || data === void 0 ? void 0 : data.data) || [];
85
+ missingValues.forEach(v => fetchedValues.add(v));
86
+ if (!options.length)
87
+ return;
88
+ setDropDownOptionsMap(prev => {
89
+ const currentOptions = prev[storeKey] || [];
90
+ const mergedOptions = mergeDropDownOptions(currentOptions, options);
91
+ if (mergedOptions.length === currentOptions.length) {
92
+ return prev;
93
+ }
94
+ return {
95
+ ...prev,
96
+ [storeKey]: mergedOptions,
97
+ };
98
+ });
99
+ }
100
+ catch (e) {
101
+ console.error('fetchDropdownData_error', e);
102
+ }
103
+ finally {
104
+ updateFetchingState(-1);
105
+ if (pendingRequestRef.current[requestCacheKey] === requestSignature) {
106
+ delete pendingRequestRef.current[requestCacheKey];
107
+ }
108
+ }
109
+ };
110
+ Promise.allSettled(dropdownFields.map(field => fetchFieldOptions(field)));
111
+ }, [dropdownFields, dataSource, fetch, setDropDownOptionsMap, workspaceId, updateFetchingState]);
112
+ };
113
+
114
+ export { useDropdownOptionsFetching, useFetchDropdownOptionsStore };
@@ -0,0 +1,21 @@
1
+ export interface DropDownOptionItem {
2
+ label: React.ReactNode;
3
+ value: string | number;
4
+ disabled?: boolean;
5
+ enable?: boolean;
6
+ icon?: string;
7
+ archived?: boolean;
8
+ name?: string;
9
+ key?: string;
10
+ itemType?: any;
11
+ values?: {
12
+ [propName: string]: any;
13
+ };
14
+ }
15
+ export declare const dropDownOptionsState: import("jotai").PrimitiveAtom<Record<string, DropDownOptionItem[]>> & {
16
+ init: Record<string, DropDownOptionItem[]>;
17
+ };
18
+ export declare const dropDownOptionsFetchingState: import("jotai").PrimitiveAtom<boolean> & {
19
+ init: boolean;
20
+ };
21
+ export declare const createDropDownOptionsStoreKey: (fieldId?: string) => string;
@@ -0,0 +1,9 @@
1
+ import { atom } from 'jotai';
2
+
3
+ const dropDownOptionsState = atom({});
4
+ const dropDownOptionsFetchingState = atom(false);
5
+ const createDropDownOptionsStoreKey = (fieldId) => {
6
+ return fieldId || '';
7
+ };
8
+
9
+ export { createDropDownOptionsStoreKey, dropDownOptionsFetchingState, dropDownOptionsState };
@@ -13,6 +13,5 @@ export type UserValueOption = {
13
13
  deleted: boolean;
14
14
  enabled: boolean;
15
15
  email?: string;
16
- bosKey?: string | null;
17
16
  };
18
17
  export declare const userDataFormat: (user: UserValue) => UserValueOption;
@@ -22,7 +22,7 @@ const generateUserDisplayName = (user, onlyNickname = false) => {
22
22
  return (user === null || user === void 0 ? void 0 : user.nickname) ? `${user === null || user === void 0 ? void 0 : user.nickname}${displaySuffix}` : user === null || user === void 0 ? void 0 : user.username;
23
23
  };
24
24
  const userDataFormat = (user) => {
25
- var _a, _b;
25
+ var _a;
26
26
  return ({
27
27
  label: generateUserDisplayName(user),
28
28
  value: (_a = user.objectId) !== null && _a !== void 0 ? _a : user.value,
@@ -31,7 +31,6 @@ const userDataFormat = (user) => {
31
31
  deleted: user.deleted,
32
32
  enabled: user.enabled,
33
33
  email: user.email,
34
- bosKey: (_b = user.bosKey) !== null && _b !== void 0 ? _b : null,
35
34
  });
36
35
  };
37
36
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@giteeteam/apps-team-components",
3
- "version": "1.11.16-alpha.2",
3
+ "version": "1.11.17",
4
4
  "description": "Gitee team components",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",