@webiny/app-audit-logs 6.6.0-alpha.0 → 6.6.0-alpha.1

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 (96) hide show
  1. package/components/Text.d.ts +1 -3
  2. package/components/Text.js +4 -9
  3. package/components/Text.js.map +1 -1
  4. package/config/list/AuditLogsListConfig.d.ts +6 -0
  5. package/config/list/AuditLogsListConfig.js +10 -1
  6. package/config/list/AuditLogsListConfig.js.map +1 -1
  7. package/config/list/Details/PreviewTab.d.ts +15 -0
  8. package/config/list/Details/PreviewTab.js +32 -0
  9. package/config/list/Details/PreviewTab.js.map +1 -0
  10. package/config/list/Details/index.d.ts +8 -0
  11. package/config/list/Details/index.js +7 -0
  12. package/config/list/Details/index.js.map +1 -0
  13. package/hooks/schema.d.ts +2 -3
  14. package/hooks/schema.js +1 -2
  15. package/hooks/schema.js.map +1 -1
  16. package/hooks/useAuditLogsList.d.ts +0 -3
  17. package/hooks/useAuditLogsList.js +11 -12
  18. package/hooks/useAuditLogsList.js.map +1 -1
  19. package/index.js +12 -5
  20. package/index.js.map +1 -1
  21. package/package.json +13 -15
  22. package/types.d.ts +2 -2
  23. package/views/Logs/Filters/FilterByAction.d.ts +1 -1
  24. package/views/Logs/Filters/FilterByAction.js +5 -3
  25. package/views/Logs/Filters/FilterByAction.js.map +1 -1
  26. package/views/Logs/Filters/FilterByApp.js +2 -1
  27. package/views/Logs/Filters/FilterByApp.js.map +1 -1
  28. package/views/Logs/Filters/FilterByCreatedBy.js +2 -1
  29. package/views/Logs/Filters/FilterByCreatedBy.js.map +1 -1
  30. package/views/Logs/Filters/FilterByCreatedOn.js +26 -27
  31. package/views/Logs/Filters/FilterByCreatedOn.js.map +1 -1
  32. package/views/Logs/Filters/FilterByEntity.d.ts +1 -1
  33. package/views/Logs/Filters/FilterByEntity.js +5 -3
  34. package/views/Logs/Filters/FilterByEntity.js.map +1 -1
  35. package/views/Logs/Filters/FilterByEntityId.js +2 -1
  36. package/views/Logs/Filters/FilterByEntityId.js.map +1 -1
  37. package/views/Logs/Filters/Filters.d.ts +1 -2
  38. package/views/Logs/Filters/Filters.js +61 -13
  39. package/views/Logs/Filters/Filters.js.map +1 -1
  40. package/views/Logs/Header/ButtonFilters/ButtonFilters.js +4 -5
  41. package/views/Logs/Header/ButtonFilters/ButtonFilters.js.map +1 -1
  42. package/views/Logs/Header/Header.d.ts +2 -4
  43. package/views/Logs/Header/Header.js +4 -7
  44. package/views/Logs/Header/Header.js.map +1 -1
  45. package/views/Logs/LoadMoreButton/styled.d.ts +4 -4
  46. package/views/Logs/LoadMoreButton/styled.js +4 -6
  47. package/views/Logs/LoadMoreButton/styled.js.map +1 -1
  48. package/views/Logs/LogsView.js +4 -8
  49. package/views/Logs/LogsView.js.map +1 -1
  50. package/views/Logs/Preview/AuditLogDetailsPresenter.d.ts +13 -0
  51. package/views/Logs/Preview/AuditLogDetailsPresenter.js +36 -0
  52. package/views/Logs/Preview/AuditLogDetailsPresenter.js.map +1 -0
  53. package/views/Logs/Preview/Preview.d.ts +4 -2
  54. package/views/Logs/Preview/Preview.js +67 -22
  55. package/views/Logs/Preview/Preview.js.map +1 -1
  56. package/views/Logs/Preview/abstractions.d.ts +14 -0
  57. package/views/Logs/Preview/abstractions.js +5 -0
  58. package/views/Logs/Preview/abstractions.js.map +1 -0
  59. package/views/Logs/Preview/feature.d.ts +5 -0
  60. package/views/Logs/Preview/feature.js +22 -0
  61. package/views/Logs/Preview/feature.js.map +1 -0
  62. package/views/Logs/Preview/index.d.ts +2 -0
  63. package/views/Logs/Preview/index.js +1 -0
  64. package/views/Logs/Preview/tabs/AiPromptTabs.d.ts +2 -0
  65. package/views/Logs/Preview/tabs/AiPromptTabs.js +25 -0
  66. package/views/Logs/Preview/tabs/AiPromptTabs.js.map +1 -0
  67. package/views/Logs/Preview/tabs/LlmResponseTab.d.ts +4 -0
  68. package/views/Logs/Preview/tabs/LlmResponseTab.js +41 -0
  69. package/views/Logs/Preview/tabs/LlmResponseTab.js.map +1 -0
  70. package/views/Logs/Preview/tabs/SystemPromptTab.d.ts +4 -0
  71. package/views/Logs/Preview/tabs/SystemPromptTab.js +24 -0
  72. package/views/Logs/Preview/tabs/SystemPromptTab.js.map +1 -0
  73. package/views/Logs/Preview/tabs/UserPromptTab.d.ts +4 -0
  74. package/views/Logs/Preview/tabs/UserPromptTab.js +18 -0
  75. package/views/Logs/Preview/tabs/UserPromptTab.js.map +1 -0
  76. package/views/Logs/Preview/tabs/shared.d.ts +28 -0
  77. package/views/Logs/Preview/tabs/shared.js +16 -0
  78. package/views/Logs/Preview/tabs/shared.js.map +1 -0
  79. package/views/Logs/Table/Table.d.ts +3 -6
  80. package/views/Logs/Table/Table.js +25 -16
  81. package/views/Logs/Table/Table.js.map +1 -1
  82. package/views/Logs/Table/styled.d.ts +1 -16
  83. package/views/Logs/Table/styled.js +15 -55
  84. package/views/Logs/Table/styled.js.map +1 -1
  85. package/views/Logs/Filters/FilterByTimestamp.d.ts +0 -2
  86. package/views/Logs/Filters/FilterByTimestamp.js +0 -39
  87. package/views/Logs/Filters/FilterByTimestamp.js.map +0 -1
  88. package/views/Logs/Filters/styled.d.ts +0 -4
  89. package/views/Logs/Filters/styled.js +0 -13
  90. package/views/Logs/Filters/styled.js.map +0 -1
  91. package/views/Logs/Logs.d.ts +0 -3
  92. package/views/Logs/Logs.js +0 -76
  93. package/views/Logs/Logs.js.map +0 -1
  94. package/views/Logs/Preview/styled.d.ts +0 -5
  95. package/views/Logs/Preview/styled.js +0 -32
  96. package/views/Logs/Preview/styled.js.map +0 -1
@@ -1,22 +1,70 @@
1
- import react from "react";
1
+ import react, { useEffect, useMemo } from "react";
2
2
  import { addMinutes, format } from "date-fns";
3
- import { CodeEditor, Dialog, Grid, Tooltip } from "@webiny/admin-ui";
3
+ import { CodeEditor, Drawer, Grid, Tabs, Tooltip } from "@webiny/admin-ui";
4
+ import { createReactiveComponent } from "@webiny/app-admin";
4
5
  import { Action } from "../Table/index.js";
5
6
  import { Text } from "../../../components/Text.js";
