@solidxai/core-ui 0.1.13-beta.1 → 0.1.13-beta.3

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.
Files changed (94) hide show
  1. package/dist/components/common/SolidFieldTooltip.d.ts.map +1 -1
  2. package/dist/components/common/SolidFieldTooltip.js +33 -1
  3. package/dist/components/common/SolidFieldTooltip.js.map +1 -1
  4. package/dist/components/common/SolidFieldTooltip.tsx +64 -8
  5. package/dist/components/core/chatter/SolidChatter.d.ts.map +1 -1
  6. package/dist/components/core/chatter/SolidChatter.js +4 -2
  7. package/dist/components/core/chatter/SolidChatter.js.map +1 -1
  8. package/dist/components/core/chatter/SolidChatter.tsx +4 -1
  9. package/dist/components/core/chatter/SolidChatterMentionMenu.d.ts +9 -0
  10. package/dist/components/core/chatter/SolidChatterMentionMenu.d.ts.map +1 -0
  11. package/dist/components/core/chatter/SolidChatterMentionMenu.js +18 -0
  12. package/dist/components/core/chatter/SolidChatterMentionMenu.js.map +1 -0
  13. package/dist/components/core/chatter/SolidChatterMentionMenu.tsx +45 -0
  14. package/dist/components/core/chatter/SolidChatterMessageBox.d.ts +1 -0
  15. package/dist/components/core/chatter/SolidChatterMessageBox.d.ts.map +1 -1
  16. package/dist/components/core/chatter/SolidChatterMessageBox.js +29 -5
  17. package/dist/components/core/chatter/SolidChatterMessageBox.js.map +1 -1
  18. package/dist/components/core/chatter/SolidChatterMessageBox.tsx +57 -4
  19. package/dist/components/core/chatter/SolidMessageComposer.d.ts.map +1 -1
  20. package/dist/components/core/chatter/SolidMessageComposer.js +33 -7
  21. package/dist/components/core/chatter/SolidMessageComposer.js.map +1 -1
  22. package/dist/components/core/chatter/SolidMessageComposer.tsx +61 -7
  23. package/dist/components/core/chatter/chatter.module.css +63 -0
  24. package/dist/components/core/chatter/chatterMentions.d.ts +17 -0
  25. package/dist/components/core/chatter/chatterMentions.d.ts.map +1 -0
  26. package/dist/components/core/chatter/chatterMentions.js +50 -0
  27. package/dist/components/core/chatter/chatterMentions.js.map +1 -0
  28. package/dist/components/core/chatter/chatterMentions.ts +59 -0
  29. package/dist/components/core/chatter/useChatterMentions.d.ts +26 -0
  30. package/dist/components/core/chatter/useChatterMentions.d.ts.map +1 -0
  31. package/dist/components/core/chatter/useChatterMentions.js +204 -0
  32. package/dist/components/core/chatter/useChatterMentions.js.map +1 -0
  33. package/dist/components/core/chatter/useChatterMentions.ts +160 -0
  34. package/dist/components/core/form/fields/SolidMediaMultipleField.d.ts.map +1 -1
  35. package/dist/components/core/form/fields/SolidMediaMultipleField.js +111 -106
  36. package/dist/components/core/form/fields/SolidMediaMultipleField.js.map +1 -1
  37. package/dist/components/core/form/fields/SolidMediaMultipleField.tsx +165 -134
  38. package/dist/components/core/form/fields/SolidMediaSingleField.d.ts.map +1 -1
  39. package/dist/components/core/form/fields/SolidMediaSingleField.js +81 -84
  40. package/dist/components/core/form/fields/SolidMediaSingleField.js.map +1 -1
  41. package/dist/components/core/form/fields/SolidMediaSingleField.tsx +97 -86
  42. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.d.ts +1 -1
  43. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.d.ts.map +1 -1
  44. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js +4 -0
  45. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js.map +1 -1
  46. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.tsx +6 -0
  47. package/dist/components/core/list/SolidListView.d.ts.map +1 -1
  48. package/dist/components/core/list/SolidListView.js +4 -3
  49. package/dist/components/core/list/SolidListView.js.map +1 -1
  50. package/dist/components/core/list/SolidListView.tsx +4 -3
  51. package/dist/components/core/list/columns/SolidMediaMultipleColumn.d.ts.map +1 -1
  52. package/dist/components/core/list/columns/SolidMediaMultipleColumn.js +42 -81
  53. package/dist/components/core/list/columns/SolidMediaMultipleColumn.js.map +1 -1
  54. package/dist/components/core/list/columns/SolidMediaMultipleColumn.tsx +90 -120
  55. package/dist/components/core/list/columns/SolidMediaSingleColumn.d.ts.map +1 -1
  56. package/dist/components/core/list/columns/SolidMediaSingleColumn.js +34 -42
  57. package/dist/components/core/list/columns/SolidMediaSingleColumn.js.map +1 -1
  58. package/dist/components/core/list/columns/SolidMediaSingleColumn.tsx +51 -46
  59. package/dist/components/core/model/CreateModel.d.ts.map +1 -1
  60. package/dist/components/core/model/CreateModel.js +3 -2
  61. package/dist/components/core/model/CreateModel.js.map +1 -1
  62. package/dist/components/core/model/CreateModel.tsx +4 -1
  63. package/dist/components/core/model/FieldMetaData.d.ts +1 -1
  64. package/dist/components/core/model/FieldMetaData.d.ts.map +1 -1
  65. package/dist/components/core/model/FieldMetaData.js +17 -17
  66. package/dist/components/core/model/FieldMetaData.js.map +1 -1
  67. package/dist/components/core/model/FieldMetaData.tsx +10 -2
  68. package/dist/components/shad-cn-ui/SolidTextarea.d.ts +1 -1
  69. package/dist/components/shad-cn-ui/SolidTextarea.d.ts.map +1 -1
  70. package/dist/components/shad-cn-ui/SolidTextarea.js +4 -3
  71. package/dist/components/shad-cn-ui/SolidTextarea.js.map +1 -1
  72. package/dist/components/shad-cn-ui/SolidTextarea.tsx +4 -2
  73. package/dist/helpers/downloadMediaFile.d.ts.map +1 -1
  74. package/dist/helpers/downloadMediaFile.js +10 -3
  75. package/dist/helpers/downloadMediaFile.js.map +1 -1
  76. package/dist/helpers/downloadMediaFile.tsx +13 -7
  77. package/dist/helpers/fileTypeIcon.d.ts +3 -2
  78. package/dist/helpers/fileTypeIcon.d.ts.map +1 -1
  79. package/dist/helpers/fileTypeIcon.js +11 -7
  80. package/dist/helpers/fileTypeIcon.js.map +1 -1
  81. package/dist/helpers/fileTypeIcon.tsx +12 -7
  82. package/dist/helpers/mediaType.d.ts +7 -0
  83. package/dist/helpers/mediaType.d.ts.map +1 -1
  84. package/dist/helpers/mediaType.js +39 -8
  85. package/dist/helpers/mediaType.js.map +1 -1
  86. package/dist/helpers/mediaType.ts +46 -7
  87. package/dist/helpers/mediaUrl.d.ts +2 -0
  88. package/dist/helpers/mediaUrl.d.ts.map +1 -0
  89. package/dist/helpers/mediaUrl.js +10 -0
  90. package/dist/helpers/mediaUrl.js.map +1 -0
  91. package/dist/helpers/mediaUrl.ts +11 -0
  92. package/dist/resources/globals.css +14 -0
  93. package/dist/resources/solid-tailwind-generated.css +1 -1
  94. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SolidFieldTooltip.d.ts","sourceRoot":"","sources":["../../../src/components/common/SolidFieldTooltip.tsx"],"names":[],"mappings":"AAQA,eAAO,MAAM,iBAAiB,qBAAsB,GAAG,mDA2BtD,CAAC"}
1
+ {"version":3,"file":"SolidFieldTooltip.d.ts","sourceRoot":"","sources":["../../../src/components/common/SolidFieldTooltip.tsx"],"names":[],"mappings":"AASA,eAAO,MAAM,iBAAiB,qBAAsB,GAAG,mDAkFtD,CAAC"}
@@ -1,4 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useEffect } from "react";
3
+ import { SolidPopover, SolidPopoverContent, SolidPopoverTrigger, } from "../shad-cn-ui";
2
4
  import { SolidTooltip, SolidTooltipContent, SolidTooltipTrigger, } from "../shad-cn-ui/SolidTooltip";
3
5
  import { SolidIcon } from "../shad-cn-ui";
