@trackunit/filters-graphql-hook 0.0.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.
Files changed (51) hide show
  1. package/README.md +22 -0
  2. package/index.cjs.d.ts +1 -0
  3. package/index.cjs.js +400 -0
  4. package/index.esm.js +384 -0
  5. package/package.json +26 -0
  6. package/src/fixTypes.d.ts +37 -0
  7. package/src/generated/graphql-api/fragment-masking.d.ts +15 -0
  8. package/src/generated/graphql-api/gql.d.ts +37 -0
  9. package/src/generated/graphql-api/graphql.d.ts +360 -0
  10. package/src/generated/graphql-api/index.d.ts +2 -0
  11. package/src/generated/graphql-api/mock.d.ts +5 -0
  12. package/src/index.d.ts +5 -0
  13. package/src/translation.d.ts +34 -0
  14. package/src/useActiveAssetFilters.d.ts +10 -0
  15. package/src/useAssetQueryFilters.d.ts +32 -0
  16. package/src/useAssetSortInput.d.ts +10 -0
  17. package/src/useCustomFieldFilters.d.ts +8 -0
  18. package/translation.cjs.js +7 -0
  19. package/translation.cjs10.js +7 -0
  20. package/translation.cjs11.js +7 -0
  21. package/translation.cjs12.js +7 -0
  22. package/translation.cjs13.js +7 -0
  23. package/translation.cjs14.js +7 -0
  24. package/translation.cjs15.js +7 -0
  25. package/translation.cjs16.js +7 -0
  26. package/translation.cjs17.js +7 -0
  27. package/translation.cjs2.js +7 -0
  28. package/translation.cjs3.js +7 -0
  29. package/translation.cjs4.js +7 -0
  30. package/translation.cjs5.js +7 -0
  31. package/translation.cjs6.js +7 -0
  32. package/translation.cjs7.js +7 -0
  33. package/translation.cjs8.js +7 -0
  34. package/translation.cjs9.js +7 -0
  35. package/translation.esm.js +5 -0
  36. package/translation.esm10.js +5 -0
  37. package/translation.esm11.js +5 -0
  38. package/translation.esm12.js +5 -0
  39. package/translation.esm13.js +5 -0
  40. package/translation.esm14.js +5 -0
  41. package/translation.esm15.js +5 -0
  42. package/translation.esm16.js +5 -0
  43. package/translation.esm17.js +5 -0
  44. package/translation.esm2.js +5 -0
  45. package/translation.esm3.js +5 -0
  46. package/translation.esm4.js +5 -0
  47. package/translation.esm5.js +5 -0
  48. package/translation.esm6.js +5 -0
  49. package/translation.esm7.js +5 -0
  50. package/translation.esm8.js +5 -0
  51. package/translation.esm9.js +5 -0
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ > **⚠️ Beta**
2
+ >
3
+ > This is a beta version and subject to change without notice.
4
+
5
+ # Trackunit Filters graphql hooks Components
6
+ The `@trackunit/filters-graphql-hook` package is the home of our graphql hooks, that can take input of filterBar values and convert to gql types.
7
+
8
+ This library is exposed publicly for use in the the Trackunit [Iris App SDK](https://www.npmjs.com/package/@trackunit/iris-app).
9
+
10
+ To browse all available components visit our [Public Storybook](https://developers.trackunit.com/page/ui-components).
11
+
12
+ For more info and a full guide on Iris App SDK Development, please visit our [Developer Hub](https://developers.trackunit.com/).
13
+
14
+ ## Development
15
+ At this point this library is only developed by Trackunit Employees.
16
+ For development related information see the [development readme](https://github.com/Trackunit/manager/blob/master/libs/react/components/DEVELOPMENT.md).
17
+
18
+ ## Trackunit
19
+ This package was developed by Trackunit ApS.
20
+ Trackunit is the leading SaaS-based IoT solution for the construction industry, offering an ecosystem of hardware, fleet management software & telematics.
21
+
22
+ ![The Trackunit logo](https://trackunit.com/wp-content/uploads/2022/03/top-logo.svg)
package/index.cjs.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/index";
package/index.cjs.js ADDED
@@ -0,0 +1,400 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ require('react/jsx-runtime');
6
+ var i18nLibraryTranslation = require('@trackunit/i18n-library-translation');
7
+ var filtersFilterBar = require('@trackunit/filters-filter-bar');
8
+ var sharedUtils = require('@trackunit/shared-utils');
9
+ var reactCoreHooks = require('@trackunit/react-core-hooks');
10
+ var react = require('react');
11
+
12
+ var defaultTranslations = {
13
+
14
+ };
15
+
16
+ /** The translation namespace for this library */
17
+ const namespace = "filters.graphql-hook";
18
+ /**
19
+ * The TranslationResource for this Library.
20
+ * Holds lazy loaded imports for all languages supported by the library.
21
+ *
22
+ * This is used to register the translations for this library before initializing i18next.
23
+ */
24
+ const translations = {
25
+ ns: namespace,
26
+ default: defaultTranslations,
27
+ languages: {
28
+ de: () => Promise.resolve().then(function () { return require('./translation.cjs.js'); }),
29
+ da: () => Promise.resolve().then(function () { return require('./translation.cjs2.js'); }),
30
+ cs: () => Promise.resolve().then(function () { return require('./translation.cjs3.js'); }),
31
+ nl: () => Promise.resolve().then(function () { return require('./translation.cjs4.js'); }),
32
+ fr: () => Promise.resolve().then(function () { return require('./translation.cjs5.js'); }),
33
+ fi: () => Promise.resolve().then(function () { return require('./translation.cjs6.js'); }),
34
+ hu: () => Promise.resolve().then(function () { return require('./translation.cjs7.js'); }),
35
+ it: () => Promise.resolve().then(function () { return require('./translation.cjs8.js'); }),
36
+ nb: () => Promise.resolve().then(function () { return require('./translation.cjs9.js'); }),
37
+ pl: () => Promise.resolve().then(function () { return require('./translation.cjs10.js'); }),
38
+ pt: () => Promise.resolve().then(function () { return require('./translation.cjs11.js'); }),
39
+ ru: () => Promise.resolve().then(function () { return require('./translation.cjs12.js'); }),
40
+ ro: () => Promise.resolve().then(function () { return require('./translation.cjs13.js'); }),
41
+ es: () => Promise.resolve().then(function () { return require('./translation.cjs14.js'); }),
42
+ sv: () => Promise.resolve().then(function () { return require('./translation.cjs15.js'); }),
43
+ ja: () => Promise.resolve().then(function () { return require('./translation.cjs16.js'); }),
44
+ th: () => Promise.resolve().then(function () { return require('./translation.cjs17.js'); }),
45
+ },
46
+ };
47
+ /**
48
+ * Registers the translations for this library
49
+ */
50
+ const setupLibraryTranslations = () => {
51
+ i18nLibraryTranslation.registerTranslations(translations);
52
+ };
53
+
54
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
+ const isStringFilterValue = (value) => {
56
+ return typeof value === "string";
57
+ };
58
+ /**
59
+ * Fix types for filter values
60
+ *
61
+ * @param values - filter values
62
+ * @param outputTypeRecord - record with output types
63
+ * @returns {Record | undefined}- fixed filter values
64
+ */
65
+ const fixTypes = (
66
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
+ values, outputTypeRecord) => {
68
+ if (!values) {
69
+ return undefined;
70
+ }
71
+ if (Array.isArray(values) && values.length === 0) {
72
+ return undefined;
73
+ }
74
+ if (filtersFilterBar.isStringArrayFilterValue(values)) {
75
+ const result = values.map(value => {
76
+ const valuesFromOutput = Object.values(outputTypeRecord);
77
+ const convertedValue = valuesFromOutput.find(v => value === v);
78
+ if (!convertedValue) {
79
+ throw Error(`Unknown value: ${value} expect one of: ${JSON.stringify(Object.values(outputTypeRecord))}`);
80
+ }
81
+ // eslint-disable-next-line local-rules/no-typescript-assertion
82
+ return convertedValue;
83
+ });
84
+ return result.filter(sharedUtils.truthy);
85
+ }
86
+ if (isStringFilterValue(values)) {
87
+ const valuesFromOutput = Object.values(outputTypeRecord);
88
+ const convertedValue = valuesFromOutput.find(v => values === v);
89
+ if (!convertedValue) {
90
+ throw Error(`Unknown value: ${values} expect one of: ${JSON.stringify(Object.values(outputTypeRecord))}`);
91
+ }
92
+ // eslint-disable-next-line local-rules/no-typescript-assertion
93
+ return [convertedValue];
94
+ }
95
+ throw Error(`Unknown value: ${values} should be a string array`);
96
+ };
97
+ /**
98
+ * Fix type for filter value
99
+ *
100
+ * @param values - filter value
101
+ * @param outputTypeRecord - record with output types
102
+ * @returns {Record | null}- fixed filter value
103
+ */
104
+ const fixType = (values, outputTypeRecord) => {
105
+ if (!values) {
106
+ return null;
107
+ }
108
+ const convertedValue = outputTypeRecord[values];
109
+ if (!convertedValue) {
110
+ throw Error(`Unknown value: ${values} expect one of: ${JSON.stringify(Object.values(outputTypeRecord))}`);
111
+ }
112
+ // eslint-disable-next-line local-rules/no-typescript-assertion
113
+ return convertedValue;
114
+ };
115
+ /**
116
+ * Check if value is not empty
117
+ */
118
+ const valuesIfNotEmpty = (
119
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
+ value) => {
121
+ if (Array.isArray(value)) {
122
+ return value.length > 0 ? value : undefined;
123
+ }
124
+ return value;
125
+ };
126
+ /**
127
+ * Check if value is string array
128
+ */
129
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
130
+ const isStringArrayValue = (value) => {
131
+ return Array.isArray(value) && value.every(item => typeof item === "string");
132
+ };
133
+ /**
134
+ * Check if value is string array or undefined
135
+ */
136
+ const stringArrayOrUndefined = (
137
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
138
+ value) => {
139
+ if (isStringArrayValue(value)) {
140
+ return value.length > 0 ? value : undefined;
141
+ }
142
+ return undefined;
143
+ };
144
+ /**
145
+ * Check if value is ValueName[]
146
+ */
147
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
148
+ const isValueName = (value) => {
149
+ return (Array.isArray(value) &&
150
+ value.every(item => typeof item === "object" && Object.keys(item).includes("name") && Object.keys(item).includes("value")));
151
+ };
152
+ /**
153
+ * Check if value is ValueName[] or undefined
154
+ */
155
+ const valueNameArrayOrUndefined = (
156
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
157
+ input) => {
158
+ if (isValueName(input) && input.length > 0) {
159
+ return input.map(item => item.value);
160
+ }
161
+ return undefined;
162
+ };
163
+
164
+ const assetActivityState = {
165
+ Idling: "IDLING",
166
+ Stopped: "STOPPED",
167
+ Unknown: "UNKNOWN",
168
+ Working: "WORKING",
169
+ };
170
+ const assetCriticalityState = {
171
+ Critical: "CRITICAL",
172
+ Low: "LOW",
173
+ None: "NONE",
174
+ };
175
+ const assetLastSeen = {
176
+ Last_7Days: "LAST_7_DAYS",
177
+ Last_24Hours: "LAST_24_HOURS",
178
+ Last_30Days: "LAST_30_DAYS",
179
+ LastHour: "LAST_HOUR",
180
+ OlderThan_30Days: "OLDER_THAN_30_DAYS",
181
+ };
182
+ const assetType = {
183
+ Attachment: "ATTACHMENT",
184
+ Equipment: "EQUIPMENT",
185
+ Gateway: "GATEWAY",
186
+ Machine: "MACHINE",
187
+ Other: "OTHER",
188
+ Tool: "TOOL",
189
+ };
190
+ const rentalStatus = {
191
+ Available: "Available",
192
+ InRepair: "InRepair",
193
+ NotOnContract: "NotOnContract",
194
+ OffRent: "OffRent",
195
+ OnRent: "OnRent",
196
+ Other: "Other",
197
+ PickupReady: "PickupReady",
198
+ Reserved: "Reserved",
199
+ Returned: "Returned",
200
+ Transfer: "Transfer",
201
+ };
202
+ const servicePlanStatus = {
203
+ Complete: "COMPLETE",
204
+ Draft: "DRAFT",
205
+ FullyConfigured: "FULLY_CONFIGURED",
206
+ HasPlan: "HAS_PLAN",
207
+ HasServiceProvider: "HAS_SERVICE_PROVIDER",
208
+ MissingPlan: "MISSING_PLAN",
209
+ MissingProvider: "MISSING_PROVIDER",
210
+ Overdue: "OVERDUE",
211
+ Planned: "PLANNED",
212
+ Unknown: "UNKNOWN",
213
+ Upcoming: "UPCOMING",
214
+ };
215
+ const siteTypeSfs = {
216
+ Area: "AREA",
217
+ ClassicPoi: "CLASSIC_POI",
218
+ ClassicZone: "CLASSIC_ZONE",
219
+ ConstructionSite: "CONSTRUCTION_SITE",
220
+ Depot: "DEPOT",
221
+ NotOnSite: "NOT_ON_SITE",
222
+ WorkPlace: "WORK_PLACE",
223
+ };
224
+
225
+ const CustomFieldPrefix$1 = "cf__";
226
+ /**
227
+ * Converts custom field filters to a format that can be used by the GraphQL API
228
+ *
229
+ * @param filters Custom field filters
230
+ * @returns {CustomFieldFilter[]} Custom field filters in a format that can be used by the GraphQL API
231
+ */
232
+ // eslint-disable-next-line @typescript-eslint/ban-types
233
+ const useCustomFieldFilters = (filters) => {
234
+ return react.useMemo(() => {
235
+ const result = [];
236
+ if (filters) {
237
+ Object.entries(filters).forEach(([key, value]) => {
238
+ const customFieldValue = value;
239
+ if (key.startsWith(CustomFieldPrefix$1)) {
240
+ const definitionId = key.replace(CustomFieldPrefix$1, "");
241
+ if (filtersFilterBar.isStringArrayFilterValue(customFieldValue) && customFieldValue.length > 0) {
242
+ result.push({
243
+ definitionId,
244
+ stringArrayValue: customFieldValue,
245
+ });
246
+ }
247
+ else if (filtersFilterBar.isMinMaxFilterValue(customFieldValue) && (customFieldValue.min || customFieldValue.max)) {
248
+ result.push({
249
+ definitionId,
250
+ numberRange: {
251
+ from: customFieldValue.min,
252
+ to: customFieldValue.max,
253
+ },
254
+ });
255
+ }
256
+ else if (filtersFilterBar.isDateRangeValue(customFieldValue) && (customFieldValue.from || customFieldValue.to)) {
257
+ result.push({
258
+ definitionId,
259
+ dateRange: {
260
+ from: customFieldValue.from,
261
+ to: customFieldValue.to,
262
+ },
263
+ });
264
+ }
265
+ else if (filtersFilterBar.isBooleanValue(customFieldValue)) {
266
+ result.push({
267
+ definitionId,
268
+ booleanValue: customFieldValue.booleanValue === undefined ? null : customFieldValue.booleanValue,
269
+ });
270
+ }
271
+ }
272
+ });
273
+ }
274
+ return result;
275
+ }, [filters]);
276
+ };
277
+
278
+ const CustomFieldPrefix = "cf__";
279
+ /**
280
+ * Converts field filters to a format that can be used by the GraphQL API for AssetFiltersInput
281
+ *
282
+ * @param filters FilterBarValues
283
+ * @returns {AssetFiltersInput} Custom field filters in a format that can be used by the GraphQL API
284
+ */
285
+ const useActiveAssetFilters = (filters) => {
286
+ const { systemOfMeasurement } = reactCoreHooks.useCurrentUserSystemOfMeasurement();
287
+ const customFields = useCustomFieldFilters({ filters });
288
+ // TODO make typesafe checks for all filters
289
+ const filter = react.useMemo(() => {
290
+ var _a, _b;
291
+ if (!filters) {
292
+ return {};
293
+ }
294
+ const followExist = filters.followed === "ALL" ? undefined : true;
295
+ return {
296
+ assetIds: stringArrayOrUndefined(filters.assetIds),
297
+ searchQuery: filters.search === "" || !filters.search ? undefined : filters.search,
298
+ activities: fixTypes(filters.activity, assetActivityState),
299
+ boundingBox: filters.boundingBox ? filters.boundingBox : undefined,
300
+ brands: stringArrayOrUndefined(filters.brands),
301
+ types: stringArrayOrUndefined(filters.types),
302
+ criticalities: fixTypes(filters.criticality, assetCriticalityState),
303
+ productionYears: valueNameArrayOrUndefined(filters.productionYears),
304
+ followed: filters.followed ? followExist : false,
305
+ lastSeen: filters.lastSeen === "ALL" || !filters.lastSeen ? undefined : (_a = fixTypes(filters.lastSeen, assetLastSeen)) === null || _a === void 0 ? void 0 : _a[0],
306
+ models: stringArrayOrUndefined(filters.models),
307
+ ownerAccountIds: valueNameArrayOrUndefined(filters.ownerAccountIds),
308
+ assetTypes: fixTypes(filters.assetType, assetType),
309
+ servicePlanStatuses: fixTypes(filters.serviceStatus, servicePlanStatus),
310
+ servicePlanAssignments: fixTypes(filters.servicePlanStatus, servicePlanStatus),
311
+ servicePlanIds: valueNameArrayOrUndefined(filters.servicePlan),
312
+ serviceProviderIds: valueNameArrayOrUndefined(filters.serviceProvider),
313
+ //currently we support only 1 filter value to be set so there won't be a second value, soon the partnerId will be transformed to a normal filter and will support an array of strings
314
+ partnerId: (_b = valueNameArrayOrUndefined(filters.partner)) === null || _b === void 0 ? void 0 : _b[0],
315
+ groups: valueNameArrayOrUndefined(filters.groups),
316
+ siteIds: valueNameArrayOrUndefined(filters.siteIds),
317
+ siteTypes: fixTypes(filters.siteType, siteTypeSfs),
318
+ rentalCustomerName: stringArrayOrUndefined(filters.rentalCustomerName),
319
+ rentalStatus: fixTypes(filters.rentalStatus, rentalStatus),
320
+ customFields: valuesIfNotEmpty(customFields),
321
+ systemOfMeasurement: systemOfMeasurement,
322
+ };
323
+ }, [filters, customFields, systemOfMeasurement]);
324
+ return filter;
325
+ };
326
+
327
+ /**
328
+ * This hook is used to convert the sorting state from the AssetSortingContext to the AssetSortInput used by the GraphQL API
329
+ */
330
+ const useAssetSortInput = () => {
331
+ const { sortingState } = reactCoreHooks.useAssetSorting();
332
+ return react.useMemo(() => convertToAssetSortInput(sortingState), [sortingState]);
333
+ };
334
+ /**
335
+ * Convert the sorting state from the AssetSortingContext to the AssetSortInput used by the GraphQL API
336
+ */
337
+ const convertToAssetSortInput = ({ sortBy, order, customFieldDefinitionId }) => {
338
+ // If any of these fails, it might be because the `AssetSortByProperty` needs to be updated to match the GraphQL enum
339
+ return {
340
+ property: sortBy,
341
+ order,
342
+ customFieldDefinitionId,
343
+ };
344
+ };
345
+
346
+ /**
347
+ * A hook used to handle asset query filters.
348
+ * It resets the pagination when filters change.
349
+ * The assetQueryVariables can be passed directly to any AssetsResolver based query.
350
+ * The filters are converted to the GraphQL API format.
351
+ *
352
+ * @example const { assetQueryVariables } = useAssetQueryFilters({ filters: filterBar.filterBarConfig.values });
353
+ * const { data: assets } = useMyAssetsQuery({
354
+ * variables: assetQueryVariables,
355
+ * });
356
+ * @returns {AssetQueryFilters} - assetQueryVariables
357
+ */
358
+ const useAssetQueryFilters = (props) => {
359
+ const filters = useActiveAssetFilters(props.filters);
360
+ const sort = useAssetSortInput();
361
+ const { systemOfMeasurement } = reactCoreHooks.useCurrentUserSystemOfMeasurement();
362
+ const assetQueryVariables = react.useMemo(() => ({
363
+ filters,
364
+ sort,
365
+ first: props.first || 50,
366
+ systemOfMeasurement: systemOfMeasurement,
367
+ // TODO only load custom fields active filters and visible custom field columns in table
368
+ // definitionIds:
369
+ // filters.customFields && filters.customFields.length > 0
370
+ // ? filters.customFields.map(customField => customField.definitionId!)
371
+ // : undefined,
372
+ definitionIds: undefined,
373
+ }), [filters, props.first, sort, systemOfMeasurement]);
374
+ return react.useMemo(() => ({
375
+ assetQueryVariables: assetQueryVariables,
376
+ }), [assetQueryVariables]);
377
+ };
378
+
379
+ /*
380
+ * ----------------------------
381
+ * | SETUP TRANSLATIONS START |
382
+ * ----------------------------
383
+ * This import and function call is needed to register translations for this library.
384
+ * Do not remove this if this library has translations.
385
+ */
386
+ setupLibraryTranslations();
387
+
388
+ exports.CustomFieldPrefix = CustomFieldPrefix;
389
+ exports.convertToAssetSortInput = convertToAssetSortInput;
390
+ exports.fixType = fixType;
391
+ exports.fixTypes = fixTypes;
392
+ exports.isStringArrayValue = isStringArrayValue;
393
+ exports.isValueName = isValueName;
394
+ exports.stringArrayOrUndefined = stringArrayOrUndefined;
395
+ exports.useActiveAssetFilters = useActiveAssetFilters;
396
+ exports.useAssetQueryFilters = useAssetQueryFilters;
397
+ exports.useAssetSortInput = useAssetSortInput;
398
+ exports.useCustomFieldFilters = useCustomFieldFilters;
399
+ exports.valueNameArrayOrUndefined = valueNameArrayOrUndefined;
400
+ exports.valuesIfNotEmpty = valuesIfNotEmpty;