-
Notifications
You must be signed in to change notification settings - Fork 0
/
form-store-service.ts
198 lines (192 loc) · 5.01 KB
/
form-store-service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import { FormTypes, SubmissionTypes } from '@oneblink/types'
import { saveAs } from 'file-saver'
import OneBlinkAppsError from './services/errors/oneBlinkAppsError'
import {
generateHeaders,
searchRequest,
postRequest,
HTTPError,
fetchWithError,
} from './services/fetch'
import tenants from './tenants'
/** Filter for a single property in a Form Store Record */
export type FormStoreFilter<T> = {
$regex?: string
$options?: string
$eq?: T
$gte?: T
$gt?: T
$lt?: T
$lte?: T
$in?: string[]
$elemMatch?: {
$in?: string[]
}
}
/** Filters available for filter Form Store Records */
export type FormStoreFilters = {
/** Filter results by the date/time they were submitted */
dateTimeSubmitted?: FormStoreFilter<string>
/** Filter results by the user that submitted */
submittedBy?: FormStoreFilter<string>
/** Filter results by the submissionId, must be a valid GUID */
submissionId?: FormStoreFilter<string>
/** Filter results by the externalId */
externalId?: FormStoreFilter<string>
/** Filter results by the submission data */
submission?: Record<string, FormStoreFilter<unknown> | undefined>
}
export type FormStoreParameters = {
/** Filters available for filter Form Store Records */
filters?: FormStoreFilters
/**
* Unwind repeatable set entries to denormalise data, this makes data cleaner
* for tabular data purposes
*/
unwindRepeatableSets?: boolean
/** Sort the results by multiple properties */
sorting?: Array<{
/** Property to sort by */
property: string
/** Sorting direction */
direction: 'ascending' | 'descending'
}>
}
/**
* Get the available form elements for a form to display form store records
*
* #### Example
*
* ```js
* const formId = 1
* const { formElements } =
* await formStoreService.getFormStoreDefinition(formId)
* ```
*
* @param formId The identified of the form you want to get the definition of
* @param abortSignal An AbortSignal to abort the request
* @returns
*/
export async function getFormStoreDefinition(
formId: number,
abortSignal?: AbortSignal,
): Promise<{ formElements: FormTypes.FormElementWithName[] }> {
try {
return await searchRequest(
`${tenants.current.apiOrigin}/form-store/elements`,
{
formId,
},
abortSignal,
)
} catch (err) {
const error = err as HTTPError
throw new OneBlinkAppsError(error.message, {
httpStatusCode: error.status,
originalError: error,
})
}
}
/**
* Search for Form Store Records
*
* #### Example
*
* ```js
* const { formStoreRecords } =
* await formStoreService.searchFormStoreRecords({
* formId: 1,
* paging: {
* limit: 50,
* offset: 0,
* },
* })
* ```
*
* @param searchParameters Search parameters for filtering, sorting, and paging
* @param abortSignal An AbortSignal to abort the request
* @returns
*/
export async function searchFormStoreRecords(
searchParameters: {
formId: number
paging: {
limit: number
offset: number
}
} & FormStoreParameters,
abortSignal: AbortSignal,
): Promise<{
formStoreRecords: SubmissionTypes.FormStoreRecord[]
meta: { limit: number; offset: number; nextOffset?: number }
}> {
try {
const { submissions, meta } = await postRequest<{
submissions: SubmissionTypes.FormStoreRecord[]
meta: { limit: number; offset: number; nextOffset?: number }
}>(`${tenants.current.apiOrigin}/form-store`, searchParameters, abortSignal)
return {
formStoreRecords: submissions,
meta,
}
} catch (err) {
const error = err as HTTPError
throw new OneBlinkAppsError(error.message, {
httpStatusCode: error.status,
originalError: error,
})
}
}
/**
* Export Form Store Records as a CSV file. This function will download the file
* automatically.
*
* #### Example
*
* ```js
* await formStoreService.exportFormStoreRecords({
* formId: 1,
* })
* ```
*
* @param fileName Name of the file to download. ".csv" will be added to the end
* of the file name if not passed
* @param searchParameters Search parameters for filtering, sorting, and
* including columns
* @param abortSignal An AbortSignal to abort the request
* @returns
*/
export async function exportFormStoreRecords(
fileName: string,
searchParameters: {
formId: number
includeColumns?: string[]
} & FormStoreParameters,
abortSignal?: AbortSignal,
): Promise<void> {
if (!fileName.toLowerCase().endsWith('.csv')) {
fileName += '.csv'
}
const headers = await generateHeaders()
headers.Accept = 'text/csv'
const response = await fetchWithError(
`${tenants.current.apiOrigin}/form-store/export`,
{
method: 'POST',
headers,
mode: 'cors',
cache: 'default',
body: JSON.stringify(searchParameters),
signal: abortSignal,
},
)
if (response.ok) {
const blob = await response.blob()
saveAs(blob, fileName)
} else {
const body = await response.json()
throw new OneBlinkAppsError(body.message, {
httpStatusCode: response.status,
})
}
}