@stapel/listings-react 0.25.10 → 0.27.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/CHANGELOG.md +259 -0
- package/MODULE.md +3 -1
- package/README.md +122 -9
- package/dist/api/generated/schema.d.ts +22 -12
- package/dist/api/generated/schema.d.ts.map +1 -1
- package/dist/default/CardBadges.d.ts.map +1 -1
- package/dist/default/CardBadges.js +3 -1
- package/dist/default/CardBadges.js.map +1 -1
- package/dist/default/ListingActions.d.ts +108 -0
- package/dist/default/ListingActions.d.ts.map +1 -0
- package/dist/default/ListingActions.js +29 -0
- package/dist/default/ListingActions.js.map +1 -0
- package/dist/default/ListingCard.d.ts.map +1 -1
- package/dist/default/ListingCard.js +15 -8
- package/dist/default/ListingCard.js.map +1 -1
- package/dist/default/ListingDetailPane.d.ts +170 -62
- package/dist/default/ListingDetailPane.d.ts.map +1 -1
- package/dist/default/ListingDetailPane.js +284 -28
- package/dist/default/ListingDetailPane.js.map +1 -1
- package/dist/default/ListingFeedCard.d.ts.map +1 -1
- package/dist/default/ListingFeedCard.js +2 -1
- package/dist/default/ListingFeedCard.js.map +1 -1
- package/dist/default/ListingPhoto.d.ts.map +1 -1
- package/dist/default/ListingPhoto.js +5 -2
- package/dist/default/ListingPhoto.js.map +1 -1
- package/dist/default/ListingSerpCard.d.ts.map +1 -1
- package/dist/default/ListingSerpCard.js +18 -4
- package/dist/default/ListingSerpCard.js.map +1 -1
- package/dist/default/MyListingsPane.d.ts.map +1 -1
- package/dist/default/MyListingsPane.js +49 -21
- package/dist/default/MyListingsPane.js.map +1 -1
- package/dist/default/ShareAction.d.ts +32 -0
- package/dist/default/ShareAction.d.ts.map +1 -0
- package/dist/default/ShareAction.js +116 -0
- package/dist/default/ShareAction.js.map +1 -0
- package/dist/default/actionRow.d.ts +58 -0
- package/dist/default/actionRow.d.ts.map +1 -0
- package/dist/default/actionRow.js +128 -0
- package/dist/default/actionRow.js.map +1 -0
- package/dist/default/cardGallery.d.ts +2 -0
- package/dist/default/cardGallery.d.ts.map +1 -1
- package/dist/default/cardGallery.js +31 -0
- package/dist/default/cardGallery.js.map +1 -1
- package/dist/default/detailGallery.d.ts +77 -0
- package/dist/default/detailGallery.d.ts.map +1 -0
- package/dist/default/detailGallery.js +91 -0
- package/dist/default/detailGallery.js.map +1 -0
- package/dist/default/favorite.d.ts +25 -0
- package/dist/default/favorite.d.ts.map +1 -1
- package/dist/default/favorite.js +29 -3
- package/dist/default/favorite.js.map +1 -1
- package/dist/default/icons.d.ts +19 -0
- package/dist/default/icons.d.ts.map +1 -1
- package/dist/default/icons.js +23 -0
- package/dist/default/icons.js.map +1 -1
- package/dist/default/index.d.ts +11 -2
- package/dist/default/index.d.ts.map +1 -1
- package/dist/default/index.js +10 -1
- package/dist/default/index.js.map +1 -1
- package/dist/default/movableCluster.d.ts +18 -0
- package/dist/default/movableCluster.d.ts.map +1 -0
- package/dist/default/movableCluster.js +110 -0
- package/dist/default/movableCluster.js.map +1 -0
- package/dist/default/notice.d.ts +14 -0
- package/dist/default/notice.d.ts.map +1 -0
- package/dist/default/notice.js +62 -0
- package/dist/default/notice.js.map +1 -0
- package/dist/headless/MyListings.d.ts +61 -19
- package/dist/headless/MyListings.d.ts.map +1 -1
- package/dist/headless/MyListings.js +58 -19
- package/dist/headless/MyListings.js.map +1 -1
- package/dist/headless/Share.d.ts +103 -0
- package/dist/headless/Share.d.ts.map +1 -0
- package/dist/headless/Share.js +190 -0
- package/dist/headless/Share.js.map +1 -0
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +21 -0
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/generated/errors.es.gen.d.ts +1 -1
- package/dist/i18n/generated/errors.es.gen.js +1 -1
- package/dist/i18n/generated/errors.gen.d.ts +18 -0
- package/dist/i18n/generated/errors.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.gen.js +9 -0
- package/dist/i18n/generated/errors.gen.js.map +1 -1
- package/dist/i18n/generated/errors.ru.gen.d.ts +1 -1
- package/dist/i18n/generated/errors.ru.gen.js +1 -1
- package/dist/i18n/keys.d.ts +45 -0
- package/dist/i18n/keys.d.ts.map +1 -1
- package/dist/i18n/keys.js +60 -0
- package/dist/i18n/keys.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +21 -0
- package/dist/i18n/ru.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/model/cardBadges.d.ts +52 -3
- package/dist/model/cardBadges.d.ts.map +1 -1
- package/dist/model/cardBadges.js +74 -12
- package/dist/model/cardBadges.js.map +1 -1
- package/dist/model/mineSource.d.ts +9 -3
- package/dist/model/mineSource.d.ts.map +1 -1
- package/dist/model/mineSource.js.map +1 -1
- package/dist/model/status.d.ts +79 -15
- package/dist/model/status.d.ts.map +1 -1
- package/dist/model/status.js +86 -17
- package/dist/model/status.js.map +1 -1
- package/llms.txt +8 -3
- package/manifest.json +96 -4
- package/nav-manifest.json +1 -1
- package/package.json +10 -10
- package/src/analytics/generated/events.json +1 -1
- package/src/api/generated/schema.ts +22 -12
- package/src/default/CardBadges.tsx +3 -1
- package/src/default/ListingActions.tsx +196 -0
- package/src/default/ListingCard.tsx +79 -43
- package/src/default/ListingDetailPane.tsx +520 -89
- package/src/default/ListingFeedCard.tsx +2 -0
- package/src/default/ListingPhoto.tsx +28 -0
- package/src/default/ListingSerpCard.tsx +39 -12
- package/src/default/MyListingsPane.tsx +81 -44
- package/src/default/ShareAction.tsx +260 -0
- package/src/default/actionRow.ts +131 -0
- package/src/default/cardGallery.ts +31 -0
- package/src/default/detailGallery.ts +97 -0
- package/src/default/favorite.tsx +68 -1
- package/src/default/icons.tsx +60 -0
- package/src/default/index.ts +37 -1
- package/src/default/movableCluster.tsx +137 -0
- package/src/default/notice.ts +68 -0
- package/src/headless/MyListings.tsx +130 -39
- package/src/headless/Share.tsx +278 -0
- package/src/i18n/es.ts +28 -0
- package/src/i18n/generated/errors.es.gen.ts +1 -1
- package/src/i18n/generated/errors.gen.ts +9 -0
- package/src/i18n/generated/errors.json +31 -0
- package/src/i18n/generated/errors.ru.gen.ts +1 -1
- package/src/i18n/keys.ts +63 -0
- package/src/i18n/ru.ts +28 -0
- package/src/index.ts +22 -0
- package/src/model/cardBadges.ts +124 -12
- package/src/model/mineSource.ts +9 -3
- package/src/model/status.ts +102 -20
package/src/model/status.ts
CHANGED
|
@@ -285,7 +285,8 @@ export function listingStatusView(
|
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
/**
|
|
288
|
-
* The
|
|
288
|
+
* The three tabs whose ROWS come off a keyset page, and the statuses each one
|
|
289
|
+
* folds together.
|
|
289
290
|
*
|
|
290
291
|
* The grouping is the SERVER's (`views.my_counters`), copied here so a tab's
|
|
291
292
|
* caption and its count cannot describe different sets: `active` includes
|
|
@@ -293,41 +294,122 @@ export function listingStatusView(
|
|
|
293
294
|
* both because a listing in those states is something the owner is still
|
|
294
295
|
* working on. A client that grouped them its own way would show "3 active"
|
|
295
296
|
* over two rows.
|
|
297
|
+
*
|
|
298
|
+
* The name is about the SOURCE, not about the counter: `MyCountersResponse`
|
|
299
|
+
* carries four integers since stapel-listings 0.22.4 (`blocked` joined the
|
|
300
|
+
* three), and this is still the set a {@link MyListingsCountedTab} —
|
|
301
|
+
* `MyListingsSource`'s whole parameter type — may name. The removed tab reads
|
|
302
|
+
* its rows off `?status=blocked` directly and unpaged, so a host that
|
|
303
|
+
* implemented the seam before the fourth tab existed is never handed it.
|
|
296
304
|
*/
|
|
297
|
-
export const
|
|
305
|
+
export const MY_LISTINGS_COUNTED_TABS = ["active", "drafts", "archived"] as const;
|
|
298
306
|
|
|
299
|
-
|
|
307
|
+
/** One of the three tabs a `MyListingsSource` is asked for. */
|
|
308
|
+
export type MyListingsCountedTab = (typeof MY_LISTINGS_COUNTED_TABS)[number];
|
|
300
309
|
|
|
301
|
-
|
|
302
|
-
Record<
|
|
310
|
+
const COUNTED_TAB_STATUSES: Readonly<
|
|
311
|
+
Record<MyListingsCountedTab, readonly ListingLifecycleStatus[]>
|
|
303
312
|
> = {
|
|
304
313
|
active: ["published", "pending"],
|
|
305
314
|
drafts: ["draft", "rejected"],
|
|
306
315
|
archived: ["archived", "paused", "expired", "sold"],
|
|
307
316
|
};
|
|
308
317
|
|
|
309
|
-
/** Which
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
export function
|
|
318
|
+
/** Which of the three keyset-paged tabs a status belongs to, or `undefined`
|
|
319
|
+
* for one none of them folds in — `blocked`, today, which has a tab and a
|
|
320
|
+
* counter of its own and a different row source under it. */
|
|
321
|
+
export function countedTabOf(
|
|
313
322
|
status: ListingLifecycleStatus
|
|
314
|
-
):
|
|
315
|
-
for (const tab of
|
|
316
|
-
if (
|
|
323
|
+
): MyListingsCountedTab | undefined {
|
|
324
|
+
for (const tab of MY_LISTINGS_COUNTED_TABS) {
|
|
325
|
+
if (COUNTED_TAB_STATUSES[tab].includes(status)) return tab;
|
|
317
326
|
}
|
|
318
327
|
return undefined;
|
|
319
328
|
}
|
|
320
329
|
|
|
321
330
|
/**
|
|
322
|
-
* The statuses
|
|
331
|
+
* The statuses none of the three paged tabs folds in — `blocked`, and nothing
|
|
332
|
+
* else today.
|
|
323
333
|
*
|
|
324
334
|
* DERIVED, not written down a second time: a status added upstream and left
|
|
325
|
-
* out of the
|
|
326
|
-
*
|
|
327
|
-
* stale.
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
335
|
+
* out of the tab groupings lands here automatically and gets shown, which is
|
|
336
|
+
* the opposite of what a hardcoded `["blocked"]` would do the day it goes
|
|
337
|
+
* stale. That the server now has a `blocked` COUNTER for the same set does not
|
|
338
|
+
* make the derivation redundant: the counter names one status and this names
|
|
339
|
+
* whatever the three groupings leave over, which is the set the fourth tab
|
|
340
|
+
* must ASK for.
|
|
331
341
|
*/
|
|
332
342
|
export const MY_LISTINGS_UNTABBED_STATUSES: readonly ListingLifecycleStatus[] =
|
|
333
|
-
LISTING_STATUSES.filter((status) =>
|
|
343
|
+
LISTING_STATUSES.filter((status) => countedTabOf(status) === undefined);
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* The fourth tab: the rows `my/counters` counts in NO tab at all.
|
|
347
|
+
*
|
|
348
|
+
* ── What was on screen (D407) ────────────────────────────────────────────
|
|
349
|
+
*
|
|
350
|
+
* A listing pulled by moderation showed "Taken down by a moderator" over a
|
|
351
|
+
* counter row reading "Active 0 · Drafts 0 · Archived 0", beside the active
|
|
352
|
+
* tab's own "nothing of yours is live". The object was on the page and in no
|
|
353
|
+
* tab and in no number — three statements, and the two loudest of them said
|
|
354
|
+
* the seller had nothing.
|
|
355
|
+
*
|
|
356
|
+
* The takedowns had a home before this (a block above the tabs) and that was
|
|
357
|
+
* the half that was wrong: a row outside the tab strip is a row the counters
|
|
358
|
+
* do not describe, and a person reads the counters. So they get a TAB, with a
|
|
359
|
+
* count, like every other state a listing can be in.
|
|
360
|
+
*
|
|
361
|
+
* ── Why a fourth tab and not the archive ─────────────────────────────────
|
|
362
|
+
*
|
|
363
|
+
* Folding `blocked` into `archived` is the other shape this could take, and
|
|
364
|
+
* it cost the count: when D407 was written `my/counters` had three integers
|
|
365
|
+
* and no fourth, so an archive tab holding takedowns would have read the
|
|
366
|
+
* server's `archived` number — `0` — until the tab was opened and its rows
|
|
367
|
+
* could raise it. The fourth tab was counted from its OWN read
|
|
368
|
+
* (`?status=blocked`, unpaged) so that the number was right while the seller
|
|
369
|
+
* was looking at a different tab, which is exactly the moment D407 was
|
|
370
|
+
* measured at. stapel-listings 0.22.4 puts `blocked` in the counter, so the
|
|
371
|
+
* number is the server's now and that read is only the tab's rows — but the
|
|
372
|
+
* property it was there to defend is the same one, and it is now defended by
|
|
373
|
+
* the wire instead of by a page.
|
|
374
|
+
*
|
|
375
|
+
* The archive keeps its meaning too, which is not nothing: "I put this away"
|
|
376
|
+
* and "a moderator took this down" are not the same sentence and a tab that
|
|
377
|
+
* said one over rows that meant the other would be the D407 defect wearing a
|
|
378
|
+
* label.
|
|
379
|
+
*/
|
|
380
|
+
export const MY_LISTINGS_REMOVED_TAB = "removed";
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Every tab the dashboard can show: the server's three, then the removed one.
|
|
384
|
+
*
|
|
385
|
+
* The removed tab is DRAWN only where there is something in it (see
|
|
386
|
+
* `headless/MyListings.tsx`) — an empty "Taken down" tab is a scare — but it
|
|
387
|
+
* is in this list unconditionally, because `?tab=removed` must parse and a
|
|
388
|
+
* host must be able to name it.
|
|
389
|
+
*/
|
|
390
|
+
export const MY_LISTINGS_TABS: readonly [
|
|
391
|
+
...typeof MY_LISTINGS_COUNTED_TABS,
|
|
392
|
+
typeof MY_LISTINGS_REMOVED_TAB,
|
|
393
|
+
] = [...MY_LISTINGS_COUNTED_TABS, MY_LISTINGS_REMOVED_TAB];
|
|
394
|
+
|
|
395
|
+
export type MyListingsTab = (typeof MY_LISTINGS_TABS)[number];
|
|
396
|
+
|
|
397
|
+
export const MY_LISTINGS_TAB_STATUSES: Readonly<
|
|
398
|
+
Record<MyListingsTab, readonly ListingLifecycleStatus[]>
|
|
399
|
+
> = {
|
|
400
|
+
...COUNTED_TAB_STATUSES,
|
|
401
|
+
[MY_LISTINGS_REMOVED_TAB]: MY_LISTINGS_UNTABBED_STATUSES,
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
/** Which tab a listing belongs to. Every status has one: the three counted
|
|
405
|
+
* groupings, and the removed tab for whatever they leave out. `undefined` is
|
|
406
|
+
* unreachable today and stays in the signature so a status this build has
|
|
407
|
+
* never heard of cannot be filed under a tab by accident. */
|
|
408
|
+
export function tabOf(
|
|
409
|
+
status: ListingLifecycleStatus
|
|
410
|
+
): MyListingsTab | undefined {
|
|
411
|
+
for (const tab of MY_LISTINGS_TABS) {
|
|
412
|
+
if (MY_LISTINGS_TAB_STATUSES[tab].includes(status)) return tab;
|
|
413
|
+
}
|
|
414
|
+
return undefined;
|
|
415
|
+
}
|