robbyson-frontend-library 1.0.186 → 1.0.188
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/pages/base-app-page.styles.js +2 -2
- package/dist/components/typing-indicator/typing-indicator.interface.js +1 -0
- package/dist/repositories/base.repository.js +3 -5
- package/dist/utils/cache-control.js +15 -16
- package/dist/utils/chat.utils.js +2 -2
- package/dist/utils/date.utils.js +6 -37
- package/dist/utils/desktop-client.utils.js +235 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/robbyson-navigate.js +13 -2
- package/index.d.ts +1 -0
- package/package.json +3 -3
- package/src/components/pages/base-app-page.styles.ts +18 -5
- package/src/components/typing-indicator/index.d.ts +1 -0
- package/src/components/typing-indicator/typing-indicator.interface.ts +6 -0
- package/src/components/typing-indicator/typing-indicator.types.d.ts +9 -0
- package/src/repositories/base.repository.ts +4 -4
- package/src/repositories/chat.repository.interface.ts +6 -0
- package/src/services/chat.service.interface.ts +6 -0
- package/src/services/dtos/chat.dto.ts +0 -1
- package/src/services/theme.service.interface.ts +6 -0
- package/src/states/main-container/root-app.state.interface.ts +1 -0
- package/src/utils/cache-control.ts +16 -16
- package/src/utils/chat.utils.ts +2 -2
- package/src/utils/date.utils.ts +10 -58
- package/src/utils/desktop-client.utils.ts +443 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/robbyson-navigate.ts +19 -1
|
@@ -13,7 +13,7 @@ var PADDING_BOTTOM_MOBILE = 24;
|
|
|
13
13
|
var HEADER_HEIGHT_DESKTOP = 40;
|
|
14
14
|
var HEADER_HEIGHT_MOBILE = 91;
|
|
15
15
|
var HEADER_HEIGHT_CUSTOM_PAGE = 40;
|
|
16
|
-
export var SidebarPadding = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n padding-left: calc(", "px + 55px);\n height: calc(100vh + 8px);\n"], ["\n padding-left: calc(", "px + 55px);\n height: calc(100vh + 8px);\n"])), SIDEBAR_WIDTH);
|
|
16
|
+
export var SidebarPadding = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n padding-left: calc(", "px + 55px);\n /*\n * 100vh com fallback. Em ambientes que injetam chrome (Tauri title\n * bar), --rbs-app-h ja desconta a barra. Em browser comum, var nao\n * existe e o fallback (100vh + 8px equivalente) mantem comportamento\n * original.\n */\n height: calc(var(--rbs-app-h, 100vh) + 8px);\n"], ["\n padding-left: calc(", "px + 55px);\n /*\n * 100vh com fallback. Em ambientes que injetam chrome (Tauri title\n * bar), --rbs-app-h ja desconta a barra. Em browser comum, var nao\n * existe e o fallback (100vh + 8px equivalente) mantem comportamento\n * original.\n */\n height: calc(var(--rbs-app-h, 100vh) + 8px);\n"])), SIDEBAR_WIDTH);
|
|
17
17
|
export var PageContainer = styled.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n padding: 32px 55px 0px calc(", "px + 55px);\n overflow: hidden;\n background: var(--solid-background);\n height: 100%;\n @media (max-width: ", "px) {\n padding: 32px 24px 0px 32px;\n }\n\n @media (max-width: ", "px) {\n padding: 24px 0px 0px 14px;\n }\n"], ["\n padding: 32px 55px 0px calc(", "px + 55px);\n overflow: hidden;\n background: var(--solid-background);\n height: 100%;\n @media (max-width: ", "px) {\n padding: 32px 24px 0px 32px;\n }\n\n @media (max-width: ", "px) {\n padding: 24px 0px 0px 14px;\n }\n"])), SIDEBAR_WIDTH, LayoutDimensions.width.horizontalIpadMini, LayoutDimensions.width.mobile);
|
|
18
18
|
export var Header = styled.div(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n ", "\n flex-direction: row !important;\n justify-content: space-between !important;\n align-items: center !important;\n gap: 16px !important;\n padding-bottom: 24px;\n\n @media (max-width: ", "px) {\n flex-direction: column !important;\n align-items: flex-start !important;\n }\n\n & > div {\n display: flex;\n align-items: center;\n }\n\n svg {\n cursor: pointer;\n }\n"], ["\n ", "\n flex-direction: row !important;\n justify-content: space-between !important;\n align-items: center !important;\n gap: 16px !important;\n padding-bottom: 24px;\n\n @media (max-width: ", "px) {\n flex-direction: column !important;\n align-items: flex-start !important;\n }\n\n & > div {\n display: flex;\n align-items: center;\n }\n\n svg {\n cursor: pointer;\n }\n"])), function (_a) {
|
|
19
19
|
var usePageHeader = _a.usePageHeader;
|
|
@@ -32,7 +32,7 @@ export var Content = styled.div(templateObject_9 || (templateObject_9 = __makeTe
|
|
|
32
32
|
? HEADER_HEIGHT_CUSTOM_PAGE
|
|
33
33
|
: HEADER_HEIGHT_MOBILE;
|
|
34
34
|
var paddingBottomDesktop = usePageHeader ? 0 : PADDING_BOTTOM_DESKTOP;
|
|
35
|
-
return css(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n height: ", ";\n\n @media (max-width: ", "px) {\n height: calc(\n 100vh -\n ", "px\n );\n }
|
|
35
|
+
return css(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n /*\n * Altura util do <Content>: desconta padding + header da viewport.\n * Usamos var(--rbs-app-h, 100vh) em vez de 100vh puro pra\n * cooperar com chrome injetado em runtime (client desktop Tauri\n * publica essa var em :root). Browser comum cai no fallback\n * 100vh \u2014 comportamento original preservado.\n */\n height: ", ";\n\n @media (max-width: ", "px) {\n height: calc(\n var(--rbs-app-h, 100vh) -\n ", "px\n );\n }\n\n @media (max-width: ", "px) {\n height: calc(\n var(--rbs-app-h, 100vh) -\n ", "px\n );\n }\n\n\n & > div:first-child {\n ", "\n "], ["\n /*\n * Altura util do <Content>: desconta padding + header da viewport.\n * Usamos var(--rbs-app-h, 100vh) em vez de 100vh puro pra\n * cooperar com chrome injetado em runtime (client desktop Tauri\n * publica essa var em :root). Browser comum cai no fallback\n * 100vh \u2014 comportamento original preservado.\n */\n height: ", ";\n\n @media (max-width: ", "px) {\n height: calc(\n var(--rbs-app-h, 100vh) -\n ", "px\n );\n }\n\n @media (max-width: ", "px) {\n height: calc(\n var(--rbs-app-h, 100vh) -\n ", "px\n );\n }\n\n\n & > div:first-child {\n ", "\n "])), "calc(var(--rbs-app-h, 100vh) - ".concat(PADDING_TOP_DESKTOP +
|
|
36
36
|
paddingBottomDesktop +
|
|
37
37
|
headerHeightDesktop +
|
|
38
38
|
contentMarginTop, "px)"), LayoutDimensions.width.horizontalIpadMini, PADDING_TOP_DESKTOP +
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -35,7 +35,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
import axios from "axios";
|
|
38
|
-
import
|
|
38
|
+
import moment from "moment";
|
|
39
39
|
import { CacheControl } from "../utils";
|
|
40
40
|
import sha1 from "crypto-js/sha1";
|
|
41
41
|
import { GlobalStore } from "redux-micro-frontend";
|
|
@@ -74,7 +74,7 @@ var BaseRepository = /** @class */ (function () {
|
|
|
74
74
|
case 0:
|
|
75
75
|
if (config && config.cache) {
|
|
76
76
|
return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
|
|
77
|
-
var key, hasCache, _a, expire, value_1,
|
|
77
|
+
var key, hasCache, _a, expire, value_1, isExpired, response_1, _b, _c, error_1;
|
|
78
78
|
var _d, _e;
|
|
79
79
|
return __generator(this, function (_f) {
|
|
80
80
|
switch (_f.label) {
|
|
@@ -88,9 +88,7 @@ var BaseRepository = /** @class */ (function () {
|
|
|
88
88
|
return [4 /*yield*/, CacheControl.getCache(key)];
|
|
89
89
|
case 2:
|
|
90
90
|
_a = (_f.sent()) || {}, expire = _a.expire, value_1 = _a.value;
|
|
91
|
-
|
|
92
|
-
expireDate = new Date(expire);
|
|
93
|
-
isExpired = isAfter(now, expireDate) || isEqual(now, expireDate);
|
|
91
|
+
isExpired = moment().isSameOrAfter(moment(expire));
|
|
94
92
|
if (value_1 && !isExpired) {
|
|
95
93
|
console.log("RECOVERED FROM CACHE", url);
|
|
96
94
|
return [2 /*return*/, setTimeout(function () { return resolve(value_1); }, (_d = config.delayOnCache) !== null && _d !== void 0 ? _d : 0)];
|
|
@@ -35,7 +35,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
import localforage from 'localforage';
|
|
38
|
-
import
|
|
38
|
+
import moment from 'moment';
|
|
39
39
|
;
|
|
40
40
|
var CacheControl = /** @class */ (function () {
|
|
41
41
|
function CacheControl() {
|
|
@@ -64,20 +64,22 @@ var CacheControl = /** @class */ (function () {
|
|
|
64
64
|
if (type === void 0) { type = ''; }
|
|
65
65
|
return __awaiter(this, void 0, void 0, function () {
|
|
66
66
|
var now, data;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
switch (_b.label) {
|
|
67
|
+
return __generator(this, function (_a) {
|
|
68
|
+
switch (_a.label) {
|
|
70
69
|
case 0:
|
|
71
|
-
now =
|
|
70
|
+
now = moment();
|
|
72
71
|
data = {
|
|
73
72
|
value: value,
|
|
74
73
|
type: type,
|
|
75
|
-
cratedAt: now.toISOString(),
|
|
76
|
-
expire:
|
|
74
|
+
cratedAt: now.toDate().toISOString(),
|
|
75
|
+
expire: now
|
|
76
|
+
.add(maxAge[0], maxAge[1])
|
|
77
|
+
.toDate()
|
|
78
|
+
.toISOString(),
|
|
77
79
|
};
|
|
78
80
|
return [4 /*yield*/, this.getDbInstance().setItem(key, data)];
|
|
79
81
|
case 1:
|
|
80
|
-
|
|
82
|
+
_a.sent();
|
|
81
83
|
return [2 /*return*/];
|
|
82
84
|
}
|
|
83
85
|
});
|
|
@@ -113,14 +115,11 @@ var CacheControl = /** @class */ (function () {
|
|
|
113
115
|
var _this = this;
|
|
114
116
|
this.getDbInstance()
|
|
115
117
|
.iterate(function (value, key, _) {
|
|
116
|
-
if (value
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return console.log("Key ".concat(key, " is cleared!"));
|
|
122
|
-
});
|
|
123
|
-
}
|
|
118
|
+
if (value &&
|
|
119
|
+
moment(value.expire).isSameOrBefore(moment.now())) {
|
|
120
|
+
_this.getDbInstance().removeItem(key, function () {
|
|
121
|
+
return console.log("Key ".concat(key, " is cleared!"));
|
|
122
|
+
});
|
|
124
123
|
}
|
|
125
124
|
})
|
|
126
125
|
.then(function () {
|
package/dist/utils/chat.utils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChatConstants } from "../constants";
|
|
2
|
-
import
|
|
2
|
+
import _ from "lodash";
|
|
3
3
|
function getCanSendToSuperiors(chat, chatPermissions, quitedGroup, identification, userHierarchy) {
|
|
4
4
|
if (quitedGroup ||
|
|
5
5
|
!chatPermissions.canSendToSuperiors ||
|
|
@@ -66,7 +66,7 @@ export function getChatName(chat) {
|
|
|
66
66
|
if (!(chat === null || chat === void 0 ? void 0 : chat.name))
|
|
67
67
|
return "";
|
|
68
68
|
return (chat === null || chat === void 0 ? void 0 : chat.type) !== ChatConstants.TYPE_CHAT.GROUP
|
|
69
|
-
? startCase((_a = chat.name) === null || _a === void 0 ? void 0 : _a.toLowerCase())
|
|
69
|
+
? _.startCase((_a = chat.name) === null || _a === void 0 ? void 0 : _a.toLowerCase())
|
|
70
70
|
: chat.name;
|
|
71
71
|
}
|
|
72
72
|
export function getPlaceholderMessage(canSendMessages, isActive) {
|
package/dist/utils/date.utils.js
CHANGED
|
@@ -1,48 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import _ from "lodash";
|
|
2
|
+
import moment from "moment";
|
|
3
3
|
import { GlobalStore } from "redux-micro-frontend";
|
|
4
4
|
var DateUtils = /** @class */ (function () {
|
|
5
5
|
function DateUtils() {
|
|
6
6
|
}
|
|
7
|
-
DateUtils.normalizeISODateString = function (dateString) {
|
|
8
|
-
if (!dateString)
|
|
9
|
-
return "";
|
|
10
|
-
if (/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
|
|
11
|
-
return "".concat(dateString, "T00:00:00");
|
|
12
|
-
}
|
|
13
|
-
return dateString;
|
|
14
|
-
};
|
|
15
|
-
DateUtils.parseISODate = function (date) {
|
|
16
|
-
if (!date)
|
|
17
|
-
return new Date();
|
|
18
|
-
if (date instanceof Date) {
|
|
19
|
-
return date;
|
|
20
|
-
}
|
|
21
|
-
return parseISO(this.normalizeISODateString(date));
|
|
22
|
-
};
|
|
23
|
-
DateUtils.formatISODate = function (date) {
|
|
24
|
-
if (!date)
|
|
25
|
-
return undefined;
|
|
26
|
-
var parsed = this.parseISODate(date);
|
|
27
|
-
return formatISO(parsed, { representation: "date" });
|
|
28
|
-
};
|
|
29
|
-
DateUtils.formatDatePattern = function (date, pattern, options) {
|
|
30
|
-
if (pattern === void 0) { pattern = "dd/MM/yyyy"; }
|
|
31
|
-
if (!date)
|
|
32
|
-
return "";
|
|
33
|
-
var parsed = this.parseISODate(date);
|
|
34
|
-
if (Number.isNaN(parsed.getTime()))
|
|
35
|
-
return "";
|
|
36
|
-
return format(parsed, pattern, options);
|
|
37
|
-
};
|
|
38
7
|
DateUtils.isSameDateAsNow = function (date) {
|
|
39
|
-
return
|
|
8
|
+
return moment(date).isSame(moment(new Date()), "day");
|
|
40
9
|
};
|
|
41
10
|
DateUtils.isPastDateAsNow = function (date) {
|
|
42
|
-
return isBefore(
|
|
11
|
+
return moment(date).isBefore(moment(new Date()));
|
|
43
12
|
};
|
|
44
13
|
DateUtils.getDateBetweenDates = function (start, end) {
|
|
45
|
-
var clonedStart = cloneDeep(start);
|
|
14
|
+
var clonedStart = _.cloneDeep(start);
|
|
46
15
|
if (!start ||
|
|
47
16
|
!end ||
|
|
48
17
|
!(start instanceof Date) ||
|
|
@@ -109,7 +78,7 @@ var DateUtils = /** @class */ (function () {
|
|
|
109
78
|
if (length === void 0) { length = 2; }
|
|
110
79
|
return time.toString().padStart(length, "0");
|
|
111
80
|
}
|
|
112
|
-
var diff =
|
|
81
|
+
var diff = moment(compareDate).diff(moment(), "seconds");
|
|
113
82
|
var days = formatTime(Math.floor(diff / (60 * 60 * 24)), 3);
|
|
114
83
|
var hours = formatTime(Math.floor((diff % (60 * 60 * 24)) / (60 * 60)));
|
|
115
84
|
var minutes = formatTime(Math.floor((diff % (60 * 60)) / 60));
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge entre a SPA web e o client desktop nativo (Tauri).
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANTE — sobre quem injeta o que:
|
|
5
|
+
*
|
|
6
|
+
* O client Tauri injeta DUAS coisas no global ANTES do primeiro byte
|
|
7
|
+
* da SPA carregar, via `initialization_script`:
|
|
8
|
+
*
|
|
9
|
+
* 1. `window.__ROBBYSON_CLIENT__` — dados crus (frozen)
|
|
10
|
+
* 2. `window.RobbysonDesktop` — API helper (frozen)
|
|
11
|
+
*
|
|
12
|
+
* AMBAS sao injetadas pelo CLIENT, nao por esta biblioteca. Por que
|
|
13
|
+
* isso importa: em Module Federation com `singleton: true`, se algum
|
|
14
|
+
* container co-carregado tem versao defasada desta lib (sem este
|
|
15
|
+
* helper), o `DesktopClient` daqui resolveria como `undefined` no
|
|
16
|
+
* runtime federado. Por isso preferimos delegar pro global injetado.
|
|
17
|
+
*
|
|
18
|
+
* O `DesktopClient` desta lib e um WRAPPER TIPADO opcional sobre
|
|
19
|
+
* `window.RobbysonDesktop`. Funciona sempre que essa lib for a versao
|
|
20
|
+
* nova; quando vc nao puder garantir isso (cenarios mistos local +
|
|
21
|
+
* cluster), use `window.RobbysonDesktop` diretamente — funciona em
|
|
22
|
+
* qualquer container, com qualquer versao da lib.
|
|
23
|
+
*
|
|
24
|
+
* Casos de uso:
|
|
25
|
+
* - login-container: aplicar tema do contratante pre-resolvido pelo
|
|
26
|
+
* client (sem flash visual no first paint)
|
|
27
|
+
* - main-container: pular fetch de tema se já veio em cache
|
|
28
|
+
* - qualquer container: esconder botões de "baixar app", trocar
|
|
29
|
+
* banner web por notificação nativa, etc.
|
|
30
|
+
*/
|
|
31
|
+
var __assign = (this && this.__assign) || function () {
|
|
32
|
+
__assign = Object.assign || function(t) {
|
|
33
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
34
|
+
s = arguments[i];
|
|
35
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
36
|
+
t[p] = s[p];
|
|
37
|
+
}
|
|
38
|
+
return t;
|
|
39
|
+
};
|
|
40
|
+
return __assign.apply(this, arguments);
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Wrapper tipado sobre `window.RobbysonDesktop` (com fallback pra
|
|
44
|
+
* `window.__ROBBYSON_CLIENT__` quando o helper nao esta presente).
|
|
45
|
+
*
|
|
46
|
+
* **Quando usar:** containers que sabem que estao na ultima versao
|
|
47
|
+
* desta lib e querem auto-completar / type safety.
|
|
48
|
+
*
|
|
49
|
+
* **Quando NAO usar:** containers que podem ser co-carregados em
|
|
50
|
+
* Module Federation com versoes mais antigas desta lib. Nesse caso,
|
|
51
|
+
* leia `window.RobbysonDesktop` diretamente — funciona em qualquer
|
|
52
|
+
* container, com qualquer versao.
|
|
53
|
+
*/
|
|
54
|
+
var DesktopClient = /** @class */ (function () {
|
|
55
|
+
function DesktopClient() {
|
|
56
|
+
}
|
|
57
|
+
/** True quando a SPA está sendo carregada pelo client desktop Tauri. */
|
|
58
|
+
DesktopClient.isRunning = function () {
|
|
59
|
+
var _a, _b;
|
|
60
|
+
if (typeof window === "undefined")
|
|
61
|
+
return false;
|
|
62
|
+
return (_b = (_a = window.RobbysonDesktop) === null || _a === void 0 ? void 0 : _a.isRunning()) !== null && _b !== void 0 ? _b : !!window.__ROBBYSON_CLIENT__;
|
|
63
|
+
};
|
|
64
|
+
/** Objeto cru injetado pelo client. Null em browser comum. */
|
|
65
|
+
DesktopClient.get = function () {
|
|
66
|
+
var _a, _b, _c;
|
|
67
|
+
if (typeof window === "undefined")
|
|
68
|
+
return null;
|
|
69
|
+
return (_c = (_b = (_a = window.RobbysonDesktop) === null || _a === void 0 ? void 0 : _a.get()) !== null && _b !== void 0 ? _b : window.__ROBBYSON_CLIENT__) !== null && _c !== void 0 ? _c : null;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Dados pre-resolvidos pelo client antes do boot da SPA (contractor +
|
|
73
|
+
* tema). Retorna null se rodando fora do client ou se o client não
|
|
74
|
+
* conseguiu resolver esses dados.
|
|
75
|
+
*/
|
|
76
|
+
DesktopClient.getBootstrap = function () {
|
|
77
|
+
var _a, _b;
|
|
78
|
+
return (_b = (_a = DesktopClient.get()) === null || _a === void 0 ? void 0 : _a.bootstrap) !== null && _b !== void 0 ? _b : null;
|
|
79
|
+
};
|
|
80
|
+
/** Capabilities expostas pelo runtime nativo. */
|
|
81
|
+
DesktopClient.getCapabilities = function () {
|
|
82
|
+
var _a, _b;
|
|
83
|
+
return (_b = (_a = DesktopClient.get()) === null || _a === void 0 ? void 0 : _a.capabilities) !== null && _b !== void 0 ? _b : null;
|
|
84
|
+
};
|
|
85
|
+
/** Atalho pra checar uma capability específica. */
|
|
86
|
+
DesktopClient.hasCapability = function (name) {
|
|
87
|
+
var _a, _b;
|
|
88
|
+
return (_b = (_a = DesktopClient.getCapabilities()) === null || _a === void 0 ? void 0 : _a[name]) !== null && _b !== void 0 ? _b : false;
|
|
89
|
+
};
|
|
90
|
+
/** Versão do client desktop (semver). Útil pra gates progressivos. */
|
|
91
|
+
DesktopClient.getVersion = function () {
|
|
92
|
+
var _a, _b;
|
|
93
|
+
return (_b = (_a = DesktopClient.get()) === null || _a === void 0 ? void 0 : _a.version) !== null && _b !== void 0 ? _b : null;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Nome do modulo em modo standalone/kiosk (ex: "chat"). Retorna null
|
|
97
|
+
* quando o client esta em modo completo (sem restricao de modulo).
|
|
98
|
+
* Combina com a flag `?standalone=true` que a plataforma ja le pra
|
|
99
|
+
* decidir entre `ApplicationRoutes` e `StandaloneRoutes` (branch
|
|
100
|
+
* `35455-standalone-modo-kiosk-para-modulo-de-chat-2`).
|
|
101
|
+
*/
|
|
102
|
+
DesktopClient.getStandaloneModule = function () {
|
|
103
|
+
var _a, _b;
|
|
104
|
+
return (_b = (_a = DesktopClient.get()) === null || _a === void 0 ? void 0 : _a.standaloneModule) !== null && _b !== void 0 ? _b : null;
|
|
105
|
+
};
|
|
106
|
+
/** True quando o client foi configurado em modo standalone. */
|
|
107
|
+
DesktopClient.isStandalone = function () {
|
|
108
|
+
return !!DesktopClient.getStandaloneModule();
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* True quando a janela atual e uma popout (janela secundaria, ex:
|
|
112
|
+
* conversa de chat destacada via `openChatWindow`). Detectado pela
|
|
113
|
+
* presenca de `?popped=true` na URL.
|
|
114
|
+
*
|
|
115
|
+
* Fallback de URL parsing para o caso de o helper global ainda nao
|
|
116
|
+
* estar disponivel (deteccao funciona fora do client desktop tambem,
|
|
117
|
+
* util pra testes e debug em browser).
|
|
118
|
+
*/
|
|
119
|
+
DesktopClient.isPopout = function () {
|
|
120
|
+
var _a;
|
|
121
|
+
if (typeof window === "undefined")
|
|
122
|
+
return false;
|
|
123
|
+
if ((_a = window.RobbysonDesktop) === null || _a === void 0 ? void 0 : _a.isPopout) {
|
|
124
|
+
return window.RobbysonDesktop.isPopout();
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
return (new URLSearchParams(window.location.search).get("popped") ===
|
|
128
|
+
"true");
|
|
129
|
+
}
|
|
130
|
+
catch (_b) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Drena deep links pendentes no buffer do client. Chamar uma vez no
|
|
136
|
+
* mount da SPA (apos os reducers/router estarem prontos pra rotear).
|
|
137
|
+
* Retorna lista vazia em browser ou em versoes antigas do client.
|
|
138
|
+
*/
|
|
139
|
+
DesktopClient.consumeDeepLinks = function () {
|
|
140
|
+
if (typeof window === "undefined")
|
|
141
|
+
return Promise.resolve([]);
|
|
142
|
+
var api = window.RobbysonDesktop;
|
|
143
|
+
if (!(api === null || api === void 0 ? void 0 : api.consumeDeepLinks))
|
|
144
|
+
return Promise.resolve([]);
|
|
145
|
+
return api.consumeDeepLinks();
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Escuta deep links entregues em tempo real (URL externa clicada com
|
|
149
|
+
* app aberto, click em notification, etc). Combine com
|
|
150
|
+
* `consumeDeepLinks` no boot pra cobrir cold start + steady state.
|
|
151
|
+
* Em browser ou versoes antigas do client retorna no-op.
|
|
152
|
+
*/
|
|
153
|
+
DesktopClient.onDeepLink = function (callback) {
|
|
154
|
+
if (typeof window === "undefined")
|
|
155
|
+
return function () { };
|
|
156
|
+
var api = window.RobbysonDesktop;
|
|
157
|
+
if (!(api === null || api === void 0 ? void 0 : api.onDeepLink))
|
|
158
|
+
return function () { };
|
|
159
|
+
return api.onDeepLink(callback);
|
|
160
|
+
};
|
|
161
|
+
return DesktopClient;
|
|
162
|
+
}());
|
|
163
|
+
export { DesktopClient };
|
|
164
|
+
var GROUP_TYPE = "group";
|
|
165
|
+
var AI_AGENT_PREFIX = "ai_agent_";
|
|
166
|
+
/**
|
|
167
|
+
* Monta `OpenChatWindowParams` a partir dos dados crus da conversa +
|
|
168
|
+
* sessao. Centralizado aqui pra evitar duplicacao entre os call sites
|
|
169
|
+
* (popout-launcher do chat-container + auto-open do main-container).
|
|
170
|
+
*
|
|
171
|
+
* Excluido aqui: `focus` (caller decide), porque a semantica eh diferente
|
|
172
|
+
* em cada use case — click manual usa default (true), auto-open passa
|
|
173
|
+
* false explicitamente.
|
|
174
|
+
*/
|
|
175
|
+
export function buildOpenChatWindowParams(input) {
|
|
176
|
+
var _a, _b, _c, _d, _e, _f;
|
|
177
|
+
var chat = input.chat, loggedUser = input.loggedUser, apiUrl = input.apiUrl, wsUrl = input.wsUrl, locale = input.locale;
|
|
178
|
+
// Tipo + agent code (espelha popout-launcher legado)
|
|
179
|
+
var chatType = "individual";
|
|
180
|
+
var aiAgentCode = null;
|
|
181
|
+
if (chat.type === GROUP_TYPE) {
|
|
182
|
+
chatType = "group";
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
var agentUser = (_a = chat.users) === null || _a === void 0 ? void 0 : _a.find(function (u) {
|
|
186
|
+
return typeof u.identification === "string" &&
|
|
187
|
+
u.identification.startsWith(AI_AGENT_PREFIX);
|
|
188
|
+
});
|
|
189
|
+
if (agentUser === null || agentUser === void 0 ? void 0 : agentUser.identification) {
|
|
190
|
+
chatType = "ai-agent";
|
|
191
|
+
aiAgentCode = agentUser.identification.substring(AI_AGENT_PREFIX.length);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Foto: 1:1 / agent = outro participante; grupo = chat.photo
|
|
195
|
+
var contactPicture;
|
|
196
|
+
if (chatType === "group") {
|
|
197
|
+
contactPicture = chat.photo;
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
var other = (_b = chat.users) === null || _b === void 0 ? void 0 : _b.find(function (u) {
|
|
201
|
+
return u.identification != null &&
|
|
202
|
+
String(u.identification) !== String(loggedUser.identification);
|
|
203
|
+
});
|
|
204
|
+
contactPicture = other === null || other === void 0 ? void 0 : other.photo;
|
|
205
|
+
}
|
|
206
|
+
// Label: nome do outro em 1:1/agent; nome do grupo caso contrario
|
|
207
|
+
var label;
|
|
208
|
+
if (chat.type !== GROUP_TYPE) {
|
|
209
|
+
var other = (_c = chat.users) === null || _c === void 0 ? void 0 : _c.find(function (u) {
|
|
210
|
+
return u.identification != null &&
|
|
211
|
+
String(u.identification) !== String(loggedUser.identification);
|
|
212
|
+
});
|
|
213
|
+
label = (_d = other === null || other === void 0 ? void 0 : other.name) !== null && _d !== void 0 ? _d : chat.name;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
label = chat.name;
|
|
217
|
+
}
|
|
218
|
+
// Chave AES — mesma derivacao da lib legacy
|
|
219
|
+
var usersForKey = ((_e = chat.users) !== null && _e !== void 0 ? _e : [])
|
|
220
|
+
.filter(function (u) { return u.initial; })
|
|
221
|
+
.map(function (u) { return u.robbyson_user_id; })
|
|
222
|
+
.sort()
|
|
223
|
+
.join("+");
|
|
224
|
+
var chatEncryptionKey = "RobbYson@".concat(chat._id, "@").concat(usersForKey, "@RobbYson");
|
|
225
|
+
// Subset pra lookup de nomes
|
|
226
|
+
var participants = ((_f = chat.users) !== null && _f !== void 0 ? _f : []).map(function (u) {
|
|
227
|
+
var _a, _b;
|
|
228
|
+
return ({
|
|
229
|
+
identification: String((_a = u.identification) !== null && _a !== void 0 ? _a : ""),
|
|
230
|
+
name: String((_b = u.name) !== null && _b !== void 0 ? _b : ""),
|
|
231
|
+
photo: u.photo,
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
return __assign({ conversationId: String(chat._id), label: label || "", chatType: chatType, aiAgentCode: aiAgentCode, participants: participants, sessionKey: loggedUser.SessionKey, currentUserId: String(loggedUser.identification), apiUrl: apiUrl, wsUrl: wsUrl, contactPicture: contactPicture, chatEncryptionKey: chatEncryptionKey }, (locale ? { locale: locale } : {}));
|
|
235
|
+
}
|
package/dist/utils/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var RobbysonNavigate = /** @class */ (function () {
|
|
|
15
15
|
function RobbysonNavigate() {
|
|
16
16
|
}
|
|
17
17
|
RobbysonNavigate.to = function (url, state) {
|
|
18
|
+
var _a;
|
|
18
19
|
RobbysonNavigate._globalStore = GlobalStore.Get();
|
|
19
20
|
RobbysonNavigate._globalState =
|
|
20
21
|
RobbysonNavigate._globalStore.GetGlobalState();
|
|
@@ -22,6 +23,16 @@ var RobbysonNavigate = /** @class */ (function () {
|
|
|
22
23
|
var routeState = __assign(__assign({}, state), { pathname: history.location.pathname });
|
|
23
24
|
this.setLocationHistory(history.location.pathname);
|
|
24
25
|
// TODO: Usar a LIB PATH para concatenar a URL
|
|
26
|
+
var isStandaloneMode = RobbysonNavigate._globalState.Global.RootApp.isStandaloneMode;
|
|
27
|
+
if (isStandaloneMode) {
|
|
28
|
+
var standaloneQueryParams = (_a = this.getQueryParams()) === null || _a === void 0 ? void 0 : _a.standalone;
|
|
29
|
+
if (standaloneQueryParams) {
|
|
30
|
+
var urlHasQueryParams = url.includes("?") ? true : false;
|
|
31
|
+
url += urlHasQueryParams
|
|
32
|
+
? "&standalone=".concat(standaloneQueryParams)
|
|
33
|
+
: "?standalone=".concat(standaloneQueryParams);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
25
36
|
history.push("/operacao".concat(url), routeState);
|
|
26
37
|
};
|
|
27
38
|
RobbysonNavigate.openInNewTab = function (url) {
|
|
@@ -85,12 +96,12 @@ var RobbysonNavigate = /** @class */ (function () {
|
|
|
85
96
|
return RobbysonNavigate.getPathname().includes(path);
|
|
86
97
|
};
|
|
87
98
|
RobbysonNavigate.getQueryParams = function () {
|
|
88
|
-
var _a;
|
|
99
|
+
var _a, _b;
|
|
89
100
|
RobbysonNavigate._globalStore = GlobalStore.Get();
|
|
90
101
|
RobbysonNavigate._globalState =
|
|
91
102
|
RobbysonNavigate._globalStore.GetGlobalState();
|
|
92
103
|
var history = (_a = RobbysonNavigate._globalState.Global) === null || _a === void 0 ? void 0 : _a.RootApp.history;
|
|
93
|
-
return queryString.parse(history === null || history === void 0 ? void 0 : history.location.search, {
|
|
104
|
+
return queryString.parse((_b = history === null || history === void 0 ? void 0 : history.location) === null || _b === void 0 ? void 0 : _b.search, {
|
|
94
105
|
sort: false,
|
|
95
106
|
});
|
|
96
107
|
};
|
package/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "robbyson-frontend-library",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.188",
|
|
4
4
|
"description": "Robbyson frontend Library",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
"@types/lovefield": "^2.1.6",
|
|
35
35
|
"axios": "^1.3.5",
|
|
36
36
|
"crypto-js": "^4.1.1",
|
|
37
|
-
"date-fns": "^3.6.0",
|
|
38
37
|
"history": "^5.3.0",
|
|
39
38
|
"js-sha256": "^0.9.0",
|
|
40
39
|
"localforage": "^1.10.0",
|
|
41
|
-
"lodash": "^4.17.
|
|
40
|
+
"lodash": "^4.17.21",
|
|
42
41
|
"lovefield": "^2.1.12",
|
|
42
|
+
"moment": "^2.29.4",
|
|
43
43
|
"query-string": "^8.1.0",
|
|
44
44
|
"react": "^18.2.0",
|
|
45
45
|
"react-inlinesvg": "^3.0.2",
|
|
@@ -23,7 +23,13 @@ const HEADER_HEIGHT_CUSTOM_PAGE = 40;
|
|
|
23
23
|
|
|
24
24
|
export const SidebarPadding = styled.div`
|
|
25
25
|
padding-left: calc(${SIDEBAR_WIDTH}px + 55px);
|
|
26
|
-
|
|
26
|
+
/*
|
|
27
|
+
* 100vh com fallback. Em ambientes que injetam chrome (Tauri title
|
|
28
|
+
* bar), --rbs-app-h ja desconta a barra. Em browser comum, var nao
|
|
29
|
+
* existe e o fallback (100vh + 8px equivalente) mantem comportamento
|
|
30
|
+
* original.
|
|
31
|
+
*/
|
|
32
|
+
height: calc(var(--rbs-app-h, 100vh) + 8px);
|
|
27
33
|
`;
|
|
28
34
|
|
|
29
35
|
export const PageContainer = styled.div`
|
|
@@ -116,7 +122,14 @@ export const Content = styled.div<ContentProps>`
|
|
|
116
122
|
const paddingBottomDesktop = usePageHeader ? 0 : PADDING_BOTTOM_DESKTOP;
|
|
117
123
|
|
|
118
124
|
return css`
|
|
119
|
-
|
|
125
|
+
/*
|
|
126
|
+
* Altura util do <Content>: desconta padding + header da viewport.
|
|
127
|
+
* Usamos var(--rbs-app-h, 100vh) em vez de 100vh puro pra
|
|
128
|
+
* cooperar com chrome injetado em runtime (client desktop Tauri
|
|
129
|
+
* publica essa var em :root). Browser comum cai no fallback
|
|
130
|
+
* 100vh — comportamento original preservado.
|
|
131
|
+
*/
|
|
132
|
+
height: ${`calc(var(--rbs-app-h, 100vh) - ${
|
|
120
133
|
PADDING_TOP_DESKTOP +
|
|
121
134
|
paddingBottomDesktop +
|
|
122
135
|
headerHeightDesktop +
|
|
@@ -125,7 +138,7 @@ export const Content = styled.div<ContentProps>`
|
|
|
125
138
|
|
|
126
139
|
@media (max-width: ${LayoutDimensions.width.horizontalIpadMini}px) {
|
|
127
140
|
height: calc(
|
|
128
|
-
100vh -
|
|
141
|
+
var(--rbs-app-h, 100vh) -
|
|
129
142
|
${
|
|
130
143
|
PADDING_TOP_DESKTOP +
|
|
131
144
|
PADDING_BOTTOM_MOBILE +
|
|
@@ -133,11 +146,11 @@ export const Content = styled.div<ContentProps>`
|
|
|
133
146
|
contentMarginTop
|
|
134
147
|
}px
|
|
135
148
|
);
|
|
136
|
-
}
|
|
149
|
+
}
|
|
137
150
|
|
|
138
151
|
@media (max-width: ${LayoutDimensions.width.mobile}px) {
|
|
139
152
|
height: calc(
|
|
140
|
-
100vh -
|
|
153
|
+
var(--rbs-app-h, 100vh) -
|
|
141
154
|
${
|
|
142
155
|
PADDING_TOP_MOBILE +
|
|
143
156
|
PADDING_BOTTOM_MOBILE +
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './typing-indicator.interface';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
///<reference types="react" />
|
|
2
|
+
///<reference types="robbyson-frontend-library" />
|
|
3
|
+
|
|
4
|
+
declare module "styleguide/TypingIndicator" {
|
|
5
|
+
import { ITypingIndicatorProps } from "robbyson-frontend-library";
|
|
6
|
+
const TypingIndicator: React.ComponentType<ITypingIndicatorProps>;
|
|
7
|
+
|
|
8
|
+
export default TypingIndicator;
|
|
9
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
|
|
2
|
-
import
|
|
2
|
+
import moment from "moment";
|
|
3
3
|
import { CacheConfig, CacheControl, Cache } from "../utils";
|
|
4
4
|
import sha1 from "crypto-js/sha1";
|
|
5
5
|
import { GlobalStore, IGlobalStore } from "redux-micro-frontend";
|
|
@@ -52,9 +52,9 @@ export class BaseRepository {
|
|
|
52
52
|
const { expire, value }: Cache =
|
|
53
53
|
(await CacheControl.getCache(key)) || {};
|
|
54
54
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
const isExpired: boolean = moment().isSameOrAfter(
|
|
56
|
+
moment(expire)
|
|
57
|
+
);
|
|
58
58
|
|
|
59
59
|
if (value && !isExpired) {
|
|
60
60
|
console.log("RECOVERED FROM CACHE", url);
|
|
@@ -58,4 +58,10 @@ export interface IChatRepository {
|
|
|
58
58
|
}): any;
|
|
59
59
|
getGroupImage(): Promise<string>;
|
|
60
60
|
updateMessage(payload: MessageModel): Promise<MessageModel>;
|
|
61
|
+
/**
|
|
62
|
+
* Reinicia o contexto da conversa user+agente. Mensagens permanecem
|
|
63
|
+
* visiveis no historico, mas o runtime do agente passa a ignorar
|
|
64
|
+
* mensagens anteriores ao reset (corte por marker session_started).
|
|
65
|
+
*/
|
|
66
|
+
resetAgentSession(agentCode: string): Promise<{ conversation_id: string }>;
|
|
61
67
|
}
|
|
@@ -140,4 +140,10 @@ export interface IChatService {
|
|
|
140
140
|
getGroupInformation(): IChatApp["group"];
|
|
141
141
|
getNewChatListWithoutRepeating(params : ChatDTO.INewChatListWithoutRepeating): ChatDTO.INewChatListWithoutRepeatingResponse;
|
|
142
142
|
countMessageNotRead(conversations: UserListModel[] | ChatModel[]) : number;
|
|
143
|
+
/**
|
|
144
|
+
* Reinicia a sessao de um agente IA (system message + AMQP session_started).
|
|
145
|
+
* Historico permanece visivel; runtime do agente passa a ignorar o
|
|
146
|
+
* que veio antes do reset (corte por marker no Build Gemini request).
|
|
147
|
+
*/
|
|
148
|
+
resetAgentSession(agentCode: string): Promise<{ conversation_id: string }>;
|
|
143
149
|
}
|
|
@@ -9,4 +9,10 @@ export interface IThemeService {
|
|
|
9
9
|
getApplicationTheme(): ThemeBase | undefined;
|
|
10
10
|
getPng(png: string): string;
|
|
11
11
|
setContractorTheme(contractorId: number): Promise<void>;
|
|
12
|
+
isStandaloneMode(): boolean;
|
|
13
|
+
enableStandalone(): void;
|
|
14
|
+
disableStandalone(): void;
|
|
15
|
+
handleInitializeStandaloneMode(): void;
|
|
16
|
+
isOperationStandaloneMode(): boolean;
|
|
17
|
+
|
|
12
18
|
}
|