4
6
  export var SolidFieldTooltip = function (_a) {
@@ -7,10 +9,40 @@ export var SolidFieldTooltip = function (_a) {
7
9
  var solidFormViewMetaData = fieldContext.solidFormViewMetaData;
8
10
  var fieldLayoutInfo = fieldContext.field;
9
11
  var fieldMetadata = fieldContext.fieldMetadata;
12
+ var _g = React.useState(false), useTapPopover = _g[0], setUseTapPopover = _g[1];
10
13
  var showTooltip = (_e = (_d = (_c = (_b = solidFormViewMetaData.data.solidView) === null || _b === void 0 ? void 0 : _b.layout) === null || _c === void 0 ? void 0 : _c.attrs) === null || _d === void 0 ? void 0 : _d.showTooltip) !== null && _e !== void 0 ? _e : true;
11
14
  var fieldDescription = (_f = fieldLayoutInfo.attrs.description) !== null && _f !== void 0 ? _f : fieldMetadata.description;
15
+ useEffect(function () {
16
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
17
+ return;
18
+ }
19
+ var touchMedia = window.matchMedia("(hover: none), (pointer: coarse)");
20
+ var responsiveMedia = window.matchMedia("(max-width: 991px)");
21
+ var updateMode = function () {
22
+ setUseTapPopover(touchMedia.matches || responsiveMedia.matches);
23
+ };
24
+ updateMode();
25
+ var addChangeListener = function (mediaQuery, listener) {
26
+ if (typeof mediaQuery.addEventListener === "function") {
27
+ mediaQuery.addEventListener("change", listener);
28
+ return function () { return mediaQuery.removeEventListener("change", listener); };
29
+ }
30
+ mediaQuery.addListener(listener);
31
+ return function () { return mediaQuery.removeListener(listener); };
32
+ };
33
+ var removeTouchListener = addChangeListener(touchMedia, updateMode);
34
+ var removeResponsiveListener = addChangeListener(responsiveMedia, updateMode);
35
+ return function () {
36
+ removeTouchListener();
37
+ removeResponsiveListener();
38
+ };
39
+ }, []);
12
40
  if (!showTooltip || !fieldDescription)
13
41
  return null;
14
- return (_jsxs(SolidTooltip, { children: [_jsx(SolidTooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "solid-field-tooltip-icon", "aria-label": "Field info", children: _jsx(SolidIcon, { name: "si-info-circle" }) }) }), _jsx(SolidTooltipContent, { side: "top", align: "center", children: fieldDescription })] }));
42
+ var triggerButton = (_jsx("button", { type: "button", className: "solid-field-tooltip-icon", "aria-label": "Field info", children: _jsx(SolidIcon, { name: "si-info-circle" }) }));
43
+ if (useTapPopover) {
44
+ return (_jsxs(SolidPopover, { children: [_jsx(SolidPopoverTrigger, { asChild: true, children: triggerButton }), _jsx(SolidPopoverContent, { side: "top", align: "center", sideOffset: 6, className: "solid-field-tooltip-popover", children: fieldDescription })] }));
45
+ }
46
+ return (_jsxs(SolidTooltip, { children: [_jsx(SolidTooltipTrigger, { asChild: true, children: triggerButton }), _jsx(SolidTooltipContent, { side: "top", align: "center", children: fieldDescription })] }));
15
47
  };
16
48
  //# sourceMappingURL=SolidFieldTooltip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SolidFieldTooltip.js","sourceRoot":"","sources":["../../../src/components/common/SolidFieldTooltip.tsx"],"names":[],"mappings":";AACA,OAAO,EACH,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,GACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,CAAC,IAAM,iBAAiB,GAAG,UAAC,EAAqB;;QAAnB,YAAY,kBAAA;IAC5C,IAAM,qBAAqB,GAAG,YAAY,CAAC,qBAAqB,CAAC;IACjE,IAAM,eAAe,GAAG,YAAY,CAAC,KAAK,CAAC;IAC3C,IAAM,aAAa,GAAG,YAAY,CAAC,aAAa,CAAC;IACjD,IAAM,WAAW,GACb,MAAA,MAAA,MAAA,MAAA,qBAAqB,CAAC,IAAI,CAAC,SAAS,0CAAE,MAAM,0CAAE,KAAK,0CAAE,WAAW,mCAAI,IAAI,CAAC;IAC7E,IAAM,gBAAgB,GAClB,MAAA,eAAe,CAAC,KAAK,CAAC,WAAW,mCAAI,aAAa,CAAC,WAAW,CAAC;IAEnE,IAAI,CAAC,WAAW,IAAI,CAAC,gBAAgB;QAAE,OAAO,IAAI,CAAC;IAEnD,OAAO,CACH,MAAC,YAAY,eACT,KAAC,mBAAmB,IAAC,OAAO,kBACxB,iBACI,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,0BAA0B,gBACzB,YAAY,YAEvB,KAAC,SAAS,IAAC,IAAI,EAAC,gBAAgB,GAAG,GAC9B,GACS,EACtB,KAAC,mBAAmB,IAAC,IAAI,EAAC,KAAK,EAAC,KAAK,EAAC,QAAQ,YACzC,gBAAgB,GACC,IACX,CAClB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import React from \"react\";\nimport {\n SolidTooltip,\n SolidTooltipContent,\n SolidTooltipTrigger,\n} from \"../shad-cn-ui/SolidTooltip\";\nimport { SolidIcon } from \"../shad-cn-ui\";\n\nexport const SolidFieldTooltip = ({ fieldContext }: any) => {\n const solidFormViewMetaData = fieldContext.solidFormViewMetaData;\n const fieldLayoutInfo = fieldContext.field;\n const fieldMetadata = fieldContext.fieldMetadata;\n const showTooltip =\n solidFormViewMetaData.data.solidView?.layout?.attrs?.showTooltip ?? true;\n const fieldDescription =\n fieldLayoutInfo.attrs.description ?? fieldMetadata.description;\n\n if (!showTooltip || !fieldDescription) return null;\n\n return (\n <SolidTooltip>\n <SolidTooltipTrigger asChild>\n <button\n type=\"button\"\n className=\"solid-field-tooltip-icon\"\n aria-label=\"Field info\"\n >\n <SolidIcon name=\"si-info-circle\" />\n </button>\n </SolidTooltipTrigger>\n <SolidTooltipContent side=\"top\" align=\"center\">\n {fieldDescription}\n </SolidTooltipContent>\n </SolidTooltip>\n );\n};\n"]}
