@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.items ?? []);
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.items ?? []);
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.198",
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.",