@mohasinac/appkit 4.30.5 → 4.30.7
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/dist/features/admin/components/AdminAddressesView.js +1 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.js +1 -1
- package/dist/features/admin/components/AdminBidsView.js +1 -1
- package/dist/features/admin/components/AdminBlogView.js +1 -1
- package/dist/features/admin/components/AdminBrandsView.js +1 -1
- package/dist/features/admin/components/AdminCarouselView.js +3 -1
- package/dist/features/admin/components/AdminCartsView.js +1 -1
- package/dist/features/admin/components/AdminCategoriesView.js +1 -1
- package/dist/features/admin/components/AdminContactView.js +1 -1
- package/dist/features/admin/components/AdminCouponsView.js +1 -1
- package/dist/features/admin/components/AdminFeaturesView.js +1 -1
- package/dist/features/admin/components/AdminGroupedListingsView.js +1 -1
- package/dist/features/admin/components/AdminHistoryView.js +1 -1
- package/dist/features/admin/components/AdminNewsletterView.js +1 -1
- package/dist/features/admin/components/AdminOffersView.js +1 -1
- package/dist/features/admin/components/AdminOrdersView.js +1 -1
- package/dist/features/admin/components/AdminPaymentMethodsView.js +1 -1
- package/dist/features/admin/components/AdminReturnRequestsView.js +1 -1
- package/dist/features/admin/components/AdminSessionsView.js +1 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +1 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +1 -1
- package/dist/features/admin/components/AdminUsersView.js +11 -1
- package/dist/features/admin/components/AdminWishlistsView.js +1 -1
- package/dist/features/admin/components/DataListingView.d.ts +30 -1
- package/dist/features/admin/components/DataListingView.js +7 -1
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +1 -1
- package/dist/features/events/components/AdminEventsView.js +1 -1
- package/dist/features/seller/components/SellerCouponsView.js +1 -1
- package/dist/features/seller/components/SellerGroupedListingsView.js +1 -1
- package/dist/features/seller/components/SellerOffersView.js +1 -1
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutsView.js +1 -1
- package/dist/features/seller/components/SellerStoreCategoriesView.js +1 -1
- package/dist/features/shipments/components/AdminShipmentsView.js +1 -1
- package/dist/features/tester/components/AdminTesterFeedbackListView.js +1 -1
- package/package.json +1 -1
|
@@ -51,7 +51,7 @@ function buildAddressConfig(onAction) {
|
|
|
51
51
|
return {
|
|
52
52
|
portal: "admin",
|
|
53
53
|
title: "Address Management",
|
|
54
|
-
|
|
54
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
55
55
|
emptyLabel: "No addresses found",
|
|
56
56
|
// URL-synced via filterKeys (2026-08-21). The ban-status chips used to
|
|
57
57
|
// live outside this config in local useState, so the selection was not in
|
|
@@ -32,7 +32,7 @@ export function AdminAllEventEntriesView({ children, ...props }) {
|
|
|
32
32
|
const config = {
|
|
33
33
|
portal: "admin",
|
|
34
34
|
title: "Event Entries",
|
|
35
|
-
|
|
35
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
36
36
|
emptyLabel: "No entries found",
|
|
37
37
|
filterKeys: ["status"],
|
|
38
38
|
defaultSort: sortBy("submittedAt", "DESC"),
|
|
@@ -41,7 +41,7 @@ export function AdminBidsView({ children, ...props }) {
|
|
|
41
41
|
const config = {
|
|
42
42
|
portal: "admin",
|
|
43
43
|
title: "Bids",
|
|
44
|
-
|
|
44
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
45
45
|
emptyLabel: "No bids found",
|
|
46
46
|
filterKeys: ["status"],
|
|
47
47
|
defaultSort: sortBy("bidDate", "DESC"),
|
|
@@ -21,7 +21,7 @@ export function AdminBlogView({ children, ...props }) {
|
|
|
21
21
|
const config = {
|
|
22
22
|
portal: "admin",
|
|
23
23
|
title: "Blog Posts",
|
|
24
|
-
|
|
24
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
25
25
|
emptyLabel: "No blog posts found",
|
|
26
26
|
filterKeys: ["status", "isFeatured"],
|
|
27
27
|
defaultSort: sortBy("publishedAt", "DESC"),
|
|
@@ -33,7 +33,7 @@ const COLUMNS = [
|
|
|
33
33
|
const ADMIN_BRANDS_CONFIG = {
|
|
34
34
|
portal: "admin",
|
|
35
35
|
title: "Brands",
|
|
36
|
-
|
|
36
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
37
37
|
emptyLabel: "No brands found",
|
|
38
38
|
filterKeys: ["isActive"],
|
|
39
39
|
defaultSort: sortBy("order", "ASC"),
|
|
@@ -145,5 +145,7 @@ export function AdminCarouselView({ children, onBulkDelete, ...props }) {
|
|
|
145
145
|
] })),
|
|
146
146
|
},
|
|
147
147
|
];
|
|
148
|
-
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput,
|
|
148
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput,
|
|
149
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
150
|
+
onSearchChange: setSearchInput, onSearchCommit: commitSearch, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), selection.selectedCount > 0 && bulkActions.length > 0 && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, actions: bulkActions, onClearSelection: selection.clearSelection })), _jsxs(Div, { paddingX: "x-sm-md", padding: "y-md", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), _jsx(DataTable, { rows: displayRows, columns: columns, isLoading: isLoading, emptyLabel: "No carousel slides \u2014 use 'New slide' to add one", rowHrefTemplate: "/admin/carousel/{id}/edit" })] }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { className: "tracking-widest", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Status" }), _jsx(Row, { wrap: true, gap: "sm", children: [{ label: "All", value: "" }, { label: "Active", value: "true" }, { label: "Inactive", value: "false" }].map((opt) => (_jsx(Button, { variant: "ghost", type: "button", onClick: () => setPendingFilters((p) => ({ ...p, active: opt.value })), className: `rounded-full px-[var(--appkit-space-3)] py-[var(--appkit-space-1)] text-[length:var(--appkit-text-xs)] font-medium border transition-colors min-h-0 h-auto ${(pendingFilters.active || "") === opt.value ? "bg-primary text-white border-primary" : "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:bg-surface-hover"}`, children: opt.label }, opt.label))) })] }) }), deleteTargetId && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Carousel Slide", message: "Delete this carousel slide? This cannot be undone.", onConfirm: () => { deleteMutation.mutate(deleteTargetId); setDeleteTargetId(null); }, onClose: () => setDeleteTargetId(null), isDeleting: deleteMutation.isPending }))] }));
|
|
149
151
|
}
|
|
@@ -32,7 +32,7 @@ function toCartItemEntries(raw) {
|
|
|
32
32
|
const ADMIN_CARTS_CONFIG = {
|
|
33
33
|
portal: "admin",
|
|
34
34
|
title: "Carts",
|
|
35
|
-
|
|
35
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
36
36
|
emptyLabel: "No carts found",
|
|
37
37
|
filterKeys: ["ownership"],
|
|
38
38
|
defaultSort: sortBy("updatedAt", "DESC"),
|
|
@@ -32,7 +32,7 @@ const COLUMNS = [
|
|
|
32
32
|
const ADMIN_CATEGORIES_CONFIG = {
|
|
33
33
|
portal: "admin",
|
|
34
34
|
title: "Categories",
|
|
35
|
-
|
|
35
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
36
36
|
emptyLabel: "No categories found",
|
|
37
37
|
filterKeys: ["isActive", "isFeatured"],
|
|
38
38
|
defaultSort: sortBy("name", "ASC"),
|
|
@@ -49,7 +49,7 @@ export function AdminContactView({ children, onBulkMarkRead, onBulkArchive, onBu
|
|
|
49
49
|
const config = {
|
|
50
50
|
portal: "admin",
|
|
51
51
|
title: "Contact Submissions",
|
|
52
|
-
|
|
52
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
53
53
|
emptyLabel: "No contact submissions found",
|
|
54
54
|
filterKeys: ["status"],
|
|
55
55
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -52,7 +52,7 @@ export function AdminCouponsView({ children, onBulkArchive, onBulkDelete, ...pro
|
|
|
52
52
|
const config = {
|
|
53
53
|
portal: "admin",
|
|
54
54
|
title: "Coupons",
|
|
55
|
-
|
|
55
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
56
56
|
emptyLabel: "No coupons found",
|
|
57
57
|
filterKeys: ["type", "showExpired"],
|
|
58
58
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -41,7 +41,7 @@ export function AdminFeaturesView({ children, ...props }) {
|
|
|
41
41
|
const config = {
|
|
42
42
|
portal: "admin",
|
|
43
43
|
title: "Features",
|
|
44
|
-
|
|
44
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
45
45
|
emptyLabel: "No features found",
|
|
46
46
|
filterKeys: [],
|
|
47
47
|
defaultSort: sortBy("displayOrder", "ASC"),
|
|
@@ -52,7 +52,7 @@ export function AdminGroupedListingsView({ children, ...props }) {
|
|
|
52
52
|
const config = React.useMemo(() => ({
|
|
53
53
|
portal: "admin",
|
|
54
54
|
title: "Grouped Listings",
|
|
55
|
-
|
|
55
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
56
56
|
emptyLabel: "No grouped listings",
|
|
57
57
|
filterKeys: [],
|
|
58
58
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -15,7 +15,7 @@ import { DataListingView } from "./DataListingView";
|
|
|
15
15
|
const ADMIN_HISTORY_CONFIG = {
|
|
16
16
|
portal: "admin",
|
|
17
17
|
title: "History",
|
|
18
|
-
|
|
18
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
19
19
|
emptyLabel: "No user history records found",
|
|
20
20
|
filterKeys: [],
|
|
21
21
|
defaultSort: sortBy("updatedAt", "DESC"),
|
|
@@ -87,7 +87,7 @@ export function AdminNewsletterView({ children, onBulkUnsubscribe, ...props }) {
|
|
|
87
87
|
const config = {
|
|
88
88
|
portal: "admin",
|
|
89
89
|
title: "Newsletter",
|
|
90
|
-
|
|
90
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
91
91
|
emptyLabel: "No subscribers found",
|
|
92
92
|
filterKeys: ["status"],
|
|
93
93
|
defaultSort: sortBy("subscribedAt", "DESC"),
|
|
@@ -103,7 +103,7 @@ export function AdminOffersView({ children, ...props }) {
|
|
|
103
103
|
const config = {
|
|
104
104
|
portal: "admin",
|
|
105
105
|
title: "Offers",
|
|
106
|
-
|
|
106
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
107
107
|
emptyLabel: "No offers found",
|
|
108
108
|
filterKeys: ["status"],
|
|
109
109
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -85,7 +85,7 @@ export function AdminOrdersView({ children, ...props }) {
|
|
|
85
85
|
const config = {
|
|
86
86
|
portal: "admin",
|
|
87
87
|
title: "Orders",
|
|
88
|
-
|
|
88
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
89
89
|
emptyLabel: "No orders found",
|
|
90
90
|
filterKeys: ["status", "paymentReview"],
|
|
91
91
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -52,7 +52,7 @@ onOpen) {
|
|
|
52
52
|
return {
|
|
53
53
|
portal: "admin",
|
|
54
54
|
title: "Payment Methods",
|
|
55
|
-
|
|
55
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
56
56
|
emptyLabel: "No payment methods found",
|
|
57
57
|
// URL-synced via filterKeys (2026-08-21) — see the matching note in
|
|
58
58
|
// AdminAddressesView. banStatus is a query param, not a Sieve clause,
|
|
@@ -46,7 +46,7 @@ export function AdminReturnRequestsView(_props) {
|
|
|
46
46
|
const config = {
|
|
47
47
|
portal: "admin",
|
|
48
48
|
title: "Return Requests",
|
|
49
|
-
|
|
49
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
50
50
|
emptyLabel: "No return requests",
|
|
51
51
|
filterKeys: [],
|
|
52
52
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -41,7 +41,7 @@ export function AdminSessionsView({ children, ...props }) {
|
|
|
41
41
|
const config = {
|
|
42
42
|
portal: "admin",
|
|
43
43
|
title: "Sessions",
|
|
44
|
-
|
|
44
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
45
45
|
emptyLabel: "No sessions found",
|
|
46
46
|
filterKeys: ["isActive"],
|
|
47
47
|
defaultSort: sortBy("lastActivity", "DESC"),
|
|
@@ -9,7 +9,7 @@ import { RecordDetailModal } from "../../../ui";
|
|
|
9
9
|
const ADMIN_STORE_ADDRESSES_CONFIG = {
|
|
10
10
|
portal: "admin",
|
|
11
11
|
title: "Store Addresses",
|
|
12
|
-
|
|
12
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
13
13
|
emptyLabel: "No store addresses found",
|
|
14
14
|
filterKeys: [],
|
|
15
15
|
defaultSort: sortBy("storeId", "ASC"),
|
|
@@ -11,7 +11,7 @@ export function AdminSublistingCategoriesView({ onBulkDelete, }) {
|
|
|
11
11
|
const config = {
|
|
12
12
|
portal: "admin",
|
|
13
13
|
title: "Sub-listing Categories",
|
|
14
|
-
|
|
14
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
15
15
|
emptyLabel: "No sub-listing categories found",
|
|
16
16
|
filterKeys: [],
|
|
17
17
|
defaultSort: sortBy("name", "ASC"),
|
|
@@ -99,7 +99,17 @@ export function AdminUsersView({ children, ...props }) {
|
|
|
99
99
|
const config = {
|
|
100
100
|
portal: "admin",
|
|
101
101
|
title: "Users",
|
|
102
|
-
|
|
102
|
+
// Exact match, and the copy has to say so. `/api/admin/users` branches on
|
|
103
|
+
// whether the term contains "@": an email resolves through
|
|
104
|
+
// `emailIndex == piiBlindIndex(q)` and a name through `displayName == q`.
|
|
105
|
+
// BOTH are equality. Email cannot be partial-matched at all — it is
|
|
106
|
+
// encrypted, and ciphertext has no usable prefix (D1) — and "seller
|
|
107
|
+
// handles" were never matched by anything.
|
|
108
|
+
search: {
|
|
109
|
+
placeholder: "Full name or email (exact match)",
|
|
110
|
+
mode: "exact",
|
|
111
|
+
fields: ["displayName", "email"],
|
|
112
|
+
},
|
|
103
113
|
emptyLabel: "No users found",
|
|
104
114
|
filterKeys: ["status", "role"],
|
|
105
115
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -11,7 +11,7 @@ import { DataListingView } from "./DataListingView";
|
|
|
11
11
|
const ADMIN_WISHLISTS_CONFIG = {
|
|
12
12
|
portal: "admin",
|
|
13
13
|
title: "Wishlists",
|
|
14
|
-
|
|
14
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
15
15
|
emptyLabel: "No user wishlists found",
|
|
16
16
|
filterKeys: [],
|
|
17
17
|
defaultSort: sortBy("updatedAt", "DESC"),
|
|
@@ -78,7 +78,36 @@ export interface ListingViewConfig<TResponse, TRow extends {
|
|
|
78
78
|
portal: "admin" | "seller" | "user";
|
|
79
79
|
title: string;
|
|
80
80
|
subtitle?: string;
|
|
81
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Search box copy. OPTIONAL — declaring it is what makes the box exist.
|
|
83
|
+
*
|
|
84
|
+
* It was REQUIRED, and `DataListingView` passed `onSearchChange`
|
|
85
|
+
* unconditionally, so a developer could not build a listing view without
|
|
86
|
+
* rendering a search box. `ListingToolbar` has always gated the box on
|
|
87
|
+
* `onSearchChange` being supplied; nothing ever declined to supply it.
|
|
88
|
+
*
|
|
89
|
+
* That is the structural cause of the dead boxes: ~39 views render a search
|
|
90
|
+
* input whose endpoint never reads `q`. The box accepts typing, the request
|
|
91
|
+
* carries the term, and the results do not change — no error anywhere.
|
|
92
|
+
*
|
|
93
|
+
* Omit it when the endpoint cannot search. Do not pass a placeholder
|
|
94
|
+
* describing a capability the endpoint lacks.
|
|
95
|
+
*/
|
|
96
|
+
searchPlaceholder?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Explicit search capability. Prefer this over a bare `searchPlaceholder`
|
|
99
|
+
* when the match semantics matter to the user — PII-backed fields are
|
|
100
|
+
* exact-match by construction (encryption and partial-match search are
|
|
101
|
+
* mutually exclusive), and a placeholder promising "search by email" over a
|
|
102
|
+
* blind index is a promise the backend cannot keep.
|
|
103
|
+
*/
|
|
104
|
+
search?: {
|
|
105
|
+
placeholder: string;
|
|
106
|
+
/** `exact` for a field resolved through an HMAC blind index. */
|
|
107
|
+
mode?: "partial" | "exact";
|
|
108
|
+
/** Fields the endpoint actually matches on. */
|
|
109
|
+
fields?: readonly string[];
|
|
110
|
+
};
|
|
82
111
|
emptyLabel?: string;
|
|
83
112
|
sortOptions: ListingSortOption[];
|
|
84
113
|
columns?: AdminTableColumn<TRow>[];
|
|
@@ -78,7 +78,13 @@ export function DataListingView({ config, }) {
|
|
|
78
78
|
window.location.href = href;
|
|
79
79
|
}
|
|
80
80
|
: undefined;
|
|
81
|
-
|
|
81
|
+
// A box exists only when the config asks for one.
|
|
82
|
+
const searchEnabled = Boolean(config.search ?? config.searchPlaceholder);
|
|
83
|
+
return (_jsxs(Div, { className: config.className ?? "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: config.search?.placeholder ?? config.searchPlaceholder,
|
|
84
|
+
// Passing this is what renders the box — ListingToolbar gates on it.
|
|
85
|
+
// Undefined when the config declares no search, so a view whose
|
|
86
|
+
// endpoint cannot search no longer shows an input that does nothing.
|
|
87
|
+
onSearchChange: searchEnabled ? setSearchInput : undefined, onSearchCommit: searchEnabled ? commitSearch : undefined, sortValue: table.get("sort") || config.defaultSort, sortOptions: config.sortOptions, onSortChange: (v) => table.set("sort", v), showTableView: !config.hideTableView, toggles: config.toggles, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState, extra: config.primaryAction || config.toolbarExtra ? (_jsxs(Row, { align: "center", gap: "sm", children: [config.toolbarExtra, config.primaryAction && (_jsxs(Button, { gap: "sm", size: "sm", onClick: () => config.primaryAction.onClick({
|
|
82
88
|
openCreatePanel: panel.openCreatePanel,
|
|
83
89
|
}), children: [config.primaryAction.icon ?? _jsx(Plus, { className: "h-4 w-4" }), config.primaryAction.label] }))] })) : undefined }), config.renderAboveContent?.(), bulkActionItems && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActionItems })), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p), pageSize: pageSize, onPageSizeChange: setPageSize, paginationConfig: { showPageSizeSelector: true, pageSizeOptions: [10, 25, 50, 100] } }) }) })), _jsxs(Div, { paddingX: "x-sm-md", padding: "y-md", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), view === "table" && !config.hideTableView && !isMobile ? (_jsx(DataTable, { columns: config.columns, rows: rows, resourceIcon: resourceIcon, isLoading: isLoading, emptyLabel: config.emptyLabel ?? `No ${config.title.toLowerCase()} found`, selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: (next) => next
|
|
84
90
|
? selection.setSelectedIds(rows.map((r) => r.id))
|
|
@@ -41,7 +41,7 @@ export function AdminCatalogueApprovalsView() {
|
|
|
41
41
|
const config = {
|
|
42
42
|
portal: "admin",
|
|
43
43
|
title: "Catalogue Approvals",
|
|
44
|
-
|
|
44
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
45
45
|
emptyLabel: "No pending catalogue requests",
|
|
46
46
|
filterKeys: [],
|
|
47
47
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -33,7 +33,7 @@ export function AdminEventsView({ children, ...props }) {
|
|
|
33
33
|
const config = {
|
|
34
34
|
portal: "admin",
|
|
35
35
|
title: "Events",
|
|
36
|
-
|
|
36
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
37
37
|
emptyLabel: "No events found",
|
|
38
38
|
filterKeys: ["status", "type"],
|
|
39
39
|
defaultSort: sortBy("startsAt", "DESC"),
|
|
@@ -49,7 +49,7 @@ export function SellerCouponsView({ onCreateClick, onEditClick, onToggle, onDele
|
|
|
49
49
|
const config = {
|
|
50
50
|
portal: "seller",
|
|
51
51
|
title: "Coupons",
|
|
52
|
-
|
|
52
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
53
53
|
emptyLabel: "No coupons found — create your first coupon",
|
|
54
54
|
filterKeys: ["isActive"],
|
|
55
55
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -54,7 +54,7 @@ export function SellerGroupedListingsView({ onCreateClick, onEditClick, onDelete
|
|
|
54
54
|
const config = {
|
|
55
55
|
portal: "seller",
|
|
56
56
|
title: "Grouped Listings",
|
|
57
|
-
|
|
57
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
58
58
|
emptyLabel: "No grouped listings yet",
|
|
59
59
|
filterKeys: [],
|
|
60
60
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -22,7 +22,7 @@ export function SellerOffersView({ children, onAcceptOffer, onRejectOffer, onCou
|
|
|
22
22
|
const config = {
|
|
23
23
|
portal: "seller",
|
|
24
24
|
title: "Offers",
|
|
25
|
-
|
|
25
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
26
26
|
emptyLabel: "No offers received",
|
|
27
27
|
filterKeys: ["status"],
|
|
28
28
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -294,7 +294,7 @@ export function SellerOrdersView({ orderDetailApiBase = SELLER_ENDPOINTS.ORDERS,
|
|
|
294
294
|
const config = {
|
|
295
295
|
portal: "seller",
|
|
296
296
|
title: "Orders",
|
|
297
|
-
|
|
297
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
298
298
|
emptyLabel: "No orders yet",
|
|
299
299
|
filterKeys: ["status"],
|
|
300
300
|
defaultSort: DEFAULT_SORT,
|
|
@@ -95,7 +95,7 @@ export function SellerPayoutsView({ children, ...props }) {
|
|
|
95
95
|
const config = {
|
|
96
96
|
portal: "seller",
|
|
97
97
|
title: "Payouts",
|
|
98
|
-
|
|
98
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
99
99
|
emptyLabel: "No payouts found",
|
|
100
100
|
filterKeys: ["status", "showAllPayouts"],
|
|
101
101
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -64,7 +64,7 @@ export function SellerStoreCategoriesView({ onCreateClick, onEditClick, onDelete
|
|
|
64
64
|
const config = {
|
|
65
65
|
portal: "seller",
|
|
66
66
|
title: "Store Categories",
|
|
67
|
-
|
|
67
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
68
68
|
emptyLabel: "No categories yet — add your first storefront category",
|
|
69
69
|
filterKeys: [],
|
|
70
70
|
defaultSort: DEFAULT_SORT,
|
|
@@ -28,7 +28,7 @@ export function AdminShipmentsView({ children, ...props }) {
|
|
|
28
28
|
const config = {
|
|
29
29
|
portal: "admin",
|
|
30
30
|
title: "Procurement Shipments",
|
|
31
|
-
|
|
31
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
32
32
|
emptyLabel: "No shipments found",
|
|
33
33
|
filterKeys: ["status"],
|
|
34
34
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
@@ -60,7 +60,7 @@ export function AdminTesterFeedbackListView(_props) {
|
|
|
60
60
|
const config = {
|
|
61
61
|
portal: "admin",
|
|
62
62
|
title: "All Submissions",
|
|
63
|
-
|
|
63
|
+
// Search intentionally absent: this endpoint does not read `q`, so the box accepted typing and changed nothing. Restore it when the collection gains searchTxt — audit-listing-search-capability tracks it.
|
|
64
64
|
emptyLabel: "No feedback submitted yet",
|
|
65
65
|
filterKeys: ["answer", "status"],
|
|
66
66
|
defaultSort: sortBy(TESTER_CHECKLIST_RESPONSE_FIELDS.CREATED_AT, "DESC"),
|