6
- import { PayloadWrapper, previewDialog } from "./styled.js";
7
- const Preview = ({ auditLog, onClose, hasAccessToUsers })=>{
7
+ import { useAuditLogsListConfig } from "../../../config/list/AuditLogsListConfig.js";
8
+ import { useAuditLogDetailsPresenter } from "./feature.js";
9
+ const EDITOR_HEIGHT = "calc(100vh - 350px)";
10
+ const Preview_PayloadTab = createReactiveComponent(function() {
11
+ const presenter = useAuditLogDetailsPresenter();
12
+ const { auditLog } = presenter.vm;
13
+ if (!auditLog) return null;
14
+ return /*#__PURE__*/ react.createElement(CodeEditor, {
15
+ language: "json",
16
+ value: JSON.stringify(JSON.parse(auditLog.content), null, 2),
17
+ height: EDITOR_HEIGHT
18
+ });
19
+ });
20
+ const Preview_Preview = createReactiveComponent(function({ auditLog, onClose, hasAccessToUsers }) {
21
+ const presenter = useAuditLogDetailsPresenter();
22
+ const config = useAuditLogsListConfig();
23
+ useEffect(()=>{
24
+ if (auditLog) presenter.init(auditLog);
25
+ }, [
26
+ presenter,
27
+ auditLog
28
+ ]);
29
+ const tabs = useMemo(()=>{
30
+ if (!auditLog) return [];
31
+ const customTabs = config.details.tabs.filter((tab)=>!tab.canRender || tab.canRender(auditLog));
32
+ return [
33
+ /*#__PURE__*/ react.createElement(Tabs.Tab, {
34
+ key: "payload",
35
+ value: "payload",
36
+ trigger: "Payload",
37
+ content: /*#__PURE__*/ react.createElement(Preview_PayloadTab, null)
38
+ }),
39
+ ...customTabs.map((tab)=>/*#__PURE__*/ react.createElement(Tabs.Tab, {
40
+ key: tab.name,
41
+ value: tab.name,
42
+ trigger: tab.label,
43
+ content: tab.element
44
+ }))
45
+ ];
46
+ }, [
47
+ auditLog,
48
+ config.details.tabs
49
+ ]);
8
50
  if (!auditLog) return null;
9
51
  const date = new Date(auditLog.createdOn);
10
- return /*#__PURE__*/ react.createElement(Dialog, {
11
- open: !!auditLog,
52
+ return /*#__PURE__*/ react.createElement(Drawer, {
53
+ open: true,
12
54
  onClose: onClose,
13
- className: previewDialog,
14
- size: "xl",
55
+ modal: true,
56
+ width: 720,
15
57
  title: auditLog.message,
16
- actions: /*#__PURE__*/ react.createElement(Dialog.CancelAction, {
17
- onClick: onClose,
18
- text: "Close"
58
+ headerSeparator: true,
59
+ bodyPadding: false,
60
+ actions: /*#__PURE__*/ react.createElement(Drawer.CancelButton, {
61
+ text: "Close",
62
+ onClick: onClose
19
63
  })
64
+ }, /*#__PURE__*/ react.createElement("div", {
65
+ className: "flex flex-col h-full"
66
+ }, /*#__PURE__*/ react.createElement("div", {
67
+ className: "shrink-0 p-md pb-0"
20
68
  }, /*#__PURE__*/ react.createElement(Grid, null, /*#__PURE__*/ react.createElement(Grid.Column, {
21
69
  span: 6
22
70
  }, /*#__PURE__*/ react.createElement(Text, {
@@ -28,7 +76,7 @@ const Preview = ({ auditLog, onClose, hasAccessToUsers })=>{
28
76
  }, /*#__PURE__*/ react.createElement(Text, {
29
77
  use: "overline"
30
78
  }, "Date"), /*#__PURE__*/ react.createElement("br", null), /*#__PURE__*/ react.createElement(Tooltip, {
31
- side: "right",
79
+ side: "left",
32
80
  content: `UTC: ${format(addMinutes(date, date.getTimezoneOffset()), "yyyy-MM-dd HH:mm:ss")}`,
33
81
  trigger: /*#__PURE__*/ react.createElement(Text, {
34
82
  use: "subtitle2"
@@ -68,15 +116,12 @@ const Preview = ({ auditLog, onClose, hasAccessToUsers })=>{
68
116
  use: "subtitle2"
69
117
  }, auditLog.createdBy.displayName)), /*#__PURE__*/ react.createElement(Text, {
70
118
  use: "body2"
71
- }, ` (${auditLog.createdBy.role})`)) : void 0, /*#__PURE__*/ react.createElement(Grid.Column, {
72
- span: 12
73
- }, /*#__PURE__*/ react.createElement(Text, {
74
- use: "overline"
75
- }, "Payload"), /*#__PURE__*/ react.createElement(PayloadWrapper, null, /*#__PURE__*/ react.createElement(CodeEditor, {
76
- language: "json",
77
- value: JSON.stringify(JSON.parse(auditLog.content), null, 2)
78
- })))));
79
- };
80
- export { Preview };
119
+ }, ` (${auditLog.createdBy.role})`)) : null)), /*#__PURE__*/ react.createElement("div", {
120
+ className: "px-md pb-md"
121
+ }, /*#__PURE__*/ react.createElement(Tabs, {
122
+ tabs: tabs
123
+ }))));
124
+ });
125
+ export { Preview_Preview as Preview };
81
126
 
82
127
  //# sourceMappingURL=Preview.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"views/Logs/Preview/Preview.js","sources":["../../../../src/views/Logs/Preview/Preview.tsx"],"sourcesContent":["import React from \"react\";\nimport { addMinutes, format } from \"date-fns\";\nimport { Grid, Dialog, CodeEditor, Tooltip } from \"@webiny/admin-ui\";\nimport { Action } from \"~/views/Logs/Table/index.js\";\nimport { Text } from \"~/components/Text.js\";\nimport { PayloadWrapper, previewDialog } from \"./styled.js\";\nimport type { IAuditLog } from \"~/types.js\";\n\ninterface HeaderProps {\n auditLog: IAuditLog | null;\n onClose: () => void;\n hasAccessToUsers: boolean;\n}\n\nexport const Preview = ({ auditLog, onClose, hasAccessToUsers }: HeaderProps) => {\n if (!auditLog) {\n return null;\n }\n const date = new Date(auditLog.createdOn);\n\n return (\n <Dialog\n open={!!auditLog}\n onClose={onClose}\n className={previewDialog}\n size={\"xl\"}\n title={auditLog.message}\n actions={<Dialog.CancelAction onClick={onClose} text={\"Close\"} />}\n >\n <Grid>\n <Grid.Column span={6}>\n <Text use=\"overline\">Application</Text>\n <br />\n <Text use=\"subtitle2\">{auditLog.app}</Text>\n </Grid.Column>\n <Grid.Column span={6}>\n <Text use=\"overline\">Date</Text>\n <br />\n <Tooltip\n side=\"right\"\n content={`UTC: ${format(\n addMinutes(date, date.getTimezoneOffset()),\n \"yyyy-MM-dd HH:mm:ss\"\n )}`}\n trigger={\n <Text use={\"subtitle2\"}>{format(date, \"yyyy-MM-dd HH:mm:ss (O)\")}</Text>\n }\n />\n </Grid.Column>\n <Grid.Column span={6}>\n <Text use=\"overline\">Entity</Text>\n <br />\n <Text use=\"subtitle2\">{auditLog.entity.label}</Text>\n </Grid.Column>\n <Grid.Column span={6}>\n <Text use=\"overline\">Entity Id</Text>\n <br />\n {auditLog.entity.link ? (\n <a href={auditLog.entity.link} target={\"blank\"}>\n <Text use=\"subtitle2\">{auditLog.entityId}</Text>\n </a>\n ) : (\n <Text use=\"subtitle2\">{auditLog.entityId}</Text>\n )}\n </Grid.Column>\n <Grid.Column span={6}>\n <Text use=\"overline\">Action</Text>\n <br />\n <Action label={auditLog.action.label} value={auditLog.action.value} />\n </Grid.Column>\n {\n (hasAccessToUsers ? (\n <Grid.Column span={6}>\n <Text use=\"overline\">Initiator</Text>\n <br />\n <a href={`/admin-users?id=${auditLog.createdBy.id}`} target={\"blank\"}>\n <Text use={\"subtitle2\"}>{auditLog.createdBy.displayName}</Text>\n </a>\n <Text use={\"body2\"}>{` (${auditLog.createdBy.role})`}</Text>\n </Grid.Column>\n ) : undefined) as any\n }\n <Grid.Column span={12}>\n <Text use=\"overline\">Payload</Text>\n <PayloadWrapper>\n <CodeEditor\n language=\"json\"\n value={JSON.stringify(JSON.parse(auditLog.content), null, 2)}\n />\n </PayloadWrapper>\n </Grid.Column>\n </Grid>\n </Dialog>\n );\n};\n"],"names":["Preview","auditLog","onClose","hasAccessToUsers","date","Date","Dialog","previewDialog","Grid","Text","Tooltip","format","addMinutes","Action","undefined","PayloadWrapper","CodeEditor","JSON"],"mappings":";;;;;;AAcO,MAAMA,UAAU,CAAC,EAAEC,QAAQ,EAAEC,OAAO,EAAEC,gBAAgB,EAAe;IACxE,IAAI,CAACF,UACD,OAAO;IAEX,MAAMG,OAAO,IAAIC,KAAKJ,SAAS,SAAS;IAExC,OAAO,WAAP,GACI,oBAACK,QAAMA;QACH,MAAM,CAAC,CAACL;QACR,SAASC;QACT,WAAWK;QACX,MAAM;QACN,OAAON,SAAS,OAAO;QACvB,uBAAS,oBAACK,OAAO,YAAY;YAAC,SAASJ;YAAS,MAAM;;qBAEtD,oBAACM,MAAIA,MAAAA,WAAAA,GACD,oBAACA,KAAK,MAAM;QAAC,MAAM;qBACf,oBAACC,MAAIA;QAAC,KAAI;OAAW,8BACrB,oBAAC,2BACD,oBAACA,MAAIA;QAAC,KAAI;OAAaR,SAAS,GAAG,kBAEvC,oBAACO,KAAK,MAAM;QAAC,MAAM;qBACf,oBAACC,MAAIA;QAAC,KAAI;OAAW,uBACrB,oBAAC,2BACD,oBAACC,SAAOA;QACJ,MAAK;QACL,SAAS,CAAC,KAAK,EAAEC,OACbC,WAAWR,MAAMA,KAAK,iBAAiB,KACvC,wBACD;QACH,uBACI,oBAACK,MAAIA;YAAC,KAAK;WAAcE,OAAOP,MAAM;uBAIlD,oBAACI,KAAK,MAAM;QAAC,MAAM;qBACf,oBAACC,MAAIA;QAAC,KAAI;OAAW,yBACrB,oBAAC,2BACD,oBAACA,MAAIA;QAAC,KAAI;OAAaR,SAAS,MAAM,CAAC,KAAK,kBAEhD,oBAACO,KAAK,MAAM;QAAC,MAAM;qBACf,oBAACC,MAAIA;QAAC,KAAI;OAAW,4BACrB,oBAAC,aACAR,SAAS,MAAM,CAAC,IAAI,GAAG,WAAH,GACjB,oBAAC;QAAE,MAAMA,SAAS,MAAM,CAAC,IAAI;QAAE,QAAQ;qBACnC,oBAACQ,MAAIA;QAAC,KAAI;OAAaR,SAAS,QAAQ,mBAG5C,oBAACQ,MAAIA;QAAC,KAAI;OAAaR,SAAS,QAAQ,kBAGhD,oBAACO,KAAK,MAAM;QAAC,MAAM;qBACf,oBAACC,MAAIA;QAAC,KAAI;OAAW,yBACrB,oBAAC,2BACD,oBAACI,QAAMA;QAAC,OAAOZ,SAAS,MAAM,CAAC,KAAK;QAAE,OAAOA,SAAS,MAAM,CAAC,KAAK;SAGjEE,mBAAmB,WAAnBA,GACG,oBAACK,KAAK,MAAM;QAAC,MAAM;qBACf,oBAACC,MAAIA;QAAC,KAAI;OAAW,4BACrB,oBAAC,2BACD,oBAAC;QAAE,MAAM,CAAC,gBAAgB,EAAER,SAAS,SAAS,CAAC,EAAE,EAAE;QAAE,QAAQ;qBACzD,oBAACQ,MAAIA;QAAC,KAAK;OAAcR,SAAS,SAAS,CAAC,WAAW,kBAE3D,oBAACQ,MAAIA;QAAC,KAAK;OAAU,CAAC,EAAE,EAAER,SAAS,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,KAExDa,QAAAA,WAAAA,GAER,oBAACN,KAAK,MAAM;QAAC,MAAM;qBACf,oBAACC,MAAIA;QAAC,KAAI;OAAW,0BACrB,oBAACM,gBAAcA,MAAAA,WAAAA,GACX,oBAACC,YAAUA;QACP,UAAS;QACT,OAAOC,KAAK,SAAS,CAACA,KAAK,KAAK,CAAChB,SAAS,OAAO,GAAG,MAAM;;AAOtF"}
1
+ {"version":3,"file":"views/Logs/Preview/Preview.js","sources":["../../../../src/views/Logs/Preview/Preview.tsx"],"sourcesContent":["import React, { useEffect, useMemo } from \"react\";\nimport { addMinutes, format } from \"date-fns\";\nimport { Grid, Drawer, CodeEditor, Tooltip, Tabs } from \"@webiny/admin-ui\";\nimport { createReactiveComponent } from \"@webiny/app-admin\";\nimport { Action } from \"~/views/Logs/Table/index.js\";\nimport { Text } from \"~/components/Text.js\";\nimport { useAuditLogsListConfig } from \"~/config/list/AuditLogsListConfig.js\";\nimport { useAuditLogDetailsPresenter } from \"./feature.js\";\nimport type { IAuditLog } from \"~/types.js\";\n\ninterface PreviewProps {\n auditLog: IAuditLog | null;\n onClose: () => void;\n hasAccessToUsers: boolean;\n}\n\nconst EDITOR_HEIGHT = \"calc(100vh - 350px)\";\n\nconst PayloadTab = createReactiveComponent(function PayloadTab() {\n const presenter = useAuditLogDetailsPresenter();\n const { auditLog } = presenter.vm;\n if (!auditLog) {\n return null;\n }\n return (\n <CodeEditor\n language=\"json\"\n value={JSON.stringify(JSON.parse(auditLog.content), null, 2)}\n height={EDITOR_HEIGHT}\n />\n );\n});\n\nexport const Preview = createReactiveComponent(function Preview({\n auditLog,\n onClose,\n hasAccessToUsers\n}: PreviewProps) {\n const presenter = useAuditLogDetailsPresenter();\n const config = useAuditLogsListConfig();\n\n useEffect(() => {\n if (auditLog) {\n presenter.init(auditLog);\n }\n }, [presenter, auditLog]);\n\n const tabs = useMemo(() => {\n if (!auditLog) {\n return [];\n }\n\n const customTabs = config.details.tabs.filter(\n tab => !tab.canRender || tab.canRender(auditLog)\n );\n\n return [\n <Tabs.Tab key=\"payload\" value=\"payload\" trigger=\"Payload\" content={<PayloadTab />} />,\n ...customTabs.map(tab => (\n <Tabs.Tab\n key={tab.name}\n value={tab.name}\n trigger={tab.label}\n content={tab.element}\n />\n ))\n ];\n }, [auditLog, config.details.tabs]);\n\n if (!auditLog) {\n return null;\n }\n\n const date = new Date(auditLog.createdOn);\n\n return (\n <Drawer\n open={true}\n onClose={onClose}\n modal={true}\n width={720}\n title={auditLog.message}\n headerSeparator={true}\n bodyPadding={false}\n actions={<Drawer.CancelButton text={\"Close\"} onClick={onClose} />}\n >\n <div className={\"flex flex-col h-full\"}>\n <div className={\"shrink-0 p-md pb-0\"}>\n <Grid>\n <Grid.Column span={6}>\n <Text use=\"overline\">Application</Text>\n <br />\n <Text use=\"subtitle2\">{auditLog.app}</Text>\n </Grid.Column>\n <Grid.Column span={6}>\n <Text use=\"overline\">Date</Text>\n <br />\n <Tooltip\n side=\"left\"\n content={`UTC: ${format(\n addMinutes(date, date.getTimezoneOffset()),\n \"yyyy-MM-dd HH:mm:ss\"\n )}`}\n trigger={\n <Text use={\"subtitle2\"}>\n {format(date, \"yyyy-MM-dd HH:mm:ss (O)\")}\n </Text>\n }\n />\n </Grid.Column>\n <Grid.Column span={6}>\n <Text use=\"overline\">Entity</Text>\n <br />\n <Text use=\"subtitle2\">{auditLog.entity.label}</Text>\n </Grid.Column>\n <Grid.Column span={6}>\n <Text use=\"overline\">Entity Id</Text>\n <br />\n {auditLog.entity.link ? (\n <a href={auditLog.entity.link} target={\"blank\"}>\n <Text use=\"subtitle2\">{auditLog.entityId}</Text>\n </a>\n ) : (\n <Text use=\"subtitle2\">{auditLog.entityId}</Text>\n )}\n </Grid.Column>\n <Grid.Column span={6}>\n <Text use=\"overline\">Action</Text>\n <br />\n <Action label={auditLog.action.label} value={auditLog.action.value} />\n </Grid.Column>\n {hasAccessToUsers ? (\n <Grid.Column span={6}>\n <Text use=\"overline\">Initiator</Text>\n <br />\n <a\n href={`/admin-users?id=${auditLog.createdBy.id}`}\n target={\"blank\"}\n >\n <Text use={\"subtitle2\"}>{auditLog.createdBy.displayName}</Text>\n </a>\n <Text use={\"body2\"}>{` (${auditLog.createdBy.role})`}</Text>\n </Grid.Column>\n ) : null}\n </Grid>\n </div>\n <div className={\"px-md pb-md\"}>\n <Tabs tabs={tabs} />\n </div>\n </div>\n </Drawer>\n );\n});\n"],"names":["EDITOR_HEIGHT","PayloadTab","createReactiveComponent","presenter","useAuditLogDetailsPresenter","auditLog","CodeEditor","JSON","Preview","onClose","hasAccessToUsers","config","useAuditLogsListConfig","useEffect","tabs","useMemo","customTabs","tab","Tabs","date","Date","Drawer","Grid","Text","Tooltip","format","addMinutes","Action"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { IAuditLog } from "../../../types.js";
2
+ export interface IAuditLogDetailsVm {
3
+ auditLog: IAuditLog | null;
4
+ content: Record<string, unknown>;
5
+ }
6
+ export interface IAuditLogDetailsPresenter {
7
+ readonly vm: IAuditLogDetailsVm;
8
+ init(auditLog: IAuditLog): void;
9
+ }
10
+ export declare const AuditLogDetailsPresenter: import("@webiny/di").Abstraction<IAuditLogDetailsPresenter>;
11
+ export declare namespace AuditLogDetailsPresenter {
12
+ type Interface = IAuditLogDetailsPresenter;
13
+ type ViewModel = IAuditLogDetailsVm;
14
+ }
@@ -0,0 +1,5 @@
1
+ import { createAbstraction } from "@webiny/feature/admin";
2
+ const AuditLogDetailsPresenter = createAbstraction("AuditLogDetailsPresenter");
3
+ export { AuditLogDetailsPresenter };
4
+
5
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views/Logs/Preview/abstractions.js","sources":["../../../../src/views/Logs/Preview/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { IAuditLog } from \"~/types.js\";\n\nexport interface IAuditLogDetailsVm {\n auditLog: IAuditLog | null;\n content: Record<string, unknown>;\n}\n\nexport interface IAuditLogDetailsPresenter {\n readonly vm: IAuditLogDetailsVm;\n init(auditLog: IAuditLog): void;\n}\n\nexport const AuditLogDetailsPresenter = createAbstraction<IAuditLogDetailsPresenter>(\n \"AuditLogDetailsPresenter\"\n);\n\nexport namespace AuditLogDetailsPresenter {\n export type Interface = IAuditLogDetailsPresenter;\n export type ViewModel = IAuditLogDetailsVm;\n}\n"],"names":["AuditLogDetailsPresenter","createAbstraction"],"mappings":";AAaO,MAAMA,2BAA2BC,kBACpC"}
@@ -0,0 +1,5 @@
1
+ import { AuditLogDetailsPresenter as Abstraction } from "./abstractions.js";
2
+ export declare const AuditLogDetailsPresenterFeature: import("@webiny/feature/admin").FeatureDefinition<{
3
+ presenter: import("./abstractions.js").IAuditLogDetailsPresenter;
4
+ }, []>;
5
+ export declare function useAuditLogDetailsPresenter(): Abstraction.Interface;
@@ -0,0 +1,22 @@
1
+ import { createFeature } from "@webiny/feature/admin";
2
+ import { useFeature } from "@webiny/app-admin";
3
+ import { AuditLogDetailsPresenter } from "./abstractions.js";
4
+ import { AuditLogDetailsPresenter as external_AuditLogDetailsPresenter_js_AuditLogDetailsPresenter } from "./AuditLogDetailsPresenter.js";
5
+ const AuditLogDetailsPresenterFeature = createFeature({
6
+ name: "AuditLogs/DetailsPresenter",
7
+ register (container) {
8
+ container.register(external_AuditLogDetailsPresenter_js_AuditLogDetailsPresenter).inSingletonScope();
9
+ },
10
+ resolve (container) {
11
+ return {
12
+ presenter: container.resolve(AuditLogDetailsPresenter)
13
+ };
14
+ }
15
+ });
16
+ function useAuditLogDetailsPresenter() {
17
+ const { presenter } = useFeature(AuditLogDetailsPresenterFeature);
18
+ return presenter;
19
+ }
20
+ export { AuditLogDetailsPresenterFeature, useAuditLogDetailsPresenter };
21
+
22
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views/Logs/Preview/feature.js","sources":["../../../../src/views/Logs/Preview/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { useFeature } from \"@webiny/app-admin\";\nimport { AuditLogDetailsPresenter as Abstraction } from \"./abstractions.js\";\nimport { AuditLogDetailsPresenter } from \"./AuditLogDetailsPresenter.js\";\n\nexport const AuditLogDetailsPresenterFeature = createFeature({\n name: \"AuditLogs/DetailsPresenter\",\n register(container) {\n container.register(AuditLogDetailsPresenter).inSingletonScope();\n },\n resolve(container) {\n return {\n presenter: container.resolve(Abstraction)\n };\n }\n});\n\nexport function useAuditLogDetailsPresenter(): Abstraction.Interface {\n const { presenter } = useFeature(AuditLogDetailsPresenterFeature);\n return presenter;\n}\n"],"names":["AuditLogDetailsPresenterFeature","createFeature","container","AuditLogDetailsPresenter","Abstraction","useAuditLogDetailsPresenter","presenter","useFeature"],"mappings":";;;;AAKO,MAAMA,kCAAkCC,cAAc;IACzD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,+DAA0B,gBAAgB;IACjE;IACA,SAAQD,SAAS;QACb,OAAO;YACH,WAAWA,UAAU,OAAO,CAACE;QACjC;IACJ;AACJ;AAEO,SAASC;IACZ,MAAM,EAAEC,SAAS,EAAE,GAAGC,WAAWP;IACjC,OAAOM;AACX"}
@@ -1 +1,3 @@
1
1
  export * from "./Preview.js";
2
+ export { useAuditLogDetailsPresenter } from "./feature.js";
3
+ export type { IAuditLogDetailsPresenter, IAuditLogDetailsVm } from "./abstractions.js";
@@ -1 +1,2 @@
1
1
  export * from "./Preview.js";
2
+ export { useAuditLogDetailsPresenter } from "./feature.js";
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export declare const AiPromptPreviewTabs: () => React.JSX.Element;
@@ -0,0 +1,25 @@
1
+ import react from "react";
2
+ import { AuditLogsListConfig } from "../../../../config/list/index.js";
3
+ import { SystemPromptTab } from "./SystemPromptTab.js";
4
+ import { UserPromptTab } from "./UserPromptTab.js";
5
+ import { LlmResponseTab } from "./LlmResponseTab.js";
6
+ import { hasAfter, isAiGenerateText } from "./shared.js";
7
+ const AiPromptPreviewTabs = ()=>/*#__PURE__*/ react.createElement(AuditLogsListConfig, null, /*#__PURE__*/ react.createElement(AuditLogsListConfig.Details.Tab, {
8
+ name: "systemPrompt",
9
+ label: "System Prompt",
10
+ element: /*#__PURE__*/ react.createElement(SystemPromptTab, null),
11
+ canRender: isAiGenerateText
12
+ }), /*#__PURE__*/ react.createElement(AuditLogsListConfig.Details.Tab, {
13
+ name: "userPrompt",
14
+ label: "User Prompt",
15
+ element: /*#__PURE__*/ react.createElement(UserPromptTab, null),
16
+ canRender: isAiGenerateText
17
+ }), /*#__PURE__*/ react.createElement(AuditLogsListConfig.Details.Tab, {
18
+ name: "llmResponse",
19
+ label: "LLM Response",
20
+ element: /*#__PURE__*/ react.createElement(LlmResponseTab, null),
21
+ canRender: hasAfter
22
+ }));
23
+ export { AiPromptPreviewTabs };
24
+
25
+ //# sourceMappingURL=AiPromptTabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views/Logs/Preview/tabs/AiPromptTabs.js","sources":["../../../../../src/views/Logs/Preview/tabs/AiPromptTabs.tsx"],"sourcesContent":["import React from \"react\";\nimport { AuditLogsListConfig } from \"~/config/list/index.js\";\nimport { SystemPromptTab } from \"./SystemPromptTab.js\";\nimport { UserPromptTab } from \"./UserPromptTab.js\";\nimport { LlmResponseTab } from \"./LlmResponseTab.js\";\nimport { isAiGenerateText, hasAfter } from \"./shared.js\";\n\nexport const AiPromptPreviewTabs = () => {\n return (\n <AuditLogsListConfig>\n <AuditLogsListConfig.Details.Tab\n name=\"systemPrompt\"\n label=\"System Prompt\"\n element={<SystemPromptTab />}\n canRender={isAiGenerateText}\n />\n <AuditLogsListConfig.Details.Tab\n name=\"userPrompt\"\n label=\"User Prompt\"\n element={<UserPromptTab />}\n canRender={isAiGenerateText}\n />\n <AuditLogsListConfig.Details.Tab\n name=\"llmResponse\"\n label=\"LLM Response\"\n element={<LlmResponseTab />}\n canRender={hasAfter}\n />\n </AuditLogsListConfig>\n );\n};\n"],"names":["AiPromptPreviewTabs","AuditLogsListConfig","SystemPromptTab","isAiGenerateText","UserPromptTab","LlmResponseTab","hasAfter"],"mappings":";;;;;;AAOO,MAAMA,sBAAsB,IACxB,WAAP,GACI,oBAACC,qBAAmBA,MAAAA,WAAAA,GAChB,oBAACA,oBAAoB,OAAO,CAAC,GAAG;QAC5B,MAAK;QACL,OAAM;QACN,uBAAS,oBAACC,iBAAeA;QACzB,WAAWC;sBAEf,oBAACF,oBAAoB,OAAO,CAAC,GAAG;QAC5B,MAAK;QACL,OAAM;QACN,uBAAS,oBAACG,eAAaA;QACvB,WAAWD;sBAEf,oBAACF,oBAAoB,OAAO,CAAC,GAAG;QAC5B,MAAK;QACL,OAAM;QACN,uBAAS,oBAACI,gBAAcA;QACxB,WAAWC"}
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ export declare const LlmResponseTab: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
3
+ readonly type: () => React.JSX.Element;
4
+ };
@@ -0,0 +1,41 @@
1
+ import react from "react";
2
+ import { CodeEditor } from "@webiny/admin-ui";
3
+ import { createReactiveComponent } from "@webiny/app-admin";
4
+ import { useAuditLogDetailsPresenter } from "../feature.js";
5
+ import { EDITOR_HEIGHT } from "./shared.js";
6
+ const LlmResponseTab = createReactiveComponent(()=>{
7
+ const presenter = useAuditLogDetailsPresenter();
8
+ const after = presenter.vm.content.after;
9
+ if (!after) return /*#__PURE__*/ react.createElement(CodeEditor, {
10
+ language: "markdown",
11
+ value: "(pending — no response yet)",
12
+ height: EDITOR_HEIGHT
13
+ });
14
+ if ("error" === after.status) {
15
+ const errorText = [
16
+ `# Error: ${after.error?.name ?? "Unknown"}`,
17
+ "",
18
+ after.error?.message ?? "No error message available.",
19
+ "",
20
+ null != after.duration ? `Duration: ${after.duration}ms` : ""
21
+ ].join("\n");
22
+ return /*#__PURE__*/ react.createElement(CodeEditor, {
23
+ language: "markdown",
24
+ value: errorText,
25
+ height: EDITOR_HEIGHT
26
+ });
27
+ }
28
+ const text = after.text ?? "";
29
+ let formatted = text;
30
+ try {
31
+ formatted = JSON.stringify(JSON.parse(text), null, 2);
32
+ } catch {}
33
+ return /*#__PURE__*/ react.createElement(CodeEditor, {
34
+ language: "json",
35
+ value: formatted,
36
+ height: EDITOR_HEIGHT
37
+ });
38
+ });
39
+ export { LlmResponseTab };
40
+
41
+ //# sourceMappingURL=LlmResponseTab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views/Logs/Preview/tabs/LlmResponseTab.js","sources":["../../../../../src/views/Logs/Preview/tabs/LlmResponseTab.tsx"],"sourcesContent":["import React from \"react\";\nimport { CodeEditor } from \"@webiny/admin-ui\";\nimport { createReactiveComponent } from \"@webiny/app-admin\";\nimport { useAuditLogDetailsPresenter } from \"~/views/Logs/Preview/feature.js\";\nimport { EDITOR_HEIGHT, type AiAuditPayload } from \"./shared.js\";\n\nexport const LlmResponseTab = createReactiveComponent(() => {\n const presenter = useAuditLogDetailsPresenter();\n const after = presenter.vm.content.after as AiAuditPayload[\"after\"];\n\n if (!after) {\n return (\n <CodeEditor\n language=\"markdown\"\n value=\"(pending — no response yet)\"\n height={EDITOR_HEIGHT}\n />\n );\n }\n\n if (after.status === \"error\") {\n const errorText = [\n `# Error: ${after.error?.name ?? \"Unknown\"}`,\n \"\",\n after.error?.message ?? \"No error message available.\",\n \"\",\n after.duration != null ? `Duration: ${after.duration}ms` : \"\"\n ].join(\"\\n\");\n\n return <CodeEditor language=\"markdown\" value={errorText} height={EDITOR_HEIGHT} />;\n }\n\n const text = after.text ?? \"\";\n let formatted = text;\n try {\n formatted = JSON.stringify(JSON.parse(text), null, 2);\n } catch {\n // not JSON, show as-is\n }\n\n return <CodeEditor language=\"json\" value={formatted} height={EDITOR_HEIGHT} />;\n});\n"],"names":["LlmResponseTab","createReactiveComponent","presenter","useAuditLogDetailsPresenter","after","CodeEditor","EDITOR_HEIGHT","errorText","text","formatted","JSON"],"mappings":";;;;;AAMO,MAAMA,iBAAiBC,wBAAwB;IAClD,MAAMC,YAAYC;IAClB,MAAMC,QAAQF,UAAU,EAAE,CAAC,OAAO,CAAC,KAAK;IAExC,IAAI,CAACE,OACD,OAAO,WAAP,GACI,oBAACC,YAAUA;QACP,UAAS;QACT,OAAM;QACN,QAAQC;;IAKpB,IAAIF,AAAiB,YAAjBA,MAAM,MAAM,EAAc;QAC1B,MAAMG,YAAY;YACd,CAAC,SAAS,EAAEH,MAAM,KAAK,EAAE,QAAQ,WAAW;YAC5C;YACAA,MAAM,KAAK,EAAE,WAAW;YACxB;YACkB,QAAlBA,MAAM,QAAQ,GAAW,CAAC,UAAU,EAAEA,MAAM,QAAQ,CAAC,EAAE,CAAC,GAAG;SAC9D,CAAC,IAAI,CAAC;QAEP,OAAO,WAAP,GAAO,oBAACC,YAAUA;YAAC,UAAS;YAAW,OAAOE;YAAW,QAAQD;;IACrE;IAEA,MAAME,OAAOJ,MAAM,IAAI,IAAI;IAC3B,IAAIK,YAAYD;IAChB,IAAI;QACAC,YAAYC,KAAK,SAAS,CAACA,KAAK,KAAK,CAACF,OAAO,MAAM;IACvD,EAAE,OAAM,CAER;IAEA,OAAO,WAAP,GAAO,oBAACH,YAAUA;QAAC,UAAS;QAAO,OAAOI;QAAW,QAAQH;;AACjE"}
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ export declare const SystemPromptTab: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
3
+ readonly type: () => React.JSX.Element;
4
+ };
@@ -0,0 +1,24 @@
1
+ import react from "react";
2
+ import { CodeEditor } from "@webiny/admin-ui";
3
+ import { createReactiveComponent } from "@webiny/app-admin";
4
+ import { useAuditLogDetailsPresenter } from "../feature.js";
5
+ import { EDITOR_HEIGHT } from "./shared.js";
6
+ function extractSystemPrompt(content) {
7
+ const before = content.before;
8
+ const system = before?.system;
9
+ if ("string" == typeof system) return system;
10
+ if (system && "string" == typeof system.content) return system.content;
11
+ return "";
12
+ }
13
+ const SystemPromptTab = createReactiveComponent(()=>{
14
+ const presenter = useAuditLogDetailsPresenter();
15
+ const text = extractSystemPrompt(presenter.vm.content);
16
+ return /*#__PURE__*/ react.createElement(CodeEditor, {
17
+ language: "markdown",
18
+ value: text || "(empty)",
19
+ height: EDITOR_HEIGHT
20
+ });
21
+ });
22
+ export { SystemPromptTab };
23
+
24
+ //# sourceMappingURL=SystemPromptTab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views/Logs/Preview/tabs/SystemPromptTab.js","sources":["../../../../../src/views/Logs/Preview/tabs/SystemPromptTab.tsx"],"sourcesContent":["import React from \"react\";\nimport { CodeEditor } from \"@webiny/admin-ui\";\nimport { createReactiveComponent } from \"@webiny/app-admin\";\nimport { useAuditLogDetailsPresenter } from \"~/views/Logs/Preview/feature.js\";\nimport { EDITOR_HEIGHT, type AiAuditPayload } from \"./shared.js\";\n\nfunction extractSystemPrompt(content: Record<string, unknown>): string {\n const before = content.before as AiAuditPayload[\"before\"];\n const system = before?.system;\n if (typeof system === \"string\") {\n return system;\n }\n if (system && typeof system.content === \"string\") {\n return system.content;\n }\n return \"\";\n}\n\nexport const SystemPromptTab = createReactiveComponent(() => {\n const presenter = useAuditLogDetailsPresenter();\n const text = extractSystemPrompt(presenter.vm.content);\n return <CodeEditor language=\"markdown\" value={text || \"(empty)\"} height={EDITOR_HEIGHT} />;\n});\n"],"names":["extractSystemPrompt","content","before","system","SystemPromptTab","createReactiveComponent","presenter","useAuditLogDetailsPresenter","text","CodeEditor","EDITOR_HEIGHT"],"mappings":";;;;;AAMA,SAASA,oBAAoBC,OAAgC;IACzD,MAAMC,SAASD,QAAQ,MAAM;IAC7B,MAAME,SAASD,QAAQ;IACvB,IAAI,AAAkB,YAAlB,OAAOC,QACP,OAAOA;IAEX,IAAIA,UAAU,AAA0B,YAA1B,OAAOA,OAAO,OAAO,EAC/B,OAAOA,OAAO,OAAO;IAEzB,OAAO;AACX;AAEO,MAAMC,kBAAkBC,wBAAwB;IACnD,MAAMC,YAAYC;IAClB,MAAMC,OAAOR,oBAAoBM,UAAU,EAAE,CAAC,OAAO;IACrD,OAAO,WAAP,GAAO,oBAACG,YAAUA;QAAC,UAAS;QAAW,OAAOD,QAAQ;QAAW,QAAQE;;AAC7E"}
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ export declare const UserPromptTab: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
3
+ readonly type: () => React.JSX.Element;
4
+ };
@@ -0,0 +1,18 @@
1
+ import react from "react";
2
+ import { CodeEditor } from "@webiny/admin-ui";
3
+ import { createReactiveComponent } from "@webiny/app-admin";
4
+ import { useAuditLogDetailsPresenter } from "../feature.js";
5
+ import { EDITOR_HEIGHT } from "./shared.js";
6
+ const UserPromptTab = createReactiveComponent(()=>{
7
+ const presenter = useAuditLogDetailsPresenter();
8
+ const before = presenter.vm.content.before;
9
+ const text = before?.prompt ?? "";
10
+ return /*#__PURE__*/ react.createElement(CodeEditor, {
11
+ language: "markdown",
12
+ value: text || "(empty)",
13
+ height: EDITOR_HEIGHT
14
+ });
15
+ });
16
+ export { UserPromptTab };
17
+
18
+ //# sourceMappingURL=UserPromptTab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views/Logs/Preview/tabs/UserPromptTab.js","sources":["../../../../../src/views/Logs/Preview/tabs/UserPromptTab.tsx"],"sourcesContent":["import React from \"react\";\nimport { CodeEditor } from \"@webiny/admin-ui\";\nimport { createReactiveComponent } from \"@webiny/app-admin\";\nimport { useAuditLogDetailsPresenter } from \"~/views/Logs/Preview/feature.js\";\nimport { EDITOR_HEIGHT, type AiAuditPayload } from \"./shared.js\";\n\nexport const UserPromptTab = createReactiveComponent(() => {\n const presenter = useAuditLogDetailsPresenter();\n const before = presenter.vm.content.before as AiAuditPayload[\"before\"];\n const text = before?.prompt ?? \"\";\n return <CodeEditor language=\"markdown\" value={text || \"(empty)\"} height={EDITOR_HEIGHT} />;\n});\n"],"names":["UserPromptTab","createReactiveComponent","presenter","useAuditLogDetailsPresenter","before","text","CodeEditor","EDITOR_HEIGHT"],"mappings":";;;;;AAMO,MAAMA,gBAAgBC,wBAAwB;IACjD,MAAMC,YAAYC;IAClB,MAAMC,SAASF,UAAU,EAAE,CAAC,OAAO,CAAC,MAAM;IAC1C,MAAMG,OAAOD,QAAQ,UAAU;IAC/B,OAAO,WAAP,GAAO,oBAACE,YAAUA;QAAC,UAAS;QAAW,OAAOD,QAAQ;QAAW,QAAQE;;AAC7E"}
@@ -0,0 +1,28 @@
1
+ import type { IAuditLog } from "../../../../types.js";
2
+ export declare const EDITOR_HEIGHT = "calc(100vh - 350px)";
3
+ export interface AiAuditPayload {
4
+ before?: {
5
+ model?: string;
6
+ system?: string | {
7
+ content?: string;
8
+ role?: string;
9
+ };
10
+ prompt?: string;
11
+ tools?: string[];
12
+ };
13
+ after?: {
14
+ status?: "success" | "error";
15
+ duration?: number;
16
+ text?: string;
17
+ usage?: unknown;
18
+ finishReason?: string;
19
+ steps?: number;
20
+ toolCalls?: number;
21
+ error?: {
22
+ message?: string;
23
+ name?: string;
24
+ };
25
+ };
26
+ }
27
+ export declare function isAiGenerateText(auditLog: IAuditLog): boolean;
28
+ export declare function hasAfter(auditLog: IAuditLog): boolean;
@@ -0,0 +1,16 @@
1
+ const EDITOR_HEIGHT = "calc(100vh - 350px)";
2
+ function isAiGenerateText(auditLog) {
3
+ return "AI" === auditLog.app && "TEXT" === auditLog.entity.value;
4
+ }
5
+ function hasAfter(auditLog) {
6
+ if (!isAiGenerateText(auditLog)) return false;
7
+ try {
8
+ const content = JSON.parse(auditLog.content);
9
+ return !!content.after;
10
+ } catch {
11
+ return false;
12
+ }
13
+ }
14
+ export { EDITOR_HEIGHT, hasAfter, isAiGenerateText };
15
+
16
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views/Logs/Preview/tabs/shared.js","sources":["../../../../../src/views/Logs/Preview/tabs/shared.ts"],"sourcesContent":["import type { IAuditLog } from \"~/types.js\";\n\nexport const EDITOR_HEIGHT = \"calc(100vh - 350px)\";\n\nexport interface AiAuditPayload {\n before?: {\n model?: string;\n system?: string | { content?: string; role?: string };\n prompt?: string;\n tools?: string[];\n };\n after?: {\n status?: \"success\" | \"error\";\n duration?: number;\n text?: string;\n usage?: unknown;\n finishReason?: string;\n steps?: number;\n toolCalls?: number;\n error?: { message?: string; name?: string };\n };\n}\n\nexport function isAiGenerateText(auditLog: IAuditLog): boolean {\n return auditLog.app === \"AI\" && auditLog.entity.value === \"TEXT\";\n}\n\nexport function hasAfter(auditLog: IAuditLog): boolean {\n if (!isAiGenerateText(auditLog)) {\n return false;\n }\n try {\n const content = JSON.parse(auditLog.content);\n return !!content.after;\n } catch {\n return false;\n }\n}\n"],"names":["EDITOR_HEIGHT","isAiGenerateText","auditLog","hasAfter","content","JSON"],"mappings":"AAEO,MAAMA,gBAAgB;AAqBtB,SAASC,iBAAiBC,QAAmB;IAChD,OAAOA,AAAiB,SAAjBA,SAAS,GAAG,IAAaA,AAA0B,WAA1BA,SAAS,MAAM,CAAC,KAAK;AACzD;AAEO,SAASC,SAASD,QAAmB;IACxC,IAAI,CAACD,iBAAiBC,WAClB,OAAO;IAEX,IAAI;QACA,MAAME,UAAUC,KAAK,KAAK,CAACH,SAAS,OAAO;QAC3C,OAAO,CAAC,CAACE,QAAQ,KAAK;IAC1B,EAAE,OAAM;QACJ,OAAO;IACX;AACJ"}
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
- import type { DataTableSorting, OnDataTableSortingChange } from "@webiny/admin-ui";
3
- import type { ActionType, IAuditLog } from "../../../types.js";
2
+ import { type DataTableSorting, type OnDataTableSortingChange } from "@webiny/admin-ui";
3
+ import type { IAuditLog } from "../../../types.js";
4
4
  interface ActionProps {
5
5
  label: string;
6
- value: ActionType;
6
+ value: string;
7
7
  }
