@procore/saved-views 6.0.2 → 6.2.0
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/README.md +13 -2
- package/dist/legacy/adapters/hub-data-loader.d.mts +22 -0
- package/dist/legacy/adapters/hub-data-loader.d.ts +22 -0
- package/dist/legacy/adapters/hub-data-loader.js +273 -0
- package/dist/legacy/adapters/hub-data-loader.mjs +273 -0
- package/dist/legacy/chunk-6DZX6EAA.mjs +37 -0
- package/dist/legacy/chunk-QGM4M3NI.js +37 -0
- package/dist/legacy/index.d.mts +22 -3
- package/dist/legacy/index.d.ts +22 -3
- package/dist/legacy/index.js +755 -487
- package/dist/legacy/index.mjs +493 -268
- package/dist/legacy/transport/default.d.mts +15 -0
- package/dist/legacy/transport/default.d.ts +15 -0
- package/dist/legacy/transport/default.js +104 -0
- package/dist/legacy/transport/default.mjs +104 -0
- package/dist/legacy/types-BWhJ-on3.d.mts +109 -0
- package/dist/legacy/types-BWhJ-on3.d.ts +109 -0
- package/dist/modern/adapters/hub-data-loader.d.mts +22 -0
- package/dist/modern/adapters/hub-data-loader.d.ts +22 -0
- package/dist/modern/adapters/hub-data-loader.js +270 -0
- package/dist/modern/adapters/hub-data-loader.mjs +270 -0
- package/dist/modern/chunk-6DZX6EAA.mjs +37 -0
- package/dist/modern/chunk-QGM4M3NI.js +37 -0
- package/dist/modern/index.d.mts +22 -3
- package/dist/modern/index.d.ts +22 -3
- package/dist/modern/index.js +807 -540
- package/dist/modern/index.mjs +492 -268
- package/dist/modern/transport/default.d.mts +15 -0
- package/dist/modern/transport/default.d.ts +15 -0
- package/dist/modern/transport/default.js +104 -0
- package/dist/modern/transport/default.mjs +104 -0
- package/dist/modern/types-BWhJ-on3.d.mts +109 -0
- package/dist/modern/types-BWhJ-on3.d.ts +109 -0
- package/package.json +35 -2
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }require('../chunk-QGM4M3NI.js');
|
|
2
|
+
|
|
3
|
+
// src/transport/hub-data-loader.tsx
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
var _react = require('react'); var _react2 = _interopRequireDefault(_react);
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
var _websdkhubdataloader = require('@procore/web-sdk-hub-data-loader');
|
|
17
|
+
var HubDataLoaderCache = class {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
20
|
+
}
|
|
21
|
+
getOrCreate(key) {
|
|
22
|
+
let entry = this.entries.get(key);
|
|
23
|
+
if (!entry) {
|
|
24
|
+
entry = { data: void 0, listeners: /* @__PURE__ */ new Set() };
|
|
25
|
+
this.entries.set(key, entry);
|
|
26
|
+
}
|
|
27
|
+
return entry;
|
|
28
|
+
}
|
|
29
|
+
subscribe(key, listener) {
|
|
30
|
+
const entry = this.getOrCreate(key);
|
|
31
|
+
entry.listeners.add(listener);
|
|
32
|
+
return () => {
|
|
33
|
+
entry.listeners.delete(listener);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
get(key) {
|
|
37
|
+
return _optionalChain([this, 'access', _ => _.entries, 'access', _2 => _2.get, 'call', _3 => _3(key), 'optionalAccess', _4 => _4.data]);
|
|
38
|
+
}
|
|
39
|
+
set(key, data) {
|
|
40
|
+
const entry = this.getOrCreate(key);
|
|
41
|
+
entry.data = data;
|
|
42
|
+
entry.listeners.forEach((listener) => listener());
|
|
43
|
+
}
|
|
44
|
+
invalidate(key) {
|
|
45
|
+
const entry = this.entries.get(key);
|
|
46
|
+
if (!entry) return;
|
|
47
|
+
entry.data = void 0;
|
|
48
|
+
entry.listeners.forEach((listener) => listener());
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
var stringifyQueryKey = (queryKey) => JSON.stringify(queryKey);
|
|
52
|
+
var HubDataLoaderCacheContext = _react.createContext.call(void 0, void 0);
|
|
53
|
+
var useHubDataLoaderCache = () => {
|
|
54
|
+
const ctx = _react.useContext.call(void 0, HubDataLoaderCacheContext);
|
|
55
|
+
if (!ctx) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
"HubDataLoaderCacheProvider is missing. This indicates the saved-views transport was not constructed via createHubDataLoaderTransport()."
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return ctx.cache;
|
|
61
|
+
};
|
|
62
|
+
var METHOD_TO_OPERATION_TYPE = {
|
|
63
|
+
GET: "GET",
|
|
64
|
+
POST: "POST",
|
|
65
|
+
PUT: "PUT",
|
|
66
|
+
DELETE: "DELETE"
|
|
67
|
+
};
|
|
68
|
+
var splitUrl = (url) => {
|
|
69
|
+
const queryIndex = url.indexOf("?");
|
|
70
|
+
if (queryIndex === -1) {
|
|
71
|
+
return { operationName: url, queryParams: {} };
|
|
72
|
+
}
|
|
73
|
+
const operationName = url.slice(0, queryIndex);
|
|
74
|
+
const search = new URLSearchParams(url.slice(queryIndex + 1));
|
|
75
|
+
const queryParams = {};
|
|
76
|
+
search.forEach((value, key) => {
|
|
77
|
+
queryParams[key] = value;
|
|
78
|
+
});
|
|
79
|
+
return { operationName, queryParams };
|
|
80
|
+
};
|
|
81
|
+
var parseBody = (body) => {
|
|
82
|
+
if (body === void 0 || body === null) return void 0;
|
|
83
|
+
if (typeof body === "string") {
|
|
84
|
+
try {
|
|
85
|
+
return JSON.parse(body);
|
|
86
|
+
} catch (e) {
|
|
87
|
+
return void 0;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (typeof body === "object") {
|
|
91
|
+
return body;
|
|
92
|
+
}
|
|
93
|
+
return void 0;
|
|
94
|
+
};
|
|
95
|
+
var createHubDataLoaderTransport = (options) => {
|
|
96
|
+
const { hubCardId, systemEvents } = options;
|
|
97
|
+
const CacheProvider = ({ children }) => {
|
|
98
|
+
const cacheRef = _react.useRef.call(void 0, );
|
|
99
|
+
if (!cacheRef.current) {
|
|
100
|
+
cacheRef.current = new HubDataLoaderCache();
|
|
101
|
+
}
|
|
102
|
+
const value = _react.useMemo.call(void 0,
|
|
103
|
+
() => ({ cache: cacheRef.current }),
|
|
104
|
+
[]
|
|
105
|
+
);
|
|
106
|
+
return /* @__PURE__ */ _react2.default.createElement(HubDataLoaderCacheContext.Provider, { value }, children);
|
|
107
|
+
};
|
|
108
|
+
const useHttp = () => {
|
|
109
|
+
const { sendRequest } = _websdkhubdataloader.useHubDataLoader.call(void 0, hubCardId, systemEvents);
|
|
110
|
+
return _react.useCallback.call(void 0,
|
|
111
|
+
async (req) => {
|
|
112
|
+
const { operationName, queryParams } = splitUrl(req.url);
|
|
113
|
+
const params = {
|
|
114
|
+
operationName,
|
|
115
|
+
operationType: METHOD_TO_OPERATION_TYPE[req.method],
|
|
116
|
+
queryParams,
|
|
117
|
+
body: parseBody(req.body),
|
|
118
|
+
headers: req.headers,
|
|
119
|
+
// Read saved-views GETs fresh from the network. This transport keeps
|
|
120
|
+
// its own local subscription cache (HubDataLoaderCache) and gates
|
|
121
|
+
// refetches on a local-cache miss, so it doesn't benefit from the
|
|
122
|
+
// host's stale-while-revalidate cache. Without preferFresh the host
|
|
123
|
+
// serves the GET via `ensureQueryData`, which returns the cached
|
|
124
|
+
// (pre-mutation) list — so a freshly created/renamed/deleted view
|
|
125
|
+
// wouldn't appear until the host cache expired. preferFresh routes
|
|
126
|
+
// the read through `fetchQuery({ staleTime: 0 })`, guaranteeing the
|
|
127
|
+
// post-mutation refetch reflects the change immediately.
|
|
128
|
+
preferFresh: req.method === "GET"
|
|
129
|
+
};
|
|
130
|
+
const response = await sendRequest(params);
|
|
131
|
+
if (response.error) {
|
|
132
|
+
throw response.error;
|
|
133
|
+
}
|
|
134
|
+
return response.responseData;
|
|
135
|
+
},
|
|
136
|
+
[sendRequest]
|
|
137
|
+
);
|
|
138
|
+
};
|
|
139
|
+
const useQueryAdapter = (args) => {
|
|
140
|
+
const cache = useHubDataLoaderCache();
|
|
141
|
+
const key = _react.useMemo.call(void 0,
|
|
142
|
+
() => stringifyQueryKey(args.queryKey),
|
|
143
|
+
[args.queryKey]
|
|
144
|
+
);
|
|
145
|
+
const queryFnRef = _react.useRef.call(void 0, args.queryFn);
|
|
146
|
+
queryFnRef.current = args.queryFn;
|
|
147
|
+
const subscribe = _react.useCallback.call(void 0,
|
|
148
|
+
(listener) => cache.subscribe(key, listener),
|
|
149
|
+
[cache, key]
|
|
150
|
+
);
|
|
151
|
+
const getSnapshot = _react.useCallback.call(void 0,
|
|
152
|
+
() => cache.get(key),
|
|
153
|
+
[cache, key]
|
|
154
|
+
);
|
|
155
|
+
const data = _react.useSyncExternalStore.call(void 0, subscribe, getSnapshot, getSnapshot);
|
|
156
|
+
const [isLoading, setIsLoading] = _react.useState.call(void 0,
|
|
157
|
+
args.enabled !== false && data === void 0
|
|
158
|
+
);
|
|
159
|
+
const [error, setError] = _react.useState.call(void 0, void 0);
|
|
160
|
+
const fetchInFlight = _react.useRef.call(void 0, false);
|
|
161
|
+
_react.useEffect.call(void 0, () => {
|
|
162
|
+
if (args.enabled === false) {
|
|
163
|
+
setIsLoading(false);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (data !== void 0) {
|
|
167
|
+
setIsLoading(false);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (fetchInFlight.current) return;
|
|
171
|
+
let abandoned = false;
|
|
172
|
+
fetchInFlight.current = true;
|
|
173
|
+
setIsLoading(true);
|
|
174
|
+
setError(void 0);
|
|
175
|
+
queryFnRef.current().then((result) => {
|
|
176
|
+
if (!abandoned) {
|
|
177
|
+
cache.set(key, result);
|
|
178
|
+
setError(void 0);
|
|
179
|
+
}
|
|
180
|
+
}).catch((err) => {
|
|
181
|
+
if (!abandoned) setError(err);
|
|
182
|
+
}).finally(() => {
|
|
183
|
+
if (!abandoned) {
|
|
184
|
+
fetchInFlight.current = false;
|
|
185
|
+
setIsLoading(false);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
return () => {
|
|
189
|
+
abandoned = true;
|
|
190
|
+
fetchInFlight.current = false;
|
|
191
|
+
};
|
|
192
|
+
}, [cache, key, args.enabled, data]);
|
|
193
|
+
return {
|
|
194
|
+
data,
|
|
195
|
+
isLoading,
|
|
196
|
+
isError: error !== void 0,
|
|
197
|
+
error
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
const useMutationAdapter = (args) => {
|
|
201
|
+
const [isPending, setIsPending] = _react.useState.call(void 0, false);
|
|
202
|
+
const [error, setError] = _react.useState.call(void 0, null);
|
|
203
|
+
const mutationFnRef = _react.useRef.call(void 0, args.mutationFn);
|
|
204
|
+
const onSuccessRef = _react.useRef.call(void 0, args.onSuccess);
|
|
205
|
+
const onErrorRef = _react.useRef.call(void 0, args.onError);
|
|
206
|
+
mutationFnRef.current = args.mutationFn;
|
|
207
|
+
onSuccessRef.current = args.onSuccess;
|
|
208
|
+
onErrorRef.current = args.onError;
|
|
209
|
+
const mutate = _react.useCallback.call(void 0,
|
|
210
|
+
(variables, callOptions) => {
|
|
211
|
+
setIsPending(true);
|
|
212
|
+
setError(null);
|
|
213
|
+
mutationFnRef.current(variables).then((result) => {
|
|
214
|
+
_optionalChain([onSuccessRef, 'access', _5 => _5.current, 'optionalCall', _6 => _6(result, variables)]);
|
|
215
|
+
_optionalChain([callOptions, 'optionalAccess', _7 => _7.onSuccess, 'optionalCall', _8 => _8(result, variables)]);
|
|
216
|
+
}).catch((err) => {
|
|
217
|
+
setError(err);
|
|
218
|
+
_optionalChain([onErrorRef, 'access', _9 => _9.current, 'optionalCall', _10 => _10(err, variables)]);
|
|
219
|
+
_optionalChain([callOptions, 'optionalAccess', _11 => _11.onError, 'optionalCall', _12 => _12(err, variables)]);
|
|
220
|
+
}).finally(() => {
|
|
221
|
+
setIsPending(false);
|
|
222
|
+
});
|
|
223
|
+
},
|
|
224
|
+
[]
|
|
225
|
+
);
|
|
226
|
+
const reset = _react.useCallback.call(void 0, () => {
|
|
227
|
+
setError(null);
|
|
228
|
+
setIsPending(false);
|
|
229
|
+
}, []);
|
|
230
|
+
return { mutate, isPending, error, reset };
|
|
231
|
+
};
|
|
232
|
+
const useCacheControl = () => {
|
|
233
|
+
const cache = useHubDataLoaderCache();
|
|
234
|
+
return {
|
|
235
|
+
invalidate: (queryKey) => {
|
|
236
|
+
cache.invalidate(stringifyQueryKey(queryKey));
|
|
237
|
+
},
|
|
238
|
+
setData: (queryKey, updater) => {
|
|
239
|
+
const key = stringifyQueryKey(queryKey);
|
|
240
|
+
const existing = cache.get(key);
|
|
241
|
+
const next = updater(existing);
|
|
242
|
+
cache.set(key, next);
|
|
243
|
+
},
|
|
244
|
+
getData: (queryKey) => cache.get(stringifyQueryKey(queryKey))
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
const useUrlAdapter = () => ({
|
|
248
|
+
// Hub Cards cannot read or write the host's URL. The host owns routing.
|
|
249
|
+
// The saved-views package falls back to localStorage-only persistence
|
|
250
|
+
// when these return null / no-op.
|
|
251
|
+
getViewToken: () => null,
|
|
252
|
+
setViewToken: () => {
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
return {
|
|
256
|
+
// Hub Cards cannot own the host URL, so the `?saved-view=<token>` share link
|
|
257
|
+
// cannot be read back on load. Hide the copy-link affordance in this context
|
|
258
|
+
// (see routing-in-hub-cards.md). The rest of saved views works unchanged.
|
|
259
|
+
supportsUrlSharing: false,
|
|
260
|
+
CacheProvider,
|
|
261
|
+
useHttp,
|
|
262
|
+
useQueryAdapter,
|
|
263
|
+
useMutationAdapter,
|
|
264
|
+
useCacheControl,
|
|
265
|
+
useUrlAdapter
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
exports.createHubDataLoaderTransport = createHubDataLoaderTransport;
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import "../chunk-6DZX6EAA.mjs";
|
|
2
|
+
|
|
3
|
+
// src/transport/hub-data-loader.tsx
|
|
4
|
+
import React, {
|
|
5
|
+
createContext,
|
|
6
|
+
useCallback,
|
|
7
|
+
useContext,
|
|
8
|
+
useEffect,
|
|
9
|
+
useMemo,
|
|
10
|
+
useRef,
|
|
11
|
+
useState,
|
|
12
|
+
useSyncExternalStore
|
|
13
|
+
} from "react";
|
|
14
|
+
import {
|
|
15
|
+
useHubDataLoader
|
|
16
|
+
} from "@procore/web-sdk-hub-data-loader";
|
|
17
|
+
var HubDataLoaderCache = class {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
20
|
+
}
|
|
21
|
+
getOrCreate(key) {
|
|
22
|
+
let entry = this.entries.get(key);
|
|
23
|
+
if (!entry) {
|
|
24
|
+
entry = { data: void 0, listeners: /* @__PURE__ */ new Set() };
|
|
25
|
+
this.entries.set(key, entry);
|
|
26
|
+
}
|
|
27
|
+
return entry;
|
|
28
|
+
}
|
|
29
|
+
subscribe(key, listener) {
|
|
30
|
+
const entry = this.getOrCreate(key);
|
|
31
|
+
entry.listeners.add(listener);
|
|
32
|
+
return () => {
|
|
33
|
+
entry.listeners.delete(listener);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
get(key) {
|
|
37
|
+
return this.entries.get(key)?.data;
|
|
38
|
+
}
|
|
39
|
+
set(key, data) {
|
|
40
|
+
const entry = this.getOrCreate(key);
|
|
41
|
+
entry.data = data;
|
|
42
|
+
entry.listeners.forEach((listener) => listener());
|
|
43
|
+
}
|
|
44
|
+
invalidate(key) {
|
|
45
|
+
const entry = this.entries.get(key);
|
|
46
|
+
if (!entry) return;
|
|
47
|
+
entry.data = void 0;
|
|
48
|
+
entry.listeners.forEach((listener) => listener());
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
var stringifyQueryKey = (queryKey) => JSON.stringify(queryKey);
|
|
52
|
+
var HubDataLoaderCacheContext = createContext(void 0);
|
|
53
|
+
var useHubDataLoaderCache = () => {
|
|
54
|
+
const ctx = useContext(HubDataLoaderCacheContext);
|
|
55
|
+
if (!ctx) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
"HubDataLoaderCacheProvider is missing. This indicates the saved-views transport was not constructed via createHubDataLoaderTransport()."
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return ctx.cache;
|
|
61
|
+
};
|
|
62
|
+
var METHOD_TO_OPERATION_TYPE = {
|
|
63
|
+
GET: "GET",
|
|
64
|
+
POST: "POST",
|
|
65
|
+
PUT: "PUT",
|
|
66
|
+
DELETE: "DELETE"
|
|
67
|
+
};
|
|
68
|
+
var splitUrl = (url) => {
|
|
69
|
+
const queryIndex = url.indexOf("?");
|
|
70
|
+
if (queryIndex === -1) {
|
|
71
|
+
return { operationName: url, queryParams: {} };
|
|
72
|
+
}
|
|
73
|
+
const operationName = url.slice(0, queryIndex);
|
|
74
|
+
const search = new URLSearchParams(url.slice(queryIndex + 1));
|
|
75
|
+
const queryParams = {};
|
|
76
|
+
search.forEach((value, key) => {
|
|
77
|
+
queryParams[key] = value;
|
|
78
|
+
});
|
|
79
|
+
return { operationName, queryParams };
|
|
80
|
+
};
|
|
81
|
+
var parseBody = (body) => {
|
|
82
|
+
if (body === void 0 || body === null) return void 0;
|
|
83
|
+
if (typeof body === "string") {
|
|
84
|
+
try {
|
|
85
|
+
return JSON.parse(body);
|
|
86
|
+
} catch {
|
|
87
|
+
return void 0;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (typeof body === "object") {
|
|
91
|
+
return body;
|
|
92
|
+
}
|
|
93
|
+
return void 0;
|
|
94
|
+
};
|
|
95
|
+
var createHubDataLoaderTransport = (options) => {
|
|
96
|
+
const { hubCardId, systemEvents } = options;
|
|
97
|
+
const CacheProvider = ({ children }) => {
|
|
98
|
+
const cacheRef = useRef();
|
|
99
|
+
if (!cacheRef.current) {
|
|
100
|
+
cacheRef.current = new HubDataLoaderCache();
|
|
101
|
+
}
|
|
102
|
+
const value = useMemo(
|
|
103
|
+
() => ({ cache: cacheRef.current }),
|
|
104
|
+
[]
|
|
105
|
+
);
|
|
106
|
+
return /* @__PURE__ */ React.createElement(HubDataLoaderCacheContext.Provider, { value }, children);
|
|
107
|
+
};
|
|
108
|
+
const useHttp = () => {
|
|
109
|
+
const { sendRequest } = useHubDataLoader(hubCardId, systemEvents);
|
|
110
|
+
return useCallback(
|
|
111
|
+
async (req) => {
|
|
112
|
+
const { operationName, queryParams } = splitUrl(req.url);
|
|
113
|
+
const params = {
|
|
114
|
+
operationName,
|
|
115
|
+
operationType: METHOD_TO_OPERATION_TYPE[req.method],
|
|
116
|
+
queryParams,
|
|
117
|
+
body: parseBody(req.body),
|
|
118
|
+
headers: req.headers,
|
|
119
|
+
// Read saved-views GETs fresh from the network. This transport keeps
|
|
120
|
+
// its own local subscription cache (HubDataLoaderCache) and gates
|
|
121
|
+
// refetches on a local-cache miss, so it doesn't benefit from the
|
|
122
|
+
// host's stale-while-revalidate cache. Without preferFresh the host
|
|
123
|
+
// serves the GET via `ensureQueryData`, which returns the cached
|
|
124
|
+
// (pre-mutation) list — so a freshly created/renamed/deleted view
|
|
125
|
+
// wouldn't appear until the host cache expired. preferFresh routes
|
|
126
|
+
// the read through `fetchQuery({ staleTime: 0 })`, guaranteeing the
|
|
127
|
+
// post-mutation refetch reflects the change immediately.
|
|
128
|
+
preferFresh: req.method === "GET"
|
|
129
|
+
};
|
|
130
|
+
const response = await sendRequest(params);
|
|
131
|
+
if (response.error) {
|
|
132
|
+
throw response.error;
|
|
133
|
+
}
|
|
134
|
+
return response.responseData;
|
|
135
|
+
},
|
|
136
|
+
[sendRequest]
|
|
137
|
+
);
|
|
138
|
+
};
|
|
139
|
+
const useQueryAdapter = (args) => {
|
|
140
|
+
const cache = useHubDataLoaderCache();
|
|
141
|
+
const key = useMemo(
|
|
142
|
+
() => stringifyQueryKey(args.queryKey),
|
|
143
|
+
[args.queryKey]
|
|
144
|
+
);
|
|
145
|
+
const queryFnRef = useRef(args.queryFn);
|
|
146
|
+
queryFnRef.current = args.queryFn;
|
|
147
|
+
const subscribe = useCallback(
|
|
148
|
+
(listener) => cache.subscribe(key, listener),
|
|
149
|
+
[cache, key]
|
|
150
|
+
);
|
|
151
|
+
const getSnapshot = useCallback(
|
|
152
|
+
() => cache.get(key),
|
|
153
|
+
[cache, key]
|
|
154
|
+
);
|
|
155
|
+
const data = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
156
|
+
const [isLoading, setIsLoading] = useState(
|
|
157
|
+
args.enabled !== false && data === void 0
|
|
158
|
+
);
|
|
159
|
+
const [error, setError] = useState(void 0);
|
|
160
|
+
const fetchInFlight = useRef(false);
|
|
161
|
+
useEffect(() => {
|
|
162
|
+
if (args.enabled === false) {
|
|
163
|
+
setIsLoading(false);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (data !== void 0) {
|
|
167
|
+
setIsLoading(false);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (fetchInFlight.current) return;
|
|
171
|
+
let abandoned = false;
|
|
172
|
+
fetchInFlight.current = true;
|
|
173
|
+
setIsLoading(true);
|
|
174
|
+
setError(void 0);
|
|
175
|
+
queryFnRef.current().then((result) => {
|
|
176
|
+
if (!abandoned) {
|
|
177
|
+
cache.set(key, result);
|
|
178
|
+
setError(void 0);
|
|
179
|
+
}
|
|
180
|
+
}).catch((err) => {
|
|
181
|
+
if (!abandoned) setError(err);
|
|
182
|
+
}).finally(() => {
|
|
183
|
+
if (!abandoned) {
|
|
184
|
+
fetchInFlight.current = false;
|
|
185
|
+
setIsLoading(false);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
return () => {
|
|
189
|
+
abandoned = true;
|
|
190
|
+
fetchInFlight.current = false;
|
|
191
|
+
};
|
|
192
|
+
}, [cache, key, args.enabled, data]);
|
|
193
|
+
return {
|
|
194
|
+
data,
|
|
195
|
+
isLoading,
|
|
196
|
+
isError: error !== void 0,
|
|
197
|
+
error
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
const useMutationAdapter = (args) => {
|
|
201
|
+
const [isPending, setIsPending] = useState(false);
|
|
202
|
+
const [error, setError] = useState(null);
|
|
203
|
+
const mutationFnRef = useRef(args.mutationFn);
|
|
204
|
+
const onSuccessRef = useRef(args.onSuccess);
|
|
205
|
+
const onErrorRef = useRef(args.onError);
|
|
206
|
+
mutationFnRef.current = args.mutationFn;
|
|
207
|
+
onSuccessRef.current = args.onSuccess;
|
|
208
|
+
onErrorRef.current = args.onError;
|
|
209
|
+
const mutate = useCallback(
|
|
210
|
+
(variables, callOptions) => {
|
|
211
|
+
setIsPending(true);
|
|
212
|
+
setError(null);
|
|
213
|
+
mutationFnRef.current(variables).then((result) => {
|
|
214
|
+
onSuccessRef.current?.(result, variables);
|
|
215
|
+
callOptions?.onSuccess?.(result, variables);
|
|
216
|
+
}).catch((err) => {
|
|
217
|
+
setError(err);
|
|
218
|
+
onErrorRef.current?.(err, variables);
|
|
219
|
+
callOptions?.onError?.(err, variables);
|
|
220
|
+
}).finally(() => {
|
|
221
|
+
setIsPending(false);
|
|
222
|
+
});
|
|
223
|
+
},
|
|
224
|
+
[]
|
|
225
|
+
);
|
|
226
|
+
const reset = useCallback(() => {
|
|
227
|
+
setError(null);
|
|
228
|
+
setIsPending(false);
|
|
229
|
+
}, []);
|
|
230
|
+
return { mutate, isPending, error, reset };
|
|
231
|
+
};
|
|
232
|
+
const useCacheControl = () => {
|
|
233
|
+
const cache = useHubDataLoaderCache();
|
|
234
|
+
return {
|
|
235
|
+
invalidate: (queryKey) => {
|
|
236
|
+
cache.invalidate(stringifyQueryKey(queryKey));
|
|
237
|
+
},
|
|
238
|
+
setData: (queryKey, updater) => {
|
|
239
|
+
const key = stringifyQueryKey(queryKey);
|
|
240
|
+
const existing = cache.get(key);
|
|
241
|
+
const next = updater(existing);
|
|
242
|
+
cache.set(key, next);
|
|
243
|
+
},
|
|
244
|
+
getData: (queryKey) => cache.get(stringifyQueryKey(queryKey))
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
const useUrlAdapter = () => ({
|
|
248
|
+
// Hub Cards cannot read or write the host's URL. The host owns routing.
|
|
249
|
+
// The saved-views package falls back to localStorage-only persistence
|
|
250
|
+
// when these return null / no-op.
|
|
251
|
+
getViewToken: () => null,
|
|
252
|
+
setViewToken: () => {
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
return {
|
|
256
|
+
// Hub Cards cannot own the host URL, so the `?saved-view=<token>` share link
|
|
257
|
+
// cannot be read back on load. Hide the copy-link affordance in this context
|
|
258
|
+
// (see routing-in-hub-cards.md). The rest of saved views works unchanged.
|
|
259
|
+
supportsUrlSharing: false,
|
|
260
|
+
CacheProvider,
|
|
261
|
+
useHttp,
|
|
262
|
+
useQueryAdapter,
|
|
263
|
+
useMutationAdapter,
|
|
264
|
+
useCacheControl,
|
|
265
|
+
useUrlAdapter
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
export {
|
|
269
|
+
createHubDataLoaderTransport
|
|
270
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
+
}) : x)(function(x) {
|
|
10
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
+
});
|
|
13
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
14
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
15
|
+
};
|
|
16
|
+
var __copyProps = (to, from, except, desc) => {
|
|
17
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
|
+
for (let key of __getOwnPropNames(from))
|
|
19
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
20
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
+
mod
|
|
31
|
+
));
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
__require,
|
|
35
|
+
__commonJS,
|
|
36
|
+
__toESM
|
|
37
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
+
}) : x)(function(x) {
|
|
10
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
+
});
|
|
13
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
14
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
15
|
+
};
|
|
16
|
+
var __copyProps = (to, from, except, desc) => {
|
|
17
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
|
+
for (let key of __getOwnPropNames(from))
|
|
19
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
20
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
+
mod
|
|
31
|
+
));
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
exports.__require = __require; exports.__commonJS = __commonJS; exports.__toESM = __toESM;
|
package/dist/modern/index.d.mts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { Locale } from '@procore/globalization-toolkit';
|
|
2
2
|
import * as React$1 from 'react';
|
|
3
|
-
import React__default from 'react';
|
|
3
|
+
import React__default, { PropsWithChildren } from 'react';
|
|
4
4
|
import { DataTableConfig, TableApi, ColumnDefinition } from '@procore/data-table';
|
|
5
5
|
import { ColumnState, FilterModel, GridApi } from 'ag-grid-community';
|
|
6
6
|
import * as _procore_core_react_dist_Panel_Panel_types from '@procore/core-react/dist/Panel/Panel.types';
|
|
7
7
|
import * as styled_components_dist_types from 'styled-components/dist/types';
|
|
8
8
|
import * as _procore_core_react from '@procore/core-react';
|
|
9
|
+
import { S as SavedViewsTransport } from './types-BWhJ-on3.mjs';
|
|
10
|
+
export { a as SavedViewsCacheControl, b as SavedViewsHttpRequest, c as SavedViewsMutationArgs, d as SavedViewsMutationResult, e as SavedViewsQueryArgs, f as SavedViewsQueryResult, g as SavedViewsUrlAdapter } from './types-BWhJ-on3.mjs';
|
|
9
11
|
|
|
10
12
|
declare function getTranslations(envLocale: Locale): Record<string, object>;
|
|
11
13
|
|
|
12
14
|
declare const useSavedViewsPanel: (domain: string, tableName: string) => {
|
|
13
15
|
isOpen: boolean;
|
|
14
16
|
SavedViewsButton: () => React__default.JSX.Element;
|
|
17
|
+
SavedViewsProvider: ({ children, }: React__default.PropsWithChildren) => React__default.JSX.Element;
|
|
15
18
|
};
|
|
16
19
|
|
|
17
20
|
interface IQueryInputProps {
|
|
@@ -64,6 +67,15 @@ interface IBaseSavedViewsProps {
|
|
|
64
67
|
projectId?: number;
|
|
65
68
|
companyId: number;
|
|
66
69
|
stickyViewsKey: string;
|
|
70
|
+
/**
|
|
71
|
+
* Optional transport that injects HTTP, query/mutation, cache, and URL
|
|
72
|
+
* adapters. Defaults to a transport backed by `@procore/core-http`,
|
|
73
|
+
* `@tanstack/react-query`, and `react-router-dom` (today's behavior).
|
|
74
|
+
*
|
|
75
|
+
* Hub Card consumers should pass the result of `createHubDataLoaderTransport`
|
|
76
|
+
* from `@procore/saved-views/adapters/hub-data-loader`.
|
|
77
|
+
*/
|
|
78
|
+
transport?: SavedViewsTransport;
|
|
67
79
|
}
|
|
68
80
|
interface ISavedViewsProps extends Omit<IBaseSavedViewsProps, 'stickyViewsKey'> {
|
|
69
81
|
defaultView: ISavedView;
|
|
@@ -116,6 +128,13 @@ interface IPanelContentProps {
|
|
|
116
128
|
onClearTemporary?: () => void;
|
|
117
129
|
}
|
|
118
130
|
|
|
131
|
+
interface SavedViewsSelectionContextValue {
|
|
132
|
+
selectedView: ISavedView | null;
|
|
133
|
+
setSelectedView: (view: ISavedView | null) => void;
|
|
134
|
+
}
|
|
135
|
+
declare const SavedViewsSelectionProvider: ({ children, }: PropsWithChildren) => React__default.JSX.Element;
|
|
136
|
+
declare const useSavedViewsSelection: () => SavedViewsSelectionContextValue | null;
|
|
137
|
+
|
|
119
138
|
type SavedViewCollectionMenuItemProps = {
|
|
120
139
|
item: ISavedView;
|
|
121
140
|
key?: string;
|
|
@@ -158,7 +177,7 @@ declare const ExpandedPanel: styled_components_dist_types.IStyledComponentBase<"
|
|
|
158
177
|
|
|
159
178
|
declare const PanelContent: (props: IPanelContentProps) => React__default.JSX.Element;
|
|
160
179
|
|
|
161
|
-
declare const SavedViews: (props: ISavedViewsProps) => React__default.JSX.Element;
|
|
180
|
+
declare const SavedViews: (props: ISavedViewsProps) => React__default.JSX.Element | null;
|
|
162
181
|
|
|
163
182
|
type Props = {
|
|
164
183
|
onDelete(): void;
|
|
@@ -189,4 +208,4 @@ interface IDataTableSavedViewsRef {
|
|
|
189
208
|
}
|
|
190
209
|
declare const DataTableSavedViews: React__default.ForwardRefExoticComponent<IDataTableSavedViewsExternalConsumerProps & React__default.RefAttributes<IDataTableSavedViewsRef>>;
|
|
191
210
|
|
|
192
|
-
export { DataTableSavedViews, ExpandedPanel, FormModal, type IDataTableDefaultViewConfig, type IDataTableSavedViewsRef, type ISmartGridDefaultViewConfig, PanelContent, SavedViewCollectionMenuItem, SavedViews, SavedViewsDeleteConfirmationModalShared, SmartGridSavedViews, getTranslations, useSavedViewsPanel };
|
|
211
|
+
export { DataTableSavedViews, ExpandedPanel, FormModal, type IDataTableDefaultViewConfig, type IDataTableSavedViewsRef, type ISmartGridDefaultViewConfig, PanelContent, SavedViewCollectionMenuItem, SavedViews, SavedViewsDeleteConfirmationModalShared, type SavedViewsSelectionContextValue, SavedViewsSelectionProvider, SavedViewsTransport, SmartGridSavedViews, getTranslations, useSavedViewsPanel, useSavedViewsSelection };
|