1
+ {"version":3,"file":"SolidFieldTooltip.js","sourceRoot":"","sources":["../../../src/components/common/SolidFieldTooltip.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAC,YAAY,EAAC,mBAAmB,EAAC,mBAAmB,GAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EACH,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,GACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,CAAC,IAAM,iBAAiB,GAAG,UAAC,EAAqB;;QAAnB,YAAY,kBAAA;IAC5C,IAAM,qBAAqB,GAAG,YAAY,CAAC,qBAAqB,CAAC;IACjE,IAAM,eAAe,GAAG,YAAY,CAAC,KAAK,CAAC;IAC3C,IAAM,aAAa,GAAG,YAAY,CAAC,aAAa,CAAC;IAC3C,IAAA,KAAoC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAxD,aAAa,QAAA,EAAE,gBAAgB,QAAyB,CAAC;IAChE,IAAM,WAAW,GACb,MAAA,MAAA,MAAA,MAAA,qBAAqB,CAAC,IAAI,CAAC,SAAS,0CAAE,MAAM,0CAAE,KAAK,0CAAE,WAAW,mCAAI,IAAI,CAAC;IAC7E,IAAM,gBAAgB,GAClB,MAAA,eAAe,CAAC,KAAK,CAAC,WAAW,mCAAI,aAAa,CAAC,WAAW,CAAC;IAEnE,SAAS,CAAC;QACN,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE;YAC1E,OAAO;SACV;QAED,IAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,kCAAkC,CAAC,CAAC;QACzE,IAAM,eAAe,GAAG,MAAM,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC;QAChE,IAAM,UAAU,GAAG;YACf,gBAAgB,CAAC,UAAU,CAAC,OAAO,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;QACpE,CAAC,CAAC;QAEF,UAAU,EAAE,CAAC;QAEb,IAAM,iBAAiB,GAAG,UAAC,UAA0B,EAAE,QAAoB;YACvE,IAAI,OAAO,UAAU,CAAC,gBAAgB,KAAK,UAAU,EAAE;gBACnD,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBAChD,OAAO,cAAM,OAAA,UAAU,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAlD,CAAkD,CAAC;aACnE;YAED,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YACjC,OAAO,cAAM,OAAA,UAAU,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAnC,CAAmC,CAAC;QACrD,CAAC,CAAC;QAEF,IAAM,mBAAmB,GAAG,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACtE,IAAM,wBAAwB,GAAG,iBAAiB,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;QAEhF,OAAO;YACH,mBAAmB,EAAE,CAAC;YACtB,wBAAwB,EAAE,CAAC;QAC/B,CAAC,CAAC;IACN,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAI,CAAC,WAAW,IAAI,CAAC,gBAAgB;QAAE,OAAO,IAAI,CAAC;IAEnD,IAAM,aAAa,GAAG,CAClB,iBACI,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,0BAA0B,gBACzB,YAAY,YAEvB,KAAC,SAAS,IAAC,IAAI,EAAC,gBAAgB,GAAG,GAC9B,CACZ,CAAC;IAEF,IAAI,aAAa,EAAE;QACf,OAAO,CACH,MAAC,YAAY,eACT,KAAC,mBAAmB,IAAC,OAAO,kBACvB,aAAa,GACI,EACtB,KAAC,mBAAmB,IAChB,IAAI,EAAC,KAAK,EACV,KAAK,EAAC,QAAQ,EACd,UAAU,EAAE,CAAC,EACb,SAAS,EAAC,6BAA6B,YAEtC,gBAAgB,GACC,IACX,CAClB,CAAC;KACL;IAED,OAAO,CACH,MAAC,YAAY,eACT,KAAC,mBAAmB,IAAC,OAAO,kBACvB,aAAa,GACI,EACtB,KAAC,mBAAmB,IAAC,IAAI,EAAC,KAAK,EAAC,KAAK,EAAC,QAAQ,YACzC,gBAAgB,GACC,IACX,CAClB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import React, { useEffect } from \"react\";\nimport {SolidPopover,SolidPopoverContent,SolidPopoverTrigger,} from \"../shad-cn-ui\";\nimport {\n SolidTooltip,\n SolidTooltipContent,\n SolidTooltipTrigger,\n} from \"../shad-cn-ui/SolidTooltip\";\nimport { SolidIcon } from \"../shad-cn-ui\";\n\nexport const SolidFieldTooltip = ({ fieldContext }: any) => {\n const solidFormViewMetaData = fieldContext.solidFormViewMetaData;\n const fieldLayoutInfo = fieldContext.field;\n const fieldMetadata = fieldContext.fieldMetadata;\n const [useTapPopover, setUseTapPopover] = React.useState(false);\n const showTooltip =\n solidFormViewMetaData.data.solidView?.layout?.attrs?.showTooltip ?? true;\n const fieldDescription =\n fieldLayoutInfo.attrs.description ?? fieldMetadata.description;\n\n useEffect(() => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return;\n }\n\n const touchMedia = window.matchMedia(\"(hover: none), (pointer: coarse)\");\n const responsiveMedia = window.matchMedia(\"(max-width: 991px)\");\n const updateMode = () => {\n setUseTapPopover(touchMedia.matches || responsiveMedia.matches);\n };\n\n updateMode();\n\n const addChangeListener = (mediaQuery: MediaQueryList, listener: () => void) => {\n if (typeof mediaQuery.addEventListener === \"function\") {\n mediaQuery.addEventListener(\"change\", listener);\n return () => mediaQuery.removeEventListener(\"change\", listener);\n }\n\n mediaQuery.addListener(listener);\n return () => mediaQuery.removeListener(listener);\n };\n\n const removeTouchListener = addChangeListener(touchMedia, updateMode);\n const removeResponsiveListener = addChangeListener(responsiveMedia, updateMode);\n\n return () => {\n removeTouchListener();\n removeResponsiveListener();\n };\n }, []);\n\n if (!showTooltip || !fieldDescription) return null;\n\n const triggerButton = (\n <button\n type=\"button\"\n className=\"solid-field-tooltip-icon\"\n aria-label=\"Field info\"\n >\n <SolidIcon name=\"si-info-circle\" />\n </button>\n );\n\n if (useTapPopover) {\n return (\n <SolidPopover>\n <SolidPopoverTrigger asChild>\n {triggerButton}\n </SolidPopoverTrigger>\n <SolidPopoverContent\n side=\"top\"\n align=\"center\"\n sideOffset={6}\n className=\"solid-field-tooltip-popover\"\n >\n {fieldDescription}\n </SolidPopoverContent>\n </SolidPopover>\n );\n }\n\n return (\n <SolidTooltip>\n <SolidTooltipTrigger asChild>\n {triggerButton}\n </SolidTooltipTrigger>\n <SolidTooltipContent side=\"top\" align=\"center\">\n {fieldDescription}\n </SolidTooltipContent>\n </SolidTooltip>\n );\n};\n"]}
@@ -1,4 +1,5 @@
1
- import React from "react";
1
+ import React, { useEffect } from "react";
2
+ import {SolidPopover,SolidPopoverContent,SolidPopoverTrigger,} from "../shad-cn-ui";
2
3
  import {
3
4
  SolidTooltip,
4
5
  SolidTooltipContent,
@@ -10,23 +11,78 @@ export const SolidFieldTooltip = ({ fieldContext }: any) => {
10
11
  const solidFormViewMetaData = fieldContext.solidFormViewMetaData;
11
12
  const fieldLayoutInfo = fieldContext.field;
12
13
  const fieldMetadata = fieldContext.fieldMetadata;
14
+ const [useTapPopover, setUseTapPopover] = React.useState(false);
13
15
  const showTooltip =
14
16
  solidFormViewMetaData.data.solidView?.layout?.attrs?.showTooltip ?? true;
15
17
  const fieldDescription =
16
18
  fieldLayoutInfo.attrs.description ?? fieldMetadata.description;
17
19
 
20
+ useEffect(() => {
21
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
22
+ return;
23
+ }
24
+
25
+ const touchMedia = window.matchMedia("(hover: none), (pointer: coarse)");
26
+ const responsiveMedia = window.matchMedia("(max-width: 991px)");
27
+ const updateMode = () => {
28
+ setUseTapPopover(touchMedia.matches || responsiveMedia.matches);
29
+ };
30
+
31
+ updateMode();
32
+
33
+ const addChangeListener = (mediaQuery: MediaQueryList, listener: () => void) => {
34
+ if (typeof mediaQuery.addEventListener === "function") {
35
+ mediaQuery.addEventListener("change", listener);
36
+ return () => mediaQuery.removeEventListener("change", listener);
37
+ }
38
+
39
+ mediaQuery.addListener(listener);
40
+ return () => mediaQuery.removeListener(listener);
41
+ };
42
+
43
+ const removeTouchListener = addChangeListener(touchMedia, updateMode);
44
+ const removeResponsiveListener = addChangeListener(responsiveMedia, updateMode);
45
+
46
+ return () => {
47
+ removeTouchListener();
48
+ removeResponsiveListener();
49
+ };
50
+ }, []);
51
+
18
52
  if (!showTooltip || !fieldDescription) return null;
19
53
 
54
+ const triggerButton = (
55
+ <button
56
+ type="button"
57
+ className="solid-field-tooltip-icon"
58
+ aria-label="Field info"
59
+ >
60
+ <SolidIcon name="si-info-circle" />
61
+ </button>
62
+ );
63
+
64
+ if (useTapPopover) {
65
+ return (
66
+ <SolidPopover>
67
+ <SolidPopoverTrigger asChild>
68
+ {triggerButton}
69
+ </SolidPopoverTrigger>
70
+ <SolidPopoverContent
71
+ side="top"
72
+ align="center"
73
+ sideOffset={6}
74
+ className="solid-field-tooltip-popover"
75
+ >
76
+ {fieldDescription}
77
+ </SolidPopoverContent>
78
+ </SolidPopover>
79
+ );
80
+ }
81
+
20
82
  return (
21
83
  <SolidTooltip>
22
84
  <SolidTooltipTrigger asChild>
23
- <button
24
- type="button"
25
- className="solid-field-tooltip-icon"
26
- aria-label="Field info"
27
- >
28
- <SolidIcon name="si-info-circle" />
29
- </button>
85
+ {triggerButton}
30
86
  </SolidTooltipTrigger>
31
87
  <SolidTooltipContent side="top" align="center">
32
88
  {fieldDescription}
@@ -1 +1 @@
1
- {"version":3,"file":"SolidChatter.d.ts","sourceRoot":"","sources":["../../../../src/components/core/chatter/SolidChatter.tsx"],"names":[],"mappings":"AA0BA,eAAO,MAAM,YAAY;uBAA+I,GAAG;QAAM,GAAG;2BAAyB,OAAO;sCAAoC,OAAO,KAAK,IAAI;;;;6CA+RvQ,CAAA"}
1
+ {"version":3,"file":"SolidChatter.d.ts","sourceRoot":"","sources":["../../../../src/components/core/chatter/SolidChatter.tsx"],"names":[],"mappings":"AA2BA,eAAO,MAAM,YAAY;uBAA+I,GAAG;QAAM,GAAG;2BAAyB,OAAO;sCAAoC,OAAO,KAAK,IAAI;;;;6CAiSvQ,CAAA"}
@@ -45,6 +45,7 @@ import { ERROR_MESSAGES } from '../../../constants/error-messages';
45
45
  import { permissionExpression } from '../../../helpers/permissions';
46
46
  import { SolidButton, SolidMessage } from '../../shad-cn-ui';
47
47
  import { Inbox, Loader2 } from 'lucide-react';
48
+ import { renderMessageBodyMentions } from './chatterMentions';
48
49
  var isEmptyAuditValue = function (value) {
49
50
  if (value == null)
50
51
  return true;
@@ -164,7 +165,8 @@ export var SolidChatter = function (_a) {
164
165
  user: ((_a = msg.user) === null || _a === void 0 ? void 0 : _a.fullName) || "System",
165
166
  userId: (_b = msg.user) === null || _b === void 0 ? void 0 : _b.id,
166
167
  messageType: "custom",
167
- message: msg.messageBody,
168
+ message: renderMessageBodyMentions(msg.messageBody, msg.messageBodyMentions),
169
+ messageBodyMentions: msg.messageBodyMentions,
168
170
  time: new Date(displayTimeSource).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
169
171
  createdAt: displayTimeSource,
170
172
  date: formatDate(displayTimeSource),
@@ -241,7 +243,7 @@ export var SolidChatter = function (_a) {
241
243
  var permissionError = function () { return (_jsx("div", { className: 'p-3', children: _jsx(SolidMessage, { severity: 'warn', text: "You do not have permission to view these messages.", className: 'justify-start' }) })); };
242
244
  var renderMessages = function () { return (_jsxs("div", { className: 'flex flex-col gap-4', children: [messages.map(function (message, index) {
243
245
  var showDateDivider = index === 0 || message.date !== messages[index - 1].date;
244
- return (_jsxs("div", { children: [showDateDivider && _jsx(SolidChatterDateDivider, { date: message.date }), _jsx(SolidChatterMessageBox, { messageId: message.id, user: message.user, userId: message.userId, messageType: message.messageType, message: message.message, time: message.time, auditRecord: message.auditRecord, media: message.media, messageSubType: message.messageSubType, status: message.status, modelDisplayName: message.modelDisplayName, modelUserKey: message.modelUserKey, onRefresh: fetchData })] }, message.id));
246
+ return (_jsxs("div", { children: [showDateDivider && _jsx(SolidChatterDateDivider, { date: message.date }), _jsx(SolidChatterMessageBox, { messageId: message.id, user: message.user, userId: message.userId, messageType: message.messageType, message: message.message, messageBodyMentions: message.messageBodyMentions, time: message.time, auditRecord: message.auditRecord, media: message.media, messageSubType: message.messageSubType, status: message.status, modelDisplayName: message.modelDisplayName, modelUserKey: message.modelUserKey, onRefresh: fetchData })] }, message.id));
245
247
  }), totalRecords > messages.length && (_jsx("div", { className: 'flex justify-center', children: _jsx(SolidButton, { type: 'button', size: 'sm', variant: 'outline', onClick: handleLoadMore, children: "Load more" }) }))] })); };
246
248
  return (_jsxs("div", { className: 'h-full', children: [_jsx(SolidChatterHeader, { id: id, refetch: fetchData, modelSingularName: modelSingularName, activeTab: activeTab, handleTabClick: handleTabClick, visibleBox: visibleBox, onFilterChange: handleFilterChange, onComposerCancel: function () { return setVisibleBox(null); }, title: title, modelUserKey: modelUserKey }), _jsx("div", { className: 'solid-chatter-body', style: {
247
249
  height: isMobileViewport
@@ -1 +1 @@
1
- {"version":3,"file":"SolidChatter.js","sourceRoot":"","sources":["../../../../src/components/core/chatter/SolidChatter.tsx"],"names":[],"mappings":"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","sourcesContent":["\nimport React, { useState, useEffect } from 'react'\nimport { SolidChatterHeader } from './SolidChatterHeader'\nimport { SolidChatterDateDivider } from './SolidChatterDateDivider'\nimport { SolidChatterMessageBox } from './SolidChatterMessageBox'\nimport { useLazyGetchatterMessageQuery } from '../../../redux/api/solidChatterMessageApi'\nimport qs from \"qs\";\nimport { ERROR_MESSAGES } from '../../../constants/error-messages'\nimport { permissionExpression } from '../../../helpers/permissions'\nimport { SolidButton, SolidMessage } from '../../shad-cn-ui'\nimport { Inbox, Loader2 } from 'lucide-react'\n\ninterface FilterState {\n name: string;\n startDate: Date | null;\n endDate: Date | null;\n}\n\nconst isEmptyAuditValue = (value: string | null | undefined) => {\n if (value == null) return true;\n if (typeof value !== 'string') return false;\n\n const normalizedValue = value.trim().toLowerCase();\n return normalizedValue === '' || normalizedValue === 'none' || normalizedValue === 'null';\n};\n\nexport const SolidChatter = ({ modelSingularName, id, refreshChatterMessage, setRefreshChatterMessage, actionsAllowed = [], title, modelUserKey }: { modelSingularName: any, id: any, refreshChatterMessage: boolean, setRefreshChatterMessage: (value: boolean) => void, actionsAllowed?: string[], title?: string, modelUserKey?: string }) => {\n const [activeTab, setActiveTab] = useState<'email-message' | 'log' | null>('email-message');\n const [visibleBox, setVisibleBox] = useState<'email-message' | 'log' | null>(null);\n const [messages, setMessages] = useState<any[]>([]);\n const [limit, setLimit] = useState<number>(25);\n const [totalRecords, setTotalRecords] = useState<number>(0);\n const [filters, setFilters] = useState<FilterState>({\n name: '',\n startDate: null,\n endDate: null\n });\n const [isMobileViewport, setIsMobileViewport] = useState(false);\n\n const [getchatterMessage, { isLoading: isChatterLoading }] = useLazyGetchatterMessageQuery();\n\n useEffect(() => {\n const updateViewport = () => setIsMobileViewport(window.innerWidth <= 1199);\n updateViewport();\n window.addEventListener('resize', updateViewport);\n return () => window.removeEventListener('resize', updateViewport);\n }, []);\n\n useEffect(() => {\n if (refreshChatterMessage) {\n if (id !== 'new') {\n fetchData();\n setRefreshChatterMessage(false);\n }\n }\n }, [refreshChatterMessage]);\n\n useEffect(() => {\n if (id !== 'new') {\n fetchData();\n }\n }, [filters, limit]);\n\n const handleTabClick = (tab: 'email-message' | 'log') => {\n setActiveTab(tab);\n setVisibleBox(prev => (prev === tab ? null : tab));\n }\n\n const formatDate = (dateString: string) => {\n const date = new Date(dateString);\n const today = new Date();\n const yesterday = new Date(today);\n yesterday.setDate(yesterday.getDate() - 1);\n\n if (date.toDateString() === today.toDateString()) {\n return 'Today';\n } else if (date.toDateString() === yesterday.toDateString()) {\n return 'Yesterday';\n } else {\n return dateString;\n }\n };\n\n const fetchData = async () => {\n try {\n const queryData: any = {\n populate: ['user', 'chatterMessageDetails'],\n limit: limit\n };\n\n if (filters.name) {\n queryData.filters = queryData.filters || {};\n queryData.filters['user'] = { fullName: { $containsi: filters.name }};\n }\n const startOfDay = (d: Date) => {\n const x = new Date(d);\n x.setHours(0, 0, 0, 0);\n return x;\n };\n const endOfDay = (d: Date) => {\n const x = new Date(d);\n x.setHours(23, 59, 59, 999);\n return x;\n };\n if (filters.startDate && filters.endDate) {\n queryData.filters = queryData.filters || {};\n queryData.filters.createdAt = {\n $between: [startOfDay(filters.startDate).toISOString(), endOfDay(filters.endDate).toISOString()]\n };\n } else if (filters.startDate) {\n queryData.filters = queryData.filters || {};\n queryData.filters.createdAt = { $gte: startOfDay(filters.startDate).toISOString() };\n } else if (filters.endDate) {\n queryData.filters = queryData.filters || {};\n queryData.filters.createdAt = { $lte: endOfDay(filters.endDate).toISOString() };\n }\n\n const queryString = qs.stringify(queryData, {\n encodeValuesOnly: true,\n });\n const response = await getchatterMessage({\n entityId: id,\n entityName: modelSingularName,\n qs: queryString\n }).unwrap();\n const processedMessages = response.data.records.map((msg: any) => {\n if (msg.messageType === 'custom') {\n const displayTimeSource = msg.updatedAt || msg.createdAt;\n // Custom message\n return {\n id: msg.id,\n user: msg.user?.fullName || \"System\",\n userId: msg.user?.id,\n messageType: \"custom\",\n message: msg.messageBody,\n time: new Date(displayTimeSource).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),\n createdAt: displayTimeSource,\n date: formatDate(displayTimeSource),\n media: msg._media,\n messageSubType: msg.messageSubType,\n status: msg.status,\n modelDisplayName: msg.modelDisplayName,\n modelUserKey: msg.modelUserKey\n };\n } else {\n // Audit message\n const auditRecord = msg.chatterMessageDetails?.map((detail: any) => ({\n field: detail.fieldName,\n fieldDisplayName: detail.fieldDisplayName,\n fieldType: detail.fieldType,\n previous: detail.oldValue,\n current: detail.newValue,\n previousDisplay: detail.oldValueDisplay,\n currentDisplay: detail.newValueDisplay,\n })).filter((detail: any) => {\n const previousValue = detail.previousDisplay ?? detail.previous;\n const currentValue = detail.currentDisplay ?? detail.current;\n\n return !(isEmptyAuditValue(previousValue) && isEmptyAuditValue(currentValue));\n }) || [];\n\n if (auditRecord.length === 0) {\n return null;\n }\n\n return {\n id: msg.id,\n user: msg.user?.fullName || \"System\",\n userId: msg.user?.id,\n messageType: \"audit\",\n time: new Date(msg.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),\n auditRecord: auditRecord,\n createdAt: msg.createdAt,\n date: formatDate(msg.createdAt),\n messageSubType: msg.messageSubType,\n modelDisplayName: msg.modelDisplayName,\n modelUserKey: msg.modelUserKey,\n message: msg.messageBody,\n };\n }\n }).filter(Boolean);\n setMessages(processedMessages);\n setTotalRecords(response?.data?.meta?.totalRecords || 0);\n } catch (error) {\n console.error(ERROR_MESSAGES.FETCHING_MESSAGE, error);\n }\n }\n\n const handleFilterChange = (newFilters: FilterState) => {\n setFilters({\n name: newFilters.name,\n startDate: newFilters.startDate,\n endDate: newFilters.endDate\n });\n setLimit(25);\n };\n\n const handleLoadMore = () => {\n setLimit(prevLimit => prevLimit + 25);\n };\n\n const canViewMessages = actionsAllowed.includes(`${permissionExpression('chatterMessage', 'findMany')}`);\n\n const renderLoadingState = () => (\n <div className='flex h-full flex-col items-center justify-center gap-2 text-center text-color-secondary'>\n <Loader2 size={20} className='animate-spin text-[var(--primary-color)]' />\n <span className='text-sm'>Loading recent activity…</span>\n </div>\n );\n\n const renderEmptyState = () => {\n const isLogComposerOpen = visibleBox === 'log';\n return (\n <div className='flex h-full items-center justify-center'>\n <div className='flex flex-col items-center gap-2 px-3 text-center text-color-secondary'>\n <div className='rounded bg-[var(--primary-color-text)] p-2 text-[var(--primary-color)]'>\n <Inbox size={20} />\n </div>\n <p className='m-0 text-base font-medium text-color'>No activity yet</p>\n <p className='m-0 text-sm'>Log your first internal note or send a message to get things started.</p>\n <SolidButton size='sm' variant='outline' onClick={() => handleTabClick('log')}>\n {isLogComposerOpen ? 'Cancel' : 'Log a note'}\n </SolidButton>\n </div>\n </div>\n );\n };\n\n const permissionError = () => (\n <div className='p-3'>\n <SolidMessage severity='warn' text=\"You do not have permission to view these messages.\" className='justify-start' />\n </div>\n );\n\n const renderMessages = () => (\n <div className='flex flex-col gap-4'>\n {messages.map((message, index) => {\n const showDateDivider = index === 0 || message.date !== messages[index - 1].date;\n return (\n <div key={message.id}>\n {showDateDivider && <SolidChatterDateDivider date={message.date} />}\n <SolidChatterMessageBox\n messageId={message.id}\n user={message.user}\n userId={message.userId}\n messageType={message.messageType}\n message={message.message}\n time={message.time}\n auditRecord={message.auditRecord}\n media={message.media}\n messageSubType={message.messageSubType}\n status={message.status}\n modelDisplayName={message.modelDisplayName}\n modelUserKey={message.modelUserKey}\n onRefresh={fetchData}\n />\n </div>\n );\n })}\n {totalRecords > messages.length && (\n <div className='flex justify-center'>\n <SolidButton\n type='button'\n size='sm'\n variant='outline'\n onClick={handleLoadMore}\n >\n Load more\n </SolidButton>\n </div>\n )}\n </div>\n );\n\n return (\n <div className='h-full'>\n <SolidChatterHeader\n id={id}\n refetch={fetchData}\n modelSingularName={modelSingularName}\n activeTab={activeTab}\n handleTabClick={handleTabClick}\n visibleBox={visibleBox}\n onFilterChange={handleFilterChange}\n onComposerCancel={() => setVisibleBox(null)}\n title={title}\n modelUserKey={modelUserKey}\n />\n <div className='solid-chatter-body' style={{\n height:\n isMobileViewport\n ? (visibleBox === 'email-message'\n ? 'calc(100dvh - 248px)'\n : visibleBox === 'log'\n ? 'calc(100dvh - 210px)'\n : 'calc(100dvh - 60px)')\n : (visibleBox === 'email-message'\n ? 'calc(100vh - 196px)'\n : visibleBox === 'log'\n ? 'calc(100vh - 292px)'\n : 'calc(100vh - 127px)'),\n }}>\n {isChatterLoading\n ? renderLoadingState()\n : !canViewMessages\n ? permissionError()\n : messages.length === 0\n ? renderEmptyState()\n : renderMessages()\n }\n </div>\n </div>\n )\n}\n"]}
1
+ {"version":3,"file":"SolidChatter.js","sourceRoot":"","sources":["../../../../src/components/core/chatter/SolidChatter.tsx"],"names":[],"mappings":"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","sourcesContent":["\nimport React, { useState, useEffect } from 'react'\nimport { SolidChatterHeader } from './SolidChatterHeader'\nimport { SolidChatterDateDivider } from './SolidChatterDateDivider'\nimport { SolidChatterMessageBox } from './SolidChatterMessageBox'\nimport { useLazyGetchatterMessageQuery } from '../../../redux/api/solidChatterMessageApi'\nimport qs from \"qs\";\nimport { ERROR_MESSAGES } from '../../../constants/error-messages'\nimport { permissionExpression } from '../../../helpers/permissions'\nimport { SolidButton, SolidMessage } from '../../shad-cn-ui'\nimport { Inbox, Loader2 } from 'lucide-react'\nimport { renderMessageBodyMentions } from './chatterMentions'\n\ninterface FilterState {\n name: string;\n startDate: Date | null;\n endDate: Date | null;\n}\n\nconst isEmptyAuditValue = (value: string | null | undefined) => {\n if (value == null) return true;\n if (typeof value !== 'string') return false;\n\n const normalizedValue = value.trim().toLowerCase();\n return normalizedValue === '' || normalizedValue === 'none' || normalizedValue === 'null';\n};\n\nexport const SolidChatter = ({ modelSingularName, id, refreshChatterMessage, setRefreshChatterMessage, actionsAllowed = [], title, modelUserKey }: { modelSingularName: any, id: any, refreshChatterMessage: boolean, setRefreshChatterMessage: (value: boolean) => void, actionsAllowed?: string[], title?: string, modelUserKey?: string }) => {\n const [activeTab, setActiveTab] = useState<'email-message' | 'log' | null>('email-message');\n const [visibleBox, setVisibleBox] = useState<'email-message' | 'log' | null>(null);\n const [messages, setMessages] = useState<any[]>([]);\n const [limit, setLimit] = useState<number>(25);\n const [totalRecords, setTotalRecords] = useState<number>(0);\n const [filters, setFilters] = useState<FilterState>({\n name: '',\n startDate: null,\n endDate: null\n });\n const [isMobileViewport, setIsMobileViewport] = useState(false);\n\n const [getchatterMessage, { isLoading: isChatterLoading }] = useLazyGetchatterMessageQuery();\n\n useEffect(() => {\n const updateViewport = () => setIsMobileViewport(window.innerWidth <= 1199);\n updateViewport();\n window.addEventListener('resize', updateViewport);\n return () => window.removeEventListener('resize', updateViewport);\n }, []);\n\n useEffect(() => {\n if (refreshChatterMessage) {\n if (id !== 'new') {\n fetchData();\n setRefreshChatterMessage(false);\n }\n }\n }, [refreshChatterMessage]);\n\n useEffect(() => {\n if (id !== 'new') {\n fetchData();\n }\n }, [filters, limit]);\n\n const handleTabClick = (tab: 'email-message' | 'log') => {\n setActiveTab(tab);\n setVisibleBox(prev => (prev === tab ? null : tab));\n }\n\n const formatDate = (dateString: string) => {\n const date = new Date(dateString);\n const today = new Date();\n const yesterday = new Date(today);\n yesterday.setDate(yesterday.getDate() - 1);\n\n if (date.toDateString() === today.toDateString()) {\n return 'Today';\n } else if (date.toDateString() === yesterday.toDateString()) {\n return 'Yesterday';\n } else {\n return dateString;\n }\n };\n\n const fetchData = async () => {\n try {\n const queryData: any = {\n populate: ['user', 'chatterMessageDetails'],\n limit: limit\n };\n\n if (filters.name) {\n queryData.filters = queryData.filters || {};\n queryData.filters['user'] = { fullName: { $containsi: filters.name }};\n }\n const startOfDay = (d: Date) => {\n const x = new Date(d);\n x.setHours(0, 0, 0, 0);\n return x;\n };\n const endOfDay = (d: Date) => {\n const x = new Date(d);\n x.setHours(23, 59, 59, 999);\n return x;\n };\n if (filters.startDate && filters.endDate) {\n queryData.filters = queryData.filters || {};\n queryData.filters.createdAt = {\n $between: [startOfDay(filters.startDate).toISOString(), endOfDay(filters.endDate).toISOString()]\n };\n } else if (filters.startDate) {\n queryData.filters = queryData.filters || {};\n queryData.filters.createdAt = { $gte: startOfDay(filters.startDate).toISOString() };\n } else if (filters.endDate) {\n queryData.filters = queryData.filters || {};\n queryData.filters.createdAt = { $lte: endOfDay(filters.endDate).toISOString() };\n }\n\n const queryString = qs.stringify(queryData, {\n encodeValuesOnly: true,\n });\n const response = await getchatterMessage({\n entityId: id,\n entityName: modelSingularName,\n qs: queryString\n }).unwrap();\n const processedMessages = response.data.records.map((msg: any) => {\n if (msg.messageType === 'custom') {\n const displayTimeSource = msg.updatedAt || msg.createdAt;\n // Custom message\n return {\n id: msg.id,\n user: msg.user?.fullName || \"System\",\n userId: msg.user?.id,\n messageType: \"custom\",\n message: renderMessageBodyMentions(msg.messageBody, msg.messageBodyMentions),\n messageBodyMentions: msg.messageBodyMentions,\n time: new Date(displayTimeSource).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),\n createdAt: displayTimeSource,\n date: formatDate(displayTimeSource),\n media: msg._media,\n messageSubType: msg.messageSubType,\n status: msg.status,\n modelDisplayName: msg.modelDisplayName,\n modelUserKey: msg.modelUserKey\n };\n } else {\n // Audit message\n const auditRecord = msg.chatterMessageDetails?.map((detail: any) => ({\n field: detail.fieldName,\n fieldDisplayName: detail.fieldDisplayName,\n fieldType: detail.fieldType,\n previous: detail.oldValue,\n current: detail.newValue,\n previousDisplay: detail.oldValueDisplay,\n currentDisplay: detail.newValueDisplay,\n })).filter((detail: any) => {\n const previousValue = detail.previousDisplay ?? detail.previous;\n const currentValue = detail.currentDisplay ?? detail.current;\n\n return !(isEmptyAuditValue(previousValue) && isEmptyAuditValue(currentValue));\n }) || [];\n\n if (auditRecord.length === 0) {\n return null;\n }\n\n return {\n id: msg.id,\n user: msg.user?.fullName || \"System\",\n userId: msg.user?.id,\n messageType: \"audit\",\n time: new Date(msg.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),\n auditRecord: auditRecord,\n createdAt: msg.createdAt,\n date: formatDate(msg.createdAt),\n messageSubType: msg.messageSubType,\n modelDisplayName: msg.modelDisplayName,\n modelUserKey: msg.modelUserKey,\n message: msg.messageBody,\n };\n }\n }).filter(Boolean);\n setMessages(processedMessages);\n setTotalRecords(response?.data?.meta?.totalRecords || 0);\n } catch (error) {\n console.error(ERROR_MESSAGES.FETCHING_MESSAGE, error);\n }\n }\n\n const handleFilterChange = (newFilters: FilterState) => {\n setFilters({\n name: newFilters.name,\n startDate: newFilters.startDate,\n endDate: newFilters.endDate\n });\n setLimit(25);\n };\n\n const handleLoadMore = () => {\n setLimit(prevLimit => prevLimit + 25);\n };\n\n const canViewMessages = actionsAllowed.includes(`${permissionExpression('chatterMessage', 'findMany')}`);\n\n const renderLoadingState = () => (\n <div className='flex h-full flex-col items-center justify-center gap-2 text-center text-color-secondary'>\n <Loader2 size={20} className='animate-spin text-[var(--primary-color)]' />\n <span className='text-sm'>Loading recent activity…</span>\n </div>\n );\n\n const renderEmptyState = () => {\n const isLogComposerOpen = visibleBox === 'log';\n return (\n <div className='flex h-full items-center justify-center'>\n <div className='flex flex-col items-center gap-2 px-3 text-center text-color-secondary'>\n <div className='rounded bg-[var(--primary-color-text)] p-2 text-[var(--primary-color)]'>\n <Inbox size={20} />\n </div>\n <p className='m-0 text-base font-medium text-color'>No activity yet</p>\n <p className='m-0 text-sm'>Log your first internal note or send a message to get things started.</p>\n <SolidButton size='sm' variant='outline' onClick={() => handleTabClick('log')}>\n {isLogComposerOpen ? 'Cancel' : 'Log a note'}\n </SolidButton>\n </div>\n </div>\n );\n };\n\n const permissionError = () => (\n <div className='p-3'>\n <SolidMessage severity='warn' text=\"You do not have permission to view these messages.\" className='justify-start' />\n </div>\n );\n\n const renderMessages = () => (\n <div className='flex flex-col gap-4'>\n {messages.map((message, index) => {\n const showDateDivider = index === 0 || message.date !== messages[index - 1].date;\n return (\n <div key={message.id}>\n {showDateDivider && <SolidChatterDateDivider date={message.date} />}\n <SolidChatterMessageBox\n messageId={message.id}\n user={message.user}\n userId={message.userId}\n messageType={message.messageType}\n message={message.message}\n messageBodyMentions={message.messageBodyMentions}\n time={message.time}\n auditRecord={message.auditRecord}\n media={message.media}\n messageSubType={message.messageSubType}\n status={message.status}\n modelDisplayName={message.modelDisplayName}\n modelUserKey={message.modelUserKey}\n onRefresh={fetchData}\n />\n </div>\n );\n })}\n {totalRecords > messages.length && (\n <div className='flex justify-center'>\n <SolidButton\n type='button'\n size='sm'\n variant='outline'\n onClick={handleLoadMore}\n >\n Load more\n </SolidButton>\n </div>\n )}\n </div>\n );\n\n return (\n <div className='h-full'>\n <SolidChatterHeader\n id={id}\n refetch={fetchData}\n modelSingularName={modelSingularName}\n activeTab={activeTab}\n handleTabClick={handleTabClick}\n visibleBox={visibleBox}\n onFilterChange={handleFilterChange}\n onComposerCancel={() => setVisibleBox(null)}\n title={title}\n modelUserKey={modelUserKey}\n />\n <div className='solid-chatter-body' style={{\n height:\n isMobileViewport\n ? (visibleBox === 'email-message'\n ? 'calc(100dvh - 248px)'\n : visibleBox === 'log'\n ? 'calc(100dvh - 210px)'\n : 'calc(100dvh - 60px)')\n : (visibleBox === 'email-message'\n ? 'calc(100vh - 196px)'\n : visibleBox === 'log'\n ? 'calc(100vh - 292px)'\n : 'calc(100vh - 127px)'),\n }}>\n {isChatterLoading\n ? renderLoadingState()\n : !canViewMessages\n ? permissionError()\n : messages.length === 0\n ? renderEmptyState()\n : renderMessages()\n }\n </div>\n </div>\n )\n}\n"]}
@@ -9,6 +9,7 @@ import { ERROR_MESSAGES } from '../../../constants/error-messages'
9
9
  import { permissionExpression } from '../../../helpers/permissions'
10
10
  import { SolidButton, SolidMessage } from '../../shad-cn-ui'
11
11
  import { Inbox, Loader2 } from 'lucide-react'
12
+ import { renderMessageBodyMentions } from './chatterMentions'
12
13
 
13
14
  interface FilterState {
14
15
  name: string;
@@ -132,7 +133,8 @@ export const SolidChatter = ({ modelSingularName, id, refreshChatterMessage, set
132
133
  user: msg.user?.fullName || "System",
133
134
  userId: msg.user?.id,
134
135
  messageType: "custom",
135
- message: msg.messageBody,
136
+ message: renderMessageBodyMentions(msg.messageBody, msg.messageBodyMentions),
137
+ messageBodyMentions: msg.messageBodyMentions,
136
138
  time: new Date(displayTimeSource).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
137
139
  createdAt: displayTimeSource,
138
140
  date: formatDate(displayTimeSource),
@@ -245,6 +247,7 @@ export const SolidChatter = ({ modelSingularName, id, refreshChatterMessage, set
245
247
  userId={message.userId}
246
248
  messageType={message.messageType}
247
249
  message={message.message}
250
+ messageBodyMentions={message.messageBodyMentions}
248
251
  time={message.time}
249
252
  auditRecord={message.auditRecord}
250
253
  media={message.media}
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ isLoading: boolean;
3
+ users: any[];
4
+ activeIndex: number;
5
+ onSelect: (user: any) => void;
6
+ }
7
+ export declare const SolidChatterMentionMenu: ({ isLoading, users, activeIndex, onSelect }: Props) => import("react/jsx-runtime").JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=SolidChatterMentionMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SolidChatterMentionMenu.d.ts","sourceRoot":"","sources":["../../../../src/components/core/chatter/SolidChatterMentionMenu.tsx"],"names":[],"mappings":"AAGA,UAAU,KAAK;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;CACjC;AAED,eAAO,MAAM,uBAAuB,gDAAiD,KAAK,4CAkCzF,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from 'react';
3
+ import styles from './chatter.module.css';
4
+ export var SolidChatterMentionMenu = function (_a) {
5
+ var isLoading = _a.isLoading, users = _a.users, activeIndex = _a.activeIndex, onSelect = _a.onSelect;
6
+ var activeOptionRef = useRef(null);
7
+ useEffect(function () {
8
+ var _a;
9
+ (_a = activeOptionRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
10
+ block: 'nearest',
11
+ });
12
+ }, [activeIndex]);
13
+ return (_jsxs("div", { className: styles.chatterMentionMenu, children: [isLoading && (_jsx("div", { className: styles.chatterMentionEmpty, children: "Searching users..." })), !isLoading && users.length === 0 && (_jsx("div", { className: styles.chatterMentionEmpty, children: "No users found" })), !isLoading && users.map(function (user, index) { return (_jsxs("button", { ref: index === activeIndex ? activeOptionRef : null, type: "button", className: "".concat(styles.chatterMentionOption, " ").concat(index === activeIndex ? styles.chatterMentionOptionActive : ''), onMouseDown: function (event) {
14
+ event.preventDefault();
15
+ onSelect(user);
16
+ }, children: [_jsx("span", { className: styles.chatterMentionName, children: user.fullName || user.username }), _jsxs("span", { className: styles.chatterMentionUsername, children: ["@", user.username] })] }, user.id)); })] }));
17
+ };
18
+ //# sourceMappingURL=SolidChatterMentionMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SolidChatterMentionMenu.js","sourceRoot":"","sources":["../../../../src/components/core/chatter/SolidChatterMentionMenu.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,MAAM,MAAM,sBAAsB,CAAC;AAS1C,MAAM,CAAC,IAAM,uBAAuB,GAAG,UAAC,EAAkD;QAAhD,SAAS,eAAA,EAAE,KAAK,WAAA,EAAE,WAAW,iBAAA,EAAE,QAAQ,cAAA;IAC7E,IAAM,eAAe,GAAG,MAAM,CAA2B,IAAI,CAAC,CAAC;IAE/D,SAAS,CAAC;;QACN,MAAA,eAAe,CAAC,OAAO,0CAAE,cAAc,CAAC;YACpC,KAAK,EAAE,SAAS;SACnB,CAAC,CAAC;IACP,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,OAAO,CACH,eAAK,SAAS,EAAE,MAAM,CAAC,kBAAkB,aACpC,SAAS,IAAI,CACV,cAAK,SAAS,EAAE,MAAM,CAAC,mBAAmB,mCAA0B,CACvE,EACA,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CACjC,cAAK,SAAS,EAAE,MAAM,CAAC,mBAAmB,+BAAsB,CACnE,EACA,CAAC,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,UAAC,IAAI,EAAE,KAAK,IAAK,OAAA,CACtC,kBAEI,GAAG,EAAE,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,EACnD,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,UAAG,MAAM,CAAC,oBAAoB,cAAI,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE,CAAE,EAC7G,WAAW,EAAE,UAAC,KAAK;oBACf,KAAK,CAAC,cAAc,EAAE,CAAC;oBACvB,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACnB,CAAC,aAED,eAAM,SAAS,EAAE,MAAM,CAAC,kBAAkB,YAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,GAAQ,EACnF,gBAAM,SAAS,EAAE,MAAM,CAAC,sBAAsB,kBAAI,IAAI,CAAC,QAAQ,IAAQ,KAVlE,IAAI,CAAC,EAAE,CAWP,CACZ,EAdyC,CAczC,CAAC,IACA,CACT,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { useEffect, useRef } from 'react';\nimport styles from './chatter.module.css';\n\ninterface Props {\n isLoading: boolean;\n users: any[];\n activeIndex: number;\n onSelect: (user: any) => void;\n}\n\nexport const SolidChatterMentionMenu = ({ isLoading, users, activeIndex, onSelect }: Props) => {\n const activeOptionRef = useRef<HTMLButtonElement | null>(null);\n\n useEffect(() => {\n activeOptionRef.current?.scrollIntoView({\n block: 'nearest',\n });\n }, [activeIndex]);\n\n return (\n <div className={styles.chatterMentionMenu}>\n {isLoading && (\n <div className={styles.chatterMentionEmpty}>Searching users...</div>\n )}\n {!isLoading && users.length === 0 && (\n <div className={styles.chatterMentionEmpty}>No users found</div>\n )}\n {!isLoading && users.map((user, index) => (\n <button\n key={user.id}\n ref={index === activeIndex ? activeOptionRef : null}\n type=\"button\"\n className={`${styles.chatterMentionOption} ${index === activeIndex ? styles.chatterMentionOptionActive : ''}`}\n onMouseDown={(event) => {\n event.preventDefault();\n onSelect(user);\n }}\n >\n <span className={styles.chatterMentionName}>{user.fullName || user.username}</span>\n <span className={styles.chatterMentionUsername}>@{user.username}</span>\n </button>\n ))}\n </div>\n );\n};\n"]}
@@ -0,0 +1,45 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import styles from './chatter.module.css';
3
+
4
+ interface Props {
5
+ isLoading: boolean;
6
+ users: any[];
7
+ activeIndex: number;
8
+ onSelect: (user: any) => void;
9
+ }
10
+
11
+ export const SolidChatterMentionMenu = ({ isLoading, users, activeIndex, onSelect }: Props) => {
12
+ const activeOptionRef = useRef<HTMLButtonElement | null>(null);
13
+
14
+ useEffect(() => {
15
+ activeOptionRef.current?.scrollIntoView({
16
+ block: 'nearest',
17
+ });
18
+ }, [activeIndex]);
19
+
20
+ return (
21
+ <div className={styles.chatterMentionMenu}>
22
+ {isLoading && (
23
+ <div className={styles.chatterMentionEmpty}>Searching users...</div>
24
+ )}
25
+ {!isLoading && users.length === 0 && (
26
+ <div className={styles.chatterMentionEmpty}>No users found</div>
27
+ )}
28
+ {!isLoading && users.map((user, index) => (
29
+ <button
30
+ key={user.id}
31
+ ref={index === activeIndex ? activeOptionRef : null}
32
+ type="button"
33
+ className={`${styles.chatterMentionOption} ${index === activeIndex ? styles.chatterMentionOptionActive : ''}`}
34
+ onMouseDown={(event) => {
35
+ event.preventDefault();
36
+ onSelect(user);
37
+ }}
38
+ >
39
+ <span className={styles.chatterMentionName}>{user.fullName || user.username}</span>
40
+ <span className={styles.chatterMentionUsername}>@{user.username}</span>
41
+ </button>
42
+ ))}
43
+ </div>
44
+ );
45
+ };
@@ -4,6 +4,7 @@ interface Props {
4
4
  userId?: number;
5
5
  messageType?: string;
6
6
  message?: any;
7
+ messageBodyMentions?: unknown;
7
8
  time?: string;
8
9
  auditRecord?: any;
9
10
  messageSubType?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"SolidChatterMessageBox.d.ts","sourceRoot":"","sources":["../../../../src/components/core/chatter/SolidChatterMessageBox.tsx"],"names":[],"mappings":"AAaA,UAAU,KAAK;IACX,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE;QACJ,kBAAkB,CAAC,EAAE,KAAK,CAAC;YACvB,EAAE,EAAE,MAAM,CAAC;YACX,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,MAAM,CAAC;YACjB,gBAAgB,EAAE,MAAM,CAAC;YACzB,SAAS,EAAE,MAAM,CAAC;SACrB,CAAC,CAAC;KACN,CAAC;CACL;AAsBD,eAAO,MAAM,sBAAsB,UAAW,KAAK,4CAqalD,CAAA"}
1
+ {"version":3,"file":"SolidChatterMessageBox.d.ts","sourceRoot":"","sources":["../../../../src/components/core/chatter/SolidChatterMessageBox.tsx"],"names":[],"mappings":"AAgBA,UAAU,KAAK;IACX,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE;QACJ,kBAAkB,CAAC,EAAE,KAAK,CAAC;YACvB,EAAE,EAAE,MAAM,CAAC;YACX,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,MAAM,CAAC;YACjB,gBAAgB,EAAE,MAAM,CAAC;YACzB,SAAS,EAAE,MAAM,CAAC;SACrB,CAAC,CAAC;KACN,CAAC;CACL;AAsBD,eAAO,MAAM,sBAAsB,UAAW,KAAK,4CAsdlD,CAAA"}
@@ -54,6 +54,9 @@ import { Check, GitBranch, MessageSquare, Paperclip, Pencil, Trash2, X } from 'l
54
54
  import { SolidButton, SolidLightbox, SolidTag, SolidTooltip, SolidTooltipContent, SolidTooltipTrigger, SolidIcon, SolidTextarea } from '../../shad-cn-ui';
55
55
  import { usePatchChatterMessageMutation, useUpdateChatterNoteMessageMutation } from '../../../redux/api/solidChatterMessageApi';
56
56
  import { useSession } from '../../../hooks/useSession';
57
+ import { buildMessageBodyWithMentionTokens, parseMessageBodyMentions } from './chatterMentions';
58
+ import { useChatterMentions } from './useChatterMentions';
59
+ import { SolidChatterMentionMenu } from './SolidChatterMentionMenu';
57
60
  var getFileIcon = function (mimeType) {
58
61
  if (mimeType.startsWith('image/')) {
59
62
  return 'si-image';
@@ -75,7 +78,7 @@ var getFileIcon = function (mimeType) {
75
78
  };
76
79
  export var SolidChatterMessageBox = function (props) {
77
80
  var _a;
78
- var messageId = props.messageId, user = props.user, userId = props.userId, messageType = props.messageType, message = props.message, time = props.time, auditRecord = props.auditRecord, media = props.media, messageSubType = props.messageSubType, status = props.status, modelDisplayName = props.modelDisplayName, modelUserKey = props.modelUserKey, onRefresh = props.onRefresh;
81
+ var messageId = props.messageId, user = props.user, userId = props.userId, messageType = props.messageType, message = props.message, messageBodyMentions = props.messageBodyMentions, time = props.time, auditRecord = props.auditRecord, media = props.media, messageSubType = props.messageSubType, status = props.status, modelDisplayName = props.modelDisplayName, modelUserKey = props.modelUserKey, onRefresh = props.onRefresh;
79
82
  var _b = useState([]), lightboxSlides = _b[0], setLightboxSlides = _b[1];
80
83
  var _c = useState(false), openLightbox = _c[0], setOpenLightbox = _c[1];
81
84
  var _d = useState(status), taskStatus = _d[0], setTaskStatus = _d[1];
@@ -88,9 +91,15 @@ export var SolidChatterMessageBox = function (props) {
88
91
  var _l = useState([]), optimisticRemovedAttachmentIds = _l[0], setOptimisticRemovedAttachmentIds = _l[1];
89
92
  var _m = useState(false), hasPendingOptimisticAttachmentUpdate = _m[0], setHasPendingOptimisticAttachmentUpdate = _m[1];
90
93
  var fileInputRef = useRef(null);
94
+ var editTextareaRef = useRef(null);
91
95
  var _o = usePatchChatterMessageMutation(), patchChatterMessage = _o[0], isUpdatingTaskStatus = _o[1].isLoading;
92
96
  var _p = useUpdateChatterNoteMessageMutation(), updateChatterNoteMessage = _p[0], isUpdatingNote = _p[1].isLoading;
93
97
  var session = useSession().data;
98
+ var _q = useChatterMentions({
99
+ value: editedMessage,
100
+ onChange: setEditedMessage,
101
+ textareaRef: editTextareaRef,
102
+ }), editMentions = _q.mentions, mentionRange = _q.mentionRange, mentionSuggestions = _q.mentionSuggestions, activeMentionIndex = _q.activeMentionIndex, isFetchingMentionUsers = _q.isFetchingMentionUsers, handleMentionTextChange = _q.handleMentionTextChange, handleMentionKeyDown = _q.handleMentionKeyDown, handleMentionKeyUp = _q.handleMentionKeyUp, handleMentionClick = _q.handleMentionClick, handleSelectMention = _q.handleSelectMention, resetMentions = _q.resetMentions;
94
103
  var avatarStyle = useMemo(function () {
95
104
  var bg = stringToColor(user);
96
105
  var color = getTextColor(bg);
@@ -208,7 +217,7 @@ export var SolidChatterMessageBox = function (props) {
208
217
  });
209
218
  }); };
210
219
  var handleEditSave = function () { return __awaiter(void 0, void 0, void 0, function () {
211
- var trimmedMessage, hasBodyChange, hasAttachmentOps, nextMessage, formData_1, e_2;
220
+ var trimmedMessage, hasBodyChange, hasAttachmentOps, nextMessage, messageBody, formData_1, e_2;
212
221
  return __generator(this, function (_a) {
213
222
  switch (_a.label) {
214
223
  case 0:
@@ -233,8 +242,10 @@ export var SolidChatterMessageBox = function (props) {
233
242
  _a.label = 1;
234
243
  case 1:
235
244
  _a.trys.push([1, 3, , 4]);
245
+ messageBody = buildMessageBodyWithMentionTokens(nextMessage, editMentions);
236
246
  formData_1 = new FormData();
237
- formData_1.append('messageBody', nextMessage);
247
+ formData_1.append('messageBody', messageBody.body);
248
+ formData_1.append('messageBodyMentions', JSON.stringify(messageBody.mentions));
238
249
  if (removedAttachmentIds.length > 0) {
239
250
  formData_1.append('removeAttachmentIds', removedAttachmentIds.join(','));
240
251
  }
@@ -257,10 +268,20 @@ export var SolidChatterMessageBox = function (props) {
257
268
  }
258
269
  });
259
270
  }); };
271
+ var handleEditKeyDown = function (event) {
272
+ handleMentionKeyDown(event);
273
+ if (event.defaultPrevented)
274
+ return;
275
+ if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
276
+ event.preventDefault();
277
+ handleEditSave();
278
+ }
279
+ };
260
280
  var handleCancelEdit = function () {
261
281
  setEditedMessage(localMessage !== null && localMessage !== void 0 ? localMessage : '');
262
282
  setSelectedFiles([]);
263
283
  setRemovedAttachmentIds([]);
284
+ resetMentions(parseMessageBodyMentions(messageBodyMentions));
264
285
  setIsEditing(false);
265
286
  };
266
287
  var formatFileSize = function (size) {
@@ -279,9 +300,12 @@ export var SolidChatterMessageBox = function (props) {
279
300
  : __spreadArray(__spreadArray([], prev, true), [attachmentId], false);
280
301
  });
281
302
  };
282
- return (_jsxs("div", { className: styles.solidChatterMessageBox, children: [_jsx("div", { className: styles.solidChatterMessageCard, children: _jsxs("div", { className: styles.solidChatterMessageLayout, children: [_jsx("div", { className: styles.solidChatterAvatar, style: avatarStyle, children: initials || user.charAt(0).toUpperCase() }), _jsxs("div", { className: styles.solidChatterMessageContent, children: [_jsxs("div", { className: styles.solidChatterMessageHeader, children: [_jsxs("div", { className: 'flex items-center gap-2 flex-wrap', children: [_jsx("p", { className: styles.solidChatterUser, children: user }), _jsxs(SolidTooltip, { children: [_jsx(SolidTooltipTrigger, { asChild: true, children: _jsx("span", { className: "".concat(styles.solidChatterBadge, " ").concat(messageType === 'audit' ? styles.audit : styles.custom), "aria-label": messageLabel, children: _jsx(TypeIcon, { size: 12 }) }) }), _jsx(SolidTooltipContent, { side: "right", children: messageLabel })] })] }), _jsxs("div", { className: 'flex items-center gap-2', children: [canEditNote && !isEditing && (_jsx(SolidButton, { type: "button", size: "sm", variant: "ghost", className: "solid-icon-button", leftIcon: _jsx(Pencil, { size: 12 }), onClick: function () { return setIsEditing(true); }, "aria-label": "Edit note", title: "Edit note" })), _jsx("span", { className: styles.solidChatterTime, children: time })] })] }), modelDisplayName && (_jsxs("p", { className: "".concat(styles.solidChatterMeta, " m-0"), children: [modelDisplayName, modelUserKey && _jsxs(_Fragment, { children: [" \u00B7 ", _jsx("span", { className: 'font-medium', children: modelUserKey })] })] })), localMessage && !isEditing && (_jsx("div", { className: styles.solidMessageWrapper, children: messageType === 'audit'
303
+ return (_jsxs("div", { className: styles.solidChatterMessageBox, children: [_jsx("div", { className: styles.solidChatterMessageCard, children: _jsxs("div", { className: styles.solidChatterMessageLayout, children: [_jsx("div", { className: styles.solidChatterAvatar, style: avatarStyle, children: initials || user.charAt(0).toUpperCase() }), _jsxs("div", { className: styles.solidChatterMessageContent, children: [_jsxs("div", { className: styles.solidChatterMessageHeader, children: [_jsxs("div", { className: 'flex items-center gap-2 flex-wrap', children: [_jsx("p", { className: styles.solidChatterUser, children: user }), _jsxs(SolidTooltip, { children: [_jsx(SolidTooltipTrigger, { asChild: true, children: _jsx("span", { className: "".concat(styles.solidChatterBadge, " ").concat(messageType === 'audit' ? styles.audit : styles.custom), "aria-label": messageLabel, children: _jsx(TypeIcon, { size: 12 }) }) }), _jsx(SolidTooltipContent, { side: "right", children: messageLabel })] })] }), _jsxs("div", { className: 'flex items-center gap-2', children: [canEditNote && !isEditing && (_jsx(SolidButton, { type: "button", size: "sm", variant: "ghost", className: "solid-icon-button", leftIcon: _jsx(Pencil, { size: 12 }), onClick: function () {
304
+ resetMentions(parseMessageBodyMentions(messageBodyMentions));
305
+ setIsEditing(true);
306
+ }, "aria-label": "Edit note", title: "Edit note" })), _jsx("span", { className: styles.solidChatterTime, children: time })] })] }), modelDisplayName && (_jsxs("p", { className: "".concat(styles.solidChatterMeta, " m-0"), children: [modelDisplayName, modelUserKey && _jsxs(_Fragment, { children: [" \u00B7 ", _jsx("span", { className: 'font-medium', children: modelUserKey })] })] })), localMessage && !isEditing && (_jsx("div", { className: styles.solidMessageWrapper, children: messageType === 'audit'
283
307
  ? _jsx(SolidChatterAuditMessage, { auditRecord: auditRecord })
284
- : _jsx(SolidChatterCustomMessage, { message: localMessage }) })), isEditing && (_jsxs("div", { className: 'flex flex-col gap-2', children: [_jsx(SolidTextarea, { value: editedMessage, onChange: function (e) { return setEditedMessage(e.target.value); }, rows: 4, className: "w-full py-2" }), _jsxs("div", { className: 'flex flex-col gap-2', children: [_jsx("input", { ref: fileInputRef, id: "note-edit-file-".concat(messageId), type: "file", multiple: true, onChange: handleFileSelect, style: { display: 'none' } }), selectedFiles.length > 0 && (_jsx("div", { className: 'flex flex-col gap-1', children: selectedFiles.map(function (file, index) { return (_jsxs("div", { className: 'flex items-center justify-between text-xs', children: [_jsxs("span", { children: [file.name, " (", formatFileSize(file.size), ")"] }), _jsx(SolidButton, { type: "button", size: "sm", variant: "ghost", className: 'solid-icon-button', leftIcon: _jsx(X, { size: 12 }), onClick: function () { return setSelectedFiles(function (prev) { return prev.filter(function (_, i) { return i !== index; }); }); }, "aria-label": "Remove ".concat(file.name) })] }, "".concat(file.name, "-").concat(index))); }) }))] }), _jsxs("div", { className: 'flex items-center justify-between gap-2 flex-wrap', children: [_jsxs("div", { className: 'flex items-center gap-2', children: [_jsx(SolidButton, { type: "button", size: "sm", variant: "ghost", className: "solid-icon-button", leftIcon: _jsx(Paperclip, { size: 14 }), onClick: function () { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, "aria-label": "Attach files", title: "Attach files" }), _jsx("span", { className: 'text-xs text-color-secondary', children: "Attach file" })] }), _jsxs("div", { className: 'flex items-center justify-end gap-2', children: [_jsx(SolidButton, { type: "button", size: "sm", variant: "outline", leftIcon: _jsx(X, { size: 12 }), onClick: handleCancelEdit, children: "Cancel" }), _jsx(SolidButton, { type: "button", size: "sm", variant: "primary", loading: isUpdatingNote, leftIcon: _jsx(Check, { size: 12 }), onClick: handleEditSave, disabled: !(editedMessage === null || editedMessage === void 0 ? void 0 : editedMessage.trim()) || (removedAttachmentIds.length === 0 && selectedFiles.length === 0 && editedMessage.trim() === (message !== null && message !== void 0 ? message : '').trim()), children: "Save" })] })] })] })), visibleAttachments.length > 0 && (_jsx("div", { className: styles.solidChatterAttachments, children: visibleAttachments.map(function (attachment) {
308
+ : _jsx(SolidChatterCustomMessage, { message: localMessage }) })), isEditing && (_jsxs("div", { className: 'flex flex-col gap-2', children: [_jsx(SolidTextarea, { ref: editTextareaRef, value: editedMessage, onChange: handleMentionTextChange, onKeyDown: handleEditKeyDown, onKeyUp: handleMentionKeyUp, onClick: handleMentionClick, rows: 4, className: "w-full py-2" }), _jsx("p", { className: styles.chatterComposerHelp, children: "Type @ to mention a user. Press Ctrl+Enter to save." }), mentionRange && (_jsx(SolidChatterMentionMenu, { isLoading: isFetchingMentionUsers, users: mentionSuggestions, activeIndex: activeMentionIndex, onSelect: handleSelectMention })), _jsxs("div", { className: 'flex flex-col gap-2', children: [_jsx("input", { ref: fileInputRef, id: "note-edit-file-".concat(messageId), type: "file", multiple: true, onChange: handleFileSelect, style: { display: 'none' } }), selectedFiles.length > 0 && (_jsx("div", { className: 'flex flex-col gap-1', children: selectedFiles.map(function (file, index) { return (_jsxs("div", { className: 'flex items-center justify-between text-xs', children: [_jsxs("span", { children: [file.name, " (", formatFileSize(file.size), ")"] }), _jsx(SolidButton, { type: "button", size: "sm", variant: "ghost", className: 'solid-icon-button', leftIcon: _jsx(X, { size: 12 }), onClick: function () { return setSelectedFiles(function (prev) { return prev.filter(function (_, i) { return i !== index; }); }); }, "aria-label": "Remove ".concat(file.name) })] }, "".concat(file.name, "-").concat(index))); }) }))] }), _jsxs("div", { className: 'flex items-center justify-between gap-2 flex-wrap', children: [_jsxs("div", { className: 'flex items-center gap-2', children: [_jsx(SolidButton, { type: "button", size: "sm", variant: "ghost", className: "solid-icon-button", leftIcon: _jsx(Paperclip, { size: 14 }), onClick: function () { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, "aria-label": "Attach files", title: "Attach files" }), _jsx("span", { className: 'text-xs text-color-secondary', children: "Attach file" })] }), _jsxs("div", { className: 'flex items-center justify-end gap-2', children: [_jsx(SolidButton, { type: "button", size: "sm", variant: "outline", leftIcon: _jsx(X, { size: 12 }), onClick: handleCancelEdit, children: "Cancel" }), _jsx(SolidButton, { type: "button", size: "sm", variant: "primary", loading: isUpdatingNote, leftIcon: _jsx(Check, { size: 12 }), onClick: handleEditSave, disabled: !(editedMessage === null || editedMessage === void 0 ? void 0 : editedMessage.trim()) || (removedAttachmentIds.length === 0 && selectedFiles.length === 0 && editedMessage.trim() === (message !== null && message !== void 0 ? message : '').trim()), children: "Save" })] })] })] })), visibleAttachments.length > 0 && (_jsx("div", { className: styles.solidChatterAttachments, children: visibleAttachments.map(function (attachment) {
285
309
  var isImage = attachment.mimeType.startsWith('image/');
286
310
  return (_jsxs("div", { className: styles.solidChatterAttachment, style: { position: 'relative' }, children: [isEditing && canEditNote && (_jsx(SolidButton, { type: "button", size: "sm", variant: "ghost", className: "solid-icon-button", leftIcon: _jsx(Trash2, { size: 12, color: "#dc2626" }), onClick: function () { return toggleRemoveAttachment(attachment.id); }, "aria-label": "Remove ".concat(attachment.originalFileName), title: "Remove ".concat(attachment.originalFileName), style: {
287
311
  position: 'absolute',