8
8
  export declare const Action: ({ label, value }: ActionProps) => React.JSX.Element;
9
9
  export interface TableProps {
@@ -15,9 +15,6 @@ export interface TableProps {
15
15
  hasAccessToUsers: boolean;
16
16
  }
17
17
  export interface EntryWithPreview extends IAuditLog {
18
- /**
19
- * We need the preview property because data table is expecting it in columns.
20
- */
21
18
  preview?: string;
22
19
  }
23
20
  export declare const Table: React.ForwardRefExoticComponent<TableProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,11 +1,11 @@
1
1
  import react, { forwardRef, useMemo } from "react";
2
2
  import { addMinutes, format } from "date-fns";
3
- import { ReactComponent } from "@webiny/icons/info.svg";
4
- import { DataTable, IconButton, Tooltip } from "@webiny/admin-ui";
3
+ import { ReactComponent } from "@webiny/icons/search.svg";
4
+ import { Button, DataTable, Tooltip } from "@webiny/admin-ui";
5
5
  import { Text } from "../../../components/Text.js";
6
- import { ActionWrapper, TextGray, TimezoneText, appColumn, previewColumn, wideColumn } from "./styled.js";
7
- const Action = ({ label, value })=>/*#__PURE__*/ react.createElement(ActionWrapper, {
8
- value: value
6
+ import { getActionColorClasses } from "./styled.js";
7
+ const Action = ({ label, value })=>/*#__PURE__*/ react.createElement("div", {
8
+ className: `px-sm w-fit border border-solid rounded-[5px] ${getActionColorClasses(value)}`
9
9
  }, /*#__PURE__*/ react.createElement(Text, {
10
10
  use: "subtitle1"
11
11
  }, label));
@@ -21,9 +21,11 @@ const Table = /*#__PURE__*/ forwardRef((props, ref)=>{
21
21
  content: `UTC: ${format(addMinutes(date, date.getTimezoneOffset()), "yyyy-MM-dd HH:mm:ss")}`,
22
22
  trigger: /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(Text, {
23
23
  use: "subtitle1"
24
- }, format(date, "yyyy-MM-dd HH:mm:ss")), /*#__PURE__*/ react.createElement(TimezoneText, {
24
+ }, format(date, "yyyy-MM-dd HH:mm:ss")), /*#__PURE__*/ react.createElement("span", {
25
+ className: "px-xs text-neutral-dimmed"
26
+ }, /*#__PURE__*/ react.createElement(Text, {
25
27
  use: "body2"
26
- }, format(date, "(O)")))
28
+ }, format(date, "(O)"))))
27
29
  });
