@jskit-ai/users-web 0.1.69 → 0.1.71
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/package.descriptor.mjs +7 -7
- package/package.json +11 -8
- package/src/client/bootstrap/user-bootstrap-handler.js +53 -0
- package/src/client/composables/crud/crudSchemaFormHelpers.js +1 -22
- package/src/client/composables/internal/crudListParentTitleSupport.js +14 -15
- package/src/client/composables/records/useAddEdit.js +23 -4
- package/src/client/composables/records/useCrudAddEdit.js +5 -20
- package/src/client/composables/records/useList.js +22 -22
- package/src/client/composables/records/useView.js +13 -27
- package/src/client/composables/runtime/operationValidationHelpers.js +18 -19
- package/src/client/composables/runtime/useAddEditCore.js +6 -10
- package/src/client/composables/runtime/useCommandCore.js +3 -10
- package/src/client/composables/runtime/useEndpointResource.js +75 -14
- package/src/client/composables/runtime/useListCore.js +45 -17
- package/src/client/composables/support/requestQueryRuntimeSupport.js +100 -0
- package/src/client/composables/useAccountSettingsRuntime.js +26 -19
- package/src/client/composables/useCommand.js +4 -2
- package/src/client/composables/useCrudListFilters.js +58 -255
- package/src/client/providers/UsersWebClientProvider.js +4 -2
- package/test/bootstrap.test.js +130 -0
- package/test/operationValidationHelpers.test.js +64 -0
- package/test/requestTransportOptions.test.js +107 -0
- package/test/useAddEditCore.test.js +124 -0
- package/test/useAddEditRequestQueryParams.test.js +162 -0
- package/test/useCrudAddEdit.test.js +1 -51
- package/test/useCrudListFilters.test.js +33 -4
- package/test/useCrudListParentTitle.test.js +40 -27
- package/test/useViewRequestQueryParams.test.js +10 -10
- package/src/client/composables/support/requestQueryPathSupport.js +0 -31
package/package.descriptor.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { HOME_COG_OUTLET } from "./src/shared/toolsOutletContracts.js";
|
|
|
3
3
|
export default Object.freeze({
|
|
4
4
|
packageVersion: 1,
|
|
5
5
|
packageId: "@jskit-ai/users-web",
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.71",
|
|
7
7
|
kind: "runtime",
|
|
8
8
|
description: "Users web module: account/profile UI plus shared users web widgets.",
|
|
9
9
|
dependsOn: [
|
|
@@ -159,12 +159,12 @@ export default Object.freeze({
|
|
|
159
159
|
runtime: {
|
|
160
160
|
"@tanstack/vue-query": "5.92.12",
|
|
161
161
|
"@mdi/js": "^7.4.47",
|
|
162
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
163
|
-
"@jskit-ai/realtime": "0.1.
|
|
164
|
-
"@jskit-ai/kernel": "0.1.
|
|
165
|
-
"@jskit-ai/shell-web": "0.1.
|
|
166
|
-
"@jskit-ai/uploads-image-web": "0.1.
|
|
167
|
-
"@jskit-ai/users-core": "0.1.
|
|
162
|
+
"@jskit-ai/http-runtime": "0.1.55",
|
|
163
|
+
"@jskit-ai/realtime": "0.1.55",
|
|
164
|
+
"@jskit-ai/kernel": "0.1.56",
|
|
165
|
+
"@jskit-ai/shell-web": "0.1.55",
|
|
166
|
+
"@jskit-ai/uploads-image-web": "0.1.34",
|
|
167
|
+
"@jskit-ai/users-core": "0.1.66",
|
|
168
168
|
vuetify: "^4.0.0"
|
|
169
169
|
},
|
|
170
170
|
dev: {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/users-web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.71",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -28,19 +28,22 @@
|
|
|
28
28
|
"./client/composables/usePaths": "./src/client/composables/usePaths.js",
|
|
29
29
|
"./client/composables/runtime/useUiFeedback": "./src/client/composables/runtime/useUiFeedback.js",
|
|
30
30
|
"./client/lib/httpClient": "./src/client/lib/httpClient.js",
|
|
31
|
-
"./client/lib/bootstrap": "./src/client/lib/bootstrap.js",
|
|
32
31
|
"./client/lib/permissions": "./src/client/lib/permissions.js",
|
|
33
32
|
"./client/support/contractGuards": "./src/client/support/contractGuards.js"
|
|
34
33
|
},
|
|
35
34
|
"dependencies": {
|
|
36
35
|
"@tanstack/vue-query": "5.92.12",
|
|
37
36
|
"@mdi/js": "^7.4.47",
|
|
38
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
39
|
-
"@jskit-ai/kernel": "0.1.
|
|
40
|
-
"@jskit-ai/realtime": "0.1.
|
|
41
|
-
"@jskit-ai/shell-web": "0.1.
|
|
42
|
-
"@jskit-ai/uploads-image-web": "0.1.
|
|
43
|
-
"@jskit-ai/users-core": "0.1.
|
|
37
|
+
"@jskit-ai/http-runtime": "0.1.55",
|
|
38
|
+
"@jskit-ai/kernel": "0.1.56",
|
|
39
|
+
"@jskit-ai/realtime": "0.1.55",
|
|
40
|
+
"@jskit-ai/shell-web": "0.1.55",
|
|
41
|
+
"@jskit-ai/uploads-image-web": "0.1.34",
|
|
42
|
+
"@jskit-ai/users-core": "0.1.66",
|
|
44
43
|
"vuetify": "^4.0.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"vue": "^3.5.13",
|
|
47
|
+
"vue-router": "^5.0.4"
|
|
45
48
|
}
|
|
46
49
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
registerBootstrapPayloadHandler,
|
|
3
|
+
resolveBootstrapErrorStatusCode
|
|
4
|
+
} from "@jskit-ai/shell-web/client/bootstrap";
|
|
5
|
+
import { resolvePlacementUserFromBootstrapPayload } from "../lib/bootstrap.js";
|
|
6
|
+
|
|
7
|
+
function createUsersBootstrapUserHandler() {
|
|
8
|
+
return Object.freeze({
|
|
9
|
+
handlerId: "users.web.bootstrap.user",
|
|
10
|
+
order: 50,
|
|
11
|
+
applyBootstrapPayload({ payload = {}, placementRuntime, source } = {}) {
|
|
12
|
+
if (!placementRuntime || typeof placementRuntime.setContext !== "function") {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const context = placementRuntime.getContext?.() || {};
|
|
17
|
+
placementRuntime.setContext(
|
|
18
|
+
{
|
|
19
|
+
user: resolvePlacementUserFromBootstrapPayload(payload, context?.user)
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
source
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
},
|
|
26
|
+
handleBootstrapError({ error, placementRuntime, source } = {}) {
|
|
27
|
+
if (!placementRuntime || typeof placementRuntime.setContext !== "function") {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (resolveBootstrapErrorStatusCode(error) !== 401) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
placementRuntime.setContext(
|
|
35
|
+
{
|
|
36
|
+
user: null
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
source
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function registerUsersBootstrapPayloadHandlers(app) {
|
|
47
|
+
registerBootstrapPayloadHandler(app, "users.web.bootstrap.user-handler", () => createUsersBootstrapUserHandler());
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export {
|
|
51
|
+
createUsersBootstrapUserHandler,
|
|
52
|
+
registerUsersBootstrapPayloadHandlers
|
|
53
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { validateOperationSection } from "@jskit-ai/http-runtime/shared/validators/operationValidation";
|
|
2
1
|
import { asPlainObject } from "../support/scopeHelpers.js";
|
|
3
2
|
import { toRouteParamValue } from "../support/routeTemplateHelpers.js";
|
|
4
3
|
|
|
@@ -337,25 +336,6 @@ function resolveCrudFieldErrors(fieldErrors = {}, fieldKey = "") {
|
|
|
337
336
|
return resolveStableFieldErrorList(key, message);
|
|
338
337
|
}
|
|
339
338
|
|
|
340
|
-
function parseCrudResourceOperationInput({
|
|
341
|
-
resource = null,
|
|
342
|
-
operationName = "",
|
|
343
|
-
rawPayload = {},
|
|
344
|
-
context = {}
|
|
345
|
-
} = {}) {
|
|
346
|
-
const normalizedOperationName = String(operationName || "").trim();
|
|
347
|
-
const operations = asPlainObject(asPlainObject(resource).operations);
|
|
348
|
-
const operation = asPlainObject(operations[normalizedOperationName]);
|
|
349
|
-
|
|
350
|
-
const parsed = validateOperationSection({
|
|
351
|
-
operation,
|
|
352
|
-
section: "bodyValidator",
|
|
353
|
-
value: rawPayload,
|
|
354
|
-
context
|
|
355
|
-
});
|
|
356
|
-
return parsed;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
339
|
export {
|
|
360
340
|
normalizeCrudFormFields,
|
|
361
341
|
createCrudFormModel,
|
|
@@ -363,6 +343,5 @@ export {
|
|
|
363
343
|
applyCrudPayloadToForm,
|
|
364
344
|
resolveCrudRouteBoundFieldValues,
|
|
365
345
|
applyCrudRouteBoundFieldValues,
|
|
366
|
-
resolveCrudFieldErrors
|
|
367
|
-
parseCrudResourceOperationInput
|
|
346
|
+
resolveCrudFieldErrors
|
|
368
347
|
};
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
resolveCrudLookupApiPathFromNamespace,
|
|
4
4
|
resolveCrudLookupFieldKeyFromRouteParam
|
|
5
5
|
} from "@jskit-ai/kernel/shared/support/crudLookup";
|
|
6
|
+
import { buildCrudFieldContractMap } from "@jskit-ai/kernel/shared/support/crudFieldContract";
|
|
6
7
|
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
7
8
|
import { resolveLookupFieldDisplayValue, resolveRecordTitle } from "../crud/crudLookupFieldLabelSupport.js";
|
|
8
9
|
import { resolveRouteParamNamesInOrder, toRouteParamValue } from "../support/routeTemplateHelpers.js";
|
|
@@ -58,21 +59,19 @@ function resolveLookupFieldMeta(resource = {}, fieldKey = "") {
|
|
|
58
59
|
return null;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const relation = entry?.relation;
|
|
68
|
-
if (!relation || normalizeText(relation.kind).toLowerCase() !== "lookup") {
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
62
|
+
const entry = buildCrudFieldContractMap(resource, {
|
|
63
|
+
context: "crud list parent title resource field contract"
|
|
64
|
+
})[normalizedFieldKey];
|
|
65
|
+
if (!entry) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
71
68
|
|
|
72
|
-
|
|
69
|
+
const relation = entry?.relation;
|
|
70
|
+
if (!relation || normalizeText(relation.kind).toLowerCase() !== "lookup") {
|
|
71
|
+
return null;
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
return
|
|
74
|
+
return entry;
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
function resolveCrudListParentDescriptor({ resource = {}, route = null, recordIdParam = "recordId" } = {}) {
|
|
@@ -92,12 +91,12 @@ function resolveCrudListParentDescriptor({ resource = {}, route = null, recordId
|
|
|
92
91
|
continue;
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
const
|
|
96
|
-
if (!
|
|
94
|
+
const fieldContractEntry = resolveLookupFieldMeta(resource, fieldKey);
|
|
95
|
+
if (!fieldContractEntry) {
|
|
97
96
|
continue;
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
const relation =
|
|
99
|
+
const relation = fieldContractEntry.relation || {};
|
|
101
100
|
const relationNamespace = normalizeText(relation.namespace);
|
|
102
101
|
const containerKey = normalizeCrudLookupContainerKey(relation.containerKey, {
|
|
103
102
|
defaultValue: resource?.contract?.lookup?.containerKey || "lookups"
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
resolveResourceMessages
|
|
16
16
|
} from "../support/scopeHelpers.js";
|
|
17
|
+
import { createRequestQueryRuntime } from "../support/requestQueryRuntimeSupport.js";
|
|
17
18
|
import { resolveRouteParamNamesInOrder } from "../support/routeTemplateHelpers.js";
|
|
18
19
|
|
|
19
20
|
function useAddEdit({
|
|
@@ -28,17 +29,19 @@ function useAddEdit({
|
|
|
28
29
|
readMethod = "GET",
|
|
29
30
|
readEnabled = true,
|
|
30
31
|
writeMethod = "PATCH",
|
|
32
|
+
transport = null,
|
|
31
33
|
placementSource = "users-web.add-edit",
|
|
32
34
|
fallbackLoadError = "Unable to load resource.",
|
|
33
35
|
fallbackSaveError = "Unable to save resource.",
|
|
34
36
|
fieldErrorKeys = [],
|
|
35
37
|
clearOnRouteChange = true,
|
|
36
38
|
model,
|
|
37
|
-
|
|
39
|
+
input,
|
|
38
40
|
mapLoadedToModel,
|
|
39
41
|
buildRawPayload,
|
|
40
42
|
buildSavePayload,
|
|
41
43
|
onSaveSuccess,
|
|
44
|
+
requestQueryParams = null,
|
|
42
45
|
recordIdParam = "recordId",
|
|
43
46
|
routeParams = null,
|
|
44
47
|
routeRecordId = null,
|
|
@@ -95,13 +98,29 @@ function useAddEdit({
|
|
|
95
98
|
const canView = operationScope.permissionGate("view");
|
|
96
99
|
const canSave = operationScope.permissionGate("save");
|
|
97
100
|
const queryCanRun = operationScope.queryCanRun(canView);
|
|
101
|
+
const queryParamsContext = computed(() => {
|
|
102
|
+
return Object.freeze({
|
|
103
|
+
surfaceId: operationScope.routeContext.currentSurfaceId.value,
|
|
104
|
+
scopeParamValue: operationScope.scopeParamValue.value,
|
|
105
|
+
ownershipFilter: operationScope.normalizedOwnershipFilter,
|
|
106
|
+
recordId: addEditUiRuntime.recordId.value,
|
|
107
|
+
model
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
const requestQueryRuntime = createRequestQueryRuntime({
|
|
111
|
+
requestQueryParams,
|
|
112
|
+
context: queryParamsContext,
|
|
113
|
+
sourceQueryKey: operationScope.queryKey
|
|
114
|
+
});
|
|
98
115
|
|
|
99
116
|
const endpointResource = useEndpointResource({
|
|
100
|
-
queryKey:
|
|
117
|
+
queryKey: requestQueryRuntime.queryKey,
|
|
101
118
|
path: operationScope.apiPath,
|
|
102
119
|
enabled: queryCanRun,
|
|
103
120
|
readMethod,
|
|
104
121
|
writeMethod,
|
|
122
|
+
readQuery: requestQueryRuntime.requestQuery,
|
|
123
|
+
transport,
|
|
105
124
|
fallbackLoadError,
|
|
106
125
|
fallbackSaveError: String(fallbackSaveError || effectiveMessages.saveError || "Unable to save resource.")
|
|
107
126
|
});
|
|
@@ -114,11 +133,11 @@ function useAddEdit({
|
|
|
114
133
|
const addEdit = useAddEditCore({
|
|
115
134
|
model,
|
|
116
135
|
resource: endpointResource,
|
|
117
|
-
queryKey:
|
|
136
|
+
queryKey: requestQueryRuntime.queryKey,
|
|
118
137
|
canSave,
|
|
119
138
|
fieldBag,
|
|
120
139
|
feedback,
|
|
121
|
-
|
|
140
|
+
input,
|
|
122
141
|
mapLoadedToModel,
|
|
123
142
|
buildRawPayload,
|
|
124
143
|
buildSavePayload,
|
|
@@ -11,8 +11,7 @@ import {
|
|
|
11
11
|
buildCrudFormPayload,
|
|
12
12
|
applyCrudPayloadToForm,
|
|
13
13
|
resolveCrudRouteBoundFieldValues,
|
|
14
|
-
resolveCrudFieldErrors
|
|
15
|
-
parseCrudResourceOperationInput
|
|
14
|
+
resolveCrudFieldErrors
|
|
16
15
|
} from "../crud/crudSchemaFormHelpers.js";
|
|
17
16
|
import { hasResolvedQueryData } from "../support/resourceLoadStateHelpers.js";
|
|
18
17
|
|
|
@@ -49,7 +48,7 @@ function useCrudAddEdit({
|
|
|
49
48
|
createModel = null,
|
|
50
49
|
buildPayload = null,
|
|
51
50
|
mapPayloadToModel = null,
|
|
52
|
-
|
|
51
|
+
input = null
|
|
53
52
|
} = {}) {
|
|
54
53
|
const router = useRouter();
|
|
55
54
|
const route = useRoute();
|
|
@@ -91,9 +90,7 @@ function useCrudAddEdit({
|
|
|
91
90
|
deep: true
|
|
92
91
|
}
|
|
93
92
|
);
|
|
94
|
-
const
|
|
95
|
-
? parseInput
|
|
96
|
-
: (typeof normalizedAddEditOptions.parseInput === "function" ? normalizedAddEditOptions.parseInput : null);
|
|
93
|
+
const inputOverride = input || normalizedAddEditOptions.input || null;
|
|
97
94
|
const buildPayloadOverride = typeof buildPayload === "function"
|
|
98
95
|
? buildPayload
|
|
99
96
|
: (typeof normalizedAddEditOptions.buildRawPayload === "function" ? normalizedAddEditOptions.buildRawPayload : null);
|
|
@@ -105,19 +102,7 @@ function useCrudAddEdit({
|
|
|
105
102
|
: null;
|
|
106
103
|
const shouldApplyDefaultMapPayload = normalizedAddEditOptions.readEnabled !== false;
|
|
107
104
|
const resolvedResource = normalizedAddEditOptions.resource || resource;
|
|
108
|
-
|
|
109
|
-
function resolveParseInput(rawPayload = {}, context = {}) {
|
|
110
|
-
if (parseInputOverride) {
|
|
111
|
-
return parseInputOverride(rawPayload, context);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return parseCrudResourceOperationInput({
|
|
115
|
-
resource: resolvedResource,
|
|
116
|
-
operationName,
|
|
117
|
-
rawPayload,
|
|
118
|
-
context
|
|
119
|
-
});
|
|
120
|
-
}
|
|
105
|
+
const resolvedInput = inputOverride || resolvedResource?.operations?.[operationName]?.body || null;
|
|
121
106
|
|
|
122
107
|
function resolveBuildRawPayload(model = {}, context = {}) {
|
|
123
108
|
const payload = buildPayloadOverride
|
|
@@ -187,7 +172,7 @@ function useCrudAddEdit({
|
|
|
187
172
|
resource: resolvedResource,
|
|
188
173
|
model: form,
|
|
189
174
|
fieldErrorKeys,
|
|
190
|
-
|
|
175
|
+
input: resolvedInput,
|
|
191
176
|
buildRawPayload: resolveBuildRawPayload,
|
|
192
177
|
mapLoadedToModel: effectiveMapLoadedToModel,
|
|
193
178
|
onSaveSuccess: handleSaveSuccess
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { computed, onScopeDispose, proxyRefs, ref, watch } from "vue";
|
|
2
2
|
import { useRouter } from "vue-router";
|
|
3
|
-
import { appendQueryString } from "@jskit-ai/kernel/shared/support";
|
|
4
3
|
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
5
4
|
import { ROUTE_VISIBILITY_WORKSPACE } from "@jskit-ai/kernel/shared/support/visibility";
|
|
6
5
|
import { useListCore } from "../runtime/useListCore.js";
|
|
@@ -8,6 +7,7 @@ import { resolveOperationAdapter } from "../runtime/operationAdapters.js";
|
|
|
8
7
|
import { setupOperationErrorReporting } from "../runtime/operationUiHelpers.js";
|
|
9
8
|
import { createListUiRuntime } from "../runtime/listUiRuntime.js";
|
|
10
9
|
import { asPlainObject } from "../support/scopeHelpers.js";
|
|
10
|
+
import { buildRequestQueryObject } from "../support/requestQueryRuntimeSupport.js";
|
|
11
11
|
import {
|
|
12
12
|
normalizeListSearchConfig,
|
|
13
13
|
matchesLocalSearch
|
|
@@ -43,6 +43,7 @@ function useList({
|
|
|
43
43
|
initialPageParam = null,
|
|
44
44
|
getNextPageParam,
|
|
45
45
|
selectItems,
|
|
46
|
+
transport = null,
|
|
46
47
|
requestOptions,
|
|
47
48
|
queryOptions,
|
|
48
49
|
realtime = null,
|
|
@@ -169,36 +170,34 @@ function useList({
|
|
|
169
170
|
});
|
|
170
171
|
const querySearchEnabled = computed(() => searchConfig.enabled === true && searchConfig.mode === "query");
|
|
171
172
|
const listPath = computed(() => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
return normalizeText(operationScope.apiPath.value);
|
|
174
|
+
});
|
|
175
|
+
const listRequestOptions = computed(() => {
|
|
176
|
+
const entries = [];
|
|
176
177
|
|
|
177
|
-
const searchParams = new URLSearchParams();
|
|
178
178
|
if (querySearchEnabled.value) {
|
|
179
179
|
const queryValue = activeSearchQuery.value;
|
|
180
180
|
if (queryValue) {
|
|
181
|
-
|
|
181
|
+
entries.push({
|
|
182
|
+
key: searchConfig.queryParam,
|
|
183
|
+
values: [queryValue]
|
|
184
|
+
});
|
|
182
185
|
}
|
|
183
186
|
}
|
|
184
187
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
searchParams.append(entry.key, value);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
for (const entry of activeQueryParamEntries.value) {
|
|
191
|
-
for (const value of entry.values) {
|
|
192
|
-
searchParams.append(entry.key, value);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
188
|
+
entries.push(...activeRequestQueryParamEntries.value);
|
|
189
|
+
entries.push(...activeQueryParamEntries.value);
|
|
195
190
|
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
191
|
+
const query = buildRequestQueryObject(entries);
|
|
192
|
+
const baseOptions = asPlainObject(requestOptions);
|
|
193
|
+
if (Object.keys(query).length < 1) {
|
|
194
|
+
return baseOptions;
|
|
199
195
|
}
|
|
200
196
|
|
|
201
|
-
return
|
|
197
|
+
return {
|
|
198
|
+
...baseOptions,
|
|
199
|
+
query
|
|
200
|
+
};
|
|
202
201
|
});
|
|
203
202
|
const listQueryKey = computed(() => {
|
|
204
203
|
const sourceQueryKey = operationScope.queryKey.value;
|
|
@@ -223,10 +222,11 @@ function useList({
|
|
|
223
222
|
queryKey: listQueryKey,
|
|
224
223
|
path: listPath,
|
|
225
224
|
enabled: operationScope.queryCanRun(canView),
|
|
225
|
+
transport,
|
|
226
226
|
initialPageParam,
|
|
227
227
|
getNextPageParam,
|
|
228
228
|
selectItems,
|
|
229
|
-
requestOptions,
|
|
229
|
+
requestOptions: listRequestOptions,
|
|
230
230
|
queryOptions,
|
|
231
231
|
fallbackLoadError
|
|
232
232
|
});
|
|
@@ -6,12 +6,7 @@ import { useEndpointResource } from "../runtime/useEndpointResource.js";
|
|
|
6
6
|
import { resolveOperationAdapter } from "../runtime/operationAdapters.js";
|
|
7
7
|
import { setupOperationErrorReporting } from "../runtime/operationUiHelpers.js";
|
|
8
8
|
import { createViewUiRuntime } from "../runtime/viewUiRuntime.js";
|
|
9
|
-
import {
|
|
10
|
-
resolveQueryParamDescriptors,
|
|
11
|
-
resolveActiveQueryParamEntries,
|
|
12
|
-
buildQueryParamEntriesToken
|
|
13
|
-
} from "../support/listQueryParamSupport.js";
|
|
14
|
-
import { appendRequestQueryEntriesToPath } from "../support/requestQueryPathSupport.js";
|
|
9
|
+
import { createRequestQueryRuntime } from "../support/requestQueryRuntimeSupport.js";
|
|
15
10
|
import { resolveRouteParamNamesInOrder } from "../support/routeTemplateHelpers.js";
|
|
16
11
|
|
|
17
12
|
function useView({
|
|
@@ -23,6 +18,7 @@ function useView({
|
|
|
23
18
|
viewPermissions = [],
|
|
24
19
|
readMethod = "GET",
|
|
25
20
|
readEnabled = true,
|
|
21
|
+
transport = null,
|
|
26
22
|
placementSource = "users-web.view",
|
|
27
23
|
fallbackLoadError = "Unable to load resource.",
|
|
28
24
|
notFoundStatuses = [404],
|
|
@@ -73,24 +69,13 @@ function useView({
|
|
|
73
69
|
return Object.freeze({
|
|
74
70
|
surfaceId: operationScope.routeContext.currentSurfaceId.value,
|
|
75
71
|
scopeParamValue: operationScope.scopeParamValue.value,
|
|
76
|
-
ownershipFilter: operationScope.normalizedOwnershipFilter
|
|
72
|
+
ownershipFilter: operationScope.normalizedOwnershipFilter,
|
|
73
|
+
recordId: viewUiRuntime.recordId.value
|
|
77
74
|
});
|
|
78
75
|
});
|
|
79
|
-
const
|
|
80
|
-
return resolveQueryParamDescriptors(requestQueryParams, queryParamsContext.value);
|
|
81
|
-
});
|
|
82
|
-
const activeRequestQueryParamEntries = computed(() => {
|
|
83
|
-
return resolveActiveQueryParamEntries(requestQueryParamDescriptors.value);
|
|
84
|
-
});
|
|
85
|
-
const activeRequestQueryParamsToken = computed(() => {
|
|
86
|
-
return buildQueryParamEntriesToken(activeRequestQueryParamEntries.value);
|
|
87
|
-
});
|
|
88
|
-
const queryKey = computed(() => {
|
|
76
|
+
const baseQueryKey = computed(() => {
|
|
89
77
|
const source = Array.isArray(operationScope.queryKey.value) ? operationScope.queryKey.value : [];
|
|
90
78
|
const next = [...source];
|
|
91
|
-
if (activeRequestQueryParamsToken.value) {
|
|
92
|
-
next.push("__request_query__", activeRequestQueryParamsToken.value);
|
|
93
|
-
}
|
|
94
79
|
if (!includeRecordIdInQueryKey) {
|
|
95
80
|
return next;
|
|
96
81
|
}
|
|
@@ -98,19 +83,20 @@ function useView({
|
|
|
98
83
|
const recordIdToken = String(viewUiRuntime.recordId.value || "").trim();
|
|
99
84
|
return [...next, recordIdToken];
|
|
100
85
|
});
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
);
|
|
86
|
+
const requestQueryRuntime = createRequestQueryRuntime({
|
|
87
|
+
requestQueryParams,
|
|
88
|
+
context: queryParamsContext,
|
|
89
|
+
sourceQueryKey: baseQueryKey
|
|
106
90
|
});
|
|
107
91
|
const canView = operationScope.permissionGate("view");
|
|
108
92
|
|
|
109
93
|
const resource = useEndpointResource({
|
|
110
|
-
queryKey,
|
|
111
|
-
path:
|
|
94
|
+
queryKey: requestQueryRuntime.queryKey,
|
|
95
|
+
path: operationScope.apiPath,
|
|
112
96
|
enabled: operationScope.queryCanRun(canView),
|
|
113
97
|
readMethod,
|
|
98
|
+
readQuery: requestQueryRuntime.requestQuery,
|
|
99
|
+
transport,
|
|
114
100
|
fallbackLoadError
|
|
115
101
|
});
|
|
116
102
|
|
|
@@ -2,51 +2,50 @@ import {
|
|
|
2
2
|
createValidationFailure,
|
|
3
3
|
resolveFieldErrors
|
|
4
4
|
} from "@jskit-ai/http-runtime/client";
|
|
5
|
+
import { validateSchemaPayload } from "@jskit-ai/kernel/shared/validators";
|
|
5
6
|
|
|
6
7
|
function validateOperationInput({
|
|
7
|
-
|
|
8
|
+
input,
|
|
8
9
|
rawPayload = {},
|
|
9
|
-
context = {},
|
|
10
10
|
fieldBag = null,
|
|
11
11
|
feedback = null,
|
|
12
12
|
validationMessage = "Validation failed."
|
|
13
13
|
} = {}) {
|
|
14
|
-
if (
|
|
14
|
+
if (!input) {
|
|
15
15
|
return {
|
|
16
16
|
ok: true,
|
|
17
|
-
parseResult: null,
|
|
18
17
|
parsedInput: rawPayload
|
|
19
18
|
};
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
);
|
|
27
|
-
|
|
21
|
+
try {
|
|
22
|
+
const parsedInput = validateSchemaPayload(input, rawPayload, {
|
|
23
|
+
phase: "input",
|
|
24
|
+
context: "operation input"
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
ok: true,
|
|
29
|
+
parsedInput
|
|
30
|
+
};
|
|
31
|
+
} catch (error) {
|
|
32
|
+
if (!error?.fieldErrors || typeof error.fieldErrors !== "object") {
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
28
35
|
|
|
29
|
-
if (!parseResult.ok) {
|
|
30
36
|
const failure = createValidationFailure({
|
|
31
37
|
error: String(validationMessage || "Validation failed."),
|
|
32
38
|
code: "validation_failed",
|
|
33
|
-
fieldErrors:
|
|
39
|
+
fieldErrors: error?.fieldErrors
|
|
34
40
|
});
|
|
35
41
|
fieldBag?.apply?.(resolveFieldErrors(failure));
|
|
36
42
|
feedback?.error?.(failure, failure.error);
|
|
37
43
|
return {
|
|
38
44
|
ok: false,
|
|
39
45
|
failure,
|
|
40
|
-
parseResult,
|
|
41
46
|
parsedInput: null
|
|
42
47
|
};
|
|
43
48
|
}
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
ok: true,
|
|
47
|
-
parseResult,
|
|
48
|
-
parsedInput: parseResult.value
|
|
49
|
-
};
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
export { validateOperationInput };
|
|
@@ -10,7 +10,7 @@ function useAddEditCore({
|
|
|
10
10
|
canSave,
|
|
11
11
|
fieldBag,
|
|
12
12
|
feedback,
|
|
13
|
-
|
|
13
|
+
input,
|
|
14
14
|
mapLoadedToModel,
|
|
15
15
|
buildRawPayload,
|
|
16
16
|
buildSavePayload,
|
|
@@ -49,12 +49,8 @@ function useAddEditCore({
|
|
|
49
49
|
}) : {};
|
|
50
50
|
|
|
51
51
|
const validationResult = validateOperationInput({
|
|
52
|
-
|
|
52
|
+
input,
|
|
53
53
|
rawPayload,
|
|
54
|
-
context: {
|
|
55
|
-
queryClient,
|
|
56
|
-
resource
|
|
57
|
-
},
|
|
58
54
|
fieldBag,
|
|
59
55
|
feedback,
|
|
60
56
|
validationMessage: String(messages.validation || "Validation failed.")
|
|
@@ -63,7 +59,7 @@ function useAddEditCore({
|
|
|
63
59
|
return;
|
|
64
60
|
}
|
|
65
61
|
|
|
66
|
-
const {
|
|
62
|
+
const { parsedInput } = validationResult;
|
|
67
63
|
const savePayload = typeof buildSavePayload === "function"
|
|
68
64
|
? buildSavePayload(parsedInput, {
|
|
69
65
|
rawPayload,
|
|
@@ -73,6 +69,7 @@ function useAddEditCore({
|
|
|
73
69
|
: parsedInput;
|
|
74
70
|
|
|
75
71
|
try {
|
|
72
|
+
const queryKeySnapshot = queryKey?.value;
|
|
76
73
|
const payload = await resource.save(savePayload);
|
|
77
74
|
|
|
78
75
|
if (typeof mapLoadedToModel === "function") {
|
|
@@ -82,15 +79,14 @@ function useAddEditCore({
|
|
|
82
79
|
});
|
|
83
80
|
}
|
|
84
81
|
|
|
85
|
-
if (
|
|
86
|
-
queryClient.setQueryData(
|
|
82
|
+
if (queryKeySnapshot !== undefined) {
|
|
83
|
+
queryClient.setQueryData(queryKeySnapshot, payload);
|
|
87
84
|
}
|
|
88
85
|
|
|
89
86
|
if (typeof onSaveSuccess === "function") {
|
|
90
87
|
await onSaveSuccess(payload, {
|
|
91
88
|
queryClient,
|
|
92
89
|
parsed: parsedInput,
|
|
93
|
-
parseResult,
|
|
94
90
|
rawPayload,
|
|
95
91
|
savePayload,
|
|
96
92
|
resource
|