@escapenavigator/services 1.10.138 → 1.10.140
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/api/init-client-api.d.ts +2 -0
- package/dist/api/init-client-api.js +2 -0
- package/dist/api/orders-api/create.d.ts +5 -0
- package/dist/api/profiles-api/index.d.ts +1 -1
- package/dist/api/profiles-api/index.js +1 -1
- package/dist/api/widget-sessions-api/get-full.d.ts +3 -0
- package/dist/api/widget-sessions-api/get-full.js +8 -0
- package/dist/api/widget-sessions-api/index.d.ts +12 -0
- package/dist/api/widget-sessions-api/index.js +13 -0
- package/dist/api/widget-sessions-api/list.d.ts +12 -0
- package/dist/api/widget-sessions-api/list.js +9 -0
- package/dist/api/widget-sessions-api/remove.d.ts +4 -0
- package/dist/api/widget-sessions-api/remove.js +8 -0
- package/dist/api/widget-sessions-api/update-comment.d.ts +9 -0
- package/dist/api/widget-sessions-api/update-comment.js +12 -0
- package/dist/hooks/use-api-method/index.js +47 -8
- package/dist/hooks/use-api-method/reducers/api.js +11 -1
- package/package.json +4 -4
|
@@ -71,6 +71,7 @@ import { uploadsApiDeclaration } from './uploads-api';
|
|
|
71
71
|
import { upsellingsApiDeclaration } from './upsellings-api';
|
|
72
72
|
import { userMessagesApiDeclaration } from './user-messages-api';
|
|
73
73
|
import { usersApiDeclaration } from './users-api';
|
|
74
|
+
import { widgetSessionsApiDeclaration } from './widget-sessions-api';
|
|
74
75
|
import { widgetsApiDeclaration } from './widgets-api';
|
|
75
76
|
export type InitApiDeclaration = {
|
|
76
77
|
customFieldsApi: Api<typeof customFieldsApiDeclaration>;
|
|
@@ -129,6 +130,7 @@ export type InitApiDeclaration = {
|
|
|
129
130
|
partners: Api<typeof partnersApiDeclaration>;
|
|
130
131
|
questrooms: Api<typeof questroomsApiDeclaration>;
|
|
131
132
|
widgets: Api<typeof widgetsApiDeclaration>;
|
|
133
|
+
widgetSessions: Api<typeof widgetSessionsApiDeclaration>;
|
|
132
134
|
profiles: Api<typeof profilesApiDeclaration>;
|
|
133
135
|
users: Api<typeof usersApiDeclaration>;
|
|
134
136
|
clients: Api<typeof clientsApiDeclaration>;
|
|
@@ -75,6 +75,7 @@ var uploads_api_1 = require("./uploads-api");
|
|
|
75
75
|
var upsellings_api_1 = require("./upsellings-api");
|
|
76
76
|
var user_messages_api_1 = require("./user-messages-api");
|
|
77
77
|
var users_api_1 = require("./users-api");
|
|
78
|
+
var widget_sessions_api_1 = require("./widget-sessions-api");
|
|
78
79
|
var widgets_api_1 = require("./widgets-api");
|
|
79
80
|
var initClientApi = function (url, clientOptions) { return ({
|
|
80
81
|
customFieldsApi: (0, _1.initApi)(custom_fields_api_1.customFieldsApiDeclaration, url, clientOptions),
|
|
@@ -133,6 +134,7 @@ var initClientApi = function (url, clientOptions) { return ({
|
|
|
133
134
|
partners: (0, _1.initApi)(partners_api_1.partnersApiDeclaration, url, clientOptions),
|
|
134
135
|
questrooms: (0, _1.initApi)(questrooms_api_1.questroomsApiDeclaration, url, clientOptions),
|
|
135
136
|
widgets: (0, _1.initApi)(widgets_api_1.widgetsApiDeclaration, url, clientOptions),
|
|
137
|
+
widgetSessions: (0, _1.initApi)(widget_sessions_api_1.widgetSessionsApiDeclaration, url, clientOptions),
|
|
136
138
|
profiles: (0, _1.initApi)(profiles_api_1.profilesApiDeclaration, url, clientOptions),
|
|
137
139
|
users: (0, _1.initApi)(users_api_1.usersApiDeclaration, url, clientOptions),
|
|
138
140
|
clients: (0, _1.initApi)(clients_api_1.clientsApiDeclaration, url, clientOptions),
|
|
@@ -7,10 +7,15 @@ type ParamsData = {
|
|
|
7
7
|
* Бэкенд возвращает не полный `OrderRO`, а лёгкий `{success, orderId}` —
|
|
8
8
|
* фронт использует `orderId` чтобы тут же дёрнуть `orders.getOne(orderId)`
|
|
9
9
|
* под slim `MODAL_RELATIONS` (см. `useOrderApi.refreshOrder`).
|
|
10
|
+
*
|
|
11
|
+
* `groupId` приходит только если в DTO передан `attachToOrderId`
|
|
12
|
+
* (dealAddMode): бэк атомарно прикрепил новый ордер к группе и вернул
|
|
13
|
+
* её id — фронт сразу обновляет `dealAddMode.groupId` без второго запроса.
|
|
10
14
|
*/
|
|
11
15
|
type ResponseData = {
|
|
12
16
|
success: boolean;
|
|
13
17
|
orderId: number;
|
|
18
|
+
groupId?: number;
|
|
14
19
|
};
|
|
15
20
|
export declare const create: ApiMethodDeclaration<ParamsData, ResponseData>;
|
|
16
21
|
export {};
|
|
@@ -104,9 +104,9 @@ import { paginateBills } from './subscription/paginate-bills';
|
|
|
104
104
|
import { cancelSubscription } from './subscription/remove-subscription';
|
|
105
105
|
import { updateSubscription } from './subscription/update-subscription';
|
|
106
106
|
import { update } from './update';
|
|
107
|
-
import { updateProfileCommission } from './update-profile-commission';
|
|
108
107
|
import { updateCrmVerification } from './update-crm-verification';
|
|
109
108
|
import { updatePartnerProgram } from './update-partner-program';
|
|
109
|
+
import { updateProfileCommission } from './update-profile-commission';
|
|
110
110
|
import { updateStep } from './update-step';
|
|
111
111
|
import { createProfileWaiver } from './waiver/create-profile-waiver';
|
|
112
112
|
import { getProfileWaiver } from './waiver/get-profile-waiver';
|
|
@@ -107,9 +107,9 @@ var paginate_bills_1 = require("./subscription/paginate-bills");
|
|
|
107
107
|
var remove_subscription_1 = require("./subscription/remove-subscription");
|
|
108
108
|
var update_subscription_1 = require("./subscription/update-subscription");
|
|
109
109
|
var update_2 = require("./update");
|
|
110
|
-
var update_profile_commission_1 = require("./update-profile-commission");
|
|
111
110
|
var update_crm_verification_1 = require("./update-crm-verification");
|
|
112
111
|
var update_partner_program_1 = require("./update-partner-program");
|
|
112
|
+
var update_profile_commission_1 = require("./update-profile-commission");
|
|
113
113
|
var update_step_1 = require("./update-step");
|
|
114
114
|
var create_profile_waiver_1 = require("./waiver/create-profile-waiver");
|
|
115
115
|
var get_profile_waiver_1 = require("./waiver/get-profile-waiver");
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getFull } from './get-full';
|
|
2
|
+
import { list } from './list';
|
|
3
|
+
import { remove } from './remove';
|
|
4
|
+
import { updateComment } from './update-comment';
|
|
5
|
+
type ApiDeclaration = {
|
|
6
|
+
list: typeof list;
|
|
7
|
+
getFull: typeof getFull;
|
|
8
|
+
updateComment: typeof updateComment;
|
|
9
|
+
remove: typeof remove;
|
|
10
|
+
};
|
|
11
|
+
export declare const widgetSessionsApiDeclaration: ApiDeclaration;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.widgetSessionsApiDeclaration = void 0;
|
|
4
|
+
var get_full_1 = require("./get-full");
|
|
5
|
+
var list_1 = require("./list");
|
|
6
|
+
var remove_1 = require("./remove");
|
|
7
|
+
var update_comment_1 = require("./update-comment");
|
|
8
|
+
exports.widgetSessionsApiDeclaration = {
|
|
9
|
+
list: list_1.list,
|
|
10
|
+
getFull: get_full_1.getFull,
|
|
11
|
+
updateComment: update_comment_1.updateComment,
|
|
12
|
+
remove: remove_1.remove,
|
|
13
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { QueryDto } from '@escapenavigator/types/dist/shared/query.dto';
|
|
2
|
+
import { QueryRO } from '@escapenavigator/types/dist/shared/query.ro';
|
|
3
|
+
import { WidgetSessionRO } from '@escapenavigator/types/dist/widget-sessions/widget-session.ro';
|
|
4
|
+
import { ApiMethodDeclaration } from '..';
|
|
5
|
+
type ResponseData = QueryRO<WidgetSessionRO & {
|
|
6
|
+
profile?: {
|
|
7
|
+
id: number;
|
|
8
|
+
title: string;
|
|
9
|
+
};
|
|
10
|
+
}>;
|
|
11
|
+
export declare const list: ApiMethodDeclaration<QueryDto, ResponseData>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateComment = void 0;
|
|
4
|
+
var updateComment = function (_a) {
|
|
5
|
+
var id = _a.id, comment = _a.comment;
|
|
6
|
+
return ({
|
|
7
|
+
url: "/admin/widget-sessions/".concat(id),
|
|
8
|
+
method: 'PATCH',
|
|
9
|
+
data: { comment: comment },
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
exports.updateComment = updateComment;
|
|
@@ -48,8 +48,33 @@ var api_2 = require("./reducers/api");
|
|
|
48
48
|
var useApiMethod = function (_a) {
|
|
49
49
|
var _b;
|
|
50
50
|
var api = _a.api, successCallback = _a.successCallback, errorCallback = _a.errorCallback;
|
|
51
|
-
|
|
51
|
+
// mounted стартует как `true`, а не `false`. Прежнее `useRef(false)` имело
|
|
52
|
+
// тонкий баг: между первым render'ом и первым flush-ем useEffect'а
|
|
53
|
+
// mounted=false, и если в этот микро-промежуток успевал свалиться запрос
|
|
54
|
+
// (быстрая сеть, кэш, microtask до commit'а) — catch-блок видел mounted=false
|
|
55
|
+
// и молча возвращал null без throw → консьюмер думал «всё ок», state
|
|
56
|
+
// оставался в loading навсегда. В React 18 StrictMode dev двойной mount
|
|
57
|
+
// только усугублял проблему (cleanup первой пары ставил false, и до
|
|
58
|
+
// useEffect второй пары mounted был false). Правда жизни: компонент уже
|
|
59
|
+
// смонтирован к моменту, как мы вообще можем вызвать fetch — значение
|
|
60
|
+
// должно быть true с самого начала, а cleanup сам поставит false.
|
|
61
|
+
var mounted = (0, react_1.useRef)(true);
|
|
52
62
|
var source = (0, react_1.useRef)(null);
|
|
63
|
+
// Inflight-counter для устойчивого loading-state в кейсе нескольких
|
|
64
|
+
// sequential/parallel вызовов на одном хук-инстансе. Без него каждый
|
|
65
|
+
// успех/фейл одной итерации делал dispatch(fetchSuccess|Failure) с
|
|
66
|
+
// loading=false → между итерациями кнопка мигала enabled-состоянием
|
|
67
|
+
// (риск двойного клика), скелетоны таблиц моргали. Считаем
|
|
68
|
+
// активные fetch'и и dispatch'им «loading=false» только когда счётчик
|
|
69
|
+
// вернулся в 0. На реальную семантику data/error не влияет — последний
|
|
70
|
+
// успех всё равно перетирает state.data, последняя ошибка — state.error.
|
|
71
|
+
//
|
|
72
|
+
// ВАЖНО про cancellation: useApiMethod исторически отменяет предыдущий
|
|
73
|
+
// запрос при новом fetch() (single source.current). Из-за этого Promise.all
|
|
74
|
+
// на одном инстансе ломается — все, кроме последнего вызова, возвращают
|
|
75
|
+
// null. Inflight-counter эту семантику не меняет, только сглаживает
|
|
76
|
+
// флик loading-state между быстрыми последовательными fetch'ами.
|
|
77
|
+
var inflightRef = (0, react_1.useRef)(0);
|
|
53
78
|
var _c = (0, react_1.useReducer)((api_2.apiReducer), api_2.initialState), state = _c[0], dispatch = _c[1];
|
|
54
79
|
// КРИТИЧНО: коллбэки держим в ref, а не в deps useCallback. Иначе
|
|
55
80
|
// call-site вроде `useApiMethod({ api, successCallback: () => ... })`
|
|
@@ -63,25 +88,36 @@ var useApiMethod = function (_a) {
|
|
|
63
88
|
successCallbackRef.current = successCallback;
|
|
64
89
|
errorCallbackRef.current = errorCallback;
|
|
65
90
|
var fetch = (0, react_1.useCallback)(function (params) { return __awaiter(void 0, void 0, void 0, function () {
|
|
66
|
-
var response, error_1, text, _a, err;
|
|
91
|
+
var wasIdle, response, error_1, text, _a, err;
|
|
67
92
|
var _b, _c, _d, _e;
|
|
68
93
|
return __generator(this, function (_f) {
|
|
69
94
|
switch (_f.label) {
|
|
70
95
|
case 0:
|
|
71
96
|
(_b = source.current) === null || _b === void 0 ? void 0 : _b.cancel();
|
|
72
97
|
source.current = axios_1.default.CancelToken.source();
|
|
98
|
+
wasIdle = inflightRef.current === 0;
|
|
99
|
+
inflightRef.current += 1;
|
|
73
100
|
_f.label = 1;
|
|
74
101
|
case 1:
|
|
75
|
-
_f.trys.push([1, 3, ,
|
|
76
|
-
|
|
102
|
+
_f.trys.push([1, 3, 8, 9]);
|
|
103
|
+
if (wasIdle)
|
|
104
|
+
dispatch((0, api_1.fetchStart)());
|
|
77
105
|
return [4 /*yield*/, api(params, {
|
|
78
106
|
cancelToken: source.current.token,
|
|
79
107
|
})];
|
|
80
108
|
case 2:
|
|
81
109
|
response = _f.sent();
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
dispatch
|
|
110
|
+
// Mounted-guard на success-path. Раньше успешный response
|
|
111
|
+
// после unmount всё равно дёргал successCallback (мог сделать
|
|
112
|
+
// navigate / showToast на размонтированном UI) и dispatch на
|
|
113
|
+
// мёртвый reducer (React 18 warning + лишний state-change в
|
|
114
|
+
// никуда). Теперь после unmount — тихо отдаём response наверх,
|
|
115
|
+
// и пусть консьюмер сам решает, что с ним делать.
|
|
116
|
+
if (mounted.current) {
|
|
117
|
+
if (successCallbackRef.current)
|
|
118
|
+
successCallbackRef.current(response, params);
|
|
119
|
+
dispatch((0, api_1.fetchSuccess)(response));
|
|
120
|
+
}
|
|
85
121
|
return [2 /*return*/, response];
|
|
86
122
|
case 3:
|
|
87
123
|
error_1 = _f.sent();
|
|
@@ -112,7 +148,10 @@ var useApiMethod = function (_a) {
|
|
|
112
148
|
dispatch((0, api_1.fetchFailure)(err));
|
|
113
149
|
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
|
114
150
|
throw err;
|
|
115
|
-
case 8:
|
|
151
|
+
case 8:
|
|
152
|
+
inflightRef.current = Math.max(0, inflightRef.current - 1);
|
|
153
|
+
return [7 /*endfinally*/];
|
|
154
|
+
case 9: return [2 /*return*/];
|
|
116
155
|
}
|
|
117
156
|
});
|
|
118
157
|
}); }, [api]);
|
|
@@ -24,7 +24,17 @@ var apiReducer = function (state, action) {
|
|
|
24
24
|
if (state === void 0) { state = exports.initialState; }
|
|
25
25
|
switch (action.type) {
|
|
26
26
|
case api_1.ActionTypes.FETCH_START:
|
|
27
|
-
|
|
27
|
+
// ВАЖНО: НЕ сбрасываем `data`/`response`/`statusOk` — это
|
|
28
|
+
// stale-while-revalidate. Прежнее `return { ...initialState, loading: true }`
|
|
29
|
+
// обнуляло данные на каждый ре-фетч, и любой консьюмер
|
|
30
|
+
// (таблицы списков, шапка с метой ордера, расписание) на
|
|
31
|
+
// время запроса показывал пустое состояние / скелетон, даже
|
|
32
|
+
// если новые данные через 200мс прилетят те же самые.
|
|
33
|
+
// Теперь данные сохраняются до прихода нового ответа —
|
|
34
|
+
// skeleton flicker на ре-фетчах исчезает. Только `error`
|
|
35
|
+
// ресетим, чтобы старая ошибка не «сидела» поверх нового
|
|
36
|
+
// запроса (если новый успешен, она и так заменится).
|
|
37
|
+
return __assign(__assign({}, state), { loading: true, error: null });
|
|
28
38
|
case api_1.ActionTypes.FETCH_SUCCESS:
|
|
29
39
|
return __assign(__assign({}, state), { loading: false, data: action.payload.response.data, response: action.payload.response, statusOk: true });
|
|
30
40
|
case api_1.ActionTypes.FETCH_FAILURE:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@escapenavigator/services",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.140",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "rm -rf dist && tsc --project tsconfig.json"
|
|
14
14
|
},
|
|
15
|
-
"gitHead": "
|
|
15
|
+
"gitHead": "cb2f3ab38ef5b8b2a38ab5b2c485e484a0cf9414",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@escapenavigator/types": "^1.10.
|
|
18
|
-
"@escapenavigator/utils": "^1.10.
|
|
17
|
+
"@escapenavigator/types": "^1.10.131",
|
|
18
|
+
"@escapenavigator/utils": "^1.10.135",
|
|
19
19
|
"axios": "^0.21.4",
|
|
20
20
|
"class-transformer": "^0.5.1",
|
|
21
21
|
"class-validator": "^0.13.2",
|