28
30
  },
29
31
  enableSorting: true
@@ -31,10 +33,15 @@ const Table = /*#__PURE__*/ forwardRef((props, ref)=>{
31
33
  app: {
32
34
  header: "App/Entity",
33
35
  cell: (row)=>/*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(Text, {
34
- use: "subtitle1"
35
- }, row.app), row.entity && /*#__PURE__*/ react.createElement(TextGray, {
36
+ use: "subtitle1",
37
+ className: "text-neutral-strong"
38
+ }, row.app), row.entity && /*#__PURE__*/ react.createElement(react.Fragment, null, "\xa0/\xa0", /*#__PURE__*/ react.createElement("span", {
39
+ className: "text-neutral-strong"
40
+ }, /*#__PURE__*/ react.createElement(Text, {
36
41
  use: "body2"
37
- }, ` [Entity: ${row.entity.label}]`), /*#__PURE__*/ react.createElement("br", null), /*#__PURE__*/ react.createElement(TextGray, {
42
+ }, row.entity.label))), /*#__PURE__*/ react.createElement("br", null), /*#__PURE__*/ react.createElement("span", {
43
+ className: "text-neutral-dimmed"
44
+ }, /*#__PURE__*/ react.createElement(Text, {
38
45
  use: "body2"
39
46
  }, "ID: "), row.entity.link ? /*#__PURE__*/ react.createElement("a", {
40
47
  href: row.entity.link,
@@ -43,8 +50,8 @@ const Table = /*#__PURE__*/ forwardRef((props, ref)=>{
43
50
  use: "body2"
44
51
  }, row.entityId)) : /*#__PURE__*/ react.createElement(Text, {
45
52
  use: "body2"
46
- }, row.entityId)),
47
- className: appColumn
53
+ }, row.entityId))),
54
+ className: "!w-[280px]"
48
55
  },
