@trackunit/react-date-and-time-hooks 2.1.4 → 2.1.5
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/index.cjs.js +91 -39
- package/index.esm.js +93 -39
- package/package.json +15 -8
- package/src/generated/graphql-api/fragment-masking.d.ts +19 -0
- package/src/generated/graphql-api/gql.d.ts +37 -0
- package/src/generated/graphql-api/graphql.d.ts +142 -0
- package/src/generated/graphql-api/index.d.ts +2 -0
- package/src/index.d.ts +0 -1
- package/src/test/index.d.ts +1 -0
- package/src/test/mocks/mockAssetTimezone.d.ts +17 -0
- package/src/useTimezone.d.ts +23 -7
- package/src/AssetTimezoneContext.d.ts +0 -24
package/index.cjs.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var react = require('react');
|
|
4
3
|
var dateAndTimeUtils = require('@trackunit/date-and-time-utils');
|
|
5
4
|
var sharedUtils = require('@trackunit/shared-utils');
|
|
5
|
+
var react = require('react');
|
|
6
6
|
var irisAppRuntimeCoreApi = require('@trackunit/iris-app-runtime-core-api');
|
|
7
|
+
var reactComponents = require('@trackunit/react-components');
|
|
7
8
|
var reactCoreHooks = require('@trackunit/react-core-hooks');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/** Returns the resolved asset timezone from the nearest AssetTimezoneProvider in the component tree. */
|
|
11
|
-
const useAssetTimezoneContext = () => react.useContext(AssetTimezoneContext);
|
|
9
|
+
var reactGraphqlHooks = require('@trackunit/react-graphql-hooks');
|
|
10
|
+
var zod = require('zod');
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* Try to convert to ISO standard. ex. en becomes en-GB if its in United Kingdom.
|
|
@@ -40,28 +39,78 @@ const useLocale = () => {
|
|
|
40
39
|
return userLocale || BrowserLocale;
|
|
41
40
|
};
|
|
42
41
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
42
|
+
const GetAssetTimezoneDocument = {
|
|
43
|
+
kind: "Document",
|
|
44
|
+
definitions: [
|
|
45
|
+
{
|
|
46
|
+
kind: "OperationDefinition",
|
|
47
|
+
operation: "query",
|
|
48
|
+
name: { kind: "Name", value: "GetAssetTimezone" },
|
|
49
|
+
variableDefinitions: [
|
|
50
|
+
{
|
|
51
|
+
kind: "VariableDefinition",
|
|
52
|
+
variable: { kind: "Variable", name: { kind: "Name", value: "assetId" } },
|
|
53
|
+
type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "ID" } } },
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
selectionSet: {
|
|
57
|
+
kind: "SelectionSet",
|
|
58
|
+
selections: [
|
|
59
|
+
{
|
|
60
|
+
kind: "Field",
|
|
61
|
+
name: { kind: "Name", value: "asset" },
|
|
62
|
+
arguments: [
|
|
63
|
+
{
|
|
64
|
+
kind: "Argument",
|
|
65
|
+
name: { kind: "Name", value: "id" },
|
|
66
|
+
value: { kind: "Variable", name: { kind: "Name", value: "assetId" } },
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
selectionSet: {
|
|
70
|
+
kind: "SelectionSet",
|
|
71
|
+
selections: [
|
|
72
|
+
{
|
|
73
|
+
kind: "Field",
|
|
74
|
+
name: { kind: "Name", value: "locations" },
|
|
75
|
+
selectionSet: {
|
|
76
|
+
kind: "SelectionSet",
|
|
77
|
+
selections: [
|
|
78
|
+
{
|
|
79
|
+
kind: "Field",
|
|
80
|
+
name: { kind: "Name", value: "latest" },
|
|
81
|
+
selectionSet: {
|
|
82
|
+
kind: "SelectionSet",
|
|
83
|
+
selections: [
|
|
84
|
+
{
|
|
85
|
+
kind: "Field",
|
|
86
|
+
name: { kind: "Name", value: "properties" },
|
|
87
|
+
selectionSet: {
|
|
88
|
+
kind: "SelectionSet",
|
|
89
|
+
selections: [{ kind: "Field", name: { kind: "Name", value: "timeZone" } }],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
],
|
|
55
105
|
};
|
|
106
|
+
|
|
107
|
+
const customTimeZoneSchema = zod.z.string().nullable();
|
|
56
108
|
/**
|
|
57
109
|
* Resolves the active timezone based on user preference, custom override, and optional asset location.
|
|
58
110
|
*
|
|
59
111
|
* Returns `current` (browser or custom override), `preferred` (resolved per user settings
|
|
60
112
|
* and optional asset), and `assetTimeZone` (fetched from the asset's GPS location).
|
|
61
113
|
*
|
|
62
|
-
* The asset timezone is resolved by the nearest `AssetTimezoneProvider` in the component tree.
|
|
63
|
-
* Use `AssetTimezoneProvider` on asset-detail pages to enable machine-timezone resolution.
|
|
64
|
-
*
|
|
65
114
|
* **When to use:**
|
|
66
115
|
* - Use `useTimezone` whenever you need to display or calculate dates in the correct
|
|
67
116
|
* timezone — especially on asset-detail pages where the machine's timezone may differ
|
|
@@ -70,23 +119,28 @@ const readTimezoneFromStorage = () => {
|
|
|
70
119
|
* - Do **not** rely on `Intl.DateTimeFormat().resolvedOptions().timeZone` directly —
|
|
71
120
|
* this hook respects the user's preference setting (browser, machine, or custom).
|
|
72
121
|
*/
|
|
73
|
-
const useTimezone = () => {
|
|
74
|
-
const {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
122
|
+
const useTimezone = ({ assetId } = {}) => {
|
|
123
|
+
const { timeZonePreference } = reactCoreHooks.useCurrentUserTimeZonePreference();
|
|
124
|
+
const localStorageProps = react.useMemo(() => ({
|
|
125
|
+
key: "customTimeZone",
|
|
126
|
+
defaultState: null,
|
|
127
|
+
schema: customTimeZoneSchema,
|
|
128
|
+
}), []);
|
|
129
|
+
const [customTimezone, setCustomTimezone] = reactComponents.useLocalStorage(localStorageProps);
|
|
130
|
+
const { data: timeZoneData } = reactGraphqlHooks.useQuery(GetAssetTimezoneDocument, {
|
|
131
|
+
variables: {
|
|
132
|
+
assetId: assetId ?? "",
|
|
133
|
+
},
|
|
134
|
+
skip: !assetId,
|
|
135
|
+
fetchPolicy: "cache-first",
|
|
136
|
+
});
|
|
137
|
+
const assetTimeZone = react.useMemo(() => {
|
|
138
|
+
const timezone = timeZoneData?.asset?.locations?.latest?.properties?.timeZone;
|
|
139
|
+
if (!timezone) {
|
|
140
|
+
return null;
|
|
84
141
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// null → host explicitly has no custom timezone; do NOT fall back to potentially stale iframe localStorage.
|
|
88
|
-
// string → host-provided value; use it directly.
|
|
89
|
-
const customTimezone = contextCustomTimezone !== undefined ? contextCustomTimezone : localStorageCustomTimezone;
|
|
142
|
+
return dateAndTimeUtils.getTimeZone(timezone);
|
|
143
|
+
}, [timeZoneData?.asset?.locations?.latest?.properties?.timeZone]);
|
|
90
144
|
const current = react.useMemo(() => {
|
|
91
145
|
const id = dateAndTimeUtils.Temporal.Now.timeZoneId();
|
|
92
146
|
if (timeZonePreference === irisAppRuntimeCoreApi.TimeZonePreference.CustomTimeZone && customTimezone) {
|
|
@@ -100,7 +154,7 @@ const useTimezone = () => {
|
|
|
100
154
|
}
|
|
101
155
|
return current;
|
|
102
156
|
}, [timeZonePreference, current, assetTimeZone]);
|
|
103
|
-
return react.useMemo(() => ({ current, assetTimeZone, preferred, setCustomTimezone
|
|
157
|
+
return react.useMemo(() => ({ current, assetTimeZone, preferred, setCustomTimezone }), [current, assetTimeZone, preferred, setCustomTimezone]);
|
|
104
158
|
};
|
|
105
159
|
|
|
106
160
|
/**
|
|
@@ -499,9 +553,7 @@ const useDateAndTime = () => {
|
|
|
499
553
|
]);
|
|
500
554
|
};
|
|
501
555
|
|
|
502
|
-
exports.AssetTimezoneContext = AssetTimezoneContext;
|
|
503
556
|
exports.convertToLocale = convertToLocale;
|
|
504
|
-
exports.useAssetTimezoneContext = useAssetTimezoneContext;
|
|
505
557
|
exports.useDateAndTime = useDateAndTime;
|
|
506
558
|
exports.useLocale = useLocale;
|
|
507
559
|
exports.useTimezone = useTimezone;
|
package/index.esm.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Temporal, getTimeZone, toDateUtil, toZonedDateTimeUtil, formatDateUtil, formatRangeUtil, subtractYearsUtil, subtractMonthsUtil, subtractWeeksUtil, subtractDaysUtil, subtractHoursUtil, subtractMinutesUtil, addYearsUtil, addMonthsUtil, addWeeksUtil, addDaysUtil, addHoursUtil, addMinutesUtil, startOfMonthUtil, startOfWeekUtil, startOfDayUtil, startOfHourUtil, startOfMinuteUtil, endOfMonthUtil, endOfWeekUtil, endOfDayUtil, endOfHourUtil, endOfMinuteUtil, differenceInYearsUtil, differenceInMonthsUtil, differenceInWeeksUtil, differenceInDaysUtil, differenceInHoursUtil, differenceInMinutesUtil, differenceInSecondsUtil, isBetweenUtil, isTodayUtil, isFutureUtil, isPastUtil, isSameYearUtil, isSameMonthUtil, isSameWeekUtil, isSameDayUtil, timeSinceInYears, timeSinceInMonths, timeSinceInDays, timeSinceInHours, timeSinceInMinutes, timeSinceInSeconds, timeSinceAuto, toDuration, getDurationFormat, convertMillisecondsUtil, convertSecondsUtil, convertMinutesUtil, convertHoursUtil, dayNameUtil, daysUtil, monthNameUtil, monthsUtil, getUTCFromTimeZonedUtil, isEqualUtil } from '@trackunit/date-and-time-utils';
|
|
1
|
+
import { getTimeZone, Temporal, toDateUtil, toZonedDateTimeUtil, formatDateUtil, formatRangeUtil, subtractYearsUtil, subtractMonthsUtil, subtractWeeksUtil, subtractDaysUtil, subtractHoursUtil, subtractMinutesUtil, addYearsUtil, addMonthsUtil, addWeeksUtil, addDaysUtil, addHoursUtil, addMinutesUtil, startOfMonthUtil, startOfWeekUtil, startOfDayUtil, startOfHourUtil, startOfMinuteUtil, endOfMonthUtil, endOfWeekUtil, endOfDayUtil, endOfHourUtil, endOfMinuteUtil, differenceInYearsUtil, differenceInMonthsUtil, differenceInWeeksUtil, differenceInDaysUtil, differenceInHoursUtil, differenceInMinutesUtil, differenceInSecondsUtil, isBetweenUtil, isTodayUtil, isFutureUtil, isPastUtil, isSameYearUtil, isSameMonthUtil, isSameWeekUtil, isSameDayUtil, timeSinceInYears, timeSinceInMonths, timeSinceInDays, timeSinceInHours, timeSinceInMinutes, timeSinceInSeconds, timeSinceAuto, toDuration, getDurationFormat, convertMillisecondsUtil, convertSecondsUtil, convertMinutesUtil, convertHoursUtil, dayNameUtil, daysUtil, monthNameUtil, monthsUtil, getUTCFromTimeZonedUtil, isEqualUtil } from '@trackunit/date-and-time-utils';
|
|
3
2
|
import { exhaustiveCheck } from '@trackunit/shared-utils';
|
|
3
|
+
import { useMemo, useCallback } from 'react';
|
|
4
4
|
import { TimeZonePreference } from '@trackunit/iris-app-runtime-core-api';
|
|
5
|
+
import { useLocalStorage } from '@trackunit/react-components';
|
|
5
6
|
import { useCurrentUserTimeZonePreference } from '@trackunit/react-core-hooks';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/** Returns the resolved asset timezone from the nearest AssetTimezoneProvider in the component tree. */
|
|
9
|
-
const useAssetTimezoneContext = () => useContext(AssetTimezoneContext);
|
|
7
|
+
import { useQuery } from '@trackunit/react-graphql-hooks';
|
|
8
|
+
import { z } from 'zod';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Try to convert to ISO standard. ex. en becomes en-GB if its in United Kingdom.
|
|
@@ -38,28 +37,78 @@ const useLocale = () => {
|
|
|
38
37
|
return userLocale || BrowserLocale;
|
|
39
38
|
};
|
|
40
39
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
40
|
+
const GetAssetTimezoneDocument = {
|
|
41
|
+
kind: "Document",
|
|
42
|
+
definitions: [
|
|
43
|
+
{
|
|
44
|
+
kind: "OperationDefinition",
|
|
45
|
+
operation: "query",
|
|
46
|
+
name: { kind: "Name", value: "GetAssetTimezone" },
|
|
47
|
+
variableDefinitions: [
|
|
48
|
+
{
|
|
49
|
+
kind: "VariableDefinition",
|
|
50
|
+
variable: { kind: "Variable", name: { kind: "Name", value: "assetId" } },
|
|
51
|
+
type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "ID" } } },
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
selectionSet: {
|
|
55
|
+
kind: "SelectionSet",
|
|
56
|
+
selections: [
|
|
57
|
+
{
|
|
58
|
+
kind: "Field",
|
|
59
|
+
name: { kind: "Name", value: "asset" },
|
|
60
|
+
arguments: [
|
|
61
|
+
{
|
|
62
|
+
kind: "Argument",
|
|
63
|
+
name: { kind: "Name", value: "id" },
|
|
64
|
+
value: { kind: "Variable", name: { kind: "Name", value: "assetId" } },
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
selectionSet: {
|
|
68
|
+
kind: "SelectionSet",
|
|
69
|
+
selections: [
|
|
70
|
+
{
|
|
71
|
+
kind: "Field",
|
|
72
|
+
name: { kind: "Name", value: "locations" },
|
|
73
|
+
selectionSet: {
|
|
74
|
+
kind: "SelectionSet",
|
|
75
|
+
selections: [
|
|
76
|
+
{
|
|
77
|
+
kind: "Field",
|
|
78
|
+
name: { kind: "Name", value: "latest" },
|
|
79
|
+
selectionSet: {
|
|
80
|
+
kind: "SelectionSet",
|
|
81
|
+
selections: [
|
|
82
|
+
{
|
|
83
|
+
kind: "Field",
|
|
84
|
+
name: { kind: "Name", value: "properties" },
|
|
85
|
+
selectionSet: {
|
|
86
|
+
kind: "SelectionSet",
|
|
87
|
+
selections: [{ kind: "Field", name: { kind: "Name", value: "timeZone" } }],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
],
|
|
53
103
|
};
|
|
104
|
+
|
|
105
|
+
const customTimeZoneSchema = z.string().nullable();
|
|
54
106
|
/**
|
|
55
107
|
* Resolves the active timezone based on user preference, custom override, and optional asset location.
|
|
56
108
|
*
|
|
57
109
|
* Returns `current` (browser or custom override), `preferred` (resolved per user settings
|
|
58
110
|
* and optional asset), and `assetTimeZone` (fetched from the asset's GPS location).
|
|
59
111
|
*
|
|
60
|
-
* The asset timezone is resolved by the nearest `AssetTimezoneProvider` in the component tree.
|
|
61
|
-
* Use `AssetTimezoneProvider` on asset-detail pages to enable machine-timezone resolution.
|
|
62
|
-
*
|
|
63
112
|
* **When to use:**
|
|
64
113
|
* - Use `useTimezone` whenever you need to display or calculate dates in the correct
|
|
65
114
|
* timezone — especially on asset-detail pages where the machine's timezone may differ
|
|
@@ -68,23 +117,28 @@ const readTimezoneFromStorage = () => {
|
|
|
68
117
|
* - Do **not** rely on `Intl.DateTimeFormat().resolvedOptions().timeZone` directly —
|
|
69
118
|
* this hook respects the user's preference setting (browser, machine, or custom).
|
|
70
119
|
*/
|
|
71
|
-
const useTimezone = () => {
|
|
72
|
-
const {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
120
|
+
const useTimezone = ({ assetId } = {}) => {
|
|
121
|
+
const { timeZonePreference } = useCurrentUserTimeZonePreference();
|
|
122
|
+
const localStorageProps = useMemo(() => ({
|
|
123
|
+
key: "customTimeZone",
|
|
124
|
+
defaultState: null,
|
|
125
|
+
schema: customTimeZoneSchema,
|
|
126
|
+
}), []);
|
|
127
|
+
const [customTimezone, setCustomTimezone] = useLocalStorage(localStorageProps);
|
|
128
|
+
const { data: timeZoneData } = useQuery(GetAssetTimezoneDocument, {
|
|
129
|
+
variables: {
|
|
130
|
+
assetId: assetId ?? "",
|
|
131
|
+
},
|
|
132
|
+
skip: !assetId,
|
|
133
|
+
fetchPolicy: "cache-first",
|
|
134
|
+
});
|
|
135
|
+
const assetTimeZone = useMemo(() => {
|
|
136
|
+
const timezone = timeZoneData?.asset?.locations?.latest?.properties?.timeZone;
|
|
137
|
+
if (!timezone) {
|
|
138
|
+
return null;
|
|
82
139
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// null → host explicitly has no custom timezone; do NOT fall back to potentially stale iframe localStorage.
|
|
86
|
-
// string → host-provided value; use it directly.
|
|
87
|
-
const customTimezone = contextCustomTimezone !== undefined ? contextCustomTimezone : localStorageCustomTimezone;
|
|
140
|
+
return getTimeZone(timezone);
|
|
141
|
+
}, [timeZoneData?.asset?.locations?.latest?.properties?.timeZone]);
|
|
88
142
|
const current = useMemo(() => {
|
|
89
143
|
const id = Temporal.Now.timeZoneId();
|
|
90
144
|
if (timeZonePreference === TimeZonePreference.CustomTimeZone && customTimezone) {
|
|
@@ -98,7 +152,7 @@ const useTimezone = () => {
|
|
|
98
152
|
}
|
|
99
153
|
return current;
|
|
100
154
|
}, [timeZonePreference, current, assetTimeZone]);
|
|
101
|
-
return useMemo(() => ({ current, assetTimeZone, preferred, setCustomTimezone
|
|
155
|
+
return useMemo(() => ({ current, assetTimeZone, preferred, setCustomTimezone }), [current, assetTimeZone, preferred, setCustomTimezone]);
|
|
102
156
|
};
|
|
103
157
|
|
|
104
158
|
/**
|
|
@@ -497,4 +551,4 @@ const useDateAndTime = () => {
|
|
|
497
551
|
]);
|
|
498
552
|
};
|
|
499
553
|
|
|
500
|
-
export {
|
|
554
|
+
export { convertToLocale, useDateAndTime, useLocale, useTimezone };
|
package/package.json
CHANGED
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-date-and-time-hooks",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.5",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=24.x"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@
|
|
11
|
-
"@
|
|
12
|
-
"
|
|
13
|
-
"@trackunit/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"@trackunit/
|
|
10
|
+
"@graphql-codegen/cli": "^5.0.3",
|
|
11
|
+
"@graphql-typed-document-node/core": "^3.2.0",
|
|
12
|
+
"zod": "^3.25.76",
|
|
13
|
+
"@trackunit/iris-app-api": "2.0.6",
|
|
14
|
+
"@trackunit/react-core-contexts-test": "1.17.14",
|
|
15
|
+
"@trackunit/date-and-time-utils": "1.13.15",
|
|
16
|
+
"@trackunit/shared-utils": "1.15.14",
|
|
17
|
+
"@trackunit/react-core-hooks": "1.17.18",
|
|
18
|
+
"@trackunit/react-components": "2.1.4",
|
|
19
|
+
"@trackunit/react-graphql-hooks": "2.1.4",
|
|
20
|
+
"@trackunit/iris-app-runtime-core-api": "1.16.14"
|
|
17
21
|
},
|
|
18
22
|
"peerDependencies": {
|
|
23
|
+
"@apollo/client": "^3.13.8",
|
|
24
|
+
"@tanstack/react-router": "^1.114.29",
|
|
25
|
+
"graphql": "^16.10.0",
|
|
19
26
|
"react": "^19.0.0"
|
|
20
27
|
},
|
|
21
28
|
"module": "./index.esm.js",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
2
|
+
import { Incremental } from './graphql';
|
|
3
|
+
export type FragmentType<TDocumentType extends DocumentTypeDecoration<any, any>> = TDocumentType extends DocumentTypeDecoration<infer TType, any> ? [TType] extends [{
|
|
4
|
+
' $fragmentName'?: infer TKey;
|
|
5
|
+
}] ? TKey extends string ? {
|
|
6
|
+
' $fragmentRefs'?: {
|
|
7
|
+
[key in TKey]: TType;
|
|
8
|
+
};
|
|
9
|
+
} : never : never : never;
|
|
10
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>): TType;
|
|
11
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined): TType | undefined;
|
|
12
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null): TType | null;
|
|
13
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined): TType | null | undefined;
|
|
14
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: Array<FragmentType<DocumentTypeDecoration<TType, any>>>): Array<TType>;
|
|
15
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: Array<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined): Array<TType> | null | undefined;
|
|
16
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>): ReadonlyArray<TType>;
|
|
17
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined): ReadonlyArray<TType> | null | undefined;
|
|
18
|
+
export declare function makeFragmentData<F extends DocumentTypeDecoration<any, any>, FT extends ResultOf<F>>(data: FT, _fragment: F): FragmentType<F>;
|
|
19
|
+
export declare function isFragmentReady<TQuery, TFrag>(queryNode: DocumentTypeDecoration<TQuery, any>, fragmentNode: TypedDocumentNode<TFrag>, data: FragmentType<TypedDocumentNode<Incremental<TFrag>, any>> | null | undefined): data is FragmentType<typeof fragmentNode>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as types from './graphql';
|
|
2
|
+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
3
|
+
/**
|
|
4
|
+
* Map of all GraphQL operations in the project.
|
|
5
|
+
*
|
|
6
|
+
* This map has several performance disadvantages:
|
|
7
|
+
* 1. It is not tree-shakeable, so it will include all operations in the project.
|
|
8
|
+
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
|
|
9
|
+
* 3. It does not support dead code elimination, so it will add unused operations.
|
|
10
|
+
*
|
|
11
|
+
* Therefore it is highly recommended to use the babel or swc plugin for production.
|
|
12
|
+
* Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size
|
|
13
|
+
*/
|
|
14
|
+
declare const documents: {
|
|
15
|
+
"query GetAssetTimezone($assetId: ID!) {\n asset(id: $assetId) {\n locations {\n latest {\n properties {\n timeZone\n }\n }\n }\n }\n}": DocumentNode<types.GetAssetTimezoneQuery, types.Exact<{
|
|
16
|
+
assetId: types.Scalars["ID"]["input"];
|
|
17
|
+
}>>;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
21
|
+
*
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* The query argument is unknown!
|
|
29
|
+
* Please regenerate the types.
|
|
30
|
+
*/
|
|
31
|
+
export declare function graphql(source: string): unknown;
|
|
32
|
+
/**
|
|
33
|
+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
34
|
+
*/
|
|
35
|
+
export declare function graphql(source: "query GetAssetTimezone($assetId: ID!) {\n asset(id: $assetId) {\n locations {\n latest {\n properties {\n timeZone\n }\n }\n }\n }\n}"): (typeof documents)["query GetAssetTimezone($assetId: ID!) {\n asset(id: $assetId) {\n locations {\n latest {\n properties {\n timeZone\n }\n }\n }\n }\n}"];
|
|
36
|
+
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode<infer TType, any> ? TType : never;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { TypedDocumentNode as DocumentNode } from "@graphql-typed-document-node/core";
|
|
2
|
+
import type { PublicIrisAppManifest } from "@trackunit/iris-app-api";
|
|
3
|
+
export type Maybe<T> = T | null;
|
|
4
|
+
export type InputMaybe<T> = Maybe<T> | undefined;
|
|
5
|
+
export type Exact<T extends {
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
}> = {
|
|
8
|
+
[K in keyof T]: T[K];
|
|
9
|
+
};
|
|
10
|
+
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & {
|
|
11
|
+
[SubKey in K]?: Maybe<T[SubKey]>;
|
|
12
|
+
};
|
|
13
|
+
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & {
|
|
14
|
+
[SubKey in K]: Maybe<T[SubKey]>;
|
|
15
|
+
};
|
|
16
|
+
export type MakeEmpty<T extends {
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}, K extends keyof T> = {
|
|
19
|
+
[_ in K]?: never;
|
|
20
|
+
};
|
|
21
|
+
export type Incremental<T> = T | {
|
|
22
|
+
[P in keyof T]?: P extends " $fragmentName" | "__typename" ? T[P] : never;
|
|
23
|
+
};
|
|
24
|
+
export type DateTimeISOString = string;
|
|
25
|
+
/** All built-in and custom scalars, mapped to their actual values */
|
|
26
|
+
export type Scalars = {
|
|
27
|
+
ID: {
|
|
28
|
+
input: string;
|
|
29
|
+
output: string;
|
|
30
|
+
};
|
|
31
|
+
String: {
|
|
32
|
+
input: string;
|
|
33
|
+
output: string;
|
|
34
|
+
};
|
|
35
|
+
Boolean: {
|
|
36
|
+
input: boolean;
|
|
37
|
+
output: boolean;
|
|
38
|
+
};
|
|
39
|
+
Int: {
|
|
40
|
+
input: number;
|
|
41
|
+
output: number;
|
|
42
|
+
};
|
|
43
|
+
Float: {
|
|
44
|
+
input: number;
|
|
45
|
+
output: number;
|
|
46
|
+
};
|
|
47
|
+
/** The ISO 4217 currency code of the monetary field definition. */
|
|
48
|
+
Currency: {
|
|
49
|
+
input: string;
|
|
50
|
+
output: string;
|
|
51
|
+
};
|
|
52
|
+
/** Cursor scalar. */
|
|
53
|
+
Cursor: {
|
|
54
|
+
input: string;
|
|
55
|
+
output: string;
|
|
56
|
+
};
|
|
57
|
+
/** Date without time, Eg. 2019-01-01 */
|
|
58
|
+
Date: {
|
|
59
|
+
input: DateTimeISOString;
|
|
60
|
+
output: DateTimeISOString;
|
|
61
|
+
};
|
|
62
|
+
/** DateTime represents a “date-time” as specified in section 5.6 of RFC 3339 */
|
|
63
|
+
DateTime: {
|
|
64
|
+
input: DateTimeISOString;
|
|
65
|
+
output: DateTimeISOString;
|
|
66
|
+
};
|
|
67
|
+
/** Duration represents an ISO 8601 duration */
|
|
68
|
+
Duration: {
|
|
69
|
+
input: any;
|
|
70
|
+
output: any;
|
|
71
|
+
};
|
|
72
|
+
/** Valid email address according to https://owasp.org/www-community/OWASP_Validation_Regex_Repository */
|
|
73
|
+
EmailAddress: {
|
|
74
|
+
input: string;
|
|
75
|
+
output: string;
|
|
76
|
+
};
|
|
77
|
+
/** A (possiblely multidimensional) set of coordinates following x, y, z order. */
|
|
78
|
+
GeoJSONCoordinates: {
|
|
79
|
+
input: [number, number] | [number, number][] | [number, number][][];
|
|
80
|
+
output: [number, number] | [number, number][] | [number, number][][];
|
|
81
|
+
};
|
|
82
|
+
/** Raw JSON object structure, not serialized to string */
|
|
83
|
+
JSON: {
|
|
84
|
+
input: any;
|
|
85
|
+
output: any;
|
|
86
|
+
};
|
|
87
|
+
/** The `JSONObject` scalar type represents JSON values as a string */
|
|
88
|
+
JSONObject: {
|
|
89
|
+
input: any;
|
|
90
|
+
output: any;
|
|
91
|
+
};
|
|
92
|
+
/** 24-hour clock time string in the format hh:mm:ss.sss or hh:mm:ss if partial seconds is zero */
|
|
93
|
+
LocalTime: {
|
|
94
|
+
input: any;
|
|
95
|
+
output: any;
|
|
96
|
+
};
|
|
97
|
+
/** Javascript `Long`. Type represents a 64 bit integer. */
|
|
98
|
+
Long: {
|
|
99
|
+
input: any;
|
|
100
|
+
output: any;
|
|
101
|
+
};
|
|
102
|
+
/** Phone number in E.164 format */
|
|
103
|
+
PhoneNumber: {
|
|
104
|
+
input: string;
|
|
105
|
+
output: string;
|
|
106
|
+
};
|
|
107
|
+
/** The `PublicIrisAppManifest` scalar type represents an Iris App Manifest as JSON */
|
|
108
|
+
PublicIrisAppManifest: {
|
|
109
|
+
input: PublicIrisAppManifest;
|
|
110
|
+
output: PublicIrisAppManifest;
|
|
111
|
+
};
|
|
112
|
+
/** Uniform resource locator */
|
|
113
|
+
Url: {
|
|
114
|
+
input: string;
|
|
115
|
+
output: string;
|
|
116
|
+
};
|
|
117
|
+
/** YearMonth scalar */
|
|
118
|
+
YearMonth: {
|
|
119
|
+
input: any;
|
|
120
|
+
output: any;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
export type GetAssetTimezoneQueryVariables = Exact<{
|
|
124
|
+
assetId: Scalars["ID"]["input"];
|
|
125
|
+
}>;
|
|
126
|
+
export type GetAssetTimezoneQuery = {
|
|
127
|
+
__typename?: "Query";
|
|
128
|
+
asset: {
|
|
129
|
+
__typename?: "Asset";
|
|
130
|
+
locations: {
|
|
131
|
+
__typename?: "Locations";
|
|
132
|
+
latest: {
|
|
133
|
+
__typename?: "GeoJSONFeatureForAsset";
|
|
134
|
+
properties: {
|
|
135
|
+
__typename?: "GeoJSONPropertiesForAsset";
|
|
136
|
+
timeZone: string | null;
|
|
137
|
+
} | null;
|
|
138
|
+
} | null;
|
|
139
|
+
} | null;
|
|
140
|
+
} | null;
|
|
141
|
+
};
|
|
142
|
+
export declare const GetAssetTimezoneDocument: DocumentNode<GetAssetTimezoneQuery, GetAssetTimezoneQueryVariables>;
|
package/src/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { mockAssetTimezone } from "./mocks/mockAssetTimezone";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MockedResponse } from "@apollo/client/testing";
|
|
2
|
+
import { GetAssetTimezoneQuery } from "../../generated/graphql-api/graphql";
|
|
3
|
+
type AssetTimezoneMockProps = {
|
|
4
|
+
assetId: string;
|
|
5
|
+
timeZone: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Mocks the asset timezone query.
|
|
9
|
+
*
|
|
10
|
+
* @param { AssetTimezoneMockProps} props - The properties for the asset timezone query.
|
|
11
|
+
* @param {string} [props.assetId] - The asset id
|
|
12
|
+
* @param {string} [props.timeZone] - The timezone to mock
|
|
13
|
+
*/
|
|
14
|
+
export declare const mockAssetTimezone: ({ assetId, timeZone, }: AssetTimezoneMockProps) => MockedResponse<GetAssetTimezoneQuery> & {
|
|
15
|
+
data: NonNullable<GetAssetTimezoneQuery>;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
package/src/useTimezone.d.ts
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
|
-
|
|
1
|
+
export interface TimeZone {
|
|
2
|
+
/**
|
|
3
|
+
* The unique id of the timezone
|
|
4
|
+
*
|
|
5
|
+
* @example "America/Denver"
|
|
6
|
+
*/
|
|
7
|
+
id: string;
|
|
8
|
+
/**
|
|
9
|
+
* The human-readable name of the timezone. Combines id and offset.
|
|
10
|
+
*
|
|
11
|
+
* @example "America/Denver (-06:00 MDT)"
|
|
12
|
+
*/
|
|
13
|
+
name: string;
|
|
14
|
+
/**
|
|
15
|
+
* @example "-06:00 MDT"
|
|
16
|
+
*/
|
|
17
|
+
offset: string;
|
|
18
|
+
}
|
|
2
19
|
interface UseTimezoneReturn {
|
|
3
20
|
current: TimeZone;
|
|
4
21
|
assetTimeZone: TimeZone | null;
|
|
5
22
|
preferred: TimeZone;
|
|
6
23
|
setCustomTimezone: (timezone: string | null) => void;
|
|
7
|
-
|
|
8
|
-
|
|
24
|
+
}
|
|
25
|
+
interface TimezoneProps {
|
|
26
|
+
/** supply assetId to fetch the timezone for the given machine */
|
|
27
|
+
assetId?: string;
|
|
9
28
|
}
|
|
10
29
|
/**
|
|
11
30
|
* Resolves the active timezone based on user preference, custom override, and optional asset location.
|
|
@@ -13,9 +32,6 @@ interface UseTimezoneReturn {
|
|
|
13
32
|
* Returns `current` (browser or custom override), `preferred` (resolved per user settings
|
|
14
33
|
* and optional asset), and `assetTimeZone` (fetched from the asset's GPS location).
|
|
15
34
|
*
|
|
16
|
-
* The asset timezone is resolved by the nearest `AssetTimezoneProvider` in the component tree.
|
|
17
|
-
* Use `AssetTimezoneProvider` on asset-detail pages to enable machine-timezone resolution.
|
|
18
|
-
*
|
|
19
35
|
* **When to use:**
|
|
20
36
|
* - Use `useTimezone` whenever you need to display or calculate dates in the correct
|
|
21
37
|
* timezone — especially on asset-detail pages where the machine's timezone may differ
|
|
@@ -24,5 +40,5 @@ interface UseTimezoneReturn {
|
|
|
24
40
|
* - Do **not** rely on `Intl.DateTimeFormat().resolvedOptions().timeZone` directly —
|
|
25
41
|
* this hook respects the user's preference setting (browser, machine, or custom).
|
|
26
42
|
*/
|
|
27
|
-
export declare const useTimezone: () => UseTimezoneReturn;
|
|
43
|
+
export declare const useTimezone: ({ assetId }?: TimezoneProps) => UseTimezoneReturn;
|
|
28
44
|
export {};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export interface TimeZone {
|
|
2
|
-
/**
|
|
3
|
-
* The unique id of the timezone
|
|
4
|
-
*
|
|
5
|
-
* @example "America/Denver"
|
|
6
|
-
*/
|
|
7
|
-
id: string;
|
|
8
|
-
/**
|
|
9
|
-
* The human-readable name of the timezone. Combines id and offset.
|
|
10
|
-
*
|
|
11
|
-
* @example "America/Denver (-06:00 MDT)"
|
|
12
|
-
*/
|
|
13
|
-
name: string;
|
|
14
|
-
/**
|
|
15
|
-
* @example "-06:00 MDT"
|
|
16
|
-
*/
|
|
17
|
-
offset: string;
|
|
18
|
-
}
|
|
19
|
-
export interface AssetTimezoneContextValue {
|
|
20
|
-
assetTimeZone: TimeZone | null;
|
|
21
|
-
}
|
|
22
|
-
export declare const AssetTimezoneContext: import("react").Context<AssetTimezoneContextValue>;
|
|
23
|
-
/** Returns the resolved asset timezone from the nearest AssetTimezoneProvider in the component tree. */
|
|
24
|
-
export declare const useAssetTimezoneContext: () => AssetTimezoneContextValue;
|