@7365admin1/layer-common 3.2.2-staging.198 → 3.2.2-staging.199
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.
|
@@ -169,6 +169,7 @@ const {
|
|
|
169
169
|
data: getAttendanceSettingsReq,
|
|
170
170
|
refresh: getAttendanceSettingsRefresh,
|
|
171
171
|
pending: loading,
|
|
172
|
+
error: getAttendanceSettingsError,
|
|
172
173
|
} = await useLazyAsyncData(
|
|
173
174
|
`attendance-settings-${props.site}`,
|
|
174
175
|
() => getAttendanceSettings(props.site, props.serviceType),
|
|
@@ -179,6 +180,22 @@ const {
|
|
|
179
180
|
);
|
|
180
181
|
|
|
181
182
|
watchEffect(() => {
|
|
183
|
+
// A failed read used to be indistinguishable from a site with no settings
|
|
184
|
+
// saved: the dialog just opened with geofencing off and blank fields, and
|
|
185
|
+
// the operator had no way to tell it was showing them nothing rather than
|
|
186
|
+
// the truth. Worse, a request answered by the SPA fallback resolves with a
|
|
187
|
+
// 200 and a STRING, so nothing threw - every field read off it was simply
|
|
188
|
+
// undefined. Anything that is not an object is a failure, and it is said.
|
|
189
|
+
const res: any = getAttendanceSettingsReq.value;
|
|
190
|
+
if (
|
|
191
|
+
getAttendanceSettingsError.value ||
|
|
192
|
+
(res !== null && res !== undefined && typeof res !== "object")
|
|
193
|
+
) {
|
|
194
|
+
error.value =
|
|
195
|
+
"Could not load the saved settings - what you see below is not what is saved. Close and reopen to try again.";
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
182
199
|
if (getAttendanceSettingsReq.value) {
|
|
183
200
|
isGeofencingEnabled.value =
|
|
184
201
|
getAttendanceSettingsReq.value.isGeofencingEnabled || false;
|
|
@@ -208,6 +208,16 @@
|
|
|
208
208
|
</v-list>
|
|
209
209
|
</v-menu>
|
|
210
210
|
</template>
|
|
211
|
+
<!--
|
|
212
|
+
"There are none" and "we could not fetch them" are not the same
|
|
213
|
+
sentence, and this table drew the first for both: a failed request
|
|
214
|
+
left `items` at [] and the default no-data row read "No data
|
|
215
|
+
available". That is what hid the Pending tab being unreachable in
|
|
216
|
+
six apps for months. `loadFailed` splits them.
|
|
217
|
+
-->
|
|
218
|
+
<template #no-data>
|
|
219
|
+
<DashboardEmptyState :error="loadFailed" />
|
|
220
|
+
</template>
|
|
211
221
|
</v-data-table>
|
|
212
222
|
</div>
|
|
213
223
|
|
|
@@ -812,6 +822,8 @@ const messageColor = ref("");
|
|
|
812
822
|
|
|
813
823
|
const items = ref<TableRow[]>([]);
|
|
814
824
|
const loading = ref(false);
|
|
825
|
+
/** The last load failed, as opposed to genuinely returning nothing. */
|
|
826
|
+
const loadFailed = ref(false);
|
|
815
827
|
|
|
816
828
|
const validServiceProvider = ref(false);
|
|
817
829
|
const disableServiceProvider = ref(false);
|
|
@@ -1244,6 +1256,18 @@ async function loadList() {
|
|
|
1244
1256
|
// }
|
|
1245
1257
|
|
|
1246
1258
|
loading.value = true;
|
|
1259
|
+
loadFailed.value = false;
|
|
1260
|
+
// A request that never reaches the API can still resolve: a path with no
|
|
1261
|
+
// proxy rule is answered by the SPA fallback with 200 text/html, and ofetch
|
|
1262
|
+
// hands that back as a STRING. `.items` on a string is undefined, so
|
|
1263
|
+
// `?? []` used to turn that into a clean empty table. Anything that is not
|
|
1264
|
+
// an array is a failure, not a zero - say so.
|
|
1265
|
+
const rowsOf = (data: any) => {
|
|
1266
|
+
if (!Array.isArray(data?.items)) {
|
|
1267
|
+
throw new Error("The server did not return a list. Please try again.");
|
|
1268
|
+
}
|
|
1269
|
+
return data.items;
|
|
1270
|
+
};
|
|
1247
1271
|
try {
|
|
1248
1272
|
if (listTab.value === "pending") {
|
|
1249
1273
|
// Everything that is not a finished engagement, so a rejection or a
|
|
@@ -1256,7 +1280,7 @@ async function loadList() {
|
|
|
1256
1280
|
search: searchText.value?.trim() || "",
|
|
1257
1281
|
limit: pageSize,
|
|
1258
1282
|
});
|
|
1259
|
-
items.value = mapInviteRows(data
|
|
1283
|
+
items.value = mapInviteRows(rowsOf(data));
|
|
1260
1284
|
pages.value = data.pages ?? 0;
|
|
1261
1285
|
pageRange.value = data.pageRange ?? "-- - -- of --";
|
|
1262
1286
|
return;
|
|
@@ -1270,10 +1294,11 @@ async function loadList() {
|
|
|
1270
1294
|
limit: pageSize,
|
|
1271
1295
|
status: statusParam,
|
|
1272
1296
|
});
|
|
1273
|
-
items.value = mapProviderRows(data
|
|
1297
|
+
items.value = mapProviderRows(rowsOf(data));
|
|
1274
1298
|
pages.value = data.pages ?? 0;
|
|
1275
1299
|
pageRange.value = data.pageRange ?? "-- - -- of --";
|
|
1276
1300
|
} catch (error: any) {
|
|
1301
|
+
loadFailed.value = true;
|
|
1277
1302
|
showMessage(errorConverter(error), "error");
|
|
1278
1303
|
items.value = [];
|
|
1279
1304
|
pages.value = 0;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@7365admin1/layer-common",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "3.2.2-staging.
|
|
5
|
+
"version": "3.2.2-staging.199",
|
|
6
6
|
"author": "7365admin1",
|
|
7
7
|
"main": "./nuxt.config.ts",
|
|
8
8
|
"//files": "What a consumer extending this layer actually loads. Without this npm ships the whole working tree - the changesets, the CI workflows, the render harness in tools/ and any scratch directory that happened to exist at publish time. Nuxt resolves a layer by directory, so every runtime directory below has to stay listed; adding a new top-level runtime directory means adding it here too.",
|