@orbe-agro/client-core 5.6.259 → 5.6.261
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/@ecme/assets/styles/app.css +23 -3
- package/dist/@ecme/assets/styles/tailwind/index.css +25 -3
- package/dist/@ecme/components/layouts/PostLoginLayout/PostLoginLayout.js +2 -1
- package/dist/@ecme/components/layouts/PostLoginLayout/PostLoginLayout.js.map +1 -1
- package/dist/@ecme/components/template/Footer.js +1 -1
- package/dist/@ecme/components/template/OrbeAiWidget/OrbeAiChatDrawer.js +121 -0
- package/dist/@ecme/components/template/OrbeAiWidget/OrbeAiChatDrawer.js.map +1 -0
- package/dist/@ecme/components/template/OrbeAiWidget/OrbeAiWidget.js +47 -18
- package/dist/@ecme/components/template/OrbeAiWidget/OrbeAiWidget.js.map +1 -1
- package/dist/@ecme/components/template/OrbeAiWidget/useResizablePanel.js +45 -31
- package/dist/@ecme/components/template/OrbeAiWidget/useResizablePanel.js.map +1 -1
- package/dist/@ecme/components/ui/Dropdown/DropdownMenu.js +5 -1
- package/dist/@ecme/components/ui/Dropdown/DropdownMenu.js.map +1 -1
- package/dist/@ecme/index.js +4 -1
- package/dist/@ecme/services/AiService.js +22 -0
- package/dist/@ecme/services/AiService.js.map +1 -1
- package/dist/@ecme/services/index.js +4 -1
- package/dist/@ecme/views/concepts/ai/Chat/components/ChatHistory.js +9 -23
- package/dist/@ecme/views/concepts/ai/Chat/components/ChatHistory.js.map +1 -1
- package/dist/@ecme/views/concepts/ai/Chat/components/ChatHistoryItem.js +6 -16
- package/dist/@ecme/views/concepts/ai/Chat/components/ChatHistoryItem.js.map +1 -1
- package/dist/@ecme/views/concepts/ai/Chat/components/ChatHistoryRenameDialog.js +10 -7
- package/dist/@ecme/views/concepts/ai/Chat/components/ChatHistoryRenameDialog.js.map +1 -1
- package/dist/@ecme/views/concepts/ai/Chat/components/ChatView.js +6 -4
- package/dist/@ecme/views/concepts/ai/Chat/components/ChatView.js.map +1 -1
- package/dist/@ecme/views/concepts/ai/Chat/hooks/useChatConversations.js +83 -0
- package/dist/@ecme/views/concepts/ai/Chat/hooks/useChatConversations.js.map +1 -0
- package/dist/@ecme/views/concepts/ai/Chat/hooks/useChatSend.js +3 -2
- package/dist/@ecme/views/concepts/ai/Chat/hooks/useChatSend.js.map +1 -1
- package/dist/@ecme/views/concepts/ai/Chat/hooks/useConversationMessages.js +37 -0
- package/dist/@ecme/views/concepts/ai/Chat/hooks/useConversationMessages.js.map +1 -0
- package/dist/@ecme/views/concepts/ai/Chat/store/generativeChatStore.js +25 -1
- package/dist/@ecme/views/concepts/ai/Chat/store/generativeChatStore.js.map +1 -1
- package/dist/@ecme/views/concepts/ai/Chat/utils.js +16 -1
- package/dist/@ecme/views/concepts/ai/Chat/utils.js.map +1 -1
- package/dist/@types/@ecme/components/layouts/PostLoginLayout/PostLoginLayout.d.ts.map +1 -1
- package/dist/@types/@ecme/components/template/OrbeAiWidget/OrbeAiChatDrawer.d.ts +14 -0
- package/dist/@types/@ecme/components/template/OrbeAiWidget/OrbeAiChatDrawer.d.ts.map +1 -0
- package/dist/@types/@ecme/components/template/OrbeAiWidget/OrbeAiWidget.d.ts.map +1 -1
- package/dist/@types/@ecme/components/template/OrbeAiWidget/useResizablePanel.d.ts +12 -5
- package/dist/@types/@ecme/components/template/OrbeAiWidget/useResizablePanel.d.ts.map +1 -1
- package/dist/@types/@ecme/components/ui/Dropdown/DropdownMenu.d.ts +2 -0
- package/dist/@types/@ecme/components/ui/Dropdown/DropdownMenu.d.ts.map +1 -1
- package/dist/@types/@ecme/services/AiService.d.ts +5 -0
- package/dist/@types/@ecme/services/AiService.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ChatHistory.d.ts +3 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ChatHistory.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ChatHistoryItem.d.ts +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ChatHistoryItem.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ChatHistoryRenameDialog.d.ts +5 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ChatHistoryRenameDialog.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ChatView.d.ts +8 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ChatView.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/hooks/useChatConversations.d.ts +12 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/hooks/useChatConversations.d.ts.map +1 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/hooks/useChatSend.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/hooks/useConversationMessages.d.ts +12 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/hooks/useConversationMessages.d.ts.map +1 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/store/generativeChatStore.d.ts +4 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/store/generativeChatStore.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/types.d.ts +24 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/types.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/utils.d.ts +13 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/utils.d.ts.map +1 -1
- package/dist/@types/base/configs/endpoints.config/endpoints.navigation.d.ts +8 -0
- package/dist/@types/base/configs/endpoints.config/endpoints.navigation.d.ts.map +1 -1
- package/dist/@types/base/configs/endpoints.config/transportadora/contratoFrete.d.ts +8 -0
- package/dist/@types/base/configs/endpoints.config/transportadora/contratoFrete.d.ts.map +1 -1
- package/dist/@types/base/services/modules/transportadora/ContratoFrete/ContratoFreteService.d.ts +2 -0
- package/dist/@types/base/services/modules/transportadora/ContratoFrete/ContratoFreteService.d.ts.map +1 -1
- package/dist/base/assets/styles/init.css +23 -4
- package/dist/base/configs/endpoints.config/transportadora/contratoFrete.js +3 -1
- package/dist/base/configs/endpoints.config/transportadora/contratoFrete.js.map +1 -1
- package/dist/base/index.js +3 -1
- package/dist/base/services/index.js +3 -1
- package/dist/base/services/modules/index.js +3 -1
- package/dist/base/services/modules/transportadora/ContratoFrete/ContratoFreteService.js +14 -0
- package/dist/base/services/modules/transportadora/ContratoFrete/ContratoFreteService.js.map +1 -1
- package/dist/base/services/modules/transportadora/index.js +3 -1
- package/lib/@ecme/components/layouts/PostLoginLayout/PostLoginLayout.tsx +4 -1
- package/lib/@ecme/components/template/OrbeAiWidget/OrbeAiChatDrawer.tsx +140 -0
- package/lib/@ecme/components/template/OrbeAiWidget/OrbeAiWidget.tsx +48 -16
- package/lib/@ecme/components/template/OrbeAiWidget/useResizablePanel.ts +72 -37
- package/lib/@ecme/components/ui/Dropdown/DropdownMenu.tsx +7 -1
- package/lib/@ecme/services/AiService.ts +24 -0
- package/lib/@ecme/views/concepts/ai/Chat/components/ChatHistory.tsx +11 -27
- package/lib/@ecme/views/concepts/ai/Chat/components/ChatHistoryItem.tsx +7 -13
- package/lib/@ecme/views/concepts/ai/Chat/components/ChatHistoryRenameDialog.tsx +17 -8
- package/lib/@ecme/views/concepts/ai/Chat/components/ChatView.tsx +17 -4
- package/lib/@ecme/views/concepts/ai/Chat/hooks/useChatConversations.tsx +128 -0
- package/lib/@ecme/views/concepts/ai/Chat/hooks/useChatSend.ts +3 -2
- package/lib/@ecme/views/concepts/ai/Chat/hooks/useConversationMessages.ts +68 -0
- package/lib/@ecme/views/concepts/ai/Chat/store/generativeChatStore.ts +44 -1
- package/lib/@ecme/views/concepts/ai/Chat/types.ts +28 -0
- package/lib/@ecme/views/concepts/ai/Chat/utils.ts +33 -0
- package/lib/base/configs/endpoints.config/transportadora/contratoFrete.ts +2 -0
- package/lib/base/services/modules/transportadora/ContratoFrete/ContratoFreteService.ts +14 -0
- package/package.json +1 -1
|
@@ -5079,6 +5079,10 @@ video {
|
|
|
5079
5079
|
.inset-2{
|
|
5080
5080
|
inset: 0.5rem;
|
|
5081
5081
|
}
|
|
5082
|
+
.inset-y-0{
|
|
5083
|
+
top: 0px;
|
|
5084
|
+
bottom: 0px;
|
|
5085
|
+
}
|
|
5082
5086
|
.-bottom-2{
|
|
5083
5087
|
bottom: -0.5rem;
|
|
5084
5088
|
}
|
|
@@ -5151,6 +5155,9 @@ video {
|
|
|
5151
5155
|
.top-full{
|
|
5152
5156
|
top: 100%;
|
|
5153
5157
|
}
|
|
5158
|
+
.\!z-\[10000\]{
|
|
5159
|
+
z-index: 10000 !important;
|
|
5160
|
+
}
|
|
5154
5161
|
.z-10{
|
|
5155
5162
|
z-index: 10;
|
|
5156
5163
|
}
|
|
@@ -5831,6 +5838,9 @@ video {
|
|
|
5831
5838
|
.w-\[750px\]{
|
|
5832
5839
|
width: 750px;
|
|
5833
5840
|
}
|
|
5841
|
+
.w-\[85\%\]{
|
|
5842
|
+
width: 85%;
|
|
5843
|
+
}
|
|
5834
5844
|
.w-\[950px\]{
|
|
5835
5845
|
width: 950px;
|
|
5836
5846
|
}
|
|
@@ -5995,6 +6005,9 @@ video {
|
|
|
5995
6005
|
.grow{
|
|
5996
6006
|
flex-grow: 1;
|
|
5997
6007
|
}
|
|
6008
|
+
.origin-bottom-right{
|
|
6009
|
+
transform-origin: bottom right;
|
|
6010
|
+
}
|
|
5998
6011
|
.-translate-x-1\/2{
|
|
5999
6012
|
--tw-translate-x: -50%;
|
|
6000
6013
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
@@ -6506,6 +6519,9 @@ video {
|
|
|
6506
6519
|
--tw-bg-opacity: 1;
|
|
6507
6520
|
background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));
|
|
6508
6521
|
}
|
|
6522
|
+
.bg-black\/40{
|
|
6523
|
+
background-color: rgb(0 0 0 / 0.4);
|
|
6524
|
+
}
|
|
6509
6525
|
.bg-black\/75{
|
|
6510
6526
|
background-color: rgb(0 0 0 / 0.75);
|
|
6511
6527
|
}
|
|
@@ -7698,9 +7714,6 @@ video {
|
|
|
7698
7714
|
.hover\:bg-primary:hover{
|
|
7699
7715
|
background-color: var(--primary);
|
|
7700
7716
|
}
|
|
7701
|
-
.hover\:bg-primary-deep:hover{
|
|
7702
|
-
background-color: var(--primary-deep);
|
|
7703
|
-
}
|
|
7704
7717
|
.hover\:bg-primary-mild:hover{
|
|
7705
7718
|
background-color: var(--primary-mild);
|
|
7706
7719
|
}
|
|
@@ -8419,10 +8432,17 @@ video {
|
|
|
8419
8432
|
.sm\:justify-end{
|
|
8420
8433
|
justify-content: flex-end;
|
|
8421
8434
|
}
|
|
8435
|
+
.sm\:gap-2{
|
|
8436
|
+
gap: 0.5rem;
|
|
8437
|
+
}
|
|
8422
8438
|
.sm\:px-0{
|
|
8423
8439
|
padding-left: 0px;
|
|
8424
8440
|
padding-right: 0px;
|
|
8425
8441
|
}
|
|
8442
|
+
.sm\:px-4{
|
|
8443
|
+
padding-left: 1rem;
|
|
8444
|
+
padding-right: 1rem;
|
|
8445
|
+
}
|
|
8426
8446
|
.sm\:px-6{
|
|
8427
8447
|
padding-left: 1.5rem;
|
|
8428
8448
|
padding-right: 1.5rem;
|
|
@@ -1156,6 +1156,10 @@ video {
|
|
|
1156
1156
|
.inset-2 {
|
|
1157
1157
|
inset: 0.5rem;
|
|
1158
1158
|
}
|
|
1159
|
+
.inset-y-0 {
|
|
1160
|
+
top: 0px;
|
|
1161
|
+
bottom: 0px;
|
|
1162
|
+
}
|
|
1159
1163
|
.-bottom-2 {
|
|
1160
1164
|
bottom: -0.5rem;
|
|
1161
1165
|
}
|
|
@@ -1228,6 +1232,9 @@ video {
|
|
|
1228
1232
|
.top-full {
|
|
1229
1233
|
top: 100%;
|
|
1230
1234
|
}
|
|
1235
|
+
.\!z-\[10000\] {
|
|
1236
|
+
z-index: 10000 !important;
|
|
1237
|
+
}
|
|
1231
1238
|
.z-10 {
|
|
1232
1239
|
z-index: 10;
|
|
1233
1240
|
}
|
|
@@ -1908,6 +1915,9 @@ video {
|
|
|
1908
1915
|
.w-\[750px\] {
|
|
1909
1916
|
width: 750px;
|
|
1910
1917
|
}
|
|
1918
|
+
.w-\[85\%\] {
|
|
1919
|
+
width: 85%;
|
|
1920
|
+
}
|
|
1911
1921
|
.w-\[950px\] {
|
|
1912
1922
|
width: 950px;
|
|
1913
1923
|
}
|
|
@@ -2072,6 +2082,9 @@ video {
|
|
|
2072
2082
|
.grow {
|
|
2073
2083
|
flex-grow: 1;
|
|
2074
2084
|
}
|
|
2085
|
+
.origin-bottom-right {
|
|
2086
|
+
transform-origin: bottom right;
|
|
2087
|
+
}
|
|
2075
2088
|
.-translate-x-1\/2 {
|
|
2076
2089
|
--tw-translate-x: -50%;
|
|
2077
2090
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
@@ -2585,6 +2598,9 @@ video {
|
|
|
2585
2598
|
--tw-bg-opacity: 1;
|
|
2586
2599
|
background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));
|
|
2587
2600
|
}
|
|
2601
|
+
.bg-black\/40 {
|
|
2602
|
+
background-color: rgb(0 0 0 / 0.4);
|
|
2603
|
+
}
|
|
2588
2604
|
.bg-black\/75 {
|
|
2589
2605
|
background-color: rgb(0 0 0 / 0.75);
|
|
2590
2606
|
}
|
|
@@ -3777,9 +3793,6 @@ video {
|
|
|
3777
3793
|
.hover\:bg-primary:hover {
|
|
3778
3794
|
background-color: var(--primary);
|
|
3779
3795
|
}
|
|
3780
|
-
.hover\:bg-primary-deep:hover {
|
|
3781
|
-
background-color: var(--primary-deep);
|
|
3782
|
-
}
|
|
3783
3796
|
.hover\:bg-primary-mild:hover {
|
|
3784
3797
|
background-color: var(--primary-mild);
|
|
3785
3798
|
}
|
|
@@ -4529,11 +4542,20 @@ video {
|
|
|
4529
4542
|
justify-content: flex-end;
|
|
4530
4543
|
}
|
|
4531
4544
|
|
|
4545
|
+
.sm\:gap-2 {
|
|
4546
|
+
gap: 0.5rem;
|
|
4547
|
+
}
|
|
4548
|
+
|
|
4532
4549
|
.sm\:px-0 {
|
|
4533
4550
|
padding-left: 0px;
|
|
4534
4551
|
padding-right: 0px;
|
|
4535
4552
|
}
|
|
4536
4553
|
|
|
4554
|
+
.sm\:px-4 {
|
|
4555
|
+
padding-left: 1rem;
|
|
4556
|
+
padding-right: 1rem;
|
|
4557
|
+
}
|
|
4558
|
+
|
|
4537
4559
|
.sm\:px-6 {
|
|
4538
4560
|
padding-left: 1.5rem;
|
|
4539
4561
|
padding-right: 1.5rem;
|
|
@@ -6,6 +6,7 @@ import { useLocation } from "react-router-dom";
|
|
|
6
6
|
import "../../../configs/index.js";
|
|
7
7
|
import GlobalLoading from "../../shared/loaders/GlobalLoading.js";
|
|
8
8
|
import "../../template/OrbeAiWidget/index.js";
|
|
9
|
+
import Can from "../../shared/Can.js";
|
|
9
10
|
import { protectedRoutes, publicRoutes } from "../../../configs/routes.config/routes.config.js";
|
|
10
11
|
import OrbeAiWidget from "../../template/OrbeAiWidget/OrbeAiWidget.js";
|
|
11
12
|
const layouts = {
|
|
@@ -38,7 +39,7 @@ const PostLoginLayout = ({
|
|
|
38
39
|
}, [location.pathname, layoutType]);
|
|
39
40
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
40
41
|
/* @__PURE__ */ jsx(GlobalLoading, {}),
|
|
41
|
-
/* @__PURE__ */ jsx(OrbeAiWidget, {}),
|
|
42
|
+
/* @__PURE__ */ jsx(Can, { I: "VISUALIZAR_CHAT_ORBE_AI", children: /* @__PURE__ */ jsx(OrbeAiWidget, {}) }),
|
|
42
43
|
/* @__PURE__ */ jsx(
|
|
43
44
|
Suspense,
|
|
44
45
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostLoginLayout.js","sources":["../../../../../lib/@ecme/components/layouts/PostLoginLayout/PostLoginLayout.tsx"],"sourcesContent":["import { lazy, Suspense, useMemo } from \"react\";\nimport {\n LAYOUT_COLLAPSIBLE_SIDE,\n LAYOUT_STACKED_SIDE,\n LAYOUT_TOP_BAR_CLASSIC,\n LAYOUT_FRAMELESS_SIDE,\n LAYOUT_CONTENT_OVERLAY,\n LAYOUT_BLANK,\n} from \"@/constants/theme.constant\";\nimport Loading from \"@/components/shared/Loading\";\nimport type { CommonProps } from \"@/@types/common\";\nimport type { LazyExoticComponent, JSX } from \"react\";\nimport type { LayoutType } from \"@/@types/theme\";\nimport { LinkRenderer } from \"../Layouts\";\nimport { useLocation } from \"react-router-dom\";\nimport { Routes } from \"@/@types\";\nimport { protectedRoutes, publicRoutes } from \"@/configs\";\nimport GlobalLoading from \"@/components/shared/loaders/GlobalLoading\";\nimport OrbeAiWidget from \"@/components/template/OrbeAiWidget\";\n\ntype Layouts = Record<\n string,\n LazyExoticComponent<<T extends CommonProps>(props: T) => JSX.Element>\n>;\n\ninterface PostLoginLayoutProps extends CommonProps {\n layoutType: LayoutType;\n linkRenderer?: LinkRenderer;\n pageTitle?: string;\n}\n\nconst layouts: Layouts = {\n [LAYOUT_COLLAPSIBLE_SIDE]: lazy(() => import(\"./components/CollapsibleSide\")),\n [LAYOUT_STACKED_SIDE]: lazy(() => import(\"./components/StackedSide\")),\n [LAYOUT_TOP_BAR_CLASSIC]: lazy(() => import(\"./components/TopBarClassic\")),\n [LAYOUT_FRAMELESS_SIDE]: lazy(() => import(\"./components/FrameLessSide\")),\n [LAYOUT_CONTENT_OVERLAY]: lazy(() => import(\"./components/ContentOverlay\")),\n [LAYOUT_BLANK]: lazy(() => import(\"./components/Blank\")),\n};\n\nconst findRouteByPath = (\n path: string,\n routes: Routes\n): Routes[0] | undefined => {\n for (const route of routes) {\n if (route.path === path) {\n return route;\n }\n }\n};\n\nconst PostLoginLayout = ({\n layoutType,\n children,\n linkRenderer,\n pageTitle,\n}: PostLoginLayoutProps) => {\n const location = useLocation();\n const AppLayout = useMemo(() => {\n const allRoutes = [...protectedRoutes, ...publicRoutes];\n const currentRoute = findRouteByPath(location.pathname, allRoutes);\n const layout = currentRoute?.meta?.layout ?? layoutType;\n return layouts[layout] ?? layouts[Object.keys(layouts)[0]];\n }, [location.pathname, layoutType]);\n\n return (\n <>\n <GlobalLoading />\n <OrbeAiWidget />\n <Suspense\n fallback={\n <div className=\"flex flex-auto flex-col h-[100vh]\">\n <Loading loading={true}/>\n </div>\n }\n >\n {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}\n {/* @ts-ignore */}\n <AppLayout linkRenderer={linkRenderer} pageTitle={pageTitle}>\n {children}\n </AppLayout>\n </Suspense>\n </>\n );\n};\n\nexport default PostLoginLayout;\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PostLoginLayout.js","sources":["../../../../../lib/@ecme/components/layouts/PostLoginLayout/PostLoginLayout.tsx"],"sourcesContent":["import { lazy, Suspense, useMemo } from \"react\";\nimport {\n LAYOUT_COLLAPSIBLE_SIDE,\n LAYOUT_STACKED_SIDE,\n LAYOUT_TOP_BAR_CLASSIC,\n LAYOUT_FRAMELESS_SIDE,\n LAYOUT_CONTENT_OVERLAY,\n LAYOUT_BLANK,\n} from \"@/constants/theme.constant\";\nimport Loading from \"@/components/shared/Loading\";\nimport type { CommonProps } from \"@/@types/common\";\nimport type { LazyExoticComponent, JSX } from \"react\";\nimport type { LayoutType } from \"@/@types/theme\";\nimport { LinkRenderer } from \"../Layouts\";\nimport { useLocation } from \"react-router-dom\";\nimport { Routes } from \"@/@types\";\nimport { protectedRoutes, publicRoutes } from \"@/configs\";\nimport GlobalLoading from \"@/components/shared/loaders/GlobalLoading\";\nimport OrbeAiWidget from \"@/components/template/OrbeAiWidget\";\nimport Can from \"@/components/shared/Can\";\n\ntype Layouts = Record<\n string,\n LazyExoticComponent<<T extends CommonProps>(props: T) => JSX.Element>\n>;\n\ninterface PostLoginLayoutProps extends CommonProps {\n layoutType: LayoutType;\n linkRenderer?: LinkRenderer;\n pageTitle?: string;\n}\n\nconst layouts: Layouts = {\n [LAYOUT_COLLAPSIBLE_SIDE]: lazy(() => import(\"./components/CollapsibleSide\")),\n [LAYOUT_STACKED_SIDE]: lazy(() => import(\"./components/StackedSide\")),\n [LAYOUT_TOP_BAR_CLASSIC]: lazy(() => import(\"./components/TopBarClassic\")),\n [LAYOUT_FRAMELESS_SIDE]: lazy(() => import(\"./components/FrameLessSide\")),\n [LAYOUT_CONTENT_OVERLAY]: lazy(() => import(\"./components/ContentOverlay\")),\n [LAYOUT_BLANK]: lazy(() => import(\"./components/Blank\")),\n};\n\nconst findRouteByPath = (\n path: string,\n routes: Routes\n): Routes[0] | undefined => {\n for (const route of routes) {\n if (route.path === path) {\n return route;\n }\n }\n};\n\nconst PostLoginLayout = ({\n layoutType,\n children,\n linkRenderer,\n pageTitle,\n}: PostLoginLayoutProps) => {\n const location = useLocation();\n const AppLayout = useMemo(() => {\n const allRoutes = [...protectedRoutes, ...publicRoutes];\n const currentRoute = findRouteByPath(location.pathname, allRoutes);\n const layout = currentRoute?.meta?.layout ?? layoutType;\n return layouts[layout] ?? layouts[Object.keys(layouts)[0]];\n }, [location.pathname, layoutType]);\n\n return (\n <>\n <GlobalLoading />\n <Can I=\"VISUALIZAR_CHAT_ORBE_AI\">\n <OrbeAiWidget />\n </Can>\n <Suspense\n fallback={\n <div className=\"flex flex-auto flex-col h-[100vh]\">\n <Loading loading={true}/>\n </div>\n }\n >\n {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}\n {/* @ts-ignore */}\n <AppLayout linkRenderer={linkRenderer} pageTitle={pageTitle}>\n {children}\n </AppLayout>\n </Suspense>\n </>\n );\n};\n\nexport default PostLoginLayout;\n"],"names":[],"mappings":";;;;;;;;;;;AAgCA,MAAM,UAAmB;AAAA,EACvB,CAAC,uBAAuB,GAAG,KAAK,MAAM,OAAO,iCAA8B,CAAC;AAAA,EAC5E,CAAC,mBAAmB,GAAG,KAAK,MAAM,OAAO,6BAA0B,CAAC;AAAA,EACpE,CAAC,sBAAsB,GAAG,KAAK,MAAM,OAAO,+BAA4B,CAAC;AAAA,EACzE,CAAC,qBAAqB,GAAG,KAAK,MAAM,OAAO,+BAA4B,CAAC;AAAA,EACxE,CAAC,sBAAsB,GAAG,KAAK,MAAM,OAAO,gCAA6B,CAAC;AAAA,EAC1E,CAAC,YAAY,GAAG,KAAK,MAAM,OAAO,uBAAoB,CAAC;AACzD;AAEA,MAAM,kBAAkB,CACtB,MACA,WAC0B;AAC1B,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,MAAM;AACvB,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,MAAM,kBAAkB,CAAC;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA4B;AAC1B,QAAM,WAAW,YAAA;AACjB,QAAM,YAAY,QAAQ,MAAM;AAC9B,UAAM,YAAY,CAAC,GAAG,iBAAiB,GAAG,YAAY;AACtD,UAAM,eAAe,gBAAgB,SAAS,UAAU,SAAS;AACjE,UAAM,SAAS,cAAc,MAAM,UAAU;AAC7C,WAAO,QAAQ,MAAM,KAAK,QAAQ,OAAO,KAAK,OAAO,EAAE,CAAC,CAAC;AAAA,EAC3D,GAAG,CAAC,SAAS,UAAU,UAAU,CAAC;AAElC,SACE,qBAAA,UAAA,EACE,UAAA;AAAA,IAAA,oBAAC,eAAA,EAAc;AAAA,wBACd,KAAA,EAAI,GAAE,2BACL,UAAA,oBAAC,gBAAa,GAChB;AAAA,IACA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,8BACG,OAAA,EAAI,WAAU,qCACb,UAAA,oBAAC,SAAA,EAAQ,SAAS,KAAA,CAAK,EAAA,CACzB;AAAA,QAKF,UAAA,oBAAC,WAAA,EAAU,cAA4B,WACpC,SAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;"}
|
|
@@ -3,7 +3,7 @@ import Container from "../shared/Container.js";
|
|
|
3
3
|
import classNames from "../../utils/classNames.js";
|
|
4
4
|
import { APP_NAME } from "../../constants/app.constant.js";
|
|
5
5
|
import { PAGE_CONTAINER_GUTTER_X } from "../../constants/theme.constant.js";
|
|
6
|
-
const version = true ? "5.6.
|
|
6
|
+
const version = true ? "5.6.261" : "0.0.0";
|
|
7
7
|
const FooterContent = () => {
|
|
8
8
|
return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-auto items-center justify-between", children: [
|
|
9
9
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo, useEffect } from "react";
|
|
3
|
+
import debounce from "lodash/debounce";
|
|
4
|
+
import { AnimatePresence, motion } from "framer-motion";
|
|
5
|
+
import { TbPlus, TbSearch } from "react-icons/tb";
|
|
6
|
+
import { HiX } from "react-icons/hi";
|
|
7
|
+
import "../../ui/Button/index.js";
|
|
8
|
+
import ChatHistory from "../../../views/concepts/ai/Chat/components/ChatHistory.js";
|
|
9
|
+
import { usGenerativeChatStore } from "../../../views/concepts/ai/Chat/store/generativeChatStore.js";
|
|
10
|
+
import Button from "../../ui/Button/Button.js";
|
|
11
|
+
const iconButtonClass = "flex h-8 w-8 items-center justify-center rounded-full text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200";
|
|
12
|
+
const OrbeAiChatDrawer = ({ open, onClose }) => {
|
|
13
|
+
const [queryText, setQueryText] = useState("");
|
|
14
|
+
const { setSelectedConversation } = usGenerativeChatStore();
|
|
15
|
+
const debounceFn = useMemo(
|
|
16
|
+
() => debounce((e) => {
|
|
17
|
+
setQueryText(e.target.value);
|
|
18
|
+
}, 500),
|
|
19
|
+
[]
|
|
20
|
+
);
|
|
21
|
+
useEffect(() => () => debounceFn.cancel(), [debounceFn]);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!open) {
|
|
24
|
+
debounceFn.cancel();
|
|
25
|
+
setQueryText("");
|
|
26
|
+
}
|
|
27
|
+
}, [open, debounceFn]);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (!open) return;
|
|
30
|
+
const handleKeyDown = (event) => {
|
|
31
|
+
if (event.key === "Escape") onClose();
|
|
32
|
+
};
|
|
33
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
34
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
35
|
+
}, [open, onClose]);
|
|
36
|
+
const handleNewChat = () => {
|
|
37
|
+
setSelectedConversation("");
|
|
38
|
+
onClose();
|
|
39
|
+
};
|
|
40
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
41
|
+
/* @__PURE__ */ jsx(
|
|
42
|
+
motion.div,
|
|
43
|
+
{
|
|
44
|
+
"aria-hidden": true,
|
|
45
|
+
initial: { opacity: 0 },
|
|
46
|
+
animate: { opacity: 1 },
|
|
47
|
+
exit: { opacity: 0 },
|
|
48
|
+
transition: { duration: 0.2 },
|
|
49
|
+
className: "absolute inset-0 z-40 bg-black/40",
|
|
50
|
+
onClick: onClose
|
|
51
|
+
},
|
|
52
|
+
"orbe-ai-drawer-backdrop"
|
|
53
|
+
),
|
|
54
|
+
/* @__PURE__ */ jsxs(
|
|
55
|
+
motion.aside,
|
|
56
|
+
{
|
|
57
|
+
role: "dialog",
|
|
58
|
+
"aria-modal": "true",
|
|
59
|
+
"aria-label": "Conversas",
|
|
60
|
+
initial: { x: "-100%" },
|
|
61
|
+
animate: { x: 0 },
|
|
62
|
+
exit: { x: "-100%" },
|
|
63
|
+
transition: { duration: 0.2, ease: "easeOut" },
|
|
64
|
+
className: "absolute inset-y-0 left-0 z-50 flex w-[85%] max-w-[300px] flex-col border-r border-gray-200 bg-white shadow-xl dark:border-gray-700 dark:bg-gray-800",
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 px-4 py-3 dark:border-gray-700", children: [
|
|
67
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900 dark:text-gray-100", children: "Conversas" }),
|
|
68
|
+
/* @__PURE__ */ jsx(
|
|
69
|
+
"button",
|
|
70
|
+
{
|
|
71
|
+
type: "button",
|
|
72
|
+
className: iconButtonClass,
|
|
73
|
+
onClick: onClose,
|
|
74
|
+
"aria-label": "Fechar conversas",
|
|
75
|
+
children: /* @__PURE__ */ jsx(HiX, { size: 18 })
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
] }),
|
|
79
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 px-4 pt-4", children: [
|
|
80
|
+
/* @__PURE__ */ jsx(
|
|
81
|
+
Button,
|
|
82
|
+
{
|
|
83
|
+
block: true,
|
|
84
|
+
variant: "solid",
|
|
85
|
+
size: "sm",
|
|
86
|
+
icon: /* @__PURE__ */ jsx(TbPlus, {}),
|
|
87
|
+
onClick: handleNewChat,
|
|
88
|
+
children: "Novo chat"
|
|
89
|
+
}
|
|
90
|
+
),
|
|
91
|
+
/* @__PURE__ */ jsxs("label", { className: "flex h-9 items-center gap-2 rounded-lg border border-gray-200 px-3 focus-within:border-primary dark:border-gray-600", children: [
|
|
92
|
+
/* @__PURE__ */ jsx(TbSearch, { className: "shrink-0 text-lg text-gray-400" }),
|
|
93
|
+
/* @__PURE__ */ jsx(
|
|
94
|
+
"input",
|
|
95
|
+
{
|
|
96
|
+
className: "h-full min-w-0 flex-1 bg-transparent text-sm placeholder:text-gray-400 focus:outline-none heading-text",
|
|
97
|
+
placeholder: "Buscar conversa",
|
|
98
|
+
onChange: debounceFn
|
|
99
|
+
}
|
|
100
|
+
)
|
|
101
|
+
] })
|
|
102
|
+
] }),
|
|
103
|
+
/* @__PURE__ */ jsx("div", { className: "px-4 pb-1 pt-4 text-xs font-semibold uppercase tracking-wide text-gray-400", children: "Histórico" }),
|
|
104
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx(
|
|
105
|
+
ChatHistory,
|
|
106
|
+
{
|
|
107
|
+
queryText,
|
|
108
|
+
onClick: onClose,
|
|
109
|
+
dropdownFloatingClass: "!z-[10000]"
|
|
110
|
+
}
|
|
111
|
+
) })
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
"orbe-ai-drawer"
|
|
115
|
+
)
|
|
116
|
+
] }) });
|
|
117
|
+
};
|
|
118
|
+
export {
|
|
119
|
+
OrbeAiChatDrawer as default
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=OrbeAiChatDrawer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrbeAiChatDrawer.js","sources":["../../../../../lib/@ecme/components/template/OrbeAiWidget/OrbeAiChatDrawer.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react'\nimport debounce from 'lodash/debounce'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { TbPlus, TbSearch } from 'react-icons/tb'\nimport { HiX } from 'react-icons/hi'\nimport Button from '@/components/ui/Button'\nimport ChatHistory from '@/views/concepts/ai/Chat/components/ChatHistory'\nimport { usGenerativeChatStore } from '@/views/concepts/ai/Chat/store/generativeChatStore'\nimport type { ChangeEvent } from 'react'\n\ntype OrbeAiChatDrawerProps = {\n open: boolean\n onClose: () => void\n}\n\nconst iconButtonClass =\n 'flex h-8 w-8 items-center justify-center rounded-full text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200'\n\n/**\n * Drawer de conversas DENTRO do painel do widget.\n *\n * Não usa o Drawer do ui: ele é portalizado no body com overlay em z-30 e\n * abriria atrás do widget (z-40 / z-[9999]), cobrindo a página inteira. Aqui é\n * `absolute`, então fica recortado pelo painel em qualquer tamanho.\n */\nconst OrbeAiChatDrawer = ({ open, onClose }: OrbeAiChatDrawerProps) => {\n const [queryText, setQueryText] = useState('')\n const { setSelectedConversation } = usGenerativeChatStore()\n\n // Memoizado: o store re-renderiza o drawer a cada token do streaming, e um\n // debounce recriado a cada render perderia a busca pendente.\n const debounceFn = useMemo(\n () =>\n debounce((e: ChangeEvent<HTMLInputElement>) => {\n setQueryText(e.target.value)\n }, 500),\n [],\n )\n\n useEffect(() => () => debounceFn.cancel(), [debounceFn])\n\n // O input desmonta ao fechar e volta vazio; o filtro precisa acompanhar.\n useEffect(() => {\n if (!open) {\n debounceFn.cancel()\n setQueryText('')\n }\n }, [open, debounceFn])\n\n useEffect(() => {\n if (!open) return\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose()\n }\n window.addEventListener('keydown', handleKeyDown)\n return () => window.removeEventListener('keydown', handleKeyDown)\n }, [open, onClose])\n\n const handleNewChat = () => {\n setSelectedConversation('')\n onClose()\n }\n\n return (\n <AnimatePresence>\n {open && (\n <>\n <motion.div\n key=\"orbe-ai-drawer-backdrop\"\n aria-hidden\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className=\"absolute inset-0 z-40 bg-black/40\"\n onClick={onClose}\n />\n <motion.aside\n key=\"orbe-ai-drawer\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Conversas\"\n initial={{ x: '-100%' }}\n animate={{ x: 0 }}\n exit={{ x: '-100%' }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n className=\"absolute inset-y-0 left-0 z-50 flex w-[85%] max-w-[300px] flex-col border-r border-gray-200 bg-white shadow-xl dark:border-gray-700 dark:bg-gray-800\"\n >\n <div className=\"flex items-center justify-between border-b border-gray-200 px-4 py-3 dark:border-gray-700\">\n <span className=\"font-semibold text-gray-900 dark:text-gray-100\">\n Conversas\n </span>\n <button\n type=\"button\"\n className={iconButtonClass}\n onClick={onClose}\n aria-label=\"Fechar conversas\"\n >\n <HiX size={18} />\n </button>\n </div>\n\n <div className=\"flex flex-col gap-3 px-4 pt-4\">\n <Button\n block\n variant=\"solid\"\n size=\"sm\"\n icon={<TbPlus />}\n onClick={handleNewChat}\n >\n Novo chat\n </Button>\n <label className=\"flex h-9 items-center gap-2 rounded-lg border border-gray-200 px-3 focus-within:border-primary dark:border-gray-600\">\n <TbSearch className=\"shrink-0 text-lg text-gray-400\" />\n <input\n className=\"h-full min-w-0 flex-1 bg-transparent text-sm placeholder:text-gray-400 focus:outline-none heading-text\"\n placeholder=\"Buscar conversa\"\n onChange={debounceFn}\n />\n </label>\n </div>\n\n <div className=\"px-4 pb-1 pt-4 text-xs font-semibold uppercase tracking-wide text-gray-400\">\n Histórico\n </div>\n <div className=\"min-h-0 flex-1\">\n <ChatHistory\n queryText={queryText}\n onClick={onClose}\n dropdownFloatingClass=\"!z-[10000]\"\n />\n </div>\n </motion.aside>\n </>\n )}\n </AnimatePresence>\n )\n}\n\nexport default OrbeAiChatDrawer\n"],"names":[],"mappings":"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"}
|
|
@@ -1,30 +1,41 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from "react";
|
|
2
|
+
import { useState, useCallback } from "react";
|
|
3
3
|
import { AnimatePresence, motion } from "framer-motion";
|
|
4
|
-
import { TbMessageChatbot, TbArrowsMinimize, TbArrowsMaximize } from "react-icons/tb";
|
|
4
|
+
import { TbMenu2, TbMessageChatbot, TbArrowsMinimize, TbArrowsMaximize } from "react-icons/tb";
|
|
5
5
|
import { HiX } from "react-icons/hi";
|
|
6
6
|
import ChatView from "../../../views/concepts/ai/Chat/components/ChatView.js";
|
|
7
7
|
import ChatHistoryRenameDialog from "../../../views/concepts/ai/Chat/components/ChatHistoryRenameDialog.js";
|
|
8
|
-
import useResizablePanel from "./useResizablePanel.js";
|
|
8
|
+
import useResizablePanel, { MARGIN } from "./useResizablePanel.js";
|
|
9
9
|
import ResizeHandles from "./ResizeHandles.js";
|
|
10
|
+
import OrbeAiChatDrawer from "./OrbeAiChatDrawer.js";
|
|
10
11
|
const iconButtonClass = "flex h-8 w-8 items-center justify-center rounded-full text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200";
|
|
11
12
|
const OrbeAiWidget = () => {
|
|
12
13
|
const [open, setOpen] = useState(false);
|
|
13
14
|
const [fullscreen, setFullscreen] = useState(false);
|
|
14
|
-
const
|
|
15
|
-
const
|
|
15
|
+
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
16
|
+
const { rect, startResize, anchor } = useResizablePanel();
|
|
17
|
+
const toggleOpen = () => {
|
|
18
|
+
if (!open) anchor();
|
|
19
|
+
setOpen((prev) => !prev);
|
|
20
|
+
setDrawerOpen(false);
|
|
21
|
+
};
|
|
16
22
|
const toggleFullscreen = () => setFullscreen((prev) => !prev);
|
|
23
|
+
const toggleDrawer = () => setDrawerOpen((prev) => !prev);
|
|
24
|
+
const closeDrawer = useCallback(() => setDrawerOpen(false), []);
|
|
17
25
|
const close = () => {
|
|
18
26
|
setOpen(false);
|
|
19
27
|
setFullscreen(false);
|
|
28
|
+
setDrawerOpen(false);
|
|
20
29
|
};
|
|
21
30
|
const panelStyle = fullscreen ? void 0 : {
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
right: rect.right,
|
|
32
|
+
bottom: rect.bottom,
|
|
24
33
|
width: rect.width,
|
|
25
|
-
height: rect.height
|
|
34
|
+
height: rect.height,
|
|
35
|
+
maxWidth: `calc(100% - ${rect.right + MARGIN}px)`,
|
|
36
|
+
maxHeight: `calc(100% - ${rect.bottom + MARGIN}px)`
|
|
26
37
|
};
|
|
27
|
-
const panelVariantClass = fullscreen ? "inset-0 rounded-none border-0" : "rounded-2xl border shadow-2xl";
|
|
38
|
+
const panelVariantClass = fullscreen ? "inset-0 rounded-none border-0" : "origin-bottom-right rounded-2xl border shadow-2xl";
|
|
28
39
|
return /* @__PURE__ */ jsxs(
|
|
29
40
|
"div",
|
|
30
41
|
{
|
|
@@ -41,12 +52,23 @@ const OrbeAiWidget = () => {
|
|
|
41
52
|
className: `fixed flex flex-col overflow-hidden border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800 ${panelVariantClass}`,
|
|
42
53
|
children: [
|
|
43
54
|
!fullscreen && /* @__PURE__ */ jsx(ResizeHandles, { onResizeStart: startResize }),
|
|
44
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 px-
|
|
45
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
46
|
-
/* @__PURE__ */ jsx(
|
|
47
|
-
|
|
55
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-gray-200 px-3 py-3 sm:px-4 dark:border-gray-700", children: [
|
|
56
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-1 sm:gap-2", children: [
|
|
57
|
+
/* @__PURE__ */ jsx(
|
|
58
|
+
"button",
|
|
59
|
+
{
|
|
60
|
+
type: "button",
|
|
61
|
+
className: iconButtonClass,
|
|
62
|
+
onClick: toggleDrawer,
|
|
63
|
+
"aria-label": "Abrir conversas",
|
|
64
|
+
"aria-expanded": drawerOpen,
|
|
65
|
+
children: /* @__PURE__ */ jsx(TbMenu2, { size: 20 })
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
/* @__PURE__ */ jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary text-white", children: /* @__PURE__ */ jsx(TbMessageChatbot, { size: 20 }) }),
|
|
69
|
+
/* @__PURE__ */ jsx("span", { className: "truncate font-semibold text-gray-900 dark:text-gray-100", children: "Orbe AI" })
|
|
48
70
|
] }),
|
|
49
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
71
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1 sm:gap-2", children: [
|
|
50
72
|
/* @__PURE__ */ jsx(
|
|
51
73
|
"button",
|
|
52
74
|
{
|
|
@@ -70,9 +92,16 @@ const OrbeAiWidget = () => {
|
|
|
70
92
|
] })
|
|
71
93
|
] }),
|
|
72
94
|
/* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 p-2", children: [
|
|
73
|
-
/* @__PURE__ */ jsx(ChatView, {}),
|
|
74
|
-
/* @__PURE__ */ jsx(ChatHistoryRenameDialog, {})
|
|
75
|
-
] })
|
|
95
|
+
/* @__PURE__ */ jsx(ChatView, { showMobileNav: false }),
|
|
96
|
+
/* @__PURE__ */ jsx(ChatHistoryRenameDialog, { overlayClassName: "!z-[10000]" })
|
|
97
|
+
] }),
|
|
98
|
+
/* @__PURE__ */ jsx(
|
|
99
|
+
OrbeAiChatDrawer,
|
|
100
|
+
{
|
|
101
|
+
open: drawerOpen,
|
|
102
|
+
onClose: closeDrawer
|
|
103
|
+
}
|
|
104
|
+
)
|
|
76
105
|
]
|
|
77
106
|
},
|
|
78
107
|
"orbe-ai-panel"
|
|
@@ -81,7 +110,7 @@ const OrbeAiWidget = () => {
|
|
|
81
110
|
"button",
|
|
82
111
|
{
|
|
83
112
|
type: "button",
|
|
84
|
-
className: "flex h-14 w-14 items-center justify-center rounded-full bg-primary text-
|
|
113
|
+
className: "flex h-14 w-14 items-center justify-center rounded-full bg-primary text-neutral shadow-lg transition-colors hover:bg-primary-mild focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2",
|
|
85
114
|
onClick: toggleOpen,
|
|
86
115
|
"aria-label": open ? "Fechar chat Orbe AI" : "Abrir chat Orbe AI",
|
|
87
116
|
"aria-expanded": open,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrbeAiWidget.js","sources":["../../../../../lib/@ecme/components/template/OrbeAiWidget/OrbeAiWidget.tsx"],"sourcesContent":["import { useState } from 'react'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport {\n TbMessageChatbot,\n TbArrowsMaximize,\n TbArrowsMinimize,\n} from 'react-icons/tb'\nimport { HiX } from 'react-icons/hi'\nimport ChatView from '@/views/concepts/ai/Chat/components/ChatView'\nimport ChatHistoryRenameDialog from '@/views/concepts/ai/Chat/components/ChatHistoryRenameDialog'\nimport useResizablePanel from './useResizablePanel'\nimport ResizeHandles from './ResizeHandles'\n\nconst iconButtonClass =\n 'flex h-8 w-8 items-center justify-center rounded-full text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200'\n\nconst OrbeAiWidget = () => {\n const [open, setOpen] = useState(false)\n const [fullscreen, setFullscreen] = useState(false)\n const { rect, startResize } = useResizablePanel()\n\n const toggleOpen = () => setOpen((prev) => !prev)\n const toggleFullscreen = () => setFullscreen((prev) => !prev)\n const close = () => {\n setOpen(false)\n setFullscreen(false)\n }\n\n // Tela cheia: cobre o viewport inteiro (inset-0). Flutuante: usa o retângulo do resize.\n const panelStyle = fullscreen\n ? undefined\n : {\n top: rect.top,\n left: rect.left,\n width: rect.width,\n height: rect.height,\n }\n const panelVariantClass = fullscreen\n ? 'inset-0 rounded-none border-0'\n : 'rounded-2xl border shadow-2xl'\n\n return (\n <div\n className={`fixed bottom-6 right-6 flex flex-col items-end gap-3 print:hidden ${\n fullscreen ? 'z-[9999]' : 'z-40'\n }`}\n >\n <AnimatePresence>\n {open && (\n <motion.div\n key=\"orbe-ai-panel\"\n initial={{ opacity: 0, y: 24, scale: 0.96 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 24, scale: 0.96 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n style={panelStyle}\n className={`fixed flex flex-col overflow-hidden border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800 ${panelVariantClass}`}\n >\n {!fullscreen && (\n <ResizeHandles onResizeStart={startResize} />\n )}\n\n <div className=\"flex items-center justify-between border-b border-gray-200 px-4 py-3 dark:border-gray-700\">\n <div className=\"flex items-center gap-2\">\n <span className=\"flex h-8 w-8 items-center justify-center rounded-full bg-primary text-white\">\n <TbMessageChatbot size={20} />\n </span>\n <span className=\"font-semibold text-gray-900 dark:text-gray-100\">\n Orbe AI\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n className={iconButtonClass}\n onClick={toggleFullscreen}\n aria-label={\n fullscreen\n ? 'Sair da tela cheia'\n : 'Tela cheia'\n }\n >\n {fullscreen ? (\n <TbArrowsMinimize size={18} />\n ) : (\n <TbArrowsMaximize size={18} />\n )}\n </button>\n <button\n type=\"button\"\n className={iconButtonClass}\n onClick={close}\n aria-label=\"Fechar chat Orbe AI\"\n >\n <HiX size={18} />\n </button>\n </div>\n </div>\n\n <div className=\"min-h-0 flex-1 p-2\">\n <ChatView />\n <ChatHistoryRenameDialog />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {!fullscreen && (\n <button\n type=\"button\"\n className=\"flex h-14 w-14 items-center justify-center rounded-full bg-primary text-white shadow-lg transition-colors hover:bg-primary-deep focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2\"\n onClick={toggleOpen}\n aria-label={open ? 'Fechar chat Orbe AI' : 'Abrir chat Orbe AI'}\n aria-expanded={open}\n >\n {open ? <HiX size={24} /> : <TbMessageChatbot size={26} />}\n </button>\n )}\n </div>\n )\n}\n\nexport default OrbeAiWidget\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OrbeAiWidget.js","sources":["../../../../../lib/@ecme/components/template/OrbeAiWidget/OrbeAiWidget.tsx"],"sourcesContent":["import { useCallback, useState } from 'react'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport {\n TbMessageChatbot,\n TbArrowsMaximize,\n TbArrowsMinimize,\n TbMenu2,\n} from 'react-icons/tb'\nimport { HiX } from 'react-icons/hi'\nimport ChatView from '@/views/concepts/ai/Chat/components/ChatView'\nimport ChatHistoryRenameDialog from '@/views/concepts/ai/Chat/components/ChatHistoryRenameDialog'\nimport useResizablePanel, { MARGIN } from './useResizablePanel'\nimport ResizeHandles from './ResizeHandles'\nimport OrbeAiChatDrawer from './OrbeAiChatDrawer'\n\nconst iconButtonClass =\n 'flex h-8 w-8 items-center justify-center rounded-full text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200'\n\nconst OrbeAiWidget = () => {\n const [open, setOpen] = useState(false)\n const [fullscreen, setFullscreen] = useState(false)\n const [drawerOpen, setDrawerOpen] = useState(false)\n const { rect, startResize, anchor } = useResizablePanel()\n\n const toggleOpen = () => {\n // Sempre abre colado no botão. No mesmo clique do setOpen: o React junta\n // os dois updates e o painel não pisca na posição antiga.\n if (!open) anchor()\n setOpen((prev) => !prev)\n setDrawerOpen(false)\n }\n const toggleFullscreen = () => setFullscreen((prev) => !prev)\n const toggleDrawer = () => setDrawerOpen((prev) => !prev)\n // Estável: o drawer registra o listener de Esc com ela como dependência.\n const closeDrawer = useCallback(() => setDrawerOpen(false), [])\n const close = () => {\n setOpen(false)\n setFullscreen(false)\n setDrawerOpen(false)\n }\n\n // Tela cheia: cobre o viewport inteiro (inset-0). Flutuante: ancorado no\n // canto do botão (right/bottom). O max-* limita só a exibição — o estado\n // guarda o tamanho escolhido, então ao desfazer o zoom o painel volta igual.\n // `100%` de um `fixed` é o viewport sem a barra de rolagem.\n const panelStyle = fullscreen\n ? undefined\n : {\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n maxWidth: `calc(100% - ${rect.right + MARGIN}px)`,\n maxHeight: `calc(100% - ${rect.bottom + MARGIN}px)`,\n }\n const panelVariantClass = fullscreen\n ? 'inset-0 rounded-none border-0'\n : 'origin-bottom-right rounded-2xl border shadow-2xl'\n\n return (\n <div\n className={`fixed bottom-6 right-6 flex flex-col items-end gap-3 print:hidden ${\n fullscreen ? 'z-[9999]' : 'z-40'\n }`}\n >\n <AnimatePresence>\n {open && (\n <motion.div\n key=\"orbe-ai-panel\"\n initial={{ opacity: 0, y: 24, scale: 0.96 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 24, scale: 0.96 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n style={panelStyle}\n className={`fixed flex flex-col overflow-hidden border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800 ${panelVariantClass}`}\n >\n {!fullscreen && (\n <ResizeHandles onResizeStart={startResize} />\n )}\n\n <div className=\"flex items-center justify-between gap-2 border-b border-gray-200 px-3 py-3 sm:px-4 dark:border-gray-700\">\n <div className=\"flex min-w-0 items-center gap-1 sm:gap-2\">\n <button\n type=\"button\"\n className={iconButtonClass}\n onClick={toggleDrawer}\n aria-label=\"Abrir conversas\"\n aria-expanded={drawerOpen}\n >\n <TbMenu2 size={20} />\n </button>\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary text-white\">\n <TbMessageChatbot size={20} />\n </span>\n <span className=\"truncate font-semibold text-gray-900 dark:text-gray-100\">\n Orbe AI\n </span>\n </div>\n <div className=\"flex shrink-0 items-center gap-1 sm:gap-2\">\n <button\n type=\"button\"\n className={iconButtonClass}\n onClick={toggleFullscreen}\n aria-label={\n fullscreen\n ? 'Sair da tela cheia'\n : 'Tela cheia'\n }\n >\n {fullscreen ? (\n <TbArrowsMinimize size={18} />\n ) : (\n <TbArrowsMaximize size={18} />\n )}\n </button>\n <button\n type=\"button\"\n className={iconButtonClass}\n onClick={close}\n aria-label=\"Fechar chat Orbe AI\"\n >\n <HiX size={18} />\n </button>\n </div>\n </div>\n\n <div className=\"min-h-0 flex-1 p-2\">\n <ChatView showMobileNav={false} />\n <ChatHistoryRenameDialog overlayClassName=\"!z-[10000]\" />\n </div>\n\n <OrbeAiChatDrawer\n open={drawerOpen}\n onClose={closeDrawer}\n />\n </motion.div>\n )}\n </AnimatePresence>\n\n {!fullscreen && (\n <button\n type=\"button\"\n className=\"flex h-14 w-14 items-center justify-center rounded-full bg-primary text-neutral shadow-lg transition-colors hover:bg-primary-mild focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2\"\n onClick={toggleOpen}\n aria-label={open ? 'Fechar chat Orbe AI' : 'Abrir chat Orbe AI'}\n aria-expanded={open}\n >\n {open ? <HiX size={24} /> : <TbMessageChatbot size={26} />}\n </button>\n )}\n </div>\n )\n}\n\nexport default OrbeAiWidget\n"],"names":[],"mappings":"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"}
|
|
@@ -1,61 +1,74 @@
|
|
|
1
|
-
import { useState, useCallback } from "react";
|
|
1
|
+
import { useState, useCallback, useEffect } from "react";
|
|
2
2
|
const MIN = { width: 360, height: 420 };
|
|
3
3
|
const DEFAULT = { width: 480, height: 720 };
|
|
4
4
|
const MARGIN = 12;
|
|
5
|
-
const ANCHOR = { right: 24,
|
|
5
|
+
const ANCHOR = { right: 24, bottom: 92 };
|
|
6
6
|
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
width,
|
|
12
|
-
height,
|
|
13
|
-
left: Math.max(MARGIN, window.innerWidth - width - ANCHOR.right),
|
|
14
|
-
top: Math.max(MARGIN, window.innerHeight - height - ANCHOR.bottomOffset)
|
|
15
|
-
};
|
|
16
|
-
};
|
|
7
|
+
const getViewport = () => ({
|
|
8
|
+
width: document.documentElement.clientWidth,
|
|
9
|
+
height: document.documentElement.clientHeight
|
|
10
|
+
});
|
|
17
11
|
const useResizablePanel = () => {
|
|
18
|
-
const [rect, setRect] = useState(
|
|
12
|
+
const [rect, setRect] = useState({ ...ANCHOR, ...DEFAULT });
|
|
13
|
+
const anchor = useCallback(() => {
|
|
14
|
+
setRect(
|
|
15
|
+
(prev) => prev.right === ANCHOR.right && prev.bottom === ANCHOR.bottom ? prev : { ...prev, ...ANCHOR }
|
|
16
|
+
);
|
|
17
|
+
}, []);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
window.addEventListener("resize", anchor);
|
|
20
|
+
return () => window.removeEventListener("resize", anchor);
|
|
21
|
+
}, [anchor]);
|
|
19
22
|
const startResize = useCallback(
|
|
20
23
|
(event, direction) => {
|
|
21
24
|
event.preventDefault();
|
|
22
25
|
event.stopPropagation();
|
|
23
26
|
const startX = event.clientX;
|
|
24
27
|
const startY = event.clientY;
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
+
const viewport = getViewport();
|
|
29
|
+
const start = {
|
|
30
|
+
...rect,
|
|
31
|
+
width: Math.min(rect.width, viewport.width - rect.right - MARGIN),
|
|
32
|
+
height: Math.min(
|
|
33
|
+
rect.height,
|
|
34
|
+
viewport.height - rect.bottom - MARGIN
|
|
35
|
+
)
|
|
36
|
+
};
|
|
28
37
|
const previousUserSelect = document.body.style.userSelect;
|
|
29
38
|
document.body.style.userSelect = "none";
|
|
30
39
|
const handleMove = (moveEvent) => {
|
|
31
40
|
const dx = moveEvent.clientX - startX;
|
|
32
41
|
const dy = moveEvent.clientY - startY;
|
|
33
42
|
const next = { ...start };
|
|
34
|
-
if (direction.includes("
|
|
43
|
+
if (direction.includes("left")) {
|
|
35
44
|
next.width = clamp(
|
|
36
|
-
start.width
|
|
45
|
+
start.width - dx,
|
|
37
46
|
MIN.width,
|
|
38
|
-
|
|
47
|
+
viewport.width - start.right - MARGIN
|
|
39
48
|
);
|
|
40
49
|
}
|
|
41
|
-
if (direction.includes("
|
|
42
|
-
next.width = clamp(start.width - dx, MIN.width, right - MARGIN);
|
|
43
|
-
next.left = right - next.width;
|
|
44
|
-
}
|
|
45
|
-
if (direction.includes("bottom")) {
|
|
50
|
+
if (direction.includes("top")) {
|
|
46
51
|
next.height = clamp(
|
|
47
|
-
start.height
|
|
52
|
+
start.height - dy,
|
|
48
53
|
MIN.height,
|
|
49
|
-
|
|
54
|
+
viewport.height - start.bottom - MARGIN
|
|
50
55
|
);
|
|
51
56
|
}
|
|
52
|
-
if (direction.includes("
|
|
57
|
+
if (direction.includes("right")) {
|
|
58
|
+
next.width = clamp(
|
|
59
|
+
start.width + dx,
|
|
60
|
+
MIN.width,
|
|
61
|
+
start.width + start.right - MARGIN
|
|
62
|
+
);
|
|
63
|
+
next.right = start.right - (next.width - start.width);
|
|
64
|
+
}
|
|
65
|
+
if (direction.includes("bottom")) {
|
|
53
66
|
next.height = clamp(
|
|
54
|
-
start.height
|
|
67
|
+
start.height + dy,
|
|
55
68
|
MIN.height,
|
|
56
|
-
bottom - MARGIN
|
|
69
|
+
start.height + start.bottom - MARGIN
|
|
57
70
|
);
|
|
58
|
-
next.
|
|
71
|
+
next.bottom = start.bottom - (next.height - start.height);
|
|
59
72
|
}
|
|
60
73
|
setRect(next);
|
|
61
74
|
};
|
|
@@ -69,9 +82,10 @@ const useResizablePanel = () => {
|
|
|
69
82
|
},
|
|
70
83
|
[rect]
|
|
71
84
|
);
|
|
72
|
-
return { rect, startResize };
|
|
85
|
+
return { rect, startResize, anchor };
|
|
73
86
|
};
|
|
74
87
|
export {
|
|
88
|
+
MARGIN,
|
|
75
89
|
useResizablePanel as default
|
|
76
90
|
};
|
|
77
91
|
//# sourceMappingURL=useResizablePanel.js.map
|