@hkyhy/marsun-components-core 0.1.101 → 0.1.113
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/components/Editor/VariablePicker.js +13 -13
- package/dist/components/Editor/VariablePicker.js.map +1 -1
- package/dist/components/Filter/createKneFilterField.js +42 -39
- package/dist/components/Filter/createKneFilterField.js.map +1 -1
- package/dist/components/Form/SuperSelect.js +48 -45
- package/dist/components/Form/SuperSelect.js.map +1 -1
- package/dist/components/FormInfo/RichTextField/index.js +46 -69
- package/dist/components/FormInfo/RichTextField/index.js.map +1 -1
- package/dist/components/FormInfo/VariableMentionInput/index.d.ts +1 -0
- package/dist/components/FormInfo/VariableMentionInput/index.js +53 -47
- package/dist/components/FormInfo/VariableMentionInput/index.js.map +1 -1
- package/dist/components/FormInfo/VariableMentionInput/style.module.scss.js +6 -5
- package/dist/components/FormInfo/VariableMentionInput/style.module.scss.js.map +1 -1
- package/dist/components/ReactFilter/fields/index.js +33 -26
- package/dist/components/ReactFilter/fields/index.js.map +1 -1
- package/dist/components/ReactFilter/renderSelectListItemContent.d.ts +8 -0
- package/dist/components/ReactFilter/renderSelectListItemContent.js +12 -0
- package/dist/components/ReactFilter/renderSelectListItemContent.js.map +1 -0
- package/dist/components/Tools/Inbox/InboxBell/InboxBell.d.ts +3 -0
- package/dist/components/Tools/Inbox/InboxBell/InboxBell.js +59 -49
- package/dist/components/Tools/Inbox/InboxBell/InboxBell.js.map +1 -1
- package/dist/components/Tools/Inbox/InboxBell/style.module.scss.js +20 -18
- package/dist/components/Tools/Inbox/InboxBell/style.module.scss.js.map +1 -1
- package/dist/components/Tools/Inbox/index.d.ts +1 -0
- package/dist/components/Tools/Inbox/sanitizeInboxHtml.d.ts +5 -0
- package/dist/components/Tools/Inbox/sanitizeInboxHtml.js +14 -0
- package/dist/components/Tools/Inbox/sanitizeInboxHtml.js.map +1 -0
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.d.ts +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.js +158 -137
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.js +217 -124
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/PushRulesPanel/index.d.ts +8 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/PushRulesPanel/index.js +312 -170
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/PushRulesPanel/index.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/VariablesPanel/index.js +87 -76
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/VariablesPanel/index.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/audienceSlots.d.ts +14 -0
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/audienceSlots.js +31 -0
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/audienceSlots.js.map +1 -0
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/index.d.ts +3 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/style.module.scss.js +18 -6
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/style.module.scss.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/types.d.ts +27 -0
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/types.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MsgCenterAppSwitcher/MsgCenterAppSwitcher.d.ts +22 -0
- package/dist/components/Tools/MessageCenter/MsgCenterAppSwitcher/MsgCenterAppSwitcher.js +64 -0
- package/dist/components/Tools/MessageCenter/MsgCenterAppSwitcher/MsgCenterAppSwitcher.js.map +1 -0
- package/dist/components/Tools/MessageCenter/MsgCenterAppSwitcher/index.d.ts +2 -0
- package/dist/components/Tools/MessageCenter/index.d.ts +8 -1
- package/dist/components/Tools/MessageCenter/msgCenterAppSwitch.d.ts +39 -0
- package/dist/components/Tools/MessageCenter/msgCenterAppSwitch.js +94 -0
- package/dist/components/Tools/MessageCenter/msgCenterAppSwitch.js.map +1 -0
- package/dist/components/Tools/MessageCenter/useMsgCenterAppKey.d.ts +2 -0
- package/dist/components/Tools/MessageCenter/useMsgCenterAppKey.js +18 -0
- package/dist/components/Tools/MessageCenter/useMsgCenterAppKey.js.map +1 -0
- package/dist/components/Tools/MessageCenter/utils/audienceUserSelectOptions.d.ts +16 -0
- package/dist/components/Tools/MessageCenter/utils/audienceUserSelectOptions.js +33 -0
- package/dist/components/Tools/MessageCenter/utils/audienceUserSelectOptions.js.map +1 -0
- package/dist/components/Tools/MessageCenter/utils/templateCode.js +11 -17
- package/dist/components/Tools/MessageCenter/utils/templateCode.js.map +1 -1
- package/dist/components/Tools/index.d.ts +3 -2
- package/dist/index.js +641 -626
- package/dist/index.js.map +1 -1
- package/dist/marsun-components-core.css +1 -1
- package/dist/node_modules/dompurify/dist/purify.es.js +908 -0
- package/dist/node_modules/dompurify/dist/purify.es.js.map +1 -0
- package/dist/node_modules/isomorphic-dompurify/dist/browser.js +17 -0
- package/dist/node_modules/isomorphic-dompurify/dist/browser.js.map +1 -0
- package/dist/styles/global.css +1 -1
- package/package.json +9 -1
|
@@ -11,6 +11,7 @@ export type VariableMentionFieldProps = {
|
|
|
11
11
|
variables?: VariableMentionItem[];
|
|
12
12
|
catalogError?: string;
|
|
13
13
|
className?: string;
|
|
14
|
+
size?: 'small' | 'middle' | 'large';
|
|
14
15
|
[key: string]: unknown;
|
|
15
16
|
};
|
|
16
17
|
export declare const VariableMentionField: ComponentType<VariableMentionFieldProps>;
|
|
@@ -1,73 +1,79 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import { useRef as
|
|
1
|
+
import { jsxs as V, jsx as l } from "react/jsx-runtime";
|
|
2
|
+
import * as v from "@kne/react-form-antd";
|
|
3
|
+
import { Input as x } from "antd";
|
|
4
|
+
import M from "classnames";
|
|
5
|
+
import { useRef as p } from "react";
|
|
6
6
|
import { insertVarTokenAt as y } from "../../Editor/variableMention.js";
|
|
7
|
-
import { VariablePicker as
|
|
8
|
-
import
|
|
9
|
-
const g = ({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
import { VariablePicker as R } from "../../Editor/VariablePicker.js";
|
|
8
|
+
import i from "./style.module.scss.js";
|
|
9
|
+
const g = ({
|
|
10
|
+
value: o = "",
|
|
11
|
+
onChange: e,
|
|
12
|
+
onBlur: c,
|
|
13
|
+
disabled: s,
|
|
14
|
+
variables: f,
|
|
15
|
+
catalogError: d,
|
|
16
|
+
placeholder: k,
|
|
17
|
+
className: S,
|
|
18
|
+
id: b,
|
|
19
|
+
size: a = "middle"
|
|
20
|
+
}) => {
|
|
21
|
+
const n = p(String(o || "").length), m = p(null), N = (t) => {
|
|
22
|
+
const r = y(String(o || ""), t, n.current);
|
|
23
|
+
e == null || e(r), n.current = n.current + `{{${t}}}`.length;
|
|
13
24
|
};
|
|
14
|
-
return /* @__PURE__ */
|
|
15
|
-
/* @__PURE__ */
|
|
16
|
-
|
|
25
|
+
return /* @__PURE__ */ V("div", { ref: m, className: i["var-mention-wrap"], children: [
|
|
26
|
+
/* @__PURE__ */ l(
|
|
27
|
+
x,
|
|
17
28
|
{
|
|
18
|
-
id:
|
|
29
|
+
id: b,
|
|
30
|
+
size: a,
|
|
19
31
|
value: o,
|
|
20
|
-
disabled:
|
|
21
|
-
placeholder:
|
|
22
|
-
className:
|
|
32
|
+
disabled: s,
|
|
33
|
+
placeholder: k || "点右侧「插入变量」,或手打 {{key}}",
|
|
34
|
+
className: M("marsun-var-mention-input", i["var-mention-input"], S),
|
|
35
|
+
onBlur: c,
|
|
23
36
|
onChange: (t) => {
|
|
24
37
|
const r = t.target.value;
|
|
25
|
-
|
|
38
|
+
n.current = t.target.selectionStart ?? r.length, e == null || e(r);
|
|
26
39
|
},
|
|
27
40
|
onSelect: (t) => {
|
|
28
41
|
const r = t.target;
|
|
29
|
-
|
|
42
|
+
n.current = r.selectionStart ?? -1;
|
|
30
43
|
},
|
|
31
44
|
onClick: (t) => {
|
|
32
45
|
const r = t.target;
|
|
33
|
-
|
|
46
|
+
n.current = r.selectionStart ?? -1;
|
|
34
47
|
},
|
|
35
48
|
onKeyUp: (t) => {
|
|
36
49
|
const r = t.target;
|
|
37
|
-
|
|
50
|
+
n.current = r.selectionStart ?? -1;
|
|
38
51
|
}
|
|
39
52
|
}
|
|
40
53
|
),
|
|
41
|
-
/* @__PURE__ */
|
|
42
|
-
|
|
54
|
+
/* @__PURE__ */ l(
|
|
55
|
+
R,
|
|
43
56
|
{
|
|
44
|
-
variables:
|
|
45
|
-
catalogError:
|
|
46
|
-
disabled:
|
|
47
|
-
|
|
48
|
-
|
|
57
|
+
variables: f,
|
|
58
|
+
catalogError: d,
|
|
59
|
+
disabled: s,
|
|
60
|
+
size: a,
|
|
61
|
+
className: i["var-mention-picker"],
|
|
62
|
+
getPopupContainer: () => m.current || document.body,
|
|
63
|
+
onPick: N
|
|
49
64
|
}
|
|
50
65
|
)
|
|
51
|
-
] })
|
|
52
|
-
},
|
|
53
|
-
const { useDecorator:
|
|
54
|
-
return
|
|
66
|
+
] });
|
|
67
|
+
}, u = (o) => {
|
|
68
|
+
const { useDecorator: e } = v.hooks;
|
|
69
|
+
return e({
|
|
55
70
|
fieldName: "variableMentionInput",
|
|
56
|
-
...
|
|
57
|
-
})(
|
|
58
|
-
g,
|
|
59
|
-
{
|
|
60
|
-
...e,
|
|
61
|
-
variables: c,
|
|
62
|
-
catalogError: a,
|
|
63
|
-
placeholder: s,
|
|
64
|
-
className: l
|
|
65
|
-
}
|
|
66
|
-
));
|
|
71
|
+
...o
|
|
72
|
+
})(g);
|
|
67
73
|
};
|
|
68
|
-
|
|
69
|
-
const
|
|
74
|
+
u.displayName = "VariableMentionField";
|
|
75
|
+
const K = u;
|
|
70
76
|
export {
|
|
71
|
-
|
|
77
|
+
K as VariableMentionField
|
|
72
78
|
};
|
|
73
79
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/FormInfo/VariableMentionInput/index.tsx"],"sourcesContent":["import * as ReactFormAntd from '@kne/react-form-antd';\nimport { Input
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/FormInfo/VariableMentionInput/index.tsx"],"sourcesContent":["import * as ReactFormAntd from '@kne/react-form-antd';\nimport { Input } from 'antd';\nimport classNames from 'classnames';\nimport type { ComponentType, FC, ReactNode } from 'react';\nimport { useRef } from 'react';\nimport { insertVarTokenAt, type VariableMentionItem } from '@/components/Editor/variableMention';\nimport { VariablePicker } from '@/components/Editor/VariablePicker';\nimport styles from './style.module.scss';\n\nexport type VariableMentionFieldProps = {\n name: string;\n label?: ReactNode;\n labelTips?: ReactNode | ((props: VariableMentionFieldProps) => ReactNode);\n rule?: string;\n disabled?: boolean;\n placeholder?: string;\n enableVariableMention?: boolean;\n variables?: VariableMentionItem[];\n catalogError?: string;\n className?: string;\n size?: 'small' | 'middle' | 'large';\n [key: string]: unknown;\n};\n\ntype FieldRenderProps = {\n value?: string;\n onChange?: (v: string) => void;\n onBlur?: (...args: unknown[]) => void;\n disabled?: boolean;\n id?: string;\n size?: 'small' | 'middle' | 'large';\n placeholder?: string;\n className?: string;\n variables?: VariableMentionItem[];\n catalogError?: string;\n};\n\ntype KneHooks = {\n useDecorator: (\n opts: Record<string, unknown>,\n ) => (Comp: ComponentType<FieldRenderProps>) => ReactNode;\n};\n\n/**\n * 标题变量:Input +「插入变量」按钮(明文 {{key}},可手改;无 `/` 触发)。\n * 须作为稳定组件类型交给 useDecorator(禁内联函数,否则每键 remount 丢焦)。\n */\nconst VariableMentionControl: FC<FieldRenderProps> = ({\n value = '',\n onChange,\n onBlur,\n disabled,\n variables,\n catalogError,\n placeholder,\n className,\n id,\n size = 'middle',\n}) => {\n const caretRef = useRef(String(value || '').length);\n const rootRef = useRef<HTMLDivElement>(null);\n\n const pick = (key: string) => {\n const next = insertVarTokenAt(String(value || ''), key, caretRef.current);\n onChange?.(next);\n caretRef.current = caretRef.current + `{{${key}}}`.length;\n };\n\n return (\n <div ref={rootRef} className={styles['var-mention-wrap']}>\n <Input\n id={id}\n size={size}\n value={value}\n disabled={disabled}\n placeholder={placeholder || '点右侧「插入变量」,或手打 {{key}}'}\n className={classNames('marsun-var-mention-input', styles['var-mention-input'], className)}\n onBlur={onBlur}\n onChange={(e) => {\n const next = e.target.value;\n caretRef.current = e.target.selectionStart ?? next.length;\n onChange?.(next);\n }}\n onSelect={(e) => {\n const t = e.target as HTMLInputElement;\n caretRef.current = t.selectionStart ?? -1;\n }}\n onClick={(e) => {\n const t = e.target as HTMLInputElement;\n caretRef.current = t.selectionStart ?? -1;\n }}\n onKeyUp={(e) => {\n const t = e.target as HTMLInputElement;\n caretRef.current = t.selectionStart ?? -1;\n }}\n />\n <VariablePicker\n variables={variables}\n catalogError={catalogError}\n disabled={disabled}\n size={size}\n className={styles['var-mention-picker']}\n getPopupContainer={() => rootRef.current || document.body}\n onPick={pick}\n />\n </div>\n );\n};\n\nconst VariableMentionInner: FC<VariableMentionFieldProps> = (props) => {\n const { useDecorator } = (ReactFormAntd as unknown as { hooks: KneHooks }).hooks;\n // variables / catalogError 等经 useDecorator → others 下发;禁 render(() => …) 内联类型\n const render = useDecorator({\n fieldName: 'variableMentionInput',\n ...props,\n });\n return render(VariableMentionControl);\n};\n\nVariableMentionInner.displayName = 'VariableMentionField';\n\nexport const VariableMentionField =\n VariableMentionInner as ComponentType<VariableMentionFieldProps>;\n\nexport default VariableMentionField;\n"],"names":["VariableMentionControl","value","onChange","onBlur","disabled","variables","catalogError","placeholder","className","id","size","caretRef","useRef","rootRef","pick","key","next","insertVarTokenAt","styles","jsx","Input","classNames","e","t","VariablePicker","VariableMentionInner","props","useDecorator","ReactFormAntd","VariableMentionField"],"mappings":";;;;;;;;AA+CA,MAAMA,IAA+C,CAAC;AAAA,EACpD,OAAAC,IAAQ;AAAA,EACR,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC;AAAA,EACA,IAAAC;AAAA,EACA,MAAAC,IAAO;AACT,MAAM;AACJ,QAAMC,IAAWC,EAAO,OAAOX,KAAS,EAAE,EAAE,MAAM,GAC5CY,IAAUD,EAAuB,IAAI,GAErCE,IAAO,CAACC,MAAgB;AAC5B,UAAMC,IAAOC,EAAiB,OAAOhB,KAAS,EAAE,GAAGc,GAAKJ,EAAS,OAAO;AACxE,IAAAT,KAAA,QAAAA,EAAWc,IACXL,EAAS,UAAUA,EAAS,UAAU,KAAKI,CAAG,KAAK;AAAA,EACrD;AAEA,2BACG,OAAA,EAAI,KAAKF,GAAS,WAAWK,EAAO,kBAAkB,GACrD,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,IAAAX;AAAA,QACA,MAAAC;AAAA,QACA,OAAAT;AAAA,QACA,UAAAG;AAAA,QACA,aAAaG,KAAe;AAAA,QAC5B,WAAWc,EAAW,4BAA4BH,EAAO,mBAAmB,GAAGV,CAAS;AAAA,QACxF,QAAAL;AAAA,QACA,UAAU,CAACmB,MAAM;AACf,gBAAMN,IAAOM,EAAE,OAAO;AACtB,UAAAX,EAAS,UAAUW,EAAE,OAAO,kBAAkBN,EAAK,QACnDd,KAAA,QAAAA,EAAWc;AAAA,QACb;AAAA,QACA,UAAU,CAACM,MAAM;AACf,gBAAMC,IAAID,EAAE;AACZ,UAAAX,EAAS,UAAUY,EAAE,kBAAkB;AAAA,QACzC;AAAA,QACA,SAAS,CAACD,MAAM;AACd,gBAAMC,IAAID,EAAE;AACZ,UAAAX,EAAS,UAAUY,EAAE,kBAAkB;AAAA,QACzC;AAAA,QACA,SAAS,CAACD,MAAM;AACd,gBAAMC,IAAID,EAAE;AACZ,UAAAX,EAAS,UAAUY,EAAE,kBAAkB;AAAA,QACzC;AAAA,MAAA;AAAA,IAAA;AAAA,IAEF,gBAAAJ;AAAA,MAACK;AAAA,MAAA;AAAA,QACC,WAAAnB;AAAA,QACA,cAAAC;AAAA,QACA,UAAAF;AAAA,QACA,MAAAM;AAAA,QACA,WAAWQ,EAAO,oBAAoB;AAAA,QACtC,mBAAmB,MAAML,EAAQ,WAAW,SAAS;AAAA,QACrD,QAAQC;AAAA,MAAA;AAAA,IAAA;AAAA,EACV,GACF;AAEJ,GAEMW,IAAsD,CAACC,MAAU;AACrE,QAAM,EAAE,cAAAC,MAAkBC,EAAiD;AAM3E,SAJeD,EAAa;AAAA,IAC1B,WAAW;AAAA,IACX,GAAGD;AAAA,EAAA,CACJ,EACa1B,CAAsB;AACtC;AAEAyB,EAAqB,cAAc;AAE5B,MAAMI,IACXJ;"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const n = {
|
|
2
|
-
"var-mention-wrap": "_var-mention-
|
|
3
|
-
"var-mention-input": "_var-mention-
|
|
4
|
-
"var-mention-
|
|
5
|
-
"var-mention-
|
|
6
|
-
"var-mention-
|
|
2
|
+
"var-mention-wrap": "_var-mention-wrap_7gf45_1",
|
|
3
|
+
"var-mention-input": "_var-mention-input_7gf45_9",
|
|
4
|
+
"var-mention-picker": "_var-mention-picker_7gf45_15",
|
|
5
|
+
"var-mention-option": "_var-mention-option_7gf45_20",
|
|
6
|
+
"var-mention-token": "_var-mention-token_7gf45_26",
|
|
7
|
+
"var-mention-label": "_var-mention-label_7gf45_37"
|
|
7
8
|
};
|
|
8
9
|
export {
|
|
9
10
|
n as default
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"style.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -1,41 +1,48 @@
|
|
|
1
|
-
import { jsx as
|
|
1
|
+
import { jsx as l } from "react/jsx-runtime";
|
|
2
2
|
import { useIntl as p } from "@kne/react-intl";
|
|
3
3
|
import e from "../withFieldItem.js";
|
|
4
4
|
import u from "./InputFilterItem.js";
|
|
5
|
-
import
|
|
5
|
+
import n from "./NumberRangeFilterItem.js";
|
|
6
6
|
import s from "../withLocale.js";
|
|
7
|
-
import
|
|
7
|
+
import a, { SelectTableList as f, SelectCascader as I } from "@kne/super-select";
|
|
8
8
|
import { SelectFunction as d, SelectIndustry as F, SelectAddress as S } from "@kne/super-select-plus";
|
|
9
9
|
/* empty css */
|
|
10
10
|
/* empty css */
|
|
11
11
|
/* empty css */
|
|
12
|
-
import {
|
|
13
|
-
import { default as G } from "./
|
|
14
|
-
import { default as J } from "./
|
|
15
|
-
import { default as O } from "./
|
|
16
|
-
|
|
12
|
+
import { renderSelectListItemContent as P } from "../renderSelectListItemContent.js";
|
|
13
|
+
import { default as G } from "./DatePickerFilterItem.js";
|
|
14
|
+
import { default as J } from "./DateRangePickerFilterItem.js";
|
|
15
|
+
import { default as O } from "./TypeDateRangePickerFilterItem.js";
|
|
16
|
+
import { default as U } from "./SelectTreeFilterItem.js";
|
|
17
|
+
const m = (t) => s(({ placeholder: r, label: o, ...i }) => {
|
|
17
18
|
const { formatMessage: c } = p({ moduleName: "Filter" });
|
|
18
|
-
return /* @__PURE__ */
|
|
19
|
-
|
|
19
|
+
return /* @__PURE__ */ l(
|
|
20
|
+
t,
|
|
20
21
|
{
|
|
21
|
-
...
|
|
22
|
-
label:
|
|
23
|
-
placeholder:
|
|
22
|
+
...i,
|
|
23
|
+
label: o,
|
|
24
|
+
placeholder: r || c({ id: "defaultInputPlaceholder" }, { label: o })
|
|
24
25
|
}
|
|
25
26
|
);
|
|
26
|
-
})
|
|
27
|
+
});
|
|
28
|
+
function h({ renderItemContent: t, ...r }) {
|
|
29
|
+
return /* @__PURE__ */ l(a, { ...r, renderItemContent: t || P });
|
|
30
|
+
}
|
|
31
|
+
const A = m(u), $ = m(n), j = e(h, {
|
|
32
|
+
forcePopup: !0
|
|
33
|
+
}), E = e(f, { forcePopup: !0 }), M = e(I, { forcePopup: !0 }), W = e(d, { forcePopup: !0 }), q = e(F, { forcePopup: !0 }), v = e(S, { forcePopup: !0 });
|
|
27
34
|
export {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
G as DatePickerFilterItem,
|
|
36
|
+
J as DateRangePickerFilterItem,
|
|
37
|
+
A as InputFilterItem,
|
|
38
|
+
$ as NumberRangeFilterItem,
|
|
39
|
+
v as SelectAddressFilterItem,
|
|
40
|
+
M as SelectCascaderFilterItem,
|
|
41
|
+
W as SelectFunctionFilterItem,
|
|
42
|
+
q as SelectIndustryFilterItem,
|
|
43
|
+
E as SelectTableListFilterItem,
|
|
44
|
+
U as SelectTreeFilterItem,
|
|
45
|
+
j as SuperSelectFilterItem,
|
|
46
|
+
O as TypeDateRangePickerFilterItem
|
|
40
47
|
};
|
|
41
48
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/ReactFilter/fields/index.jsx"],"sourcesContent":["// @ts-nocheck\nimport { useIntl } from '@kne/react-intl';\nimport withFieldItem from '../withFieldItem';\nimport InputFilterItemField from './InputFilterItem';\nimport NumberRangeFilterItemField from './NumberRangeFilterItem';\nimport withLocale from '../withLocale';\nimport SuperSelect, { SelectCascader, SelectTableList } from '@kne/super-select';\nimport { SelectAddress, SelectFunction, SelectIndustry } from '@kne/super-select-plus';\nimport '@kne/super-select/dist/index.css';\nimport '@kne/super-select-plus/dist/index.css';\n/** SuperSelect / SelectTree 弹层全局修补(选项撑满、checkbox、叶子 switcher-noop) */\nimport '../superSelectPopup.scss';\n\nconst withInputDefaultPlaceholder = (WrappedComponent) =>\n withLocale(({ placeholder, label, ...props }) => {\n const { formatMessage } = useIntl({ moduleName: 'Filter' });\n return (\n <WrappedComponent\n {...props}\n label={label}\n placeholder={placeholder || formatMessage({ id: 'defaultInputPlaceholder' }, { label })}\n />\n );\n });\n\nexport const InputFilterItem = withInputDefaultPlaceholder(InputFilterItemField);\nexport const NumberRangeFilterItem = withInputDefaultPlaceholder(NumberRangeFilterItemField);\n\nexport { default as DatePickerFilterItem } from './DatePickerFilterItem';\nexport { default as DateRangePickerFilterItem } from './DateRangePickerFilterItem';\nexport { default as TypeDateRangePickerFilterItem } from './TypeDateRangePickerFilterItem';\n\nexport const SuperSelectFilterItem = withFieldItem(
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/ReactFilter/fields/index.jsx"],"sourcesContent":["// @ts-nocheck\nimport { useIntl } from '@kne/react-intl';\nimport withFieldItem from '../withFieldItem';\nimport InputFilterItemField from './InputFilterItem';\nimport NumberRangeFilterItemField from './NumberRangeFilterItem';\nimport withLocale from '../withLocale';\nimport SuperSelect, { SelectCascader, SelectTableList } from '@kne/super-select';\nimport { SelectAddress, SelectFunction, SelectIndustry } from '@kne/super-select-plus';\nimport '@kne/super-select/dist/index.css';\nimport '@kne/super-select-plus/dist/index.css';\n/** SuperSelect / SelectTree 弹层全局修补(选项撑满、checkbox、叶子 switcher-noop) */\nimport '../superSelectPopup.scss';\nimport { renderSelectListItemContent } from '../renderSelectListItemContent';\n\nconst withInputDefaultPlaceholder = (WrappedComponent) =>\n withLocale(({ placeholder, label, ...props }) => {\n const { formatMessage } = useIntl({ moduleName: 'Filter' });\n return (\n <WrappedComponent\n {...props}\n label={label}\n placeholder={placeholder || formatMessage({ id: 'defaultInputPlaceholder' }, { label })}\n />\n );\n });\n\n/** 默认超长省略 + title hover;业务可传 renderItemContent 覆盖 */\nfunction SuperSelectWithLabelEllipsis({ renderItemContent, ...props }) {\n return (\n <SuperSelect {...props} renderItemContent={renderItemContent || renderSelectListItemContent} />\n );\n}\n\nexport const InputFilterItem = withInputDefaultPlaceholder(InputFilterItemField);\nexport const NumberRangeFilterItem = withInputDefaultPlaceholder(NumberRangeFilterItemField);\n\nexport { default as DatePickerFilterItem } from './DatePickerFilterItem';\nexport { default as DateRangePickerFilterItem } from './DateRangePickerFilterItem';\nexport { default as TypeDateRangePickerFilterItem } from './TypeDateRangePickerFilterItem';\n\nexport const SuperSelectFilterItem = withFieldItem(SuperSelectWithLabelEllipsis, {\n forcePopup: true,\n});\nexport const SelectTableListFilterItem = withFieldItem(SelectTableList, { forcePopup: true });\nexport { default as SelectTreeFilterItem } from './SelectTreeFilterItem';\nexport const SelectCascaderFilterItem = withFieldItem(SelectCascader, { forcePopup: true });\nexport const SelectFunctionFilterItem = withFieldItem(SelectFunction, { forcePopup: true });\nexport const SelectIndustryFilterItem = withFieldItem(SelectIndustry, { forcePopup: true });\nexport const SelectAddressFilterItem = withFieldItem(SelectAddress, { forcePopup: true });\n"],"names":["withInputDefaultPlaceholder","WrappedComponent","withLocale","placeholder","label","props","formatMessage","useIntl","jsx","SuperSelectWithLabelEllipsis","renderItemContent","SuperSelect","renderSelectListItemContent","InputFilterItem","InputFilterItemField","NumberRangeFilterItem","NumberRangeFilterItemField","SuperSelectFilterItem","withFieldItem","SelectTableListFilterItem","SelectTableList","SelectCascaderFilterItem","SelectCascader","SelectFunctionFilterItem","SelectFunction","SelectIndustryFilterItem","SelectIndustry","SelectAddressFilterItem","SelectAddress"],"mappings":";;;;;;;;;;;;;;;;AAcA,MAAMA,IAA8B,CAACC,MACnCC,EAAW,CAAC,EAAE,aAAAC,GAAa,OAAAC,GAAO,GAAGC,QAAY;AAC/C,QAAM,EAAE,eAAAC,EAAA,IAAkBC,EAAQ,EAAE,YAAY,UAAU;AAC1D,SACE,gBAAAC;AAAA,IAACP;AAAA,IAAA;AAAA,MACE,GAAGI;AAAA,MACJ,OAAAD;AAAA,MACA,aAAaD,KAAeG,EAAc,EAAE,IAAI,0BAAA,GAA6B,EAAE,OAAAF,EAAA,CAAO;AAAA,IAAA;AAAA,EAAA;AAG5F,CAAC;AAGH,SAASK,EAA6B,EAAE,mBAAAC,GAAmB,GAAGL,KAAS;AACrE,2BACGM,GAAA,EAAa,GAAGN,GAAO,mBAAmBK,KAAqBE,GAA6B;AAEjG;AAEO,MAAMC,IAAkBb,EAA4Bc,CAAoB,GAClEC,IAAwBf,EAA4BgB,CAA0B,GAM9EC,IAAwBC,EAAcT,GAA8B;AAAA,EAC/E,YAAY;AACd,CAAC,GACYU,IAA4BD,EAAcE,GAAiB,EAAE,YAAY,IAAM,GAE/EC,IAA2BH,EAAcI,GAAgB,EAAE,YAAY,IAAM,GAC7EC,IAA2BL,EAAcM,GAAgB,EAAE,YAAY,IAAM,GAC7EC,IAA2BP,EAAcQ,GAAgB,EAAE,YAAY,IAAM,GAC7EC,IAA0BT,EAAcU,GAAe,EAAE,YAAY,IAAM;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsxs as o, Fragment as d, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
function b({ item: e, props: l }) {
|
|
3
|
+
const s = (l == null ? void 0 : l.labelKey) || "label", n = e == null ? void 0 : e[s], c = typeof n == "string" || typeof n == "number" ? String(n) : void 0, t = e == null ? void 0 : e.description, r = typeof t == "string" || typeof t == "number" ? String(t) : void 0;
|
|
4
|
+
return /* @__PURE__ */ o(d, { children: [
|
|
5
|
+
/* @__PURE__ */ i("div", { className: "select-list-item-label", title: c, children: n }),
|
|
6
|
+
t ? /* @__PURE__ */ i("div", { className: "select-list-item-description", title: r, children: t }) : null
|
|
7
|
+
] });
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
b as renderSelectListItemContent
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=renderSelectListItemContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderSelectListItemContent.js","sources":["../../../src/components/ReactFilter/renderSelectListItemContent.jsx"],"sourcesContent":["/**\n * SuperSelect 列表项文案:超长省略 + 原生 title hover 看全文。\n * 覆盖 kne 默认(仅 div.select-list-item-label、无 title)。\n */\nexport function renderSelectListItemContent({ item, props }) {\n const labelKey = props?.labelKey || 'label';\n const label = item?.[labelKey];\n const title = typeof label === 'string' || typeof label === 'number' ? String(label) : undefined;\n const description = item?.description;\n const descriptionTitle =\n typeof description === 'string' || typeof description === 'number'\n ? String(description)\n : undefined;\n\n return (\n <>\n <div className=\"select-list-item-label\" title={title}>\n {label}\n </div>\n {description ? (\n <div className=\"select-list-item-description\" title={descriptionTitle}>\n {description}\n </div>\n ) : null}\n </>\n );\n}\n"],"names":["renderSelectListItemContent","item","props","labelKey","label","title","description","descriptionTitle","jsxs","Fragment","jsx"],"mappings":";AAIO,SAASA,EAA4B,EAAE,MAAAC,GAAM,OAAAC,KAAS;AAC3D,QAAMC,KAAWD,KAAA,gBAAAA,EAAO,aAAY,SAC9BE,IAAQH,KAAA,gBAAAA,EAAOE,IACfE,IAAQ,OAAOD,KAAU,YAAY,OAAOA,KAAU,WAAW,OAAOA,CAAK,IAAI,QACjFE,IAAcL,KAAA,gBAAAA,EAAM,aACpBM,IACJ,OAAOD,KAAgB,YAAY,OAAOA,KAAgB,WACtD,OAAOA,CAAW,IAClB;AAEN,SACE,gBAAAE,EAAAC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,0BAAyB,OAAAL,GACrC,UAAAD,GACH;AAAA,IACCE,sBACE,OAAA,EAAI,WAAU,gCAA+B,OAAOC,GAClD,aACH,IACE;AAAA,EAAA,GACN;AAEJ;"}
|
|
@@ -3,7 +3,10 @@ export type InboxBellMessageType = 'alert' | 'action' | 'remind' | string;
|
|
|
3
3
|
export type InboxBellItem = {
|
|
4
4
|
id: string;
|
|
5
5
|
title?: string;
|
|
6
|
+
/** 纯文本摘要(列表兼容) */
|
|
6
7
|
summary?: string;
|
|
8
|
+
/** 已渲染 HTML 正文;空则主摘要位回落 summary */
|
|
9
|
+
bodyHtml?: string | null;
|
|
7
10
|
read?: boolean;
|
|
8
11
|
messageType?: InboxBellMessageType;
|
|
9
12
|
href?: string;
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import { jsxs as b, jsx as a } from "react/jsx-runtime";
|
|
2
|
-
import { Badge as
|
|
3
|
-
import
|
|
4
|
-
import { useState as n, useCallback as
|
|
5
|
-
import
|
|
2
|
+
import { Badge as R, Button as U, Drawer as W, Space as $, message as A } from "antd";
|
|
3
|
+
import x from "classnames";
|
|
4
|
+
import { useState as n, useCallback as E, useEffect as T, useMemo as F } from "react";
|
|
5
|
+
import { sanitizeInboxHtml as D } from "../sanitizeInboxHtml.js";
|
|
6
|
+
import t from "./style.module.scss.js";
|
|
6
7
|
import { Bell as K } from "../../../Icons/Bell.js";
|
|
7
8
|
import Y from "../../../StateBar/StateBar.js";
|
|
8
9
|
import q from "../../../SegmentedRadio/SegmentedRadio.js";
|
|
9
10
|
import G from "../../../Layout/PageSpin/index.js";
|
|
10
|
-
import
|
|
11
|
-
const
|
|
11
|
+
import J from "../../../Empty/Empty.js";
|
|
12
|
+
const Q = [
|
|
12
13
|
{ key: "", label: "全部" },
|
|
13
14
|
{ key: "alert", label: "预警" },
|
|
14
15
|
{ key: "action", label: "行动" },
|
|
15
16
|
{ key: "remind", label: "提醒" }
|
|
16
|
-
],
|
|
17
|
+
], ie = ({
|
|
17
18
|
fetchInbox: o,
|
|
18
19
|
markRead: M,
|
|
19
20
|
onNavigate: v,
|
|
20
21
|
pollMs: m = 6e4,
|
|
21
22
|
pageSize: w = 50,
|
|
22
|
-
className:
|
|
23
|
-
title:
|
|
23
|
+
className: H,
|
|
24
|
+
title: I = "站内信"
|
|
24
25
|
}) => {
|
|
25
|
-
const [p, i] = n(!1), [B,
|
|
26
|
-
|
|
26
|
+
const [p, i] = n(!1), [B, N] = n(!1), [u, k] = n(""), [S, y] = n([]), [s, f] = n(0), [C, z] = n({}), [h, P] = n(""), [d, _] = n("all"), O = E(async () => {
|
|
27
|
+
N(!0), k("");
|
|
27
28
|
try {
|
|
28
29
|
const e = await o({
|
|
29
30
|
currentPage: 1,
|
|
@@ -32,16 +33,16 @@ const J = [
|
|
|
32
33
|
unreadOnly: d === "unread" || void 0,
|
|
33
34
|
readOnly: d === "read" || void 0
|
|
34
35
|
});
|
|
35
|
-
y((e == null ? void 0 : e.itemList) || []), f(typeof (e == null ? void 0 : e.unreadTotal) == "number" ? e.unreadTotal : 0),
|
|
36
|
+
y((e == null ? void 0 : e.itemList) || []), f(typeof (e == null ? void 0 : e.unreadTotal) == "number" ? e.unreadTotal : 0), z((e == null ? void 0 : e.unreadByMessageType) || {});
|
|
36
37
|
} catch (e) {
|
|
37
|
-
y([]),
|
|
38
|
+
y([]), k(e instanceof Error ? e.message : String(e));
|
|
38
39
|
} finally {
|
|
39
|
-
|
|
40
|
+
N(!1);
|
|
40
41
|
}
|
|
41
|
-
}, [o, h, w, d]), c =
|
|
42
|
+
}, [o, h, w, d]), c = E(async () => {
|
|
42
43
|
try {
|
|
43
44
|
const e = await o({ currentPage: 1, pageSize: 1 });
|
|
44
|
-
f(typeof (e == null ? void 0 : e.unreadTotal) == "number" ? e.unreadTotal : 0),
|
|
45
|
+
f(typeof (e == null ? void 0 : e.unreadTotal) == "number" ? e.unreadTotal : 0), z((e == null ? void 0 : e.unreadByMessageType) || {});
|
|
45
46
|
} catch {
|
|
46
47
|
}
|
|
47
48
|
}, [o]);
|
|
@@ -54,54 +55,54 @@ const J = [
|
|
|
54
55
|
}, m);
|
|
55
56
|
return () => window.clearInterval(e);
|
|
56
57
|
}, [m, c]), T(() => {
|
|
57
|
-
p &&
|
|
58
|
-
}, [p,
|
|
59
|
-
const
|
|
60
|
-
() =>
|
|
61
|
-
const
|
|
58
|
+
p && O();
|
|
59
|
+
}, [p, O]);
|
|
60
|
+
const j = F(
|
|
61
|
+
() => Q.map((e) => {
|
|
62
|
+
const r = e.key ? C[e.key] || 0 : s;
|
|
62
63
|
return {
|
|
63
64
|
key: e.key || "all",
|
|
64
|
-
label:
|
|
65
|
+
label: r > 0 ? `${e.label} (${r})` : e.label
|
|
65
66
|
};
|
|
66
67
|
}),
|
|
67
68
|
[C, s]
|
|
68
|
-
),
|
|
69
|
+
), L = async (e) => {
|
|
69
70
|
if (!e.read)
|
|
70
71
|
try {
|
|
71
72
|
await M(e.id), y((l) => l.map((g) => g.id === e.id ? { ...g, read: !0 } : g)), f((l) => Math.max(0, l - 1));
|
|
72
73
|
} catch (l) {
|
|
73
|
-
|
|
74
|
+
A.error(l instanceof Error ? l.message : "标记已读失败");
|
|
74
75
|
return;
|
|
75
76
|
}
|
|
76
|
-
const
|
|
77
|
-
if (
|
|
77
|
+
const r = String(e.href || "").trim();
|
|
78
|
+
if (r) {
|
|
78
79
|
if (v) {
|
|
79
|
-
v(
|
|
80
|
+
v(r, e), i(!1);
|
|
80
81
|
return;
|
|
81
82
|
}
|
|
82
|
-
|
|
83
|
+
r.startsWith("http://") || r.startsWith("https://") ? window.open(r, "_blank", "noopener,noreferrer") : window.location.assign(r), i(!1);
|
|
83
84
|
}
|
|
84
85
|
};
|
|
85
|
-
return /* @__PURE__ */ b("div", { className:
|
|
86
|
-
/* @__PURE__ */ a(
|
|
87
|
-
|
|
86
|
+
return /* @__PURE__ */ b("div", { className: x(t.bellWrap, H), children: [
|
|
87
|
+
/* @__PURE__ */ a(R, { count: s, size: "small", overflowCount: 99, offset: [-4, 4], children: /* @__PURE__ */ a(
|
|
88
|
+
U,
|
|
88
89
|
{
|
|
89
90
|
type: "text",
|
|
90
|
-
className:
|
|
91
|
+
className: t.bellBtn,
|
|
91
92
|
icon: /* @__PURE__ */ a(K, { size: 16, "aria-hidden": !0 }),
|
|
92
93
|
"aria-label": s > 0 ? `站内信,${s} 条未读` : "站内信",
|
|
93
94
|
onClick: () => i(!0)
|
|
94
95
|
}
|
|
95
96
|
) }),
|
|
96
97
|
/* @__PURE__ */ b(
|
|
97
|
-
|
|
98
|
+
W,
|
|
98
99
|
{
|
|
99
|
-
title:
|
|
100
|
+
title: I,
|
|
100
101
|
open: p,
|
|
101
102
|
onClose: () => i(!1),
|
|
102
103
|
size: 420,
|
|
103
104
|
destroyOnClose: !1,
|
|
104
|
-
className:
|
|
105
|
+
className: t.drawer,
|
|
105
106
|
styles: {
|
|
106
107
|
header: { padding: "12px 16px" },
|
|
107
108
|
body: { padding: "12px 16px" }
|
|
@@ -110,20 +111,20 @@ const J = [
|
|
|
110
111
|
/* @__PURE__ */ a(
|
|
111
112
|
Y,
|
|
112
113
|
{
|
|
113
|
-
className:
|
|
114
|
+
className: t.typeTabs,
|
|
114
115
|
size: "small",
|
|
115
116
|
activeKey: h || "all",
|
|
116
|
-
onChange: (e) =>
|
|
117
|
-
stateOption:
|
|
117
|
+
onChange: (e) => P(e === "all" ? "" : e),
|
|
118
|
+
stateOption: j,
|
|
118
119
|
isInner: !0
|
|
119
120
|
}
|
|
120
121
|
),
|
|
121
|
-
/* @__PURE__ */ a("div", { className:
|
|
122
|
+
/* @__PURE__ */ a("div", { className: t.filterRow, children: /* @__PURE__ */ a(
|
|
122
123
|
q,
|
|
123
124
|
{
|
|
124
125
|
size: "small",
|
|
125
126
|
value: d,
|
|
126
|
-
onChange: (e) =>
|
|
127
|
+
onChange: (e) => _(e),
|
|
127
128
|
options: [
|
|
128
129
|
{ value: "all", label: "全部" },
|
|
129
130
|
{ value: "unread", label: "未读" },
|
|
@@ -131,17 +132,26 @@ const J = [
|
|
|
131
132
|
]
|
|
132
133
|
}
|
|
133
134
|
) }),
|
|
134
|
-
u ? /* @__PURE__ */ a("p", { className:
|
|
135
|
-
/* @__PURE__ */ a(G, { spinning: B, children: !B && !u && S.length === 0 ? /* @__PURE__ */ a(
|
|
135
|
+
u ? /* @__PURE__ */ a("p", { className: t.error, children: u }) : null,
|
|
136
|
+
/* @__PURE__ */ a(G, { spinning: B, children: !B && !u && S.length === 0 ? /* @__PURE__ */ a(J, { description: "暂无站内信" }) : /* @__PURE__ */ a("ul", { className: t.list, children: S.map((e) => /* @__PURE__ */ a("li", { children: /* @__PURE__ */ a(
|
|
136
137
|
"button",
|
|
137
138
|
{
|
|
138
139
|
type: "button",
|
|
139
|
-
className:
|
|
140
|
-
onClick: () => void
|
|
141
|
-
children: /* @__PURE__ */ b(
|
|
142
|
-
/* @__PURE__ */ a("span", { className:
|
|
143
|
-
|
|
144
|
-
|
|
140
|
+
className: x(t.item, !e.read && t.itemUnread),
|
|
141
|
+
onClick: () => void L(e),
|
|
142
|
+
children: /* @__PURE__ */ b($, { orientation: "vertical", size: 2, style: { width: "100%" }, children: [
|
|
143
|
+
/* @__PURE__ */ a("span", { className: t.itemTitle, children: e.title || "(无标题)" }),
|
|
144
|
+
(() => {
|
|
145
|
+
const r = D(e.bodyHtml);
|
|
146
|
+
return r ? /* @__PURE__ */ a(
|
|
147
|
+
"div",
|
|
148
|
+
{
|
|
149
|
+
className: t.itemBodyHtml,
|
|
150
|
+
dangerouslySetInnerHTML: { __html: r }
|
|
151
|
+
}
|
|
152
|
+
) : e.summary ? /* @__PURE__ */ a("span", { className: t.itemSummary, children: e.summary }) : null;
|
|
153
|
+
})(),
|
|
154
|
+
/* @__PURE__ */ a("span", { className: t.itemMeta, children: [e.messageType, e.createdAt].filter(Boolean).join(" · ") || "—" })
|
|
145
155
|
] })
|
|
146
156
|
}
|
|
147
157
|
) }, e.id)) }) })
|
|
@@ -151,6 +161,6 @@ const J = [
|
|
|
151
161
|
] });
|
|
152
162
|
};
|
|
153
163
|
export {
|
|
154
|
-
|
|
164
|
+
ie as default
|
|
155
165
|
};
|
|
156
166
|
//# sourceMappingURL=InboxBell.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InboxBell.js","sources":["../../../../../src/components/Tools/Inbox/InboxBell/InboxBell.tsx"],"sourcesContent":["import { Badge, Button, Drawer, Space, message } from 'antd';\nimport classNames from 'classnames';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Empty } from '@/components/Empty';\nimport { Bell } from '@/components/Icons';\nimport { PageSpin } from '@/components/Layout';\nimport { SegmentedRadio } from '@/components/SegmentedRadio';\nimport { StateBar } from '@/components/StateBar';\nimport styles from './style.module.scss';\n\nexport type InboxBellMessageType = 'alert' | 'action' | 'remind' | string;\n\nexport type InboxBellItem = {\n id: string;\n title?: string;\n summary?: string;\n read?: boolean;\n messageType?: InboxBellMessageType;\n href?: string;\n createdAt?: string;\n level?: string;\n};\n\nexport type InboxBellListResult = {\n itemList: InboxBellItem[];\n total?: number;\n unreadTotal?: number;\n unreadByMessageType?: Partial<Record<string, number>>;\n};\n\nexport type InboxBellListParams = {\n unreadOnly?: boolean;\n readOnly?: boolean;\n messageType?: InboxBellMessageType;\n currentPage?: number;\n pageSize?: number;\n};\n\nexport type InboxBellProps = {\n /** 拉取站内信(业务注入;须带 JWT 身份,禁止无身份全表) */\n fetchInbox: (params: InboxBellListParams) => Promise<InboxBellListResult>;\n /** 标记已读 */\n markRead: (id: string) => Promise<void | InboxBellItem>;\n /** 点击条目:默认用 window.location / 业务 navigate */\n onNavigate?: (href: string, item: InboxBellItem) => void;\n /** 轮询未读角标(ms);≤0 关闭 */\n pollMs?: number;\n pageSize?: number;\n className?: string;\n /** Drawer 标题 */\n title?: string;\n};\n\nconst TYPE_TABS: Array<{ key: string; label: string }> = [\n { key: '', label: '全部' },\n { key: 'alert', label: '预警' },\n { key: 'action', label: '行动' },\n { key: 'remind', label: '提醒' },\n];\n\n/**\n * 通用站内信铃铛:列表 / 已读 / Tab / 角标。\n * 不含认领、行动等业务动作;由注入的 fetchInbox / markRead / onNavigate 对接消息服务。\n */\nconst InboxBell: React.FC<InboxBellProps> = ({\n fetchInbox,\n markRead,\n onNavigate,\n pollMs = 60_000,\n pageSize = 50,\n className,\n title = '站内信',\n}) => {\n const [open, setOpen] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [items, setItems] = useState<InboxBellItem[]>([]);\n const [unreadTotal, setUnreadTotal] = useState(0);\n const [unreadByType, setUnreadByType] = useState<Partial<Record<string, number>>>({});\n const [messageType, setMessageType] = useState<string>('');\n const [readFilter, setReadFilter] = useState<'all' | 'unread' | 'read'>('all');\n\n const load = useCallback(async () => {\n setLoading(true);\n setError('');\n try {\n const res = await fetchInbox({\n currentPage: 1,\n pageSize,\n messageType: messageType || undefined,\n unreadOnly: readFilter === 'unread' || undefined,\n readOnly: readFilter === 'read' || undefined,\n });\n setItems(res?.itemList || []);\n setUnreadTotal(typeof res?.unreadTotal === 'number' ? res.unreadTotal : 0);\n setUnreadByType(res?.unreadByMessageType || {});\n } catch (e) {\n setItems([]);\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }, [fetchInbox, messageType, pageSize, readFilter]);\n\n const refreshBadge = useCallback(async () => {\n try {\n const res = await fetchInbox({ currentPage: 1, pageSize: 1 });\n setUnreadTotal(typeof res?.unreadTotal === 'number' ? res.unreadTotal : 0);\n setUnreadByType(res?.unreadByMessageType || {});\n } catch {\n /* 角标失败不打断 UI */\n }\n }, [fetchInbox]);\n\n useEffect(() => {\n void refreshBadge();\n }, [refreshBadge]);\n\n useEffect(() => {\n if (pollMs <= 0) return undefined;\n const t = window.setInterval(() => {\n void refreshBadge();\n }, pollMs);\n return () => window.clearInterval(t);\n }, [pollMs, refreshBadge]);\n\n useEffect(() => {\n if (open) void load();\n }, [open, load]);\n\n const typeTabOptions = useMemo(\n () =>\n TYPE_TABS.map((t) => {\n const n = t.key ? unreadByType[t.key] || 0 : unreadTotal;\n return {\n key: t.key || 'all',\n label: n > 0 ? `${t.label} (${n})` : t.label,\n };\n }),\n [unreadByType, unreadTotal],\n );\n\n const handleOpenItem = async (item: InboxBellItem) => {\n if (!item.read) {\n try {\n await markRead(item.id);\n setItems((prev) => prev.map((x) => (x.id === item.id ? { ...x, read: true } : x)));\n setUnreadTotal((n) => Math.max(0, n - 1));\n } catch (e) {\n message.error(e instanceof Error ? e.message : '标记已读失败');\n return;\n }\n }\n const href = String(item.href || '').trim();\n if (!href) return;\n if (onNavigate) {\n onNavigate(href, item);\n setOpen(false);\n return;\n }\n if (href.startsWith('http://') || href.startsWith('https://')) {\n window.open(href, '_blank', 'noopener,noreferrer');\n } else {\n window.location.assign(href);\n }\n setOpen(false);\n };\n\n return (\n <div className={classNames(styles.bellWrap, className)}>\n <Badge count={unreadTotal} size=\"small\" overflowCount={99} offset={[-4, 4]}>\n <Button\n type=\"text\"\n className={styles.bellBtn}\n icon={<Bell size={16} aria-hidden />}\n aria-label={unreadTotal > 0 ? `站内信,${unreadTotal} 条未读` : '站内信'}\n onClick={() => setOpen(true)}\n />\n </Badge>\n <Drawer\n title={title}\n open={open}\n onClose={() => setOpen(false)}\n size={420}\n destroyOnClose={false}\n className={styles.drawer}\n styles={{\n header: { padding: '12px 16px' },\n body: { padding: '12px 16px' },\n }}\n >\n <StateBar\n className={styles.typeTabs}\n size=\"small\"\n activeKey={messageType || 'all'}\n onChange={(k) => setMessageType(k === 'all' ? '' : k)}\n stateOption={typeTabOptions}\n isInner\n />\n <div className={styles.filterRow}>\n <SegmentedRadio<'all' | 'unread' | 'read'>\n size=\"small\"\n value={readFilter}\n onChange={(v) => setReadFilter(v)}\n options={[\n { value: 'all', label: '全部' },\n { value: 'unread', label: '未读' },\n { value: 'read', label: '已读' },\n ]}\n />\n </div>\n {error ? <p className={styles.error}>{error}</p> : null}\n <PageSpin spinning={loading}>\n {!loading && !error && items.length === 0 ? (\n <Empty description=\"暂无站内信\" />\n ) : (\n <ul className={styles.list}>\n {items.map((item) => (\n <li key={item.id}>\n <button\n type=\"button\"\n className={classNames(styles.item, !item.read && styles.itemUnread)}\n onClick={() => void handleOpenItem(item)}\n >\n <Space orientation=\"vertical\" size={2} style={{ width: '100%' }}>\n <span className={styles.itemTitle}>{item.title || '(无标题)'}</span>\n {item.summary ? (\n <span className={styles.itemSummary}>{item.summary}</span>\n ) : null}\n <span className={styles.itemMeta}>\n {[item.messageType, item.createdAt].filter(Boolean).join(' · ') || '—'}\n </span>\n </Space>\n </button>\n </li>\n ))}\n </ul>\n )}\n </PageSpin>\n </Drawer>\n </div>\n );\n};\n\nexport default InboxBell;\n"],"names":["TYPE_TABS","InboxBell","fetchInbox","markRead","onNavigate","pollMs","pageSize","className","title","open","setOpen","useState","loading","setLoading","error","setError","items","setItems","unreadTotal","setUnreadTotal","unreadByType","setUnreadByType","messageType","setMessageType","readFilter","setReadFilter","load","useCallback","res","refreshBadge","useEffect","t","typeTabOptions","useMemo","n","handleOpenItem","item","prev","x","e","message","href","classNames","styles","jsx","Badge","Button","Bell","jsxs","Drawer","StateBar","k","SegmentedRadio","v","PageSpin","Empty","Space"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InboxBell.js","sources":["../../../../../src/components/Tools/Inbox/InboxBell/InboxBell.tsx"],"sourcesContent":["import { Badge, Button, Drawer, Space, message } from 'antd';\nimport classNames from 'classnames';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Empty } from '@/components/Empty';\nimport { Bell } from '@/components/Icons';\nimport { PageSpin } from '@/components/Layout';\nimport { SegmentedRadio } from '@/components/SegmentedRadio';\nimport { StateBar } from '@/components/StateBar';\nimport { sanitizeInboxHtml } from '../sanitizeInboxHtml';\nimport styles from './style.module.scss';\n\nexport type InboxBellMessageType = 'alert' | 'action' | 'remind' | string;\n\nexport type InboxBellItem = {\n id: string;\n title?: string;\n /** 纯文本摘要(列表兼容) */\n summary?: string;\n /** 已渲染 HTML 正文;空则主摘要位回落 summary */\n bodyHtml?: string | null;\n read?: boolean;\n messageType?: InboxBellMessageType;\n href?: string;\n createdAt?: string;\n level?: string;\n};\n\nexport type InboxBellListResult = {\n itemList: InboxBellItem[];\n total?: number;\n unreadTotal?: number;\n unreadByMessageType?: Partial<Record<string, number>>;\n};\n\nexport type InboxBellListParams = {\n unreadOnly?: boolean;\n readOnly?: boolean;\n messageType?: InboxBellMessageType;\n currentPage?: number;\n pageSize?: number;\n};\n\nexport type InboxBellProps = {\n /** 拉取站内信(业务注入;须带 JWT 身份,禁止无身份全表) */\n fetchInbox: (params: InboxBellListParams) => Promise<InboxBellListResult>;\n /** 标记已读 */\n markRead: (id: string) => Promise<void | InboxBellItem>;\n /** 点击条目:默认用 window.location / 业务 navigate */\n onNavigate?: (href: string, item: InboxBellItem) => void;\n /** 轮询未读角标(ms);≤0 关闭 */\n pollMs?: number;\n pageSize?: number;\n className?: string;\n /** Drawer 标题 */\n title?: string;\n};\n\nconst TYPE_TABS: Array<{ key: string; label: string }> = [\n { key: '', label: '全部' },\n { key: 'alert', label: '预警' },\n { key: 'action', label: '行动' },\n { key: 'remind', label: '提醒' },\n];\n\n/**\n * 通用站内信铃铛:列表 / 已读 / Tab / 角标。\n * 不含认领、行动等业务动作;由注入的 fetchInbox / markRead / onNavigate 对接消息服务。\n */\nconst InboxBell: React.FC<InboxBellProps> = ({\n fetchInbox,\n markRead,\n onNavigate,\n pollMs = 60_000,\n pageSize = 50,\n className,\n title = '站内信',\n}) => {\n const [open, setOpen] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [items, setItems] = useState<InboxBellItem[]>([]);\n const [unreadTotal, setUnreadTotal] = useState(0);\n const [unreadByType, setUnreadByType] = useState<Partial<Record<string, number>>>({});\n const [messageType, setMessageType] = useState<string>('');\n const [readFilter, setReadFilter] = useState<'all' | 'unread' | 'read'>('all');\n\n const load = useCallback(async () => {\n setLoading(true);\n setError('');\n try {\n const res = await fetchInbox({\n currentPage: 1,\n pageSize,\n messageType: messageType || undefined,\n unreadOnly: readFilter === 'unread' || undefined,\n readOnly: readFilter === 'read' || undefined,\n });\n setItems(res?.itemList || []);\n setUnreadTotal(typeof res?.unreadTotal === 'number' ? res.unreadTotal : 0);\n setUnreadByType(res?.unreadByMessageType || {});\n } catch (e) {\n setItems([]);\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }, [fetchInbox, messageType, pageSize, readFilter]);\n\n const refreshBadge = useCallback(async () => {\n try {\n const res = await fetchInbox({ currentPage: 1, pageSize: 1 });\n setUnreadTotal(typeof res?.unreadTotal === 'number' ? res.unreadTotal : 0);\n setUnreadByType(res?.unreadByMessageType || {});\n } catch {\n /* 角标失败不打断 UI */\n }\n }, [fetchInbox]);\n\n useEffect(() => {\n void refreshBadge();\n }, [refreshBadge]);\n\n useEffect(() => {\n if (pollMs <= 0) return undefined;\n const t = window.setInterval(() => {\n void refreshBadge();\n }, pollMs);\n return () => window.clearInterval(t);\n }, [pollMs, refreshBadge]);\n\n useEffect(() => {\n if (open) void load();\n }, [open, load]);\n\n const typeTabOptions = useMemo(\n () =>\n TYPE_TABS.map((t) => {\n const n = t.key ? unreadByType[t.key] || 0 : unreadTotal;\n return {\n key: t.key || 'all',\n label: n > 0 ? `${t.label} (${n})` : t.label,\n };\n }),\n [unreadByType, unreadTotal],\n );\n\n const handleOpenItem = async (item: InboxBellItem) => {\n if (!item.read) {\n try {\n await markRead(item.id);\n setItems((prev) => prev.map((x) => (x.id === item.id ? { ...x, read: true } : x)));\n setUnreadTotal((n) => Math.max(0, n - 1));\n } catch (e) {\n message.error(e instanceof Error ? e.message : '标记已读失败');\n return;\n }\n }\n const href = String(item.href || '').trim();\n if (!href) return;\n if (onNavigate) {\n onNavigate(href, item);\n setOpen(false);\n return;\n }\n if (href.startsWith('http://') || href.startsWith('https://')) {\n window.open(href, '_blank', 'noopener,noreferrer');\n } else {\n window.location.assign(href);\n }\n setOpen(false);\n };\n\n return (\n <div className={classNames(styles.bellWrap, className)}>\n <Badge count={unreadTotal} size=\"small\" overflowCount={99} offset={[-4, 4]}>\n <Button\n type=\"text\"\n className={styles.bellBtn}\n icon={<Bell size={16} aria-hidden />}\n aria-label={unreadTotal > 0 ? `站内信,${unreadTotal} 条未读` : '站内信'}\n onClick={() => setOpen(true)}\n />\n </Badge>\n <Drawer\n title={title}\n open={open}\n onClose={() => setOpen(false)}\n size={420}\n destroyOnClose={false}\n className={styles.drawer}\n styles={{\n header: { padding: '12px 16px' },\n body: { padding: '12px 16px' },\n }}\n >\n <StateBar\n className={styles.typeTabs}\n size=\"small\"\n activeKey={messageType || 'all'}\n onChange={(k) => setMessageType(k === 'all' ? '' : k)}\n stateOption={typeTabOptions}\n isInner\n />\n <div className={styles.filterRow}>\n <SegmentedRadio<'all' | 'unread' | 'read'>\n size=\"small\"\n value={readFilter}\n onChange={(v) => setReadFilter(v)}\n options={[\n { value: 'all', label: '全部' },\n { value: 'unread', label: '未读' },\n { value: 'read', label: '已读' },\n ]}\n />\n </div>\n {error ? <p className={styles.error}>{error}</p> : null}\n <PageSpin spinning={loading}>\n {!loading && !error && items.length === 0 ? (\n <Empty description=\"暂无站内信\" />\n ) : (\n <ul className={styles.list}>\n {items.map((item) => (\n <li key={item.id}>\n <button\n type=\"button\"\n className={classNames(styles.item, !item.read && styles.itemUnread)}\n onClick={() => void handleOpenItem(item)}\n >\n <Space orientation=\"vertical\" size={2} style={{ width: '100%' }}>\n <span className={styles.itemTitle}>{item.title || '(无标题)'}</span>\n {(() => {\n const safeHtml = sanitizeInboxHtml(item.bodyHtml);\n if (safeHtml) {\n return (\n <div\n className={styles.itemBodyHtml}\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n );\n }\n return item.summary ? (\n <span className={styles.itemSummary}>{item.summary}</span>\n ) : null;\n })()}\n <span className={styles.itemMeta}>\n {[item.messageType, item.createdAt].filter(Boolean).join(' · ') || '—'}\n </span>\n </Space>\n </button>\n </li>\n ))}\n </ul>\n )}\n </PageSpin>\n </Drawer>\n </div>\n );\n};\n\nexport default InboxBell;\n"],"names":["TYPE_TABS","InboxBell","fetchInbox","markRead","onNavigate","pollMs","pageSize","className","title","open","setOpen","useState","loading","setLoading","error","setError","items","setItems","unreadTotal","setUnreadTotal","unreadByType","setUnreadByType","messageType","setMessageType","readFilter","setReadFilter","load","useCallback","res","refreshBadge","useEffect","t","typeTabOptions","useMemo","n","handleOpenItem","item","prev","x","e","message","href","classNames","styles","jsx","Badge","Button","Bell","jsxs","Drawer","StateBar","k","SegmentedRadio","v","PageSpin","Empty","Space","safeHtml","sanitizeInboxHtml"],"mappings":"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"}
|