49
56
  action: {
50
57
  header: "Action",
@@ -58,7 +65,7 @@ const Table = /*#__PURE__*/ forwardRef((props, ref)=>{
58
65
  cell: (row)=>/*#__PURE__*/ react.createElement(Text, {
59
66
  use: "subtitle1"
60
67
  }, row.message),
61
- className: wideColumn
68
+ className: "!w-auto"
62
69
  },
63
70
  ...hasAccessToUsers && {
64
71
  createdBy: {
@@ -73,11 +80,13 @@ const Table = /*#__PURE__*/ forwardRef((props, ref)=>{
73
80
  },
74
81
  preview: {
75
82
  header: "",
76
- cell: (auditLog)=>/*#__PURE__*/ react.createElement(IconButton, {
83
+ cell: (auditLog)=>/*#__PURE__*/ react.createElement(Button, {
84
+ variant: "secondary",
77
85
  onClick: ()=>handleRecordSelect(auditLog),
78
- icon: /*#__PURE__*/ react.createElement(ReactComponent, null)
86
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
87
+ text: "Details"
79
88
  }),
80
- className: previewColumn
89
+ className: "!w-[100px]"
81
90
  }
82
91
  };
83
92
  const tableSorting = useMemo(()=>{
@@ -1 +1 @@
1
- {"version":3,"file":"views/Logs/Table/Table.js","sources":["../../../../src/views/Logs/Table/Table.tsx"],"sourcesContent":["import React, { forwardRef, useMemo } from \"react\";\nimport { addMinutes, format } from \"date-fns\";\n\nimport { ReactComponent as PreviewIcon } from \"@webiny/icons/info.svg\";\nimport type {\n DataTableColumns,\n DataTableSorting,\n OnDataTableSortingChange\n} from \"@webiny/admin-ui\";\nimport { DataTable, IconButton, Tooltip } from \"@webiny/admin-ui\";\n\nimport { Text } from \"~/components/Text.js\";\nimport {\n ActionWrapper,\n appColumn,\n previewColumn,\n TextGray,\n TimezoneText,\n wideColumn\n} from \"./styled.js\";\nimport type { ActionType, IAuditLog } from \"~/types.js\";\n\ninterface ActionProps {\n label: string;\n value: ActionType;\n}\n\nexport const Action = ({ label, value }: ActionProps) => {\n return (\n <ActionWrapper value={value}>\n <Text use={\"subtitle1\"}>{label}</Text>\n </ActionWrapper>\n );\n};\n\nexport interface TableProps {\n records: IAuditLog[];\n loading?: boolean;\n handleRecordSelect: (auditLog: IAuditLog) => void;\n sorting: DataTableSorting;\n onSortingChange: OnDataTableSortingChange;\n hasAccessToUsers: boolean;\n}\n\nexport interface EntryWithPreview extends IAuditLog {\n /**\n * We need the preview property because data table is expecting it in columns.\n */\n preview?: string;\n}\n\nexport const Table = forwardRef<HTMLDivElement, TableProps>((props, ref) => {\n const { records, loading, handleRecordSelect, sorting, onSortingChange, hasAccessToUsers } =\n props;\n\n const columns: DataTableColumns<EntryWithPreview> = {\n createdOn: {\n header: \"Timestamp\",\n cell: (row: EntryWithPreview) => {\n const date = new Date(row.createdOn);\n\n return (\n <Tooltip\n side=\"right\"\n content={`UTC: ${format(\n addMinutes(date, date.getTimezoneOffset()),\n \"yyyy-MM-dd HH:mm:ss\"\n )}`}\n trigger={\n <>\n <Text use={\"subtitle1\"}>{format(date, \"yyyy-MM-dd HH:mm:ss\")}</Text>\n <TimezoneText use={\"body2\"}>{format(date, \"(O)\")}</TimezoneText>\n </>\n }\n />\n );\n },\n enableSorting: true\n },\n app: {\n header: \"App/Entity\",\n cell: (row: EntryWithPreview) => (\n <>\n <Text use={\"subtitle1\"}>{row.app}</Text>\n {row.entity && (\n <TextGray use={\"body2\"}>{` [Entity: ${row.entity.label}]`}</TextGray>\n )}\n <br />\n <TextGray use={\"body2\"}>{`ID: `}</TextGray>\n {row.entity.link ? (\n <a href={row.entity.link} target={\"blank\"}>\n <Text use={\"body2\"}>{row.entityId}</Text>\n </a>\n ) : (\n <Text use={\"body2\"}>{row.entityId}</Text>\n )}\n </>\n ),\n className: appColumn\n },\n action: {\n header: \"Action\",\n cell: (row: EntryWithPreview) => (\n <Action label={row.action.label} value={row.action.value} />\n )\n },\n message: {\n header: \"Message\",\n cell: (row: EntryWithPreview) => <Text use={\"subtitle1\"}>{row.message}</Text>,\n className: wideColumn\n },\n ...(hasAccessToUsers && {\n createdBy: {\n header: \"Initiator\",\n cell: (row: EntryWithPreview) => (\n <a href={`/admin-users?id=${row.createdBy.id}`} target={\"blank\"}>\n <Text use={\"subtitle1\"}>{row.createdBy.displayName || \"-\"}</Text>\n </a>\n )\n }\n }),\n preview: {\n header: \"\",\n cell: (auditLog: EntryWithPreview) => (\n <IconButton onClick={() => handleRecordSelect(auditLog)} icon={<PreviewIcon />} />\n ),\n className: previewColumn\n }\n };\n\n const tableSorting = useMemo(() => {\n if (!Array.isArray(sorting) || sorting.length === 0) {\n return [\n {\n id: \"savedOn\",\n desc: true\n }\n ];\n }\n\n return sorting;\n }, [sorting]);\n\n return (\n <div ref={ref}>\n <DataTable\n columns={columns}\n data={records}\n loading={loading}\n stickyHeader={true}\n sorting={tableSorting}\n onSortingChange={onSortingChange}\n />\n </div>\n );\n});\n\nTable.displayName = \"Table\";\n"],"names":["Action","label","value","ActionWrapper","Text","Table","forwardRef","props","ref","records","loading","handleRecordSelect","sorting","onSortingChange","hasAccessToUsers","columns","row","date","Date","Tooltip","format","addMinutes","TimezoneText","TextGray","appColumn","wideColumn","auditLog","IconButton","PreviewIcon","previewColumn","tableSorting","useMemo","Array","DataTable"],"mappings":"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"}
1
+ {"version":3,"file":"views/Logs/Table/Table.js","sources":["../../../../src/views/Logs/Table/Table.tsx"],"sourcesContent":["import React, { forwardRef, useMemo } from \"react\";\nimport { addMinutes, format } from \"date-fns\";\nimport { ReactComponent as PreviewIcon } from \"@webiny/icons/search.svg\";\nimport {\n Button,\n type DataTableColumns,\n type DataTableSorting,\n type OnDataTableSortingChange\n} from \"@webiny/admin-ui\";\nimport { DataTable, Tooltip } from \"@webiny/admin-ui\";\n\nimport { Text } from \"~/components/Text.js\";\nimport { getActionColorClasses } from \"./styled.js\";\nimport type { IAuditLog } from \"~/types.js\";\n\ninterface ActionProps {\n label: string;\n value: string;\n}\n\nexport const Action = ({ label, value }: ActionProps) => {\n return (\n <div\n className={`px-sm w-fit border border-solid rounded-[5px] ${getActionColorClasses(value)}`}\n >\n <Text use={\"subtitle1\"}>{label}</Text>\n </div>\n );\n};\n\nexport interface TableProps {\n records: IAuditLog[];\n loading?: boolean;\n handleRecordSelect: (auditLog: IAuditLog) => void;\n sorting: DataTableSorting;\n onSortingChange: OnDataTableSortingChange;\n hasAccessToUsers: boolean;\n}\n\nexport interface EntryWithPreview extends IAuditLog {\n preview?: string;\n}\n\nexport const Table = forwardRef<HTMLDivElement, TableProps>((props, ref) => {\n const { records, loading, handleRecordSelect, sorting, onSortingChange, hasAccessToUsers } =\n props;\n\n const columns: DataTableColumns<EntryWithPreview> = {\n createdOn: {\n header: \"Timestamp\",\n cell: (row: EntryWithPreview) => {\n const date = new Date(row.createdOn);\n\n return (\n <Tooltip\n side=\"right\"\n content={`UTC: ${format(\n addMinutes(date, date.getTimezoneOffset()),\n \"yyyy-MM-dd HH:mm:ss\"\n )}`}\n trigger={\n <>\n <Text use={\"subtitle1\"}>{format(date, \"yyyy-MM-dd HH:mm:ss\")}</Text>\n <span className={\"px-xs text-neutral-dimmed\"}>\n <Text use={\"body2\"}>{format(date, \"(O)\")}</Text>\n </span>\n </>\n }\n />\n );\n },\n enableSorting: true\n },\n app: {\n header: \"App/Entity\",\n cell: (row: EntryWithPreview) => (\n <>\n <Text use={\"subtitle1\"} className={\"text-neutral-strong\"}>\n {row.app}\n </Text>\n {row.entity && (\n <>\n &nbsp;/&nbsp;\n <span className={\"text-neutral-strong\"}>\n <Text use={\"body2\"}>{row.entity.label}</Text>\n </span>\n </>\n )}\n <br />\n <span className={\"text-neutral-dimmed\"}>\n <Text use={\"body2\"}>{`ID: `}</Text>\n {row.entity.link ? (\n <a href={row.entity.link} target={\"blank\"}>\n <Text use={\"body2\"}>{row.entityId}</Text>\n </a>\n ) : (\n <Text use={\"body2\"}>{row.entityId}</Text>\n )}\n </span>\n </>\n ),\n className: \"!w-[280px]\"\n },\n action: {\n header: \"Action\",\n cell: (row: EntryWithPreview) => (\n <Action label={row.action.label} value={row.action.value} />\n )\n },\n message: {\n header: \"Message\",\n cell: (row: EntryWithPreview) => <Text use={\"subtitle1\"}>{row.message}</Text>,\n className: \"!w-auto\"\n },\n ...(hasAccessToUsers && {\n createdBy: {\n header: \"Initiator\",\n cell: (row: EntryWithPreview) => (\n <a href={`/admin-users?id=${row.createdBy.id}`} target={\"blank\"}>\n <Text use={\"subtitle1\"}>{row.createdBy.displayName || \"-\"}</Text>\n </a>\n )\n }\n }),\n preview: {\n header: \"\",\n cell: (auditLog: EntryWithPreview) => (\n <Button\n variant={\"secondary\"}\n onClick={() => handleRecordSelect(auditLog)}\n icon={<PreviewIcon />}\n text={\"Details\"}\n />\n ),\n className: \"!w-[100px]\"\n }\n };\n\n const tableSorting = useMemo(() => {\n if (!Array.isArray(sorting) || sorting.length === 0) {\n return [\n {\n id: \"savedOn\",\n desc: true\n }\n ];\n }\n\n return sorting;\n }, [sorting]);\n\n return (\n <div ref={ref}>\n <DataTable\n columns={columns}\n data={records}\n loading={loading}\n stickyHeader={true}\n sorting={tableSorting}\n onSortingChange={onSortingChange}\n />\n </div>\n );\n});\n\nTable.displayName = \"Table\";\n"],"names":["Action","label","value","getActionColorClasses","Text","Table","forwardRef","props","ref","records","loading","handleRecordSelect","sorting","onSortingChange","hasAccessToUsers","columns","row","date","Date","Tooltip","format","addMinutes","auditLog","Button","PreviewIcon","tableSorting","useMemo","Array","DataTable"],"mappings":"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"}