@ikatec/digisac-api-sdk 4.4.1 → 4.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apis/cards/CardsApi.cjs +70 -0
- package/dist/apis/cards/CardsApi.cjs.map +1 -1
- package/dist/apis/cards/CardsApi.d.ts +53 -1
- package/dist/apis/cards/CardsApi.d.ts.map +1 -1
- package/dist/apis/cards/CardsApi.mjs +70 -0
- package/dist/apis/cards/CardsApi.mjs.map +1 -1
- package/dist/apis/cards/types.d.ts +84 -0
- package/dist/apis/cards/types.d.ts.map +1 -1
- package/dist/apis/kanbanBoards/types.d.ts +33 -4
- package/dist/apis/kanbanBoards/types.d.ts.map +1 -1
- package/dist/apis/kanbanCards/KanbanCardsApi.cjs +8 -0
- package/dist/apis/kanbanCards/KanbanCardsApi.cjs.map +1 -1
- package/dist/apis/kanbanCards/KanbanCardsApi.d.ts +7 -1
- package/dist/apis/kanbanCards/KanbanCardsApi.d.ts.map +1 -1
- package/dist/apis/kanbanCards/KanbanCardsApi.mjs +8 -0
- package/dist/apis/kanbanCards/KanbanCardsApi.mjs.map +1 -1
- package/dist/apis/kanbanCards/types.d.ts +17 -5
- package/dist/apis/kanbanCards/types.d.ts.map +1 -1
- package/dist/apis/kanbanColumns/KanbanColumnsApi.cjs +9 -0
- package/dist/apis/kanbanColumns/KanbanColumnsApi.cjs.map +1 -1
- package/dist/apis/kanbanColumns/KanbanColumnsApi.d.ts +8 -1
- package/dist/apis/kanbanColumns/KanbanColumnsApi.d.ts.map +1 -1
- package/dist/apis/kanbanColumns/KanbanColumnsApi.mjs +9 -0
- package/dist/apis/kanbanColumns/KanbanColumnsApi.mjs.map +1 -1
- package/dist/apis/kanbanColumns/types.d.ts +14 -3
- package/dist/apis/kanbanColumns/types.d.ts.map +1 -1
- package/dist/apis/permissions/types.d.ts +1 -1
- package/dist/apis/permissions/types.d.ts.map +1 -1
- package/dist/apis/pipeline/PipelineApi.cjs +133 -0
- package/dist/apis/pipeline/PipelineApi.cjs.map +1 -1
- package/dist/apis/pipeline/PipelineApi.d.ts +102 -1
- package/dist/apis/pipeline/PipelineApi.d.ts.map +1 -1
- package/dist/apis/pipeline/PipelineApi.mjs +133 -0
- package/dist/apis/pipeline/PipelineApi.mjs.map +1 -1
- package/dist/apis/pipeline/types.d.ts +164 -0
- package/dist/apis/pipeline/types.d.ts.map +1 -1
- package/dist/apis/tickets/types.d.ts +37 -1
- package/dist/apis/tickets/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/apis/cards/CardsApi.test.ts +128 -0
- package/src/apis/cards/CardsApi.ts +124 -1
- package/src/apis/cards/types.ts +81 -0
- package/src/apis/kanbanBoards/types.ts +36 -4
- package/src/apis/kanbanCards/KanbanCardsApi.test.ts +46 -0
- package/src/apis/kanbanCards/KanbanCardsApi.ts +23 -1
- package/src/apis/kanbanCards/types.ts +18 -5
- package/src/apis/kanbanColumns/KanbanColumnsApi.test.ts +46 -0
- package/src/apis/kanbanColumns/KanbanColumnsApi.ts +24 -1
- package/src/apis/kanbanColumns/types.ts +15 -3
- package/src/apis/payloads.test-d.ts +53 -1
- package/src/apis/permissions/types.ts +10 -4
- package/src/apis/pipeline/PipelineApi.test.ts +193 -0
- package/src/apis/pipeline/PipelineApi.ts +274 -1
- package/src/apis/pipeline/types.ts +162 -0
- package/src/apis/tickets/types.ts +40 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Department } from '../departments/types';
|
|
2
|
+
import type { WhereClause } from '../../core/types';
|
|
2
3
|
export type PipelineStageStatus = {
|
|
3
4
|
id: string;
|
|
4
5
|
/** The default "Finalizados" stage carries `STATUS_WON` and `STATUS_LOOSE`. */
|
|
@@ -86,4 +87,167 @@ export type UpdatePipelinePayload = {
|
|
|
86
87
|
goBack?: boolean;
|
|
87
88
|
permissionToViewCard?: boolean | null;
|
|
88
89
|
};
|
|
90
|
+
/** Codes the stage routes answer (as a JSON string, with 200) instead of the stage. */
|
|
91
|
+
export type PipelineStageRefusal = 'STAGES_LIMIT' | 'STAGE_ALREADY_EXIST';
|
|
92
|
+
export type PipelineStageStatusInput = {
|
|
93
|
+
/** Send the `id` of an existing status to keep it on update; omit it to create one. */
|
|
94
|
+
id?: string;
|
|
95
|
+
name: string;
|
|
96
|
+
position: number;
|
|
97
|
+
};
|
|
98
|
+
export type PipelineStageReasonInput = {
|
|
99
|
+
/** Send the `id` of an existing reason to keep it on update; omit it to create one. */
|
|
100
|
+
id?: string;
|
|
101
|
+
name: string;
|
|
102
|
+
position: number;
|
|
103
|
+
isWon?: boolean;
|
|
104
|
+
};
|
|
105
|
+
export type CreatePipelineStagePayload = {
|
|
106
|
+
/** Up to 255 characters; must not repeat the name of another stage of the pipeline. */
|
|
107
|
+
name: string;
|
|
108
|
+
pipelineId: string;
|
|
109
|
+
/** Must be truthy — the backend `required` rule refuses `0`. */
|
|
110
|
+
position: number;
|
|
111
|
+
/** Up to 10. */
|
|
112
|
+
statuses?: PipelineStageStatusInput[];
|
|
113
|
+
/** Up to 20. */
|
|
114
|
+
reasons?: PipelineStageReasonInput[];
|
|
115
|
+
};
|
|
116
|
+
export type UpdatePipelineStagePayload = CreatePipelineStagePayload & {
|
|
117
|
+
/**
|
|
118
|
+
* The stage id. Send it: the duplicate-name check compares against the `id` of the body,
|
|
119
|
+
* so without it keeping the current name answers `'STAGE_ALREADY_EXIST'`.
|
|
120
|
+
*/
|
|
121
|
+
id?: string;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Where the cards of a deleted stage go:
|
|
125
|
+
* - `typeAction: 'move'` moves them to `idNewStage` (a stage of the same pipeline), clearing
|
|
126
|
+
* status, reason and result;
|
|
127
|
+
* - without `typeAction`, they are archived and moved to the first stage of the pipeline.
|
|
128
|
+
*/
|
|
129
|
+
export type DeletePipelineStagePayload = {
|
|
130
|
+
typeAction?: 'move';
|
|
131
|
+
idNewStage?: string;
|
|
132
|
+
/**
|
|
133
|
+
* Author of the card movements written by `'move'` — the backend reads it from the body, not
|
|
134
|
+
* from the token (the UI sends the logged user). Without it, moving a stage that has cards
|
|
135
|
+
* fails with 500 (`CardMovement.userId cannot be null`) after the cards were already moved,
|
|
136
|
+
* and the stage is kept.
|
|
137
|
+
*/
|
|
138
|
+
user?: {
|
|
139
|
+
id: string;
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
/** Answer of the stage deletion; `'PIPELINES_MIN_STAGES'` = refused, the pipeline keeps 2 stages. */
|
|
143
|
+
export type DeletePipelineStageResult = 'MESSAGE_STAGE_DELETED' | 'PIPELINES_MIN_STAGES';
|
|
144
|
+
export type PipelineStatusRef = {
|
|
145
|
+
id: string;
|
|
146
|
+
name: string;
|
|
147
|
+
};
|
|
148
|
+
/** `GET /pipelines/status/{id}`: the status plus how many cards use it. */
|
|
149
|
+
export type PipelineStageStatusWithCount = PipelineStageStatus & {
|
|
150
|
+
cardsCount: number;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* What happens to the cards of a deleted status: `'keep-without-status'` clears their status,
|
|
154
|
+
* `'move-to-another'` sets `newStatusId` (not validated by the backend).
|
|
155
|
+
*/
|
|
156
|
+
export type DeletePipelineStatusPayload = {
|
|
157
|
+
action: 'keep-without-status';
|
|
158
|
+
} | {
|
|
159
|
+
action: 'move-to-another';
|
|
160
|
+
newStatusId: string;
|
|
161
|
+
};
|
|
162
|
+
export type PipelineAutomationType = 'notification';
|
|
163
|
+
export type PipelineAutomationConfig = {
|
|
164
|
+
notify?: 'high' | 'medium' | 'medium-high';
|
|
165
|
+
frequency?: 'daily' | 'weekly' | 'biweekly' | 'monthly';
|
|
166
|
+
day?: string;
|
|
167
|
+
from?: {
|
|
168
|
+
high?: string;
|
|
169
|
+
medium?: string;
|
|
170
|
+
};
|
|
171
|
+
recipient?: 'admin' | 'owner' | 'both';
|
|
172
|
+
};
|
|
173
|
+
export type PipelineAutomation = {
|
|
174
|
+
id: string;
|
|
175
|
+
pipelineId: string;
|
|
176
|
+
type: PipelineAutomationType;
|
|
177
|
+
isArchived: boolean | null;
|
|
178
|
+
archivedAt: string | null;
|
|
179
|
+
config: PipelineAutomationConfig;
|
|
180
|
+
createdAt: string;
|
|
181
|
+
updatedAt: string;
|
|
182
|
+
};
|
|
183
|
+
export type CreatePipelineAutomationPayload = {
|
|
184
|
+
pipelineId: string;
|
|
185
|
+
/** The backend does not validate it (any string is stored); `'notification'` is the only one used. */
|
|
186
|
+
type: PipelineAutomationType;
|
|
187
|
+
config?: PipelineAutomationConfig;
|
|
188
|
+
isArchived?: boolean;
|
|
189
|
+
};
|
|
190
|
+
/** The backend validator requires `pipelineId` and `type` on update too. */
|
|
191
|
+
export type UpdatePipelineAutomationPayload = CreatePipelineAutomationPayload;
|
|
192
|
+
/** Card date filters of the CSV export; the UI sends `'YYYY-MM-DD HH:mm:ss'`. */
|
|
193
|
+
export type ExportPipelinePayload = {
|
|
194
|
+
/** Without both `createdAt*`, the range defaults to now (empty export). */
|
|
195
|
+
createdAtInit?: string;
|
|
196
|
+
createdAtFinal?: string;
|
|
197
|
+
/** With both `wonAt*`, only won cards are exported. */
|
|
198
|
+
wonAtInit?: string;
|
|
199
|
+
wonAtFinal?: string;
|
|
200
|
+
};
|
|
201
|
+
export type PipelinesWithTotalsQuery = {
|
|
202
|
+
/** `accountId` is always injected by the backend. `$and[].createdAt` filters the cards. */
|
|
203
|
+
where?: WhereClause<PipelineRecord>;
|
|
204
|
+
order?: [string, 'ASC' | 'DESC'][];
|
|
205
|
+
limit?: number;
|
|
206
|
+
/** `true` lists only the pipelines that are not archived. */
|
|
207
|
+
archive?: boolean;
|
|
208
|
+
};
|
|
209
|
+
export type PipelineTotals = {
|
|
210
|
+
id: string;
|
|
211
|
+
name: string;
|
|
212
|
+
total: number | null;
|
|
213
|
+
totalSuccess: number | null;
|
|
214
|
+
totalFailed: number | null;
|
|
215
|
+
/** A bigint, sent as a string. */
|
|
216
|
+
totalCards: string;
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* Pipelines without stages are left out; there is no pagination. With a `createdAt` filter, only
|
|
220
|
+
* the stages that have matching cards are listed, but `totals` still has every stage.
|
|
221
|
+
*/
|
|
222
|
+
export type PipelinesWithTotals = {
|
|
223
|
+
data: (PipelineRecord & {
|
|
224
|
+
stages: PipelineStage[];
|
|
225
|
+
totals: PipelineTotals[];
|
|
226
|
+
})[];
|
|
227
|
+
};
|
|
228
|
+
/** Card filters of the stage totals (same as the board filters of the UI). */
|
|
229
|
+
export type PipelineStageTotalsFilters = {
|
|
230
|
+
status?: {
|
|
231
|
+
value: string;
|
|
232
|
+
};
|
|
233
|
+
service?: {
|
|
234
|
+
id: string;
|
|
235
|
+
};
|
|
236
|
+
nameTitle?: string;
|
|
237
|
+
/** `DD/MM/YYYY`. */
|
|
238
|
+
createdFrom?: string;
|
|
239
|
+
createdUntil?: string;
|
|
240
|
+
owner?: {
|
|
241
|
+
id: string;
|
|
242
|
+
value?: string;
|
|
243
|
+
};
|
|
244
|
+
wonFrom?: string;
|
|
245
|
+
wonUntil?: string;
|
|
246
|
+
};
|
|
247
|
+
export type PipelineStageTotals = PipelineStage & {
|
|
248
|
+
totalCards: number;
|
|
249
|
+
totalCardsValue: number;
|
|
250
|
+
totalWonCardsValue: number;
|
|
251
|
+
totalLostCardsValue: number;
|
|
252
|
+
};
|
|
89
253
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/apis/pipeline/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/apis/pipeline/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Contact } from '../contacts/types';
|
|
2
2
|
import type { Department } from '../departments/types';
|
|
3
|
+
import type { Message } from '../messages/types';
|
|
3
4
|
import type { Service } from '../services/types';
|
|
4
5
|
import type { User } from '../users/types';
|
|
5
6
|
export type TicketOrigin = 'automatic' | 'manual' | 'widget';
|
|
@@ -20,6 +21,40 @@ export type TicketMetrics = {
|
|
|
20
21
|
waitingTimeTransfersAvg?: number;
|
|
21
22
|
isActiveTicket?: boolean;
|
|
22
23
|
};
|
|
24
|
+
export type TicketTransferAction = 'opened' | 'transferred' | 'closed';
|
|
25
|
+
/**
|
|
26
|
+
* A step of the history of a ticket (opening, transfer, closing), as the `ticketTransfers` include of
|
|
27
|
+
* `GET /tickets/{id}` answers it. `byUserId` is who performed the step (null when there is no user, e.g. a bot).
|
|
28
|
+
*
|
|
29
|
+
* Inside `ticketTransfers`, the route whitelist only accepts `byUser`, `fromUser`, `toUser`, `fromDepartment` and
|
|
30
|
+
* `toDepartment`: `transferredMessage`, `firstMessage` and `lastMessage` are dropped in silence and come as `null`.
|
|
31
|
+
*/
|
|
32
|
+
export type TicketTransfer = {
|
|
33
|
+
id: string;
|
|
34
|
+
action: TicketTransferAction | null;
|
|
35
|
+
comments: string | null;
|
|
36
|
+
fromDistribution: boolean;
|
|
37
|
+
accountId: string;
|
|
38
|
+
ticketId: string;
|
|
39
|
+
byUserId: string | null;
|
|
40
|
+
fromUserId: string | null;
|
|
41
|
+
toUserId: string | null;
|
|
42
|
+
fromDepartmentId: string | null;
|
|
43
|
+
toDepartmentId: string | null;
|
|
44
|
+
transferredMessageId: string | null;
|
|
45
|
+
firstMessageId: string | null;
|
|
46
|
+
lastMessageId: string | null;
|
|
47
|
+
createdAt: string;
|
|
48
|
+
updatedAt: string;
|
|
49
|
+
byUser?: User | null;
|
|
50
|
+
fromUser?: User | null;
|
|
51
|
+
toUser?: User | null;
|
|
52
|
+
fromDepartment?: Department | null;
|
|
53
|
+
toDepartment?: Department | null;
|
|
54
|
+
transferredMessage?: Message | null;
|
|
55
|
+
firstMessage?: Message | null;
|
|
56
|
+
lastMessage?: Message | null;
|
|
57
|
+
};
|
|
23
58
|
export type Ticket = {
|
|
24
59
|
id: string;
|
|
25
60
|
isOpen: boolean;
|
|
@@ -45,8 +80,9 @@ export type Ticket = {
|
|
|
45
80
|
department?: Department;
|
|
46
81
|
user?: User | null;
|
|
47
82
|
service?: Service | null;
|
|
83
|
+
ticketTransfers?: TicketTransfer[];
|
|
48
84
|
};
|
|
49
|
-
export type TicketRelationships = 'contact' | 'department' | 'user' | 'service';
|
|
85
|
+
export type TicketRelationships = 'contact' | 'department' | 'user' | 'service' | 'ticketTransfers';
|
|
50
86
|
export type CreateTicketPayload = {
|
|
51
87
|
contactId: string;
|
|
52
88
|
departmentId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/apis/tickets/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE5D,MAAM,MAAM,aAAa,GAAG;IAC1B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8EAA8E;IAC9E,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iDAAiD;IACjD,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,kDAAkD;IAClD,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,yCAAyC;IACzC,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,MAAM,GAAG;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,OAAO,EAAE,aAAa,CAAA;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,cAAc,EAAE,OAAO,CAAA;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IAEjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/apis/tickets/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import type { ApiClient } from '../../core/ApiClient'
|
|
3
|
+
import { CardsApi } from './CardsApi'
|
|
4
|
+
|
|
5
|
+
// ── Mock client factory ──────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
function createMockClient(): ApiClient {
|
|
8
|
+
return {
|
|
9
|
+
setAccessToken: vi.fn().mockReturnThis(),
|
|
10
|
+
request: vi.fn(),
|
|
11
|
+
get: vi.fn(),
|
|
12
|
+
post: vi.fn(),
|
|
13
|
+
put: vi.fn(),
|
|
14
|
+
patch: vi.fn(),
|
|
15
|
+
delete: vi.fn(),
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const headers = { 'X-Custom': 'value' }
|
|
20
|
+
|
|
21
|
+
// ── Tests ────────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
describe('CardsApi', () => {
|
|
24
|
+
let client: ReturnType<typeof createMockClient>
|
|
25
|
+
let api: CardsApi
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
client = createMockClient()
|
|
29
|
+
api = new CardsApi(client)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
describe('bulkMove', () => {
|
|
33
|
+
it('calls client.put with /cards/bulk-move and body', async () => {
|
|
34
|
+
vi.mocked(client.put).mockResolvedValue({ movedCount: 2, ignoredCount: 0 })
|
|
35
|
+
const body = {
|
|
36
|
+
ids: ['c1', 'c2'],
|
|
37
|
+
originPipelineStageId: 's1',
|
|
38
|
+
pipelineId: 'p1',
|
|
39
|
+
pipelineStageId: 's2',
|
|
40
|
+
}
|
|
41
|
+
const result = await api.bulkMove(body, headers)
|
|
42
|
+
expect(client.put).toHaveBeenCalledWith('/cards/bulk-move', body, headers)
|
|
43
|
+
expect(result).toEqual({ movedCount: 2, ignoredCount: 0 })
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
describe('updateOrder', () => {
|
|
48
|
+
it('calls client.put with /cards/order/:id and the order', async () => {
|
|
49
|
+
await api.updateOrder('c1', 3)
|
|
50
|
+
expect(client.put).toHaveBeenCalledWith('/cards/order/c1', { order: 3 }, undefined)
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
describe('products', () => {
|
|
55
|
+
it('saveProduct calls client.post with /cards/product and body', async () => {
|
|
56
|
+
vi.mocked(client.post).mockResolvedValue({ message: 'Operação realizada com sucesso.' })
|
|
57
|
+
const body = { cardId: 'c1', name: 'Plano', ammount: 2, value: 99.9 }
|
|
58
|
+
const result = await api.saveProduct(body)
|
|
59
|
+
expect(client.post).toHaveBeenCalledWith('/cards/product', body, undefined)
|
|
60
|
+
expect(result).toEqual({ message: 'Operação realizada com sucesso.' })
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('deleteProduct calls client.delete with /cards/product/:id', async () => {
|
|
64
|
+
await api.deleteProduct('pr1', headers)
|
|
65
|
+
expect(client.delete).toHaveBeenCalledWith('/cards/product/pr1', headers)
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe('comments', () => {
|
|
70
|
+
it('saveComment calls client.post with /cards/comment and body', async () => {
|
|
71
|
+
const body = { cardId: 'c1', comment: 'Ligar amanhã' }
|
|
72
|
+
await api.saveComment(body)
|
|
73
|
+
expect(client.post).toHaveBeenCalledWith('/cards/comment', body, undefined)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('saveComment edits by id', async () => {
|
|
77
|
+
const body = { id: 'cm1', comment: 'Ligar hoje', removedFileIds: ['f1'] }
|
|
78
|
+
await api.saveComment(body, headers)
|
|
79
|
+
expect(client.post).toHaveBeenCalledWith('/cards/comment', body, headers)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('deleteComment calls client.delete with /cards/comment/:id', async () => {
|
|
83
|
+
await api.deleteComment('cm1')
|
|
84
|
+
expect(client.delete).toHaveBeenCalledWith('/cards/comment/cm1', undefined)
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
describe('reads', () => {
|
|
89
|
+
it('getOwners calls client.post with /cards/owners and no body', async () => {
|
|
90
|
+
vi.mocked(client.post).mockResolvedValue([{ id: 'u1', name: 'Ana', disabled: false }])
|
|
91
|
+
const result = await api.getOwners()
|
|
92
|
+
expect(client.post).toHaveBeenCalledWith('/cards/owners', undefined, undefined)
|
|
93
|
+
expect(result).toEqual([{ id: 'u1', name: 'Ana', disabled: false }])
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('getCards calls client.post with /cards/getCards and the query', async () => {
|
|
97
|
+
const body = {
|
|
98
|
+
where: { accountId: 'a1', pipelineStageId: 's1' },
|
|
99
|
+
attributes: ['id', 'title'] as ('id' | 'title')[],
|
|
100
|
+
order: [['contact.name', 'ASC']] as ['contact.name', 'ASC'][],
|
|
101
|
+
limit: 20,
|
|
102
|
+
}
|
|
103
|
+
await api.getCards(body)
|
|
104
|
+
expect(client.post).toHaveBeenCalledWith('/cards/getCards', body, undefined)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('getContactTotals calls client.post with /cards/contact-totals/:contactId', async () => {
|
|
108
|
+
vi.mocked(client.post).mockResolvedValue({ totalOpen: 1 })
|
|
109
|
+
const result = await api.getContactTotals('ct1', headers)
|
|
110
|
+
expect(client.post).toHaveBeenCalledWith('/cards/contact-totals/ct1', undefined, headers)
|
|
111
|
+
expect(result).toEqual({ totalOpen: 1 })
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
describe('error propagation', () => {
|
|
116
|
+
it('propagates errors from bulkMove', async () => {
|
|
117
|
+
vi.mocked(client.put).mockRejectedValue(new Error('At least one card id is required.'))
|
|
118
|
+
await expect(
|
|
119
|
+
api.bulkMove({
|
|
120
|
+
ids: [],
|
|
121
|
+
originPipelineStageId: 's1',
|
|
122
|
+
pipelineId: 'p1',
|
|
123
|
+
pipelineStageId: 's2',
|
|
124
|
+
}),
|
|
125
|
+
).rejects.toThrow('At least one card id is required.')
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
})
|
|
@@ -1,9 +1,132 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
2
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
BulkMoveCardsPayload,
|
|
5
|
+
BulkMoveCardsResult,
|
|
6
|
+
Card,
|
|
7
|
+
CardContactTotals,
|
|
8
|
+
CardOperationResult,
|
|
9
|
+
CardOwner,
|
|
10
|
+
CreateCardPayload,
|
|
11
|
+
GetCardsPayload,
|
|
12
|
+
SaveCardCommentPayload,
|
|
13
|
+
SaveCardProductPayload,
|
|
14
|
+
UpdateCardPayload,
|
|
15
|
+
} from './types'
|
|
4
16
|
|
|
5
17
|
export class CardsApi extends BaseCrudApi<Card, CreateCardPayload, UpdateCardPayload> {
|
|
6
18
|
constructor(client: ApiClient) {
|
|
7
19
|
super(client, '/cards')
|
|
8
20
|
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Moves several cards of one stage to another stage (of the same or another pipeline),
|
|
24
|
+
* clearing their status/reason unless given. Cards outside the account or not in
|
|
25
|
+
* `originPipelineStageId` are skipped and counted in `ignoredCount`.
|
|
26
|
+
* @permissions pipelines.opportunity.update
|
|
27
|
+
*/
|
|
28
|
+
bulkMove(
|
|
29
|
+
body: BulkMoveCardsPayload,
|
|
30
|
+
headers?: Record<string, string>,
|
|
31
|
+
): Promise<BulkMoveCardsResult> {
|
|
32
|
+
return this.client.put<BulkMoveCardsResult, BulkMoveCardsPayload>(
|
|
33
|
+
`${this.basePath}/bulk-move`,
|
|
34
|
+
body,
|
|
35
|
+
headers,
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Moves a card to the `order` position of its stage, shifting the cards in between. Resolves
|
|
41
|
+
* to the card as stored. The backend refuses `0` (400 `required`), although the first card of
|
|
42
|
+
* a stage has order 0.
|
|
43
|
+
* @permissions pipelines.opportunity.update
|
|
44
|
+
*/
|
|
45
|
+
updateOrder(id: string, order: number, headers?: Record<string, string>): Promise<Card> {
|
|
46
|
+
return this.client.put<Card, { order: number }>(
|
|
47
|
+
`${this.basePath}/order/${id}`,
|
|
48
|
+
{ order },
|
|
49
|
+
headers,
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Adds a product to a card, or updates the product of `body.id`.
|
|
55
|
+
* @permissions pipelines.opportunity.update
|
|
56
|
+
*/
|
|
57
|
+
saveProduct(
|
|
58
|
+
body: SaveCardProductPayload,
|
|
59
|
+
headers?: Record<string, string>,
|
|
60
|
+
): Promise<CardOperationResult> {
|
|
61
|
+
return this.client.post<CardOperationResult, SaveCardProductPayload>(
|
|
62
|
+
`${this.basePath}/product`,
|
|
63
|
+
body,
|
|
64
|
+
headers,
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Deletes a product of a card. An unknown id also resolves with 200, with the message
|
|
70
|
+
* `'Produto não encontrado'`.
|
|
71
|
+
* @permissions pipelines.opportunity.update
|
|
72
|
+
*/
|
|
73
|
+
deleteProduct(id: string, headers?: Record<string, string>): Promise<CardOperationResult> {
|
|
74
|
+
return this.client.delete<CardOperationResult>(`${this.basePath}/product/${id}`, headers)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Adds a comment to a card, or edits the comment of `body.id`. Resolves to a message, not to
|
|
79
|
+
* the comment — read it back through `getById(cardId, { include: ['comments'] })`. A card or
|
|
80
|
+
* comment of another account fails with 404.
|
|
81
|
+
* @permissions pipelines.opportunity.update
|
|
82
|
+
*/
|
|
83
|
+
saveComment(
|
|
84
|
+
body: SaveCardCommentPayload,
|
|
85
|
+
headers?: Record<string, string>,
|
|
86
|
+
): Promise<CardOperationResult> {
|
|
87
|
+
return this.client.post<CardOperationResult, SaveCardCommentPayload>(
|
|
88
|
+
`${this.basePath}/comment`,
|
|
89
|
+
body,
|
|
90
|
+
headers,
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Deletes a comment of a card. Resolves with no content; unknown → 404.
|
|
96
|
+
* @permissions pipelines.opportunity.update
|
|
97
|
+
*/
|
|
98
|
+
deleteComment(id: string, headers?: Record<string, string>): Promise<void> {
|
|
99
|
+
return this.client.delete<void>(`${this.basePath}/comment/${id}`, headers)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Lists the users of the account that can own a card, sorted by name.
|
|
104
|
+
* @permissions pipelines.opportunity.view
|
|
105
|
+
*/
|
|
106
|
+
getOwners(headers?: Record<string, string>): Promise<CardOwner[]> {
|
|
107
|
+
return this.client.post<CardOwner[]>(`${this.basePath}/owners`, undefined, headers)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Lists cards with the board query of the UI. Resolves to a plain array (no pagination).
|
|
112
|
+
* @permissions pipelines.opportunity.view
|
|
113
|
+
*/
|
|
114
|
+
getCards(body: GetCardsPayload, headers?: Record<string, string>): Promise<Card[]> {
|
|
115
|
+
return this.client.post<Card[], GetCardsPayload>(`${this.basePath}/getCards`, body, headers)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Counts the open cards of a contact visible to the caller.
|
|
120
|
+
* @permissions pipelines.opportunity.view
|
|
121
|
+
*/
|
|
122
|
+
getContactTotals(
|
|
123
|
+
contactId: string,
|
|
124
|
+
headers?: Record<string, string>,
|
|
125
|
+
): Promise<CardContactTotals> {
|
|
126
|
+
return this.client.post<CardContactTotals>(
|
|
127
|
+
`${this.basePath}/contact-totals/${contactId}`,
|
|
128
|
+
undefined,
|
|
129
|
+
headers,
|
|
130
|
+
)
|
|
131
|
+
}
|
|
9
132
|
}
|
package/src/apis/cards/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ListQuery, WhereClause } from '../../core/types'
|
|
1
2
|
import type { Contact } from '../contacts/types'
|
|
2
3
|
import type {
|
|
3
4
|
Pipeline,
|
|
@@ -98,6 +99,8 @@ export type Card = {
|
|
|
98
99
|
lastMessage?: unknown
|
|
99
100
|
/** Only on getMany/getById answers: sum of the products (`ammount * value`). */
|
|
100
101
|
totalValue?: number
|
|
102
|
+
/** Only on `getCards` answers. */
|
|
103
|
+
contactName?: string
|
|
101
104
|
// relationships
|
|
102
105
|
contact?: Contact | null
|
|
103
106
|
owner?: User | null
|
|
@@ -158,3 +161,81 @@ export type UpdateCardPayload = {
|
|
|
158
161
|
success?: boolean | null
|
|
159
162
|
finishedAt?: string | null
|
|
160
163
|
}
|
|
164
|
+
|
|
165
|
+
/** Answer of the product and comment writes — the entity itself is not returned. */
|
|
166
|
+
export type CardOperationResult = { message: string }
|
|
167
|
+
|
|
168
|
+
export type BulkMoveCardsPayload = {
|
|
169
|
+
/** At least one; ids outside the account or not in `originPipelineStageId` are ignored. */
|
|
170
|
+
ids: string[]
|
|
171
|
+
originPipelineStageId: string
|
|
172
|
+
/** Destination pipeline; `pipelineStageId` must be one of its stages. */
|
|
173
|
+
pipelineId: string
|
|
174
|
+
pipelineStageId: string
|
|
175
|
+
/** Must be a status of the destination stage, unless it is the last stage. */
|
|
176
|
+
statusId?: string
|
|
177
|
+
/** Kept only when the destination is the last stage (then `finishedAt` is set). */
|
|
178
|
+
success?: boolean
|
|
179
|
+
reasonId?: string
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export type BulkMoveCardsResult = { movedCount: number; ignoredCount: number }
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Creates a product of a card, or updates the product of `id`. No validation on the backend:
|
|
186
|
+
* a missing `name`/`ammount`/`value` fails with 500.
|
|
187
|
+
*/
|
|
188
|
+
export type SaveCardProductPayload = {
|
|
189
|
+
id?: string
|
|
190
|
+
cardId: string
|
|
191
|
+
name: string
|
|
192
|
+
/** Quantity — integer (the backend column is spelled `ammount`). */
|
|
193
|
+
ammount: number
|
|
194
|
+
value: number
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Creates a comment on `cardId`, or edits the comment of `id`. It needs text or at least one
|
|
199
|
+
* file. `files` are references to files already uploaded (see `FilesApi`) — `.pdf`, `.txt`,
|
|
200
|
+
* `.html` or `.md`, up to 10 files of 10 MB.
|
|
201
|
+
*/
|
|
202
|
+
export type SaveCardCommentPayload =
|
|
203
|
+
| { id?: undefined; cardId: string; comment?: string; files?: { id: string }[] }
|
|
204
|
+
| {
|
|
205
|
+
id: string
|
|
206
|
+
cardId?: string
|
|
207
|
+
comment?: string
|
|
208
|
+
files?: { id: string }[]
|
|
209
|
+
removedFileIds?: string[]
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export type CardOwner = {
|
|
213
|
+
id: string
|
|
214
|
+
/** Suffixed with " - Sem permissão" (in the caller's language) when `disabled`. */
|
|
215
|
+
name: string
|
|
216
|
+
/** `true` for users without `pipelines.opportunity.update`. */
|
|
217
|
+
disabled: boolean
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Body of `POST /cards/getCards`: Sequelize options sent as-is. The route does **not** scope the
|
|
222
|
+
* query by account — without `where.accountId` it answers cards of other accounts. `order`
|
|
223
|
+
* accepts card fields and `contact.name`.
|
|
224
|
+
*/
|
|
225
|
+
export type GetCardsPayload = Omit<
|
|
226
|
+
ListQuery<Card>,
|
|
227
|
+
'page' | 'perPage' | 'paginate' | 'where' | 'order' | 'attributes'
|
|
228
|
+
> & {
|
|
229
|
+
where: WhereClause<Card> & { accountId: string }
|
|
230
|
+
/**
|
|
231
|
+
* The card columns to answer. Required in practice: the backend selects only these (plus the
|
|
232
|
+
* computed `contactName` and `totalValue`), so without them each card has no other field.
|
|
233
|
+
*/
|
|
234
|
+
attributes: (keyof Card & string)[]
|
|
235
|
+
order?: [(keyof Card & string) | 'contact.name', 'ASC' | 'DESC'][]
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export type CardContactTotals = {
|
|
239
|
+
/** Open cards of the contact (not archived, not finished, in a pipeline that exists). */
|
|
240
|
+
totalOpen: number
|
|
241
|
+
}
|