@webx-ui/module-catalog 0.8.9 → 0.9.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductsPage-BBmw9W4m.js","sources":["../src/BulkParamsDialog.vue","../src/BulkBar.vue","../src/ProductsPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, reactive } from 'vue'\nimport { useAdmin, useTranslate, WxSourceSelect } from '@webx-ui/module-admin'\nimport {\n useModal,\n WxButton,\n WxDialog,\n WxFormItem,\n WxInput,\n WxSelect,\n WxSpace,\n WxText,\n WxTreeSelect,\n type SelectOption,\n type TreeSelectValue,\n} from '@webx-ui/core'\nimport { useCatalogMessages } from './i18n'\nimport { useCategoryTree } from './store'\nimport type { BulkActionInfo, BulkParam } from './types'\n\n/**\n * What a bulk action asks for before it runs — a category, a label — and the last word before it\n * does: how many products it is about to touch. The fields are drawn from what the server said\n * about the action, so a satellite's action gets its dialog without this file knowing it: a\n * param with a `source` is a choice out of that reference book (a label, a brand), and one that is\n * not required says what choosing nothing does — for `set-brand`, take the brand off.\n */\nconst props = defineProps<{ action: BulkActionInfo; count: number }>()\n\nconst { open, resolve, dismiss } = useModal<Record<string, unknown>>()\n\nconst context = useAdmin()\nconst tree = useCategoryTree(context)\nuseCatalogMessages()\n\nconst t = useTranslate('webx-catalog')\n\nconst values = reactive<Record<string, unknown>>({})\n\nconst ready = computed(() =>\n props.action.params.every(\n (param) =>\n !param.rules?.includes('required') ||\n (values[param.name] !== undefined &&\n values[param.name] !== null &&\n values[param.name] !== ''),\n ),\n)\n\nonMounted(() => {\n if (props.action.params.some((param) => param.type === 'category')) {\n void tree.load().catch(() => undefined)\n }\n})\n\nfunction optionsOf(param: BulkParam): SelectOption[] {\n return Array.isArray(param.values)\n ? param.values.map((one) =>\n typeof one === 'object'\n ? { value: one.value, label: one.label }\n : { value: one, label: String(one) },\n )\n : []\n}\n\nfunction required(param: BulkParam): boolean {\n return param.rules?.includes('required') ?? false\n}\n\nfunction onCategory(param: BulkParam, value: TreeSelectValue): void {\n values[param.name] = Array.isArray(value) ? (value[0] ?? null) : value\n}\n\nfunction apply(): void {\n if (ready.value) resolve({ ...values })\n}\n</script>\n\n<template>\n <wx-dialog\n v-model:open=\"open\"\n :title=\"t('panel.bulk-confirm-title', { action: action.label })\"\n :width=\"440\"\n >\n <wx-text tone=\"muted\" size=\"sm\">{{ t('panel.bulk-confirm-text', { count }) }}</wx-text>\n\n <wx-form-item\n v-for=\"param in action.params\"\n :key=\"param.name\"\n :label=\"param.label\"\n :required=\"required(param)\"\n class=\"wx-catalog-bulk-params__field\"\n >\n <wx-tree-select\n v-if=\"param.type === 'category'\"\n :model-value=\"(values[param.name] as number | null | undefined) ?? null\"\n :nodes=\"tree.nodes.value ?? []\"\n node-key=\"id\"\n label-key=\"name\"\n children-key=\"children\"\n check-strictly\n filterable\n :placeholder=\"t('panel.pick-category')\"\n :filter-placeholder=\"t('panel.search-categories')\"\n :aria-label=\"param.label\"\n @update:model-value=\"(value: TreeSelectValue) => onCategory(param, value)\"\n />\n <wx-source-select\n v-else-if=\"param.source\"\n :model-value=\"(values[param.name] as number | null | undefined) ?? null\"\n :source=\"param.source\"\n filterable\n :clearable=\"!required(param)\"\n :placeholder=\"required(param) ? undefined : t('panel.bulk-param-empty')\"\n :aria-label=\"param.label\"\n @update:model-value=\"(value: unknown) => (values[param.name] = value)\"\n />\n <wx-select\n v-else-if=\"Array.isArray(param.values)\"\n :model-value=\"(values[param.name] as string | number | undefined) ?? null\"\n :options=\"optionsOf(param)\"\n :aria-label=\"param.label\"\n @update:model-value=\"(value: unknown) => (values[param.name] = value)\"\n />\n <wx-input v-else v-model=\"values[param.name] as string\" :aria-label=\"param.label\" />\n </wx-form-item>\n\n <template #footer>\n <wx-space size=\"sm\">\n <wx-button variant=\"outline\" @click=\"dismiss()\">{{ t('panel.cancel') }}</wx-button>\n <wx-button\n :type=\"action.permission === 'catalog.delete' && !action.trashed ? 'danger' : 'primary'\"\n :disabled=\"!ready\"\n @click=\"apply\"\n >\n {{ t('panel.bulk-apply') }}\n </wx-button>\n </wx-space>\n </template>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-catalog-bulk-params__field {\n margin-top: var(--wx-space-16);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n createModal,\n toast,\n WxButton,\n WxDropdown,\n WxDropdownItem,\n WxIcon,\n WxProgress,\n WxText,\n} from '@webx-ui/core'\nimport BulkParamsDialog from './BulkParamsDialog.vue'\nimport ExchangeExportDialog from './ExchangeExportDialog.vue'\nimport { createCatalogApi } from './api'\nimport { useCatalogMessages } from './i18n'\nimport type { ExchangeRun } from './exchange'\nimport type { BulkActionInfo, BulkRun, BulkSelection } from './types'\n\n/**\n * The actions over what is picked in the list (§11.4), and the run they start.\n *\n * Which actions there are is the server's answer — the core's and every satellite's, only the\n * ones this administrator may start. A small selection is done inside the request and answered at\n * once; a large one is a run in the background, polled here with its progress, and its refusals\n * are listed by product when it ends. The list reloads either way, and `finished` carries the ids\n * that refused — what the list leaves picked, so they can be put right and tried again.\n *\n * «Export» heads the menu (§8.1 of the exchange spec): the same selection, written to a file. It\n * is the exchange's run rather than a bulk one, and is followed in «Exchange».\n */\nconst props = withDefaults(\n defineProps<{ count: number; selection: BulkSelection; base?: string }>(),\n { base: '/catalog' },\n)\nconst emit = defineEmits<{ finished: [refused: number[]] }>()\n\n/** Often enough to look alive, rarely enough that a run of forty thousand is not a request storm. */\nconst POLL = 1500\n\nconst context = useAdmin()\nconst api = createCatalogApi(context)\nuseCatalogMessages()\n\nconst t = useTranslate('webx-catalog')\nconst message = useErrorText()\n\nconst params = createModal<Record<string, unknown>, { action: BulkActionInfo; count: number }>(\n BulkParamsDialog,\n)\nconst exporter = createModal<ExchangeRun, { selection: BulkSelection; count: number }>(\n ExchangeExportDialog,\n)\nconst router = useRouter()\n\nasync function exportSelected(): Promise<void> {\n const started = await exporter({ selection: props.selection, count: props.count })\n\n if (!started) return\n\n toast.success(t('panel.exchange-export-started'))\n void router.push({ path: `${props.base}/exchange`, query: { run: String(started.id) } })\n}\n\nconst actions = ref<BulkActionInfo[]>([])\nconst run = ref<BulkRun | null>(null)\nconst starting = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nconst running = computed(\n () => run.value !== null && (run.value.status === 'queued' || run.value.status === 'running'),\n)\nconst refused = computed(() =>\n run.value !== null && !running.value && run.value.failed > 0 ? run.value : null,\n)\n\nonMounted(async () => {\n try {\n actions.value = await api.bulkActions()\n } catch {\n actions.value = []\n }\n})\n\nonBeforeUnmount(() => clearTimeout(timer))\n\n/** An action that asks for something, or deletes, is said once more with the number in it. */\nfunction asks(action: BulkActionInfo): boolean {\n return action.params.length > 0 || (action.permission === 'catalog.delete' && !action.trashed)\n}\n\nasync function start(action: BulkActionInfo): Promise<void> {\n let given: Record<string, unknown> = {}\n\n if (asks(action)) {\n const answer = await params({ action, count: props.count })\n\n if (!answer) return\n given = answer\n }\n\n starting.value = true\n\n try {\n follow(await api.startBulk(action.key, given, props.selection))\n } catch (error) {\n toast.danger(message(error))\n } finally {\n starting.value = false\n }\n}\n\nfunction follow(answer: BulkRun): void {\n run.value = answer\n\n if (answer.status === 'queued' || answer.status === 'running') {\n timer = setTimeout(() => void poll(answer.id!), POLL)\n\n return\n }\n\n finish(answer)\n}\n\nasync function poll(id: number): Promise<void> {\n try {\n follow(await api.bulkRun(id))\n } catch {\n // A missed answer is not the end of the run: ask again.\n timer = setTimeout(() => void poll(id), POLL * 2)\n }\n}\n\nfunction finish(answer: BulkRun): void {\n if (answer.total === 0) toast.warning(t('panel.bulk-nothing'))\n else if (answer.status === 'failed') toast.danger(t('panel.bulk-stopped', { count: answer.done }))\n else if (answer.failed === 0) toast.success(t('panel.bulk-done', { count: answer.done }))\n\n if (answer.failed === 0 && answer.status !== 'failed') run.value = null\n\n emit(\n 'finished',\n answer.errors.map((error) => error.id),\n )\n}\n</script>\n\n<template>\n <div class=\"wx-catalog-bulk\">\n <wx-dropdown v-if=\"!running\" align=\"start\">\n <template #trigger>\n <wx-button size=\"sm\" variant=\"outline\" :loading=\"starting\">\n {{ t('panel.bulk-actions') }}\n <wx-icon name=\"chevron-down\" size=\"sm\" />\n </wx-button>\n </template>\n\n <wx-dropdown-item @click=\"exportSelected\">\n {{ t('panel.exchange-export') }}\n </wx-dropdown-item>\n <wx-dropdown-item\n v-for=\"action in actions\"\n :key=\"action.key\"\n :tone=\"action.permission === 'catalog.delete' && !action.trashed ? 'danger' : 'default'\"\n @click=\"start(action)\"\n >\n {{ action.label }}\n </wx-dropdown-item>\n </wx-dropdown>\n\n <div v-if=\"running && run\" class=\"wx-catalog-bulk__progress\" role=\"status\">\n <wx-progress\n :value=\"run.done + run.failed\"\n :max=\"Math.max(1, run.total)\"\n size=\"sm\"\n :aria-label=\"run.label\"\n />\n <wx-text size=\"sm\" tone=\"muted\">\n {{ run.label }} ·\n {{ t('panel.bulk-running', { done: run.done + run.failed, total: run.total }) }}\n </wx-text>\n </div>\n\n <div v-if=\"refused\" class=\"wx-catalog-bulk__refused\">\n <wx-text size=\"sm\" weight=\"medium\">\n {{ refused.label }} · {{ t('panel.bulk-done', { count: refused.done }) }} ·\n {{ t('panel.bulk-refused', { count: refused.failed }) }}\n </wx-text>\n <details class=\"wx-catalog-bulk__errors\">\n <summary>{{ t('panel.bulk-errors') }}</summary>\n <ul>\n <li v-for=\"error in refused.errors\" :key=\"error.id\">\n <strong>{{ error.name }}</strong> — {{ error.message }}\n </li>\n </ul>\n </details>\n <wx-button size=\"sm\" variant=\"text\" @click=\"run = null\">{{\n t('panel.bulk-close')\n }}</wx-button>\n </div>\n </div>\n</template>\n\n<style scoped>\n/* No box of its own: the button, the progress and the refusals stand in the selection strip\n around it, which already wraps — a box here would push the button onto a line of its own. */\n.wx-catalog-bulk {\n display: contents;\n}\n\n.wx-catalog-bulk__progress {\n display: grid;\n gap: var(--wx-space-4);\n flex: 1 1 240px;\n min-width: 0;\n}\n\n.wx-catalog-bulk__refused {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--wx-space-8);\n flex-basis: 100%;\n min-width: 0;\n}\n\n.wx-catalog-bulk__errors {\n flex-basis: 100%;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-catalog-bulk__errors summary {\n cursor: pointer;\n color: var(--wx-text-muted);\n}\n\n.wx-catalog-bulk__errors ul {\n margin: var(--wx-space-8) 0 0;\n padding-inline-start: var(--wx-space-18);\n max-height: 200px;\n overflow: auto;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, useTemplateRef, watch } from 'vue'\nimport { useRoute, useRouter, type LocationQueryRaw } from 'vue-router'\nimport {\n rowMenuWidth,\n useAdmin,\n useErrorText,\n useTranslate,\n WxDate,\n WxFilterChips,\n WxListScreen,\n WxRowMenu,\n type AppliedFilter,\n type RowAction,\n type ScreenAction,\n} from '@webx-ui/module-admin'\nimport {\n confirm,\n createModal,\n toast,\n useElementWidth,\n WxAlert,\n WxBadge,\n WxButton,\n WxEntityCard,\n WxFormItem,\n WxIcon,\n WxInputNumber,\n WxSelect,\n WxSwitch,\n WxTable,\n WxText,\n WxTooltip,\n WxTreeSelect,\n type RowKey,\n type SelectOption,\n type TabItem,\n type TableColumn,\n type TableState,\n type TabValue,\n type TreeSelectValue,\n} from '@webx-ui/core'\nimport BulkBar from './BulkBar.vue'\nimport ColumnValue from './ColumnValue.vue'\nimport ProductCreateDialog from './ProductCreateDialog.vue'\nimport { createCatalogApi } from './api'\nimport { FACET_PREFIX, readFacets, writeFacet } from './filters'\nimport { useCatalogMessages } from './i18n'\nimport { flatten, useCategoryTree, useFacetRegistry } from './store'\nimport type {\n BulkSelection,\n FacetChoice,\n FacetInfo,\n ProductDetail,\n ProductQuery,\n ProductRow,\n ProductSort,\n SortInfo,\n ProductsPage,\n} from './types'\n\n/**\n * The products of the catalogue (§11.1): a page of rows, the views of decision 3 over it, the\n * facets as filters behind the funnel, and a checkbox per row.\n *\n * The checkboxes are for the bulk actions (§11.4): a selection outlives the page it was made on,\n * which is what \"select these twelve across three pages\" needs, and \"everything found\" picks the\n * filter itself rather than its ids. The actions and their progress are `BulkBar`'s.\n *\n * What the list shows beyond the core's columns is the satellites' (`ProductColumns`, §7.4): the\n * server says which, and each row carries its values under their keys.\n */\nconst props = withDefaults(defineProps<{ base?: string }>(), { base: '/catalog' })\n\n/** Where the row stops being a row. Below it the table draws cards and this screen draws one. */\nconst CARDS = 640\n\nconst context = useAdmin()\nconst api = createCatalogApi(context)\nconst tree = useCategoryTree(context)\nconst registry = useFacetRegistry(context)\nconst route = useRoute()\nconst router = useRouter()\nuseCatalogMessages()\n\nconst t = useTranslate('webx-catalog')\n/* The words a list needs as soon as it has filters belong to the panel, not to the catalogue. */\nconst admin = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst root = useTemplateRef<HTMLElement>('root')\nconst width = useElementWidth(root)\n\nconst page = ref<ProductsPage | null>(null)\nconst loading = ref(true)\nconst selected = ref<RowKey[]>([])\n/** The whole of what the filter finds is picked, not only the ticked rows. */\nconst everything = ref(false)\n/* The table's own search and page, started from the address: coming back lands where it left. */\nconst search = ref(typeof route.query.q === 'string' ? route.query.q : '')\nconst pageNumber = ref(Number(route.query.page ?? 1) || 1)\n/* The search asked for as typed after the engine corrected it; another search is corrected again. */\nconst typedFor = ref<string | null>(null)\nconst corrected = computed(() => page.value?.corrected ?? null)\n\n/* The search index did not answer and the database did (decision 13 of the Manticore spec). */\nconst fellBack = computed(() => page.value?.fell_back === true)\n/* The database engine past its limit: `webx:doctor` says it too, but nobody reads that daily. */\nconst outgrown = computed(() => page.value?.outgrown ?? null)\n/* The page size the table last asked for: a reload after a filter has to page the same way. */\nlet perPage: number | undefined\n\nconst create = createModal<ProductDetail, Record<string, never>>(ProductCreateDialog)\n\nconst canManage = computed(() => context.can('catalog.manage'))\nconst canDelete = computed(() => context.can('catalog.delete'))\n\nconst title = computed(() => t('module.products'))\n\n/** Everything the list is looking at lives in the address — coming back lands in the same place. */\nconst view = computed<TabValue>({\n get: () => (typeof route.query.view === 'string' ? route.query.view : ''),\n set: (value) => {\n void router.replace({\n query: { ...route.query, view: value === '' ? undefined : String(value), page: undefined },\n })\n },\n})\n\n/**\n * The orders are the registry's (§7.2): a satellite adds its own, and a site without prices has\n * none by price — a sort the server does not know is a 422, so nothing is offered or asked for\n * that it did not list. Until it answers, the default order is the one there is.\n */\nconst sorts = computed<SortInfo[]>(() =>\n registry.sorts.value.length > 0\n ? registry.sorts.value\n : [{ key: 'default', label: t('panel.sort-default') }],\n)\n\nconst sort = computed<ProductSort>(() => {\n const asked = route.query.sort\n\n return typeof asked === 'string' && registry.sorts.value.some((one) => one.key === asked)\n ? asked\n : 'default'\n})\n\nconst facets = computed<FacetInfo[]>(() => registry.facets.value ?? [])\nconst chosen = computed(() => readFacets(route.query, facets.value))\n\n/** The counter of decision 3 rides on its own tab, where somebody looking for those products looks. */\nconst views = computed<TabItem[]>(() => {\n const missing = page.value?.counts.no_category ?? 0\n\n return [\n { value: '', label: t('panel.view-all') },\n { value: 'published', label: t('panel.view-published') },\n { value: 'unpublished', label: t('panel.view-unpublished') },\n {\n value: 'no-category',\n label: t('panel.view-no-category'),\n badge: missing > 0 ? missing : undefined,\n },\n ]\n})\n\n/** Absent from every row when the site switched prices off — then the column is not drawn. */\nconst priced = computed(() => (page.value?.data ?? []).some((row) => 'price' in row))\nconst extra = computed(() => page.value?.columns ?? [])\n\nconst asCards = computed(() => width.value > 0 && width.value < CARDS)\n\nconst categoryNames = computed(\n () => new Map(flatten(tree.nodes.value ?? []).map((node) => [String(node.id), node.name])),\n)\n\n/**\n * Every column but the name carries a width and the table is laid out `fixed`, so the ones that\n * drop below a breakpoint give their room to the name. They go in the order they can be spared:\n * when it changed, then the satellites', then the category — what is left is the picture, the\n * name and the state, which is what identifies a product and what somebody is looking for.\n */\nconst NAME = 180\nconst EXTRA = 120\nconst CATEGORY = 140\nconst PRICE = 120\nconst STATE = 130\n\n/*\n * Each width is what its content takes, measured, plus 32 of the cell's padding: the badges\n * «Out of stock» and «Unpublished» about 90px with their dot, a price with its old one 80. A name\n * and a category end in an ellipsis, so they are the ones that give. Wider, the columns cost\n * the satellites — at 140, 180, 150 and 150 a 1440px window held one satellite of three; now it\n * holds all three.\n *\n * The category is drawn once the name keeps its width beside the checkbox, the picture, the price,\n * the state and the menu.\n */\nconst CATEGORY_FROM = 44 + 64 + NAME + CATEGORY + PRICE + STATE + rowMenuWidth\n\n/*\n * The width each satellite's column is drawn from on: one after another after the category's, so\n * a third satellite drops first rather than taking its room out of the name — the table is laid out\n * `fixed`, and there the name's `minWidth` gives way to the widths around it (three satellites at\n * 1080px left it 59px). «Updated» goes before any of them.\n */\nconst extraFrom = (index: number) => CATEGORY_FROM + EXTRA * (index + 1)\n\nconst columns = computed<TableColumn<ProductRow>[]>(() => {\n if (asCards.value) {\n // The card is the row: a tap opens the product, and a line of its own for the `···` would make\n // every card half as tall again for a menu whose first item is that same tap.\n return [{ key: 'card', label: '' }]\n }\n\n return [\n { key: 'image', label: '', width: 64 },\n { key: 'name', label: t('panel.column-product'), minWidth: NAME },\n { key: 'category', label: t('product.category'), width: CATEGORY, hideBelow: CATEGORY_FROM },\n ...(priced.value\n ? [{ key: 'price', label: t('product.price'), width: PRICE, align: 'right' as const }]\n : []),\n ...extra.value.map((column, index) => ({\n key: `x.${column.key}`,\n label: column.label,\n width: EXTRA,\n hideBelow: extraFrom(index),\n })),\n { key: 'state', label: t('panel.column-state'), width: STATE, hideBelow: 720 },\n {\n key: 'updated_at',\n label: t('panel.column-updated'),\n width: 130,\n hideBelow: Math.max(1180, extraFrom(extra.value.length - 1) + 130),\n },\n { key: 'actions', label: '', width: rowMenuWidth, align: 'right' },\n ]\n})\n\nfunction query(state?: TableState): ProductQuery {\n const q = state?.search ?? search.value\n\n return {\n q,\n typed: typedFor.value !== null && typedFor.value === q,\n state: view.value as ProductQuery['state'],\n sort: sort.value,\n page: state?.page ?? pageNumber.value,\n per_page: state?.perPage ?? perPage,\n facets: chosen.value,\n }\n}\n\nlet asked = 0\n\nasync function load(state?: TableState): Promise<void> {\n const mine = ++asked\n\n loading.value = true\n\n try {\n const answer = await api.products(query(state))\n\n // A slower answer to an older question must not land over a newer one.\n if (mine === asked) page.value = answer\n } catch (error) {\n toast.danger(message(error))\n } finally {\n if (mine === asked) loading.value = false\n }\n}\n\nfunction onState(state: TableState): void {\n perPage = state.perPage\n\n const wanted: LocationQueryRaw = {\n ...route.query,\n q: state.search === '' ? undefined : state.search,\n page: state.page === 1 ? undefined : String(state.page),\n }\n\n void router.replace({ query: wanted })\n void load(state)\n}\n\nfunction narrow(key: string, choice: FacetChoice | null): void {\n void router.replace({\n query: { ...route.query, [`${FACET_PREFIX}${key}`]: writeFacet(choice), page: undefined },\n })\n}\n\nfunction order(value: unknown): void {\n void router.replace({\n query: {\n ...route.query,\n sort: typeof value === 'string' && value !== 'default' ? value : undefined,\n page: undefined,\n },\n })\n}\n\nfunction clearFilters(): void {\n const rest = Object.fromEntries(\n Object.entries(route.query).filter(([name]) => !name.startsWith(FACET_PREFIX)),\n )\n\n void router.replace({ query: { ...rest, page: undefined } })\n}\n\n/**\n * What a terms facet can be narrowed to: the values the list counted for it, with how many\n * products each would leave. The engine counts a facet without its own choice, so picking one\n * value does not take the others away; a chosen value that counts nothing any more stays offered,\n * or it could not be taken off.\n */\nfunction optionsOf(key: string): SelectOption[] {\n const counted = page.value?.facets?.[key]?.values ?? []\n const options: SelectOption[] = counted.map((one) => ({\n value: one.value,\n label: `${one.label} (${one.count})`,\n }))\n\n for (const value of valuesOf(key)) {\n if (!counted.some((one) => one.value === value)) options.push({ value, label: value })\n }\n\n return options\n}\n\n/** Values of a terms facet, or of the tree, for a chip: \"Category: Laptops, Tablets\". */\nfunction valueLabel(facet: FacetInfo, value: string | number): string {\n if (facet.kind === 'tree') return categoryNames.value.get(String(value)) ?? `#${value}`\n\n return (\n page.value?.facets?.[facet.key]?.values?.find((one) => one.value === String(value))?.label ??\n String(value)\n )\n}\n\n/** The bounds a range facet has in the list as it stands, said in its fields before anything is typed. */\nfunction boundOf(key: string, end: 'min' | 'max'): string {\n const bound = page.value?.facets?.[key]?.[end]\n\n return typeof bound === 'number' ? money.value.format(bound) : ''\n}\n\nconst applied = computed<AppliedFilter[]>(() =>\n facets.value.flatMap((facet) => {\n const choice = chosen.value[facet.key]\n\n if (choice === undefined) return []\n\n let said: string\n\n if (choice === true) said = facet.label\n else if (Array.isArray(choice)) {\n said = `${facet.label}: ${choice.map((value) => valueLabel(facet, value)).join(', ')}`\n } else {\n said = `${facet.label}: ${choice.min ?? '…'} – ${choice.max ?? '…'}`\n }\n\n return [{ key: facet.key, label: said, clear: () => narrow(facet.key, null) }]\n }),\n)\n\nconst emptyText = computed(() => {\n if (search.value !== '') return t('panel.empty-search')\n if (applied.value.length > 0 || view.value !== '') return t('panel.empty-search')\n\n return t('panel.empty-products')\n})\n\nfunction rangeOf(key: string): { min?: number | null; max?: number | null } {\n const choice = chosen.value[key]\n\n return choice && !Array.isArray(choice) && choice !== true ? choice : {}\n}\n\nfunction valuesOf(key: string): string[] {\n const choice = chosen.value[key]\n\n return Array.isArray(choice) ? choice.map(String) : []\n}\n\nfunction treeChoice(key: string): TreeSelectValue {\n return valuesOf(key).map(Number)\n}\n\n/** How many the list finds as it is filtered — what \"select everything found\" would pick. */\nconst found = computed(() => page.value?.total ?? 0)\n\n/**\n * \"Everything found\" is the list's query, not its ids (§11.4): the server turns it into ids when\n * the run starts, so forty thousand products never travel through the browser.\n */\nconst bulkSelection = computed<BulkSelection>(() => {\n if (!everything.value) return { ids: selected.value.map(Number) }\n\n const facetsQuery: Record<\n string,\n Array<string | number> | { min?: number | null; max?: number | null }\n > = {}\n\n for (const [key, choice] of Object.entries(chosen.value)) {\n // A toggle is sent the way the list sends it: a list with `1` in it.\n facetsQuery[key] = choice === true ? ['1'] : choice\n }\n\n return { query: { q: search.value, state: String(view.value), facets: facetsQuery } }\n})\n\nfunction clearSelection(): void {\n selected.value = []\n everything.value = false\n}\n\n/**\n * What refused stays picked, and nothing else: the strip keeps its list of refusals beside the\n * very products it names, ready for another go once they are put right.\n */\nfunction searchAsTyped(): void {\n typedFor.value = search.value\n void load()\n}\n\nfunction onBulkFinished(refused: number[]): void {\n everything.value = false\n selected.value = refused\n void load()\n}\n\n/* One source per value, not one getter returning an array: a page turn must not fire a second\n request racing the one `onState` already sent. */\nwatch([view, sort, () => JSON.stringify(chosen.value), search], () => {\n // \"Everything found\" was everything this filter found; another filter finds something else.\n everything.value = false\n})\n\nwatch([view, sort, () => JSON.stringify(chosen.value)], () => {\n // A new filter is a new list: the page it was on belongs to the list it was on. If that moves\n // the table's page, the table asks for itself; otherwise nobody would.\n if (pageNumber.value !== 1) pageNumber.value = 1\n else void load()\n})\n\nonMounted(() => {\n void registry.load().catch(() => undefined)\n void tree.load().catch(() => undefined)\n})\n\nfunction open(product: ProductRow): void {\n void router.push({ path: `${props.base}/products/${product.id}` })\n}\n\nasync function add(): Promise<void> {\n const detail = await create({})\n\n if (!detail) return\n\n open(detail.product)\n}\n\nasync function publish(product: ProductRow, on: boolean): Promise<void> {\n try {\n await api.saveProduct(product.id, { is_published: on })\n toast.success(on ? t('panel.product-published') : t('panel.product-unpublished'))\n await load()\n } catch (error) {\n // Publishing without a main category is refused (decision 3), and the server says so.\n toast.danger(message(error))\n }\n}\n\nasync function remove(product: ProductRow): Promise<void> {\n const agreed = await confirm({\n title: t('panel.delete-product-title', { name: product.name }),\n message: t('panel.delete-product-text'),\n confirmText: t('panel.delete'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n\n if (!agreed) return\n\n try {\n await api.removeProduct(product.id)\n selected.value = selected.value.filter((key) => key !== product.id)\n toast.success(t('panel.product-deleted'))\n await load()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction actionsFor(product: ProductRow): RowAction[] {\n const actions: RowAction[] = [\n { key: 'open', icon: 'edit', label: t('panel.open'), run: () => open(product) },\n ]\n\n if (product.url) {\n actions.push({ key: 'site', icon: 'link', label: t('panel.open-on-site'), href: product.url })\n }\n\n if (canManage.value) {\n actions.push(\n product.is_published\n ? {\n key: 'unpublish',\n icon: 'eye-off',\n label: t('panel.unpublish'),\n run: () => void publish(product, false),\n }\n : {\n key: 'publish',\n icon: 'eye',\n label: t('panel.publish'),\n run: () => void publish(product, true),\n },\n )\n }\n\n if (canDelete.value) {\n actions.push({\n key: 'delete',\n icon: 'trash',\n label: t('panel.delete'),\n danger: true,\n run: () => void remove(product),\n })\n }\n\n return actions\n}\n\nfunction stateType(product: ProductRow): 'success' | 'warning' | 'default' {\n if (!product.is_published) return 'default'\n\n return product.visible ? 'success' : 'warning'\n}\n\nconst money = computed(\n () =>\n new Intl.NumberFormat(context.i18n.state.locale, {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n }),\n)\n\nfunction price(value: number | null | undefined): string {\n return value === null || value === undefined ? '—' : money.value.format(value)\n}\n\nfunction unit(product: ProductRow): string {\n return product.unit ? ` / ${t(`units.${product.unit}`)}` : ''\n}\n\nfunction hasValue(value: unknown): boolean {\n return Array.isArray(value)\n ? value.length > 0\n : value !== null && value !== undefined && value !== ''\n}\n\nconst actions = computed<ScreenAction[]>(() => {\n const leads: ScreenAction[] = []\n\n if (canManage.value) {\n leads.push({\n key: 'new',\n label: t('panel.new-product'),\n icon: 'plus',\n primary: true,\n run: () => void add(),\n })\n }\n\n if (canDelete.value) {\n leads.push({\n key: 'deleted',\n label: t('module.deleted'),\n icon: 'trash',\n menu: true,\n run: () => void router.push(`${props.base}/deleted`),\n })\n }\n\n // After «Deleted» (§8.1 of the exchange spec): reading and exporting is anybody's who sees\n // the catalogue; the import inside asks for the right to write it.\n leads.push({\n key: 'exchange',\n label: t('panel.exchange-title'),\n icon: 'file-csv',\n menu: true,\n run: () => void router.push(`${props.base}/exchange`),\n })\n\n return leads\n})\n</script>\n\n<template>\n <div ref=\"root\" class=\"wx-catalog-products\">\n <wx-list-screen v-model:view=\"view\" :title=\"title\" :views=\"views\" :actions=\"actions\">\n <!-- What is picked, said above the rows it was picked from, with what can be done to it. -->\n <div v-if=\"selected.length > 0 || everything\" class=\"wx-catalog-products__selection\">\n <wx-text size=\"sm\" weight=\"medium\">\n {{\n everything\n ? t('panel.selected-all', { count: found })\n : t('panel.selected', { count: selected.length })\n }}\n </wx-text>\n <wx-button\n v-if=\"!everything && found > selected.length\"\n size=\"sm\"\n variant=\"text\"\n @click=\"everything = true\"\n >\n {{ t('panel.select-all-found', { count: found }) }}\n </wx-button>\n <wx-button size=\"sm\" variant=\"text\" @click=\"clearSelection\">\n {{ t('panel.select-clear') }}\n </wx-button>\n <bulk-bar\n v-if=\"canManage || canDelete\"\n :count=\"everything ? found : selected.length\"\n :selection=\"bulkSelection\"\n :base=\"props.base\"\n @finished=\"onBulkFinished\"\n />\n </div>\n\n <!-- Work goes on without the index, but the search is cruder: say so over the list. -->\n <wx-alert v-if=\"fellBack\" class=\"wx-catalog-products__notice\" type=\"warning\">\n {{ t('panel.fell-back') }}\n </wx-alert>\n\n <wx-alert v-if=\"outgrown\" class=\"wx-catalog-products__notice\" type=\"warning\">\n {{ t('panel.outgrown', { live: outgrown.live, limit: outgrown.limit }) }}\n </wx-alert>\n\n <!-- Found for other words than the ones typed: said, with the way back to them. -->\n <div v-if=\"corrected\" class=\"wx-catalog-products__corrected\">\n <wx-text size=\"sm\">{{ t('panel.search-corrected', { corrected }) }}</wx-text>\n <wx-button size=\"sm\" variant=\"text\" @click=\"searchAsTyped\">\n {{ t('panel.search-instead', { q: search }) }}\n </wx-button>\n </div>\n\n <wx-table\n v-model:selected=\"selected\"\n v-model:search=\"search\"\n v-model:page=\"pageNumber\"\n :data=\"page\"\n :columns=\"columns\"\n row-key=\"id\"\n searchable\n selectable\n clickable\n hover\n flush\n :loading=\"loading\"\n layout=\"fixed\"\n :cards-below=\"CARDS\"\n :filters-count=\"applied.length\"\n :filters-label=\"admin('filters.title')\"\n :select-row-label=\"admin('filters.select-row')\"\n :select-all-label=\"admin('filters.select-all')\"\n :search-placeholder=\"t('panel.search-products')\"\n :empty-text=\"emptyText\"\n :aria-label=\"title\"\n @row-click=\"open\"\n @state-change=\"onState\"\n >\n <template #filters>\n <wx-form-item :label=\"t('panel.sort')\">\n <wx-select\n :model-value=\"sort\"\n :options=\"sorts.map((one) => ({ value: one.key, label: one.label }))\"\n size=\"sm\"\n @update:model-value=\"order\"\n />\n </wx-form-item>\n\n <wx-form-item v-for=\"facet in facets\" :key=\"facet.key\" :label=\"facet.label\">\n <wx-tree-select\n v-if=\"facet.kind === 'tree'\"\n :model-value=\"treeChoice(facet.key)\"\n :nodes=\"tree.nodes.value ?? []\"\n node-key=\"id\"\n label-key=\"name\"\n children-key=\"children\"\n multiple\n check-strictly\n filterable\n clearable\n size=\"sm\"\n :placeholder=\"t('panel.any')\"\n @update:model-value=\"\n (value: TreeSelectValue) =>\n narrow(facet.key, Array.isArray(value) ? value.map(String) : [])\n \"\n />\n\n <div v-else-if=\"facet.kind === 'range'\" class=\"wx-catalog-products__range\">\n <wx-input-number\n :model-value=\"rangeOf(facet.key).min ?? null\"\n :min=\"0\"\n :controls=\"false\"\n size=\"sm\"\n :placeholder=\"boundOf(facet.key, 'min') || t('panel.range-from')\"\n :aria-label=\"`${facet.label}: ${t('panel.range-from')}`\"\n @update:model-value=\"\n (value: number | null | undefined) =>\n narrow(facet.key, { ...rangeOf(facet.key), min: value ?? null })\n \"\n />\n <wx-input-number\n :model-value=\"rangeOf(facet.key).max ?? null\"\n :min=\"0\"\n :controls=\"false\"\n size=\"sm\"\n :placeholder=\"boundOf(facet.key, 'max') || t('panel.range-to')\"\n :aria-label=\"`${facet.label}: ${t('panel.range-to')}`\"\n @update:model-value=\"\n (value: number | null | undefined) =>\n narrow(facet.key, { ...rangeOf(facet.key), max: value ?? null })\n \"\n />\n </div>\n\n <wx-switch\n v-else-if=\"facet.kind === 'toggle'\"\n :model-value=\"chosen[facet.key] === true\"\n size=\"sm\"\n @update:model-value=\"(on) => narrow(facet.key, on ? true : null)\"\n />\n\n <wx-select\n v-else\n :model-value=\"valuesOf(facet.key)\"\n :options=\"optionsOf(facet.key)\"\n multiple\n filterable\n clearable\n size=\"sm\"\n :placeholder=\"t('panel.any')\"\n @update:model-value=\"\n (value: unknown) => narrow(facet.key, Array.isArray(value) ? value.map(String) : [])\n \"\n />\n </wx-form-item>\n\n <wx-button v-if=\"applied.length > 0\" variant=\"text\" size=\"sm\" block @click=\"clearFilters\">\n <template #icon><wx-icon name=\"close\" /></template>\n {{ admin('filters.reset') }}\n </wx-button>\n </template>\n\n <template #applied>\n <wx-filter-chips :filters=\"applied\" />\n </template>\n\n <template #cell-image=\"{ row }\">\n <span class=\"wx-catalog-products__image\" :class=\"{ 'is-empty': !row.image }\">\n <img v-if=\"row.image\" :src=\"row.image.thumb ?? row.image.url\" alt=\"\" loading=\"lazy\" />\n <wx-icon v-else name=\"image\" size=\"sm\" />\n </span>\n </template>\n\n <template #cell-name=\"{ row }\">\n <div class=\"wx-catalog-products__name\">\n <span class=\"wx-catalog-products__title\">{{ row.name }}</span>\n <span class=\"wx-catalog-products__sku\">{{ row.sku ?? '' }}</span>\n </div>\n </template>\n\n <template #cell-category=\"{ row }\">\n <wx-badge v-if=\"!row.category\" type=\"warning\" size=\"sm\" round>\n {{ t('product.no-category') }}\n </wx-badge>\n <wx-text v-else size=\"sm\" truncate :tone=\"row.category.deleted ? 'muted' : undefined\">\n {{ row.category.name }}\n </wx-text>\n </template>\n\n <template #cell-price=\"{ row }\">\n <span class=\"wx-catalog-products__price\">\n <span\n >{{ price(row.price) }}<small v-if=\"row.price != null\">{{ unit(row) }}</small></span\n >\n <s v-if=\"row.old_price != null\">{{ price(row.old_price) }}</s>\n </span>\n </template>\n\n <template v-for=\"column in extra\" :key=\"column.key\" #[`cell-x.${column.key}`]=\"{ row }\">\n <column-value :value=\"row.columns?.[column.key]\" />\n </template>\n\n <template #cell-state=\"{ row }\">\n <wx-tooltip v-if=\"row.is_published && !row.visible\" :content=\"t('panel.invisible')\">\n <wx-badge :type=\"stateType(row)\" dot size=\"sm\">{{ t(`states.${row.state}`) }}</wx-badge>\n </wx-tooltip>\n <wx-badge v-else :type=\"stateType(row)\" dot size=\"sm\">\n {{ t(`states.${row.state}`) }}\n </wx-badge>\n </template>\n\n <template #cell-updated_at=\"{ row }\">\n <wx-date :value=\"row.updated_at\" compact />\n </template>\n\n <template #cell-card=\"{ row }\">\n <wx-entity-card\n variant=\"plain\"\n :title=\"row.name\"\n :image=\"row.image?.thumb ?? row.image?.url ?? undefined\"\n image-size=\"56px\"\n :title-lines=\"2\"\n :subtitle=\"row.sku ?? undefined\"\n >\n <template #meta>\n <wx-badge :type=\"stateType(row)\" dot size=\"sm\">{{\n t(`states.${row.state}`)\n }}</wx-badge>\n <wx-badge v-if=\"!row.category\" type=\"warning\" size=\"sm\" round>\n {{ t('product.no-category') }}\n </wx-badge>\n <wx-text v-if=\"priced && row.price != null\" size=\"sm\">\n {{ price(row.price) }}{{ unit(row) }}\n </wx-text>\n <!-- The satellites' values that are there; an empty one is not worth a dash on a card. -->\n <template v-for=\"column in extra\" :key=\"column.key\">\n <column-value\n v-if=\"hasValue(row.columns?.[column.key])\"\n :value=\"row.columns?.[column.key]\"\n />\n </template>\n </template>\n </wx-entity-card>\n </template>\n\n <template #cell-actions=\"{ row }\">\n <wx-row-menu :actions=\"actionsFor(row)\" :label=\"row.name\" />\n </template>\n </wx-table>\n </wx-list-screen>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-products {\n min-width: 0;\n}\n\n.wx-catalog-products__selection,\n.wx-catalog-products__corrected {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-12);\n padding: var(--wx-space-8) var(--wx-space-16);\n border-bottom: 1px solid var(--wx-border-default);\n background: var(--wx-bg-subtle);\n}\n\n.wx-catalog-products__notice {\n /* The card already pads the table: the notice keeps to the same edges. */\n margin-bottom: var(--wx-space-12);\n}\n\n.wx-catalog-products__image {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: var(--wx-radius-sm);\n overflow: clip;\n background: var(--wx-bg-subtle);\n color: var(--wx-text-muted);\n vertical-align: middle;\n}\n\n.wx-catalog-products__image img {\n width: 100%;\n height: 100%;\n min-width: 0;\n object-fit: cover;\n}\n\n.wx-catalog-products__name {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.wx-catalog-products__title {\n font-weight: var(--wx-font-weight-medium);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wx-catalog-products__sku {\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-sm);\n color: var(--wx-text-muted);\n min-height: 1em;\n}\n\n.wx-catalog-products__price {\n display: inline-flex;\n flex-direction: column;\n align-items: flex-end;\n font-variant-numeric: tabular-nums;\n}\n\n/* A price and its unit are one reading: '99 990 / pcs' broken over two lines reads as two facts. */\n.wx-catalog-products__price > * {\n white-space: nowrap;\n}\n\n.wx-catalog-products__price small,\n.wx-catalog-products__price s {\n font-size: var(--wx-font-size-sm);\n color: var(--wx-text-muted);\n}\n\n.wx-catalog-products__range {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--wx-space-8);\n}\n</style>\n"],"names":["props","__props","open","resolve","dismiss","useModal","context","useAdmin","tree","useCategoryTree","useCatalogMessages","t","useTranslate","values","reactive","ready","computed","param","onMounted","optionsOf","one","required","onCategory","value","apply","_createBlock","_unref","WxDialog","$event","_createVNode","WxSpace","WxButton","WxText","_createTextVNode","_toDisplayString","_openBlock","_createElementBlock","_Fragment","_renderList","WxFormItem","WxTreeSelect","WxSourceSelect","WxSelect","WxInput","POLL","emit","__emit","api","createCatalogApi","message","useErrorText","params","createModal","BulkParamsDialog","exporter","ExchangeExportDialog","router","useRouter","exportSelected","started","toast","actions","ref","run","starting","timer","running","refused","onBeforeUnmount","asks","action","start","given","answer","follow","error","poll","finish","id","_hoisted_1","WxDropdown","WxIcon","WxDropdownItem","_hoisted_2","WxProgress","_hoisted_3","_createElementVNode","_hoisted_4","CARDS","NAME","EXTRA","CATEGORY","PRICE","STATE","registry","useFacetRegistry","route","useRoute","admin","root","useTemplateRef","width","useElementWidth","page","loading","selected","everything","search","pageNumber","typedFor","corrected","fellBack","outgrown","perPage","create","ProductCreateDialog","canManage","canDelete","title","view","sorts","sort","asked","facets","chosen","readFacets","views","missing","priced","row","extra","asCards","categoryNames","flatten","node","CATEGORY_FROM","rowMenuWidth","extraFrom","index","columns","column","query","state","q","load","mine","onState","wanted","narrow","key","choice","FACET_PREFIX","writeFacet","order","clearFilters","rest","name","counted","options","valuesOf","valueLabel","facet","boundOf","end","bound","money","applied","said","emptyText","rangeOf","treeChoice","found","bulkSelection","facetsQuery","clearSelection","searchAsTyped","onBulkFinished","watch","product","add","detail","publish","on","remove","confirm","actionsFor","stateType","price","unit","hasValue","leads","WxListScreen","BulkBar","WxAlert","WxTable","WxInputNumber","WxSwitch","WxFilterChips","_withCtx","_normalizeClass","_hoisted_5","_hoisted_6","_hoisted_7","WxBadge","_hoisted_8","_hoisted_9","_hoisted_10","WxTooltip","WxDate","WxEntityCard","ColumnValue","WxRowMenu"],"mappings":"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"}