@panneau/lists 5.0.0-alpha.6 → 5.0.0-alpha.8
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/README.md +1 -1
- package/dist/ItemDetails.d.ts +5 -3
- package/dist/ItemDetails.d.ts.map +1 -1
- package/dist/ItemDetails.js +48 -6
- package/dist/ItemDetails.js.map +1 -1
- package/dist/List.d.ts +2 -2
- package/dist/List.js +54 -12
- package/dist/List.js.map +1 -1
- package/dist/ListSkeleton.d.ts +17 -0
- package/dist/ListSkeleton.d.ts.map +1 -0
- package/dist/ListSkeleton.js +111 -0
- package/dist/ListSkeleton.js.map +1 -0
- package/dist/ListView.d.ts +7 -4
- package/dist/ListView.d.ts.map +1 -1
- package/dist/ListView.js +494 -179
- package/dist/ListView.js.map +1 -1
- package/dist/actions/ActionButton.d.ts +1 -1
- package/dist/actions/ActionButton.js +79 -21
- package/dist/actions/ActionButton.js.map +1 -1
- package/dist/actions/ConfirmDialog.d.ts +1 -1
- package/dist/actions/ConfirmDialog.js +121 -24
- package/dist/actions/ConfirmDialog.js.map +1 -1
- package/dist/actions/RowActions.d.ts +2 -2
- package/dist/actions/RowActions.js +1 -1
- package/dist/actions/RowActions.js.map +1 -1
- package/dist/actions/actions.d.ts +1 -1
- package/dist/actions/actions.js.map +1 -1
- package/dist/actions/icons.js.map +1 -1
- package/dist/cx.js.map +1 -1
- package/dist/displays/displays.d.ts +1 -1
- package/dist/displays/displays.js +1 -1
- package/dist/displays/displays.js.map +1 -1
- package/dist/filters/Filters.d.ts +1 -1
- package/dist/filters/Filters.js +1 -1
- package/dist/filters/Filters.js.map +1 -1
- package/dist/filters/controls.d.ts +1 -1
- package/dist/filters/controls.js +1 -1
- package/dist/filters/controls.js.map +1 -1
- package/dist/filters/format.d.ts +1 -1
- package/dist/filters/format.js.map +1 -1
- package/dist/index.d.ts +19 -19
- package/dist/layouts/CardsLayout.d.ts +1 -1
- package/dist/layouts/CardsLayout.js +1 -1
- package/dist/layouts/CardsLayout.js.map +1 -1
- package/dist/layouts/ItemTitle.js +20 -7
- package/dist/layouts/ItemTitle.js.map +1 -1
- package/dist/layouts/TableLayout.d.ts +1 -1
- package/dist/layouts/TableLayout.js +1 -1
- package/dist/layouts/TableLayout.js.map +1 -1
- package/dist/layouts/builtIn.d.ts +1 -1
- package/dist/layouts/builtIn.js.map +1 -1
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/query.d.ts +1 -1
- package/dist/query.js.map +1 -1
- package/dist/selection.d.ts +1 -1
- package/dist/selection.js.map +1 -1
- package/dist/toolbar/LayoutSwitch.js +1 -1
- package/dist/toolbar/LayoutSwitch.js.map +1 -1
- package/dist/toolbar/Pagination.js +152 -41
- package/dist/toolbar/Pagination.js.map +1 -1
- package/dist/toolbar/SearchField.js +1 -1
- package/dist/toolbar/SearchField.js.map +1 -1
- package/dist/toolbar/SortSelect.d.ts +1 -1
- package/dist/toolbar/SortSelect.js +1 -1
- package/dist/toolbar/SortSelect.js.map +1 -1
- package/dist/useDraft.js.map +1 -1
- package/dist/useListState.js.map +1 -1
- package/dist/useRenderValue.d.ts +1 -1
- package/dist/useRenderValue.js +1 -1
- package/dist/useRenderValue.js.map +1 -1
- package/dist/values.d.ts +1 -1
- package/dist/values.js.map +1 -1
- package/package.json +9 -9
package/dist/ListView.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListView.js","names":["action","item","event","selection","column","id","next","skipped","styles"],"sources":["../src/ListView.tsx"],"sourcesContent":["import { type ReactNode, useRef, useState } from 'react';\n\nimport type { List } from '@panneau/core';\nimport { usePlugins } from '@panneau/core';\nimport type { Action, Field, Filter } from '@panneau/protocol';\nimport { Alert, Button, Checkbox, Spinner, usePanneauIntl, useToast } from '@panneau/ui';\n\nimport styles from './ListView.module.css';\nimport { ActionButton } from './actions/ActionButton';\nimport { ConfirmDialog, type ConfirmPreview, needsConfirmation } from './actions/ConfirmDialog';\nimport { RowActions } from './actions/RowActions';\nimport {\n type ListActions,\n getActionHref,\n groupListActions,\n hasScope,\n isAllowedOn,\n} from './actions/actions';\nimport type { ActionIcons } from './actions/icons';\nimport { cx } from './cx';\nimport { FilterChips, FilterControls, useFilterLabels } from './filters/Filters';\nimport { builtInLayouts } from './layouts/builtIn';\nimport { messages } from './messages';\nimport { countSelected, getPageSelection, isItemSelected } from './selection';\nimport { LayoutSwitch } from './toolbar/LayoutSwitch';\nimport { Pagination } from './toolbar/Pagination';\nimport { SearchField } from './toolbar/SearchField';\nimport { SortSelect } from './toolbar/SortSelect';\nimport type {\n DisplayEntry,\n FilterEntry,\n ListActionEvent,\n ListActionHandler,\n ListActionPreviewer,\n ListColumn,\n ListItem,\n ListLayoutEntry,\n} from './types';\nimport { useListState } from './useListState';\nimport { useRenderValue } from './useRenderValue';\nimport { getColumnValue, toText } from './values';\n\nexport interface ListViewProps {\n /** The list state of `@panneau/core` (`useList()`): query and selection. */\n list: List;\n /** The items of the current page. `undefined` while they load for the first time. */\n items: readonly ListItem[] | undefined;\n columns: readonly ListColumn[];\n /**\n * How many items match the query, on every page (`meta.total`). With it, the list shows\n * pagination and offers to select every matching item. Without it, `items` is the whole list.\n */\n total?: number | undefined;\n /** Shows that items are loading. Items already shown stay, dimmed. */\n isLoading?: boolean;\n /** An error while loading: an alert with a retry replaces the items. */\n error?: Error | null;\n onRetry?: () => void;\n /** Filter controls, with chips for the active filters. */\n filters?: readonly Filter[];\n /** Fields of the items, for the labels and options of filters that are not columns. */\n fields?: readonly Field[];\n /** Shows a search field (`q`). */\n search?: boolean;\n /** Layouts to choose from, the first one being the default. Defaults to `['table']`. */\n layouts?: readonly string[];\n /** The layout, controlled. */\n layout?: string;\n onLayoutChange?: (layout: string) => void;\n /** Page sizes to choose from. */\n perPageOptions?: readonly number[];\n /** Shows checkboxes. Defaults to whether there are selection actions. */\n selectable?: boolean;\n /**\n * Actions: a list (placed by their `placement`, or by scope), or grouped by placement as\n * `resolveList()` does. Those the user can't run (`abilities.run`) are hidden.\n */\n actions?: ListActions;\n /** Runs an action, after its confirmation. */\n onAction?: ListActionHandler;\n /**\n * Asks the backend how many items of a query selection (\"Select all N items\") an action will\n * skip, before the confirmation: the list only knows the abilities of the current page. Only\n * for actions with `dryRun`. `useActionPreview()` of `@panneau/actions` is one.\n */\n previewAction?: ListActionPreviewer;\n /**\n * Icons of actions by action id (`{ archive: Archive }`), for actions written in code. They\n * win over the Lucide icon an action names (`\"icon\": \"archive\"`).\n */\n actionIcons?: ActionIcons;\n /** The field that titles items, for their label (`itemTitle` of the resource). */\n itemTitle?: string;\n /** The label of an item, for checkboxes and actions. Defaults to its title, then its id. */\n getItemLabel?: (item: ListItem) => string;\n /** A link to an item, on its title. */\n getItemHref?: (item: ListItem) => string | null;\n /**\n * The item shown next to the list, such as in a panel of its details: its row is marked, and\n * the link of its title is the current page.\n */\n currentItemId?: string | null;\n /** Displays by name, over the built-in ones and those of the plugins. */\n displays?: Readonly<Record<string, DisplayEntry>>;\n /** Layouts by id, over the built-in ones and those of the plugins. */\n layoutComponents?: Readonly<Record<string, ListLayoutEntry>>;\n /** Filter controls by filter type, over the built-in ones. */\n filterControls?: Readonly<Record<string, FilterEntry>>;\n /** Content at the end of the toolbar, such as a button to create an item. */\n toolbar?: ReactNode;\n /** Shown when the list has no items, without filters or search. */\n emptyMessage?: ReactNode;\n /** Accessible name of the list. Defaults to \"Items\". */\n 'aria-label'?: string;\n className?: string;\n}\n\nfunction keyOf(action: Action, item?: ListItem): string {\n return item !== undefined ? `${action.id}\\u0000${item.id}` : action.id;\n}\n\n/**\n * Renders the list state of `@panneau/core`: the items of the current page in a layout (table or\n * cards), with sorting, search, filters and their chips, pagination, selection and actions. It\n * fetches nothing: the caller gives the items of the list's query and their total.\n */\nexport function ListView({\n list,\n items,\n columns,\n total,\n isLoading = false,\n error = null,\n onRetry,\n filters = [],\n fields = [],\n search = false,\n layouts: layoutsProp = ['table'],\n layout: controlledLayout,\n onLayoutChange,\n perPageOptions,\n selectable: selectableProp,\n actions: actionsProp,\n onAction,\n previewAction,\n actionIcons,\n itemTitle,\n getItemLabel: getItemLabelProp,\n getItemHref,\n currentItemId = null,\n displays,\n layoutComponents,\n filterControls,\n toolbar,\n emptyMessage,\n 'aria-label': ariaLabel,\n className,\n}: ListViewProps) {\n const intl = usePanneauIntl();\n const toasts = useToast();\n const plugins = usePlugins();\n const { query, selection } = useListState(list);\n const filterLabels = useFilterLabels();\n const [uncontrolledLayout, setLayout] = useState<string | null>(null);\n const [confirming, setConfirming] = useState<ListActionEvent | null>(null);\n const [preview, setPreview] = useState<ConfirmPreview | null>(null);\n // The confirmation a dry run belongs to: a later one, or a cancel, discards its answer.\n const confirmation = useRef(0);\n const [pending, setPending] = useState<string | null>(null);\n\n const label = ariaLabel ?? intl.formatMessage(messages.list);\n const pageItems = items ?? [];\n const count = total ?? pageItems.length;\n const sort = query.sort ?? [];\n const filterValues = query.filter ?? {};\n const hasQuery = Object.keys(filterValues).length > 0 || (query.q ?? '') !== '';\n\n const allLayouts: Record<string, ListLayoutEntry> = {\n ...builtInLayouts,\n ...(Object.fromEntries(plugins.listLayouts) as Record<string, ListLayoutEntry>),\n ...layoutComponents,\n };\n // Layouts without a component (a plugin's that isn't installed) are left out.\n const available = layoutsProp.filter((id) => allLayouts[id] !== undefined);\n const layouts = available.length > 0 ? available : ['table'];\n const layout = controlledLayout ?? uncontrolledLayout ?? layouts[0] ?? 'table';\n const Layout = allLayouts[layout] ?? builtInLayouts.table;\n\n const grouped = groupListActions(actionsProp);\n const rowActions = grouped.row.filter((action) => hasScope(action, 'item'));\n const rowMenu = grouped.menu.filter((action) => hasScope(action, 'item'));\n // Actions placed in the menu also apply to selections, from the toolbar (once each).\n const toolbarActions = [...grouped.toolbar, ...grouped.menu].filter(\n (action, index, all) =>\n (hasScope(action, 'selection') || hasScope(action, 'resource')) &&\n all.findIndex((candidate) => candidate.id === action.id) === index,\n );\n const selectionActions = toolbarActions.filter((action) => hasScope(action, 'selection'));\n const resourceActions = toolbarActions.filter((action) => hasScope(action, 'resource'));\n const selectable = selectableProp ?? selectionActions.length > 0;\n\n const selectedCount = selectable ? countSelected(selection, count) : 0;\n const selectedItems = pageItems.filter((item) => isItemSelected(selection, item.id));\n const pageSelection = getPageSelection(selection, pageItems);\n\n const getItemLabel = (item: ListItem): string => {\n if (getItemLabelProp !== undefined) {\n return getItemLabelProp(item);\n }\n const titleColumn =\n columns.find((column) => column.id === itemTitle) ??\n (itemTitle === undefined ? columns[0] : undefined);\n const title =\n titleColumn !== undefined\n ? toText(getColumnValue(item, titleColumn, intl.locale), intl.locale)\n : itemTitle !== undefined\n ? toText(item[itemTitle], intl.locale)\n : '';\n return title !== '' ? title : item.id;\n };\n\n const renderValue = useRenderValue(displays);\n\n const closeConfirmation = () => {\n confirmation.current += 1;\n setConfirming(null);\n setPreview(null);\n };\n\n const execute = async (event: ListActionEvent) => {\n closeConfirmation();\n setPending(keyOf(event.action, event.item));\n try {\n const outcome = await onAction?.(event);\n // `false`: the action didn't run (its parameters were cancelled).\n if (event.scope === 'selection' && outcome !== false) {\n list.clearSelection();\n }\n } catch (caught) {\n toasts.show({\n title: intl.formatMessage(messages.actionFailed, { action: event.action.label }),\n ...(caught instanceof Error && caught.message !== ''\n ? { description: caught.message }\n : {}),\n tone: 'danger',\n });\n } finally {\n setPending(null);\n }\n };\n\n const run = (event: ListActionEvent) => {\n const { action, selection } = event;\n if (\n previewAction !== undefined &&\n action.dryRun === true &&\n selection !== undefined &&\n 'query' in selection\n ) {\n // Every item matching a query: only the backend knows how many it would skip.\n const current = ++confirmation.current;\n const asks = action.confirm !== undefined && action.confirm !== false;\n setConfirming(event);\n setPreview({ status: 'loading' });\n previewAction(event).then(\n (result) => {\n if (confirmation.current !== current) {\n return;\n }\n const skipped = result?.skipped ?? event.skipped.length;\n if (skipped === 0 && !asks) {\n void execute(event);\n } else {\n setPreview(result !== null ? { status: 'done', ...result } : null);\n }\n },\n () => {\n // Without an answer, the list confirms with what it knows.\n if (confirmation.current !== current) {\n return;\n }\n if (needsConfirmation(event)) {\n setPreview(null);\n } else {\n void execute(event);\n }\n },\n );\n return;\n }\n if (needsConfirmation(event)) {\n setConfirming(event);\n } else {\n void execute(event);\n }\n };\n\n const runOnItem = (action: Action, item: ListItem) =>\n run({ action, scope: 'item', item, count: 1, skipped: [] });\n\n const runOnSelection = (action: Action) => {\n const selected = list.getSelection();\n if (selected === null) {\n return;\n }\n run({\n action,\n scope: 'selection',\n selection: selected,\n count: selectedCount,\n skipped: selectedItems.filter((item) => !isAllowedOn(action, item)),\n });\n };\n\n const runOnResource = (action: Action) =>\n run({ action, scope: 'resource', count: count, skipped: [] });\n\n const renderActions = (item: ListItem): ReactNode => {\n const allowed = rowActions.filter((action) => isAllowedOn(action, item));\n const menu = rowMenu.filter((action) => isAllowedOn(action, item));\n if (allowed.length === 0 && menu.length === 0) {\n return null;\n }\n const running =\n pending?.endsWith(`\\u0000${item.id}`) === true ? pending.split('\\u0000')[0] : null;\n return (\n <RowActions\n item={item}\n itemLabel={getItemLabel(item)}\n actions={allowed}\n menu={menu}\n pending={running ?? null}\n onRun={(action) => runOnItem(action, item)}\n icons={actionIcons}\n />\n );\n };\n\n const pageCheckbox = (\n <Checkbox\n aria-label={intl.formatMessage(messages.selectPage)}\n isSelected={pageSelection === 'all'}\n isIndeterminate={pageSelection === 'some'}\n isDisabled={pageItems.length === 0}\n onChange={() => {\n const ids = pageItems.map((item) => item.id);\n if (pageSelection === 'all') {\n list.deselect(ids);\n } else {\n list.select(ids);\n }\n }}\n />\n );\n\n const sortable = columns.some((column) => column.sortable === true);\n const showToolbar =\n search ||\n filters.length > 0 ||\n sortable ||\n layouts.length > 1 ||\n resourceActions.length > 0 ||\n toolbar !== undefined;\n\n const body = (() => {\n if (error !== null) {\n return (\n <Alert\n tone=\"danger\"\n title={intl.formatMessage(messages.loadFailed)}\n actions={\n onRetry !== undefined ? (\n <Button size=\"sm\" onPress={onRetry}>\n {intl.formatMessage(messages.retry)}\n </Button>\n ) : undefined\n }\n >\n {error.message}\n </Alert>\n );\n }\n if (items === undefined) {\n return (\n <div className={styles.state}>\n <Spinner showLabel />\n </div>\n );\n }\n if (pageItems.length === 0) {\n return (\n <div className={styles.state}>\n <p>\n {hasQuery\n ? intl.formatMessage(messages.noResults)\n : (emptyMessage ?? intl.formatMessage(messages.empty))}\n </p>\n {hasQuery ? (\n <Button size=\"sm\" onPress={() => clearFilters()}>\n {intl.formatMessage(messages.clearFilters)}\n </Button>\n ) : null}\n </div>\n );\n }\n return (\n <Layout\n items={pageItems}\n columns={columns}\n renderValue={renderValue}\n getItemLabel={getItemLabel}\n getItemHref={getItemHref}\n isCurrent={(item) => item.id === currentItemId}\n selectable={selectable}\n isSelected={(item) => isItemSelected(selection, item.id)}\n onToggle={(item) => list.toggle(item.id)}\n renderActions={renderActions}\n sort={sort}\n onSort={(column) => list.toggleSort(column.id)}\n label={label}\n pageSelection={pageCheckbox}\n />\n );\n })();\n\n function clearFilters() {\n Object.keys(filterValues).forEach((id) => list.setFilter(id, undefined));\n if ((query.q ?? '') !== '') {\n list.setSearch('');\n }\n }\n\n return (\n <div className={cx(styles.list, className)}>\n {showToolbar ? (\n <div className={styles.toolbar}>\n <div className={styles.toolbarStart}>\n {search ? (\n <SearchField\n value={query.q ?? ''}\n onChange={(q) => list.setSearch(q)}\n />\n ) : null}\n {filters.length > 0 ? (\n <FilterControls\n filters={filters}\n values={filterValues}\n onChange={(id, value) => list.setFilter(id, value)}\n onLabel={filterLabels.remember}\n controls={filterControls}\n columns={columns}\n fields={fields}\n labels={filterLabels.labels}\n />\n ) : null}\n </div>\n <div className={styles.toolbarEnd}>\n {sortable ? (\n <div className={layout === 'table' ? styles.tableSort : undefined}>\n <SortSelect\n columns={columns}\n sort={sort}\n onChange={(next) => list.setSort(next)}\n />\n </div>\n ) : null}\n {layouts.length > 1 ? (\n <LayoutSwitch\n layouts={layouts}\n value={layout}\n onChange={(next) => {\n setLayout(next);\n onLayoutChange?.(next);\n }}\n />\n ) : null}\n {resourceActions\n .filter(\n (action) => selectedCount === 0 || !hasScope(action, 'selection'),\n )\n .map((action) => (\n <ActionButton\n key={action.id}\n action={action}\n icons={actionIcons}\n size=\"md\"\n href={getActionHref(action)}\n isPending={pending === keyOf(action)}\n onPress={() => runOnResource(action)}\n />\n ))}\n {toolbar}\n </div>\n </div>\n ) : null}\n <FilterChips\n filters={filters}\n values={filterValues}\n q={query.q}\n onRemove={(id) => list.setFilter(id, undefined)}\n onClearSearch={() => list.setSearch('')}\n onClear={clearFilters}\n columns={columns}\n fields={fields}\n labels={filterLabels.labels}\n />\n {selectedCount > 0 ? (\n <div className={styles.selection}>\n <span className={styles.selectionCount} role=\"status\">\n {selection.mode === 'all'\n ? intl.formatMessage(messages.allMatchingSelected, {\n total: selectedCount,\n })\n : intl.formatMessage(messages.selectedCount, { count: selectedCount })}\n </span>\n {selection.mode === 'ids' &&\n pageSelection === 'all' &&\n count > pageItems.length ? (\n <Button size=\"sm\" variant=\"ghost\" onPress={() => list.selectAllMatching()}>\n {intl.formatMessage(messages.selectAllMatching, { total: count })}\n </Button>\n ) : null}\n <Button size=\"sm\" variant=\"ghost\" onPress={() => list.clearSelection()}>\n {intl.formatMessage(messages.clearSelection)}\n </Button>\n {selectionActions.length > 0 ? (\n <div className={styles.selectionActions}>\n {selectionActions.map((action) => {\n const skipped = selectedItems.filter(\n (item) => !isAllowedOn(action, item),\n ).length;\n return (\n <ActionButton\n key={action.id}\n action={action}\n icons={actionIcons}\n size=\"md\"\n href={null}\n isPending={pending === keyOf(action)}\n isDisabled={\n (pending !== null && pending !== keyOf(action)) ||\n skipped >= selectedCount\n }\n onPress={() => runOnSelection(action)}\n />\n );\n })}\n </div>\n ) : null}\n </div>\n ) : null}\n <div className={styles.body} aria-busy={isLoading && items !== undefined}>\n {body}\n </div>\n {total !== undefined && error === null && total > 0 ? (\n <Pagination\n page={query.page ?? 1}\n perPage={query.perPage ?? pageItems.length}\n total={total}\n onPageChange={(page) => list.setPage(page)}\n perPageOptions={perPageOptions}\n onPerPageChange={(perPage) => list.setPerPage(perPage)}\n />\n ) : null}\n <ConfirmDialog\n event={confirming}\n preview={preview}\n onConfirm={(event) => void execute(event)}\n onCancel={closeConfirmation}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ListView.js","names":["ReactNode","useRef","useState","List","usePlugins","Action","Field","Filter","Alert","Button","Checkbox","usePanneauIntl","useToast","ListSkeleton","styles","ActionButton","ConfirmDialog","ConfirmPreview","needsConfirmation","RowActions","ListActions","getActionHref","groupListActions","hasScope","isAllowedOn","ActionIcons","cx","FilterChips","FilterControls","useFilterLabels","builtInLayouts","messages","countSelected","getPageSelection","isItemSelected","LayoutSwitch","Pagination","SearchField","SortSelect","DisplayEntry","FilterEntry","ListActionEvent","ListActionHandler","ListActionPreviewer","ListColumn","ListItem","ListLayoutEntry","useListState","useRenderValue","getColumnValue","toText","ListViewProps","list","items","columns","total","isLoading","error","Error","onRetry","filters","fields","search","layouts","layout","onLayoutChange","perPageOptions","selectable","actions","onAction","previewAction","actionIcons","itemTitle","getItemLabel","item","getItemHref","currentItemId","displays","Readonly","Record","layoutComponents","filterControls","toolbar","emptyMessage","className","keyOf","action","undefined","id","ListView","t0","$","_c","t1","t2","t3","t4","t5","t6","controlledLayout","selectableProp","actionsProp","getItemLabelProp","t7","ariaLabel","t8","t9","t10","layoutsProp","intl","toasts","plugins","query","selection","filterLabels","uncontrolledLayout","setLayout","confirming","setConfirming","preview","setPreview","confirmation","pending","setPending","t11","formatMessage","label","pageItems","count","length","t12","sort","t13","filter","filterValues","t14","q","Object","keys","hasQuery","t15","listLayouts","fromEntries","t16","t17","allLayouts","t18","t19","available","Layout","table","grouped","rowActions","row","_temp","rowMenu","menu","_temp2","toolbarActions","_temp3","selectionActions","_temp4","resourceActions","_temp5","selectedCount","t20","selectedItems","pageSelection","t21","locale","item_0","titleColumn","find","column","title","renderValue","closeConfirmation","current","execute","event","Promise","resolve","then","outcome","scope","clearSelection","catch","caught","show","actionFailed","message","description","tone","run","event_0","action_4","selection_0","dryRun","asks","confirm","status","result","skipped","runOnItem","action_5","item_1","runOnSelection","action_6","selected","getSelection","item_2","runOnResource","action_7","renderActions","item_3","allowed","action_8","action_9","running","endsWith","split","action_10","t22","selectPage","pageCheckbox","ids","map","_temp6","deselect","select","sortable","some","_temp7","showToolbar","t23","clearFilters","forEach","id_0","setFilter","setSearch","t24","bb0","t25","loadFailed","t26","retry","t27","perPage","noResults","empty","t28","state","item_5","item_6","item_7","toggle","column_1","toggleSort","body","toolbarStart","id_1","value","remember","labels","toolbarEnd","tableSort","next","setSort","next_0","action_11","action_12","id_2","t29","t30","selectionCount","mode","allMatchingSelected","selectAllMatching","action_13","skipped_0","item_8","t31","t32","t33","page","setPage","setPerPage","t34","event_1","t35","t36","column_0","item_4","action_3","action_2","action_1","index","all","findIndex","candidate","action_0","_c","styles"],"sources":["../src/ListView.tsx"],"sourcesContent":["import { type ReactNode, useRef, useState } from 'react';\n\nimport type { List } from '@panneau/core';\nimport { usePlugins } from '@panneau/core';\nimport type { Action, Field, Filter } from '@panneau/protocol';\nimport { Alert, Button, Checkbox, usePanneauIntl, useToast } from '@panneau/ui';\n\nimport { ListSkeleton } from './ListSkeleton';\nimport styles from './ListView.module.css';\nimport { ActionButton } from './actions/ActionButton';\nimport { ConfirmDialog, type ConfirmPreview, needsConfirmation } from './actions/ConfirmDialog';\nimport { RowActions } from './actions/RowActions';\nimport {\n type ListActions,\n getActionHref,\n groupListActions,\n hasScope,\n isAllowedOn,\n} from './actions/actions';\nimport type { ActionIcons } from './actions/icons';\nimport { cx } from './cx';\nimport { FilterChips, FilterControls, useFilterLabels } from './filters/Filters';\nimport { builtInLayouts } from './layouts/builtIn';\nimport { messages } from './messages';\nimport { countSelected, getPageSelection, isItemSelected } from './selection';\nimport { LayoutSwitch } from './toolbar/LayoutSwitch';\nimport { Pagination } from './toolbar/Pagination';\nimport { SearchField } from './toolbar/SearchField';\nimport { SortSelect } from './toolbar/SortSelect';\nimport type {\n DisplayEntry,\n FilterEntry,\n ListActionEvent,\n ListActionHandler,\n ListActionPreviewer,\n ListColumn,\n ListItem,\n ListLayoutEntry,\n} from './types';\nimport { useListState } from './useListState';\nimport { useRenderValue } from './useRenderValue';\nimport { getColumnValue, toText } from './values';\n\nexport interface ListViewProps {\n /** The list state of `@panneau/core` (`useList()`): query and selection. */\n list: List;\n /**\n * The items of the current page. `undefined` while they load for the first time: the list\n * draws a skeleton of its rows, from its columns and its page size.\n */\n items: readonly ListItem[] | undefined;\n columns: readonly ListColumn[];\n /**\n * How many items match the query, on every page (`meta.total`). With it, the list shows\n * pagination and offers to select every matching item. Without it, `items` is the whole list.\n */\n total?: number | undefined;\n /** Shows that items are loading. Items already shown stay, dimmed. */\n isLoading?: boolean;\n /** An error while loading: an alert with a retry replaces the items. */\n error?: Error | null;\n onRetry?: () => void;\n /** Filter controls, with chips for the active filters. */\n filters?: readonly Filter[];\n /** Fields of the items, for the labels and options of filters that are not columns. */\n fields?: readonly Field[];\n /** Shows a search field (`q`). */\n search?: boolean;\n /** Layouts to choose from, the first one being the default. Defaults to `['table']`. */\n layouts?: readonly string[];\n /** The layout, controlled. */\n layout?: string;\n onLayoutChange?: (layout: string) => void;\n /** Page sizes to choose from. */\n perPageOptions?: readonly number[];\n /** Shows checkboxes. Defaults to whether there are selection actions. */\n selectable?: boolean;\n /**\n * Actions: a list (placed by their `placement`, or by scope), or grouped by placement as\n * `resolveList()` does. Those the user can't run (`abilities.run`) are hidden.\n */\n actions?: ListActions;\n /** Runs an action, after its confirmation. */\n onAction?: ListActionHandler;\n /**\n * Asks the backend how many items of a query selection (\"Select all N items\") an action will\n * skip, before the confirmation: the list only knows the abilities of the current page. Only\n * for actions with `dryRun`. `useActionPreview()` of `@panneau/actions` is one.\n */\n previewAction?: ListActionPreviewer;\n /**\n * Icons of actions by action id (`{ archive: Archive }`), for actions written in code. They\n * win over the Lucide icon an action names (`\"icon\": \"archive\"`).\n */\n actionIcons?: ActionIcons;\n /** The field that titles items, for their label (`itemTitle` of the resource). */\n itemTitle?: string;\n /** The label of an item, for checkboxes and actions. Defaults to its title, then its id. */\n getItemLabel?: (item: ListItem) => string;\n /** A link to an item, on its title. */\n getItemHref?: (item: ListItem) => string | null;\n /**\n * The item shown next to the list, such as in a panel of its details: its row is marked, and\n * the link of its title is the current page.\n */\n currentItemId?: string | null;\n /** Displays by name, over the built-in ones and those of the plugins. */\n displays?: Readonly<Record<string, DisplayEntry>>;\n /** Layouts by id, over the built-in ones and those of the plugins. */\n layoutComponents?: Readonly<Record<string, ListLayoutEntry>>;\n /** Filter controls by filter type, over the built-in ones. */\n filterControls?: Readonly<Record<string, FilterEntry>>;\n /** Content at the end of the toolbar, such as a button to create an item. */\n toolbar?: ReactNode;\n /** Shown when the list has no items, without filters or search. */\n emptyMessage?: ReactNode;\n /** Accessible name of the list. Defaults to \"Items\". */\n 'aria-label'?: string;\n className?: string;\n}\n\nfunction keyOf(action: Action, item?: ListItem): string {\n return item !== undefined ? `${action.id}\\u0000${item.id}` : action.id;\n}\n\n/**\n * Renders the list state of `@panneau/core`: the items of the current page in a layout (table or\n * cards), with sorting, search, filters and their chips, pagination, selection and actions. It\n * fetches nothing: the caller gives the items of the list's query and their total.\n */\nexport function ListView({\n list,\n items,\n columns,\n total,\n isLoading = false,\n error = null,\n onRetry,\n filters = [],\n fields = [],\n search = false,\n layouts: layoutsProp = ['table'],\n layout: controlledLayout,\n onLayoutChange,\n perPageOptions,\n selectable: selectableProp,\n actions: actionsProp,\n onAction,\n previewAction,\n actionIcons,\n itemTitle,\n getItemLabel: getItemLabelProp,\n getItemHref,\n currentItemId = null,\n displays,\n layoutComponents,\n filterControls,\n toolbar,\n emptyMessage,\n 'aria-label': ariaLabel,\n className,\n}: ListViewProps) {\n const intl = usePanneauIntl();\n const toasts = useToast();\n const plugins = usePlugins();\n const { query, selection } = useListState(list);\n const filterLabels = useFilterLabels();\n const [uncontrolledLayout, setLayout] = useState<string | null>(null);\n const [confirming, setConfirming] = useState<ListActionEvent | null>(null);\n const [preview, setPreview] = useState<ConfirmPreview | null>(null);\n // The confirmation a dry run belongs to: a later one, or a cancel, discards its answer.\n const confirmation = useRef(0);\n const [pending, setPending] = useState<string | null>(null);\n\n const label = ariaLabel ?? intl.formatMessage(messages.list);\n const pageItems = items ?? [];\n const count = total ?? pageItems.length;\n const sort = query.sort ?? [];\n const filterValues = query.filter ?? {};\n const hasQuery = Object.keys(filterValues).length > 0 || (query.q ?? '') !== '';\n\n const allLayouts: Record<string, ListLayoutEntry> = {\n ...builtInLayouts,\n ...(Object.fromEntries(plugins.listLayouts) as Record<string, ListLayoutEntry>),\n ...layoutComponents,\n };\n // Layouts without a component (a plugin's that isn't installed) are left out.\n const available = layoutsProp.filter((id) => allLayouts[id] !== undefined);\n const layouts = available.length > 0 ? available : ['table'];\n const layout = controlledLayout ?? uncontrolledLayout ?? layouts[0] ?? 'table';\n const Layout = allLayouts[layout] ?? builtInLayouts.table;\n\n const grouped = groupListActions(actionsProp);\n const rowActions = grouped.row.filter((action) => hasScope(action, 'item'));\n const rowMenu = grouped.menu.filter((action) => hasScope(action, 'item'));\n // Actions placed in the menu also apply to selections, from the toolbar (once each).\n const toolbarActions = [...grouped.toolbar, ...grouped.menu].filter(\n (action, index, all) =>\n (hasScope(action, 'selection') || hasScope(action, 'resource')) &&\n all.findIndex((candidate) => candidate.id === action.id) === index,\n );\n const selectionActions = toolbarActions.filter((action) => hasScope(action, 'selection'));\n const resourceActions = toolbarActions.filter((action) => hasScope(action, 'resource'));\n const selectable = selectableProp ?? selectionActions.length > 0;\n\n const selectedCount = selectable ? countSelected(selection, count) : 0;\n const selectedItems = pageItems.filter((item) => isItemSelected(selection, item.id));\n const pageSelection = getPageSelection(selection, pageItems);\n\n const getItemLabel = (item: ListItem): string => {\n if (getItemLabelProp !== undefined) {\n return getItemLabelProp(item);\n }\n const titleColumn =\n columns.find((column) => column.id === itemTitle) ??\n (itemTitle === undefined ? columns[0] : undefined);\n const title =\n titleColumn !== undefined\n ? toText(getColumnValue(item, titleColumn, intl.locale), intl.locale)\n : itemTitle !== undefined\n ? toText(item[itemTitle], intl.locale)\n : '';\n return title !== '' ? title : item.id;\n };\n\n const renderValue = useRenderValue(displays);\n\n const closeConfirmation = () => {\n confirmation.current += 1;\n setConfirming(null);\n setPreview(null);\n };\n\n const execute = async (event: ListActionEvent) => {\n closeConfirmation();\n setPending(keyOf(event.action, event.item));\n // A promise chain rather than `try`, which the React Compiler only handles in part.\n await Promise.resolve()\n .then(() => onAction?.(event))\n .then((outcome) => {\n // `false`: the action didn't run (its parameters were cancelled).\n if (event.scope === 'selection' && outcome !== false) {\n list.clearSelection();\n }\n })\n .catch((caught: unknown) => {\n toasts.show({\n title: intl.formatMessage(messages.actionFailed, {\n action: event.action.label,\n }),\n ...(caught instanceof Error && caught.message !== ''\n ? { description: caught.message }\n : {}),\n tone: 'danger',\n });\n });\n setPending(null);\n };\n\n const run = (event: ListActionEvent) => {\n const { action, selection } = event;\n if (\n previewAction !== undefined &&\n action.dryRun === true &&\n selection !== undefined &&\n 'query' in selection\n ) {\n // Every item matching a query: only the backend knows how many it would skip.\n const current = ++confirmation.current;\n const asks = action.confirm !== undefined && action.confirm !== false;\n setConfirming(event);\n setPreview({ status: 'loading' });\n previewAction(event).then(\n (result) => {\n if (confirmation.current !== current) {\n return;\n }\n const skipped = result?.skipped ?? event.skipped.length;\n if (skipped === 0 && !asks) {\n void execute(event);\n } else {\n setPreview(result !== null ? { status: 'done', ...result } : null);\n }\n },\n () => {\n // Without an answer, the list confirms with what it knows.\n if (confirmation.current !== current) {\n return;\n }\n if (needsConfirmation(event)) {\n setPreview(null);\n } else {\n void execute(event);\n }\n },\n );\n return;\n }\n if (needsConfirmation(event)) {\n setConfirming(event);\n } else {\n void execute(event);\n }\n };\n\n const runOnItem = (action: Action, item: ListItem) =>\n run({ action, scope: 'item', item, count: 1, skipped: [] });\n\n const runOnSelection = (action: Action) => {\n const selected = list.getSelection();\n if (selected === null) {\n return;\n }\n run({\n action,\n scope: 'selection',\n selection: selected,\n count: selectedCount,\n skipped: selectedItems.filter((item) => !isAllowedOn(action, item)),\n });\n };\n\n const runOnResource = (action: Action) =>\n run({ action, scope: 'resource', count: count, skipped: [] });\n\n const renderActions = (item: ListItem): ReactNode => {\n const allowed = rowActions.filter((action) => isAllowedOn(action, item));\n const menu = rowMenu.filter((action) => isAllowedOn(action, item));\n if (allowed.length === 0 && menu.length === 0) {\n return null;\n }\n const running =\n pending?.endsWith(`\\u0000${item.id}`) === true ? pending.split('\\u0000')[0] : null;\n return (\n <RowActions\n item={item}\n itemLabel={getItemLabel(item)}\n actions={allowed}\n menu={menu}\n pending={running ?? null}\n onRun={(action) => runOnItem(action, item)}\n icons={actionIcons}\n />\n );\n };\n\n const pageCheckbox = (\n <Checkbox\n aria-label={intl.formatMessage(messages.selectPage)}\n isSelected={pageSelection === 'all'}\n isIndeterminate={pageSelection === 'some'}\n isDisabled={pageItems.length === 0}\n onChange={() => {\n const ids = pageItems.map((item) => item.id);\n if (pageSelection === 'all') {\n list.deselect(ids);\n } else {\n list.select(ids);\n }\n }}\n />\n );\n\n const sortable = columns.some((column) => column.sortable === true);\n const showToolbar =\n search ||\n filters.length > 0 ||\n sortable ||\n layouts.length > 1 ||\n resourceActions.length > 0 ||\n toolbar !== undefined;\n\n function clearFilters() {\n Object.keys(filterValues).forEach((id) => list.setFilter(id, undefined));\n if ((query.q ?? '') !== '') {\n list.setSearch('');\n }\n }\n\n const body = (() => {\n if (error !== null) {\n return (\n <Alert\n tone=\"danger\"\n title={intl.formatMessage(messages.loadFailed)}\n actions={\n onRetry !== undefined ? (\n <Button size=\"sm\" onPress={onRetry}>\n {intl.formatMessage(messages.retry)}\n </Button>\n ) : undefined\n }\n >\n {error.message}\n </Alert>\n );\n }\n if (items === undefined) {\n return (\n <ListSkeleton\n Layout={Layout}\n columns={columns}\n perPage={query.perPage}\n sort={sort}\n label={label}\n />\n );\n }\n if (pageItems.length === 0) {\n return (\n <div className={styles.state}>\n <p>\n {hasQuery\n ? intl.formatMessage(messages.noResults)\n : (emptyMessage ?? intl.formatMessage(messages.empty))}\n </p>\n {hasQuery ? (\n <Button size=\"sm\" onPress={() => clearFilters()}>\n {intl.formatMessage(messages.clearFilters)}\n </Button>\n ) : null}\n </div>\n );\n }\n return (\n <Layout\n items={pageItems}\n columns={columns}\n renderValue={renderValue}\n getItemLabel={getItemLabel}\n getItemHref={getItemHref}\n isCurrent={(item) => item.id === currentItemId}\n selectable={selectable}\n isSelected={(item) => isItemSelected(selection, item.id)}\n onToggle={(item) => list.toggle(item.id)}\n renderActions={renderActions}\n sort={sort}\n onSort={(column) => list.toggleSort(column.id)}\n label={label}\n pageSelection={pageCheckbox}\n />\n );\n })();\n\n return (\n <div className={cx(styles.list, className)}>\n {showToolbar ? (\n <div className={styles.toolbar}>\n <div className={styles.toolbarStart}>\n {search ? (\n <SearchField\n value={query.q ?? ''}\n onChange={(q) => list.setSearch(q)}\n />\n ) : null}\n {filters.length > 0 ? (\n <FilterControls\n filters={filters}\n values={filterValues}\n onChange={(id, value) => list.setFilter(id, value)}\n onLabel={filterLabels.remember}\n controls={filterControls}\n columns={columns}\n fields={fields}\n labels={filterLabels.labels}\n />\n ) : null}\n </div>\n <div className={styles.toolbarEnd}>\n {sortable ? (\n <div className={layout === 'table' ? styles.tableSort : undefined}>\n <SortSelect\n columns={columns}\n sort={sort}\n onChange={(next) => list.setSort(next)}\n />\n </div>\n ) : null}\n {layouts.length > 1 ? (\n <LayoutSwitch\n layouts={layouts}\n value={layout}\n onChange={(next) => {\n setLayout(next);\n onLayoutChange?.(next);\n }}\n />\n ) : null}\n {resourceActions\n .filter(\n (action) => selectedCount === 0 || !hasScope(action, 'selection'),\n )\n .map((action) => (\n <ActionButton\n key={action.id}\n action={action}\n icons={actionIcons}\n size=\"md\"\n href={getActionHref(action)}\n isPending={pending === keyOf(action)}\n onPress={() => runOnResource(action)}\n />\n ))}\n {toolbar}\n </div>\n </div>\n ) : null}\n <FilterChips\n filters={filters}\n values={filterValues}\n q={query.q}\n onRemove={(id) => list.setFilter(id, undefined)}\n onClearSearch={() => list.setSearch('')}\n onClear={clearFilters}\n columns={columns}\n fields={fields}\n labels={filterLabels.labels}\n />\n {selectedCount > 0 ? (\n <div className={styles.selection}>\n <span className={styles.selectionCount} role=\"status\">\n {selection.mode === 'all'\n ? intl.formatMessage(messages.allMatchingSelected, {\n total: selectedCount,\n })\n : intl.formatMessage(messages.selectedCount, { count: selectedCount })}\n </span>\n {selection.mode === 'ids' &&\n pageSelection === 'all' &&\n count > pageItems.length ? (\n <Button size=\"sm\" variant=\"ghost\" onPress={() => list.selectAllMatching()}>\n {intl.formatMessage(messages.selectAllMatching, { total: count })}\n </Button>\n ) : null}\n <Button size=\"sm\" variant=\"ghost\" onPress={() => list.clearSelection()}>\n {intl.formatMessage(messages.clearSelection)}\n </Button>\n {selectionActions.length > 0 ? (\n <div className={styles.selectionActions}>\n {selectionActions.map((action) => {\n const skipped = selectedItems.filter(\n (item) => !isAllowedOn(action, item),\n ).length;\n return (\n <ActionButton\n key={action.id}\n action={action}\n icons={actionIcons}\n size=\"md\"\n href={null}\n isPending={pending === keyOf(action)}\n isDisabled={\n (pending !== null && pending !== keyOf(action)) ||\n skipped >= selectedCount\n }\n onPress={() => runOnSelection(action)}\n />\n );\n })}\n </div>\n ) : null}\n </div>\n ) : null}\n <div className={styles.body} aria-busy={isLoading && items !== undefined}>\n {body}\n </div>\n {total !== undefined && error === null && total > 0 ? (\n <Pagination\n page={query.page ?? 1}\n perPage={query.perPage ?? pageItems.length}\n total={total}\n onPageChange={(page) => list.setPage(page)}\n perPageOptions={perPageOptions}\n onPerPageChange={(perPage) => list.setPerPage(perPage)}\n />\n ) : null}\n <ConfirmDialog\n event={confirming}\n preview={preview}\n onConfirm={(event) => void execute(event)}\n onCancel={closeConfirmation}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,32 +1,90 @@
|
|
|
1
1
|
import Actions_module_default from "./Actions.module.js";
|
|
2
2
|
import { getActionIcon } from "./icons.js";
|
|
3
3
|
import { cx } from "../cx.js";
|
|
4
|
+
import { c } from "react/compiler-runtime";
|
|
4
5
|
import { Button, Icon } from "@panneau/ui";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
import { Link } from "react-aria-components";
|
|
7
8
|
//#region src/actions/ActionButton.tsx
|
|
8
9
|
/** An action as a button, or as a link for a `link` action with a URL. */
|
|
9
|
-
function ActionButton(
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
10
|
+
function ActionButton(t0) {
|
|
11
|
+
const $ = c(24);
|
|
12
|
+
const { action, icons, href, onPress, isPending: t1, isDisabled: t2, size: t3, "aria-label": ariaLabel } = t0;
|
|
13
|
+
const isPending = t1 === void 0 ? false : t1;
|
|
14
|
+
const isDisabled = t2 === void 0 ? false : t2;
|
|
15
|
+
const size = t3 === void 0 ? "sm" : t3;
|
|
16
|
+
let t4;
|
|
17
|
+
if ($[0] !== action || $[1] !== icons) {
|
|
18
|
+
t4 = getActionIcon(action, icons);
|
|
19
|
+
$[0] = action;
|
|
20
|
+
$[1] = icons;
|
|
21
|
+
$[2] = t4;
|
|
22
|
+
} else t4 = $[2];
|
|
23
|
+
const icon = t4;
|
|
24
|
+
if (href !== null) {
|
|
25
|
+
const t5 = size === "md" && Actions_module_default.linkMd;
|
|
26
|
+
let t6;
|
|
27
|
+
if ($[3] !== t5) {
|
|
28
|
+
t6 = cx(Actions_module_default.link, t5);
|
|
29
|
+
$[3] = t5;
|
|
30
|
+
$[4] = t6;
|
|
31
|
+
} else t6 = $[4];
|
|
32
|
+
let t7;
|
|
33
|
+
if ($[5] !== icon) {
|
|
34
|
+
t7 = icon !== void 0 ? /* @__PURE__ */ jsx(Icon, {
|
|
35
|
+
icon,
|
|
36
|
+
size: "sm"
|
|
37
|
+
}) : null;
|
|
38
|
+
$[5] = icon;
|
|
39
|
+
$[6] = t7;
|
|
40
|
+
} else t7 = $[6];
|
|
41
|
+
let t8;
|
|
42
|
+
if ($[7] !== action.label || $[8] !== ariaLabel || $[9] !== href || $[10] !== t6 || $[11] !== t7) {
|
|
43
|
+
t8 = /* @__PURE__ */ jsxs(Link, {
|
|
44
|
+
href,
|
|
45
|
+
"aria-label": ariaLabel,
|
|
46
|
+
className: t6,
|
|
47
|
+
children: [t7, action.label]
|
|
48
|
+
});
|
|
49
|
+
$[7] = action.label;
|
|
50
|
+
$[8] = ariaLabel;
|
|
51
|
+
$[9] = href;
|
|
52
|
+
$[10] = t6;
|
|
53
|
+
$[11] = t7;
|
|
54
|
+
$[12] = t8;
|
|
55
|
+
} else t8 = $[12];
|
|
56
|
+
return t8;
|
|
57
|
+
}
|
|
58
|
+
const t5 = action.destructive === true ? "danger" : size === "sm" ? "ghost" : "secondary";
|
|
59
|
+
let t6;
|
|
60
|
+
if ($[13] !== icon) {
|
|
61
|
+
t6 = icon !== void 0 ? { icon } : {};
|
|
62
|
+
$[13] = icon;
|
|
63
|
+
$[14] = t6;
|
|
64
|
+
} else t6 = $[14];
|
|
65
|
+
let t7;
|
|
66
|
+
if ($[15] !== action.label || $[16] !== ariaLabel || $[17] !== isDisabled || $[18] !== isPending || $[19] !== onPress || $[20] !== size || $[21] !== t5 || $[22] !== t6) {
|
|
67
|
+
t7 = /* @__PURE__ */ jsx(Button, {
|
|
68
|
+
size,
|
|
69
|
+
variant: t5,
|
|
70
|
+
...t6,
|
|
71
|
+
isPending,
|
|
72
|
+
isDisabled,
|
|
73
|
+
"aria-label": ariaLabel,
|
|
74
|
+
onPress,
|
|
75
|
+
children: action.label
|
|
76
|
+
});
|
|
77
|
+
$[15] = action.label;
|
|
78
|
+
$[16] = ariaLabel;
|
|
79
|
+
$[17] = isDisabled;
|
|
80
|
+
$[18] = isPending;
|
|
81
|
+
$[19] = onPress;
|
|
82
|
+
$[20] = size;
|
|
83
|
+
$[21] = t5;
|
|
84
|
+
$[22] = t6;
|
|
85
|
+
$[23] = t7;
|
|
86
|
+
} else t7 = $[23];
|
|
87
|
+
return t7;
|
|
30
88
|
}
|
|
31
89
|
//#endregion
|
|
32
90
|
export { ActionButton };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionButton.js","names":["styles"],"sources":["../../src/actions/ActionButton.tsx"],"sourcesContent":["import { Link } from 'react-aria-components';\n\nimport type { Action } from '@panneau/protocol';\nimport { Button, Icon } from '@panneau/ui';\n\nimport { cx } from '../cx';\nimport styles from './Actions.module.css';\nimport { type ActionIcons, getActionIcon } from './icons';\n\nexport interface ActionButtonProps {\n action: Action;\n /** Icons of actions by id, over the icon the action names. */\n icons?: ActionIcons | undefined;\n /** The link of a `link` action. Links go through React Aria, so an app's router handles them. */\n href: string | null;\n onPress: () => void;\n isPending?: boolean;\n isDisabled?: boolean;\n size?: 'sm' | 'md';\n /** Accessible label, when the label alone isn't enough (`Edit Ada Lovelace`). */\n 'aria-label'?: string;\n}\n\n/** An action as a button, or as a link for a `link` action with a URL. */\nexport function ActionButton({\n action,\n icons,\n href,\n onPress,\n isPending = false,\n isDisabled = false,\n size = 'sm',\n 'aria-label': ariaLabel,\n}: ActionButtonProps) {\n const icon = getActionIcon(action, icons);\n if (href !== null) {\n return (\n <Link\n href={href}\n aria-label={ariaLabel}\n className={cx(styles.link, size === 'md' && styles.linkMd)}\n >\n {icon !== undefined ? <Icon icon={icon} size=\"sm\" /> : null}\n {action.label}\n </Link>\n );\n }\n return (\n <Button\n size={size}\n variant={action.destructive === true ? 'danger' : size === 'sm' ? 'ghost' : 'secondary'}\n {...(icon !== undefined ? { icon } : {})}\n isPending={isPending}\n isDisabled={isDisabled}\n aria-label={ariaLabel}\n onPress={onPress}\n >\n {action.label}\n </Button>\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ActionButton.js","names":["Link","Action","Button","Icon","cx","styles","ActionIcons","getActionIcon","ActionButtonProps","action","icons","href","onPress","isPending","isDisabled","size","ActionButton","t0","$","_c","t1","t2","t3","ariaLabel","undefined","t4","icon","t5","linkMd","t6","link","t7","t8","label","destructive","_c","styles"],"sources":["../../src/actions/ActionButton.tsx"],"sourcesContent":["import { Link } from 'react-aria-components';\n\nimport type { Action } from '@panneau/protocol';\nimport { Button, Icon } from '@panneau/ui';\n\nimport { cx } from '../cx';\nimport styles from './Actions.module.css';\nimport { type ActionIcons, getActionIcon } from './icons';\n\nexport interface ActionButtonProps {\n action: Action;\n /** Icons of actions by id, over the icon the action names. */\n icons?: ActionIcons | undefined;\n /** The link of a `link` action. Links go through React Aria, so an app's router handles them. */\n href: string | null;\n onPress: () => void;\n isPending?: boolean;\n isDisabled?: boolean;\n size?: 'sm' | 'md';\n /** Accessible label, when the label alone isn't enough (`Edit Ada Lovelace`). */\n 'aria-label'?: string;\n}\n\n/** An action as a button, or as a link for a `link` action with a URL. */\nexport function ActionButton({\n action,\n icons,\n href,\n onPress,\n isPending = false,\n isDisabled = false,\n size = 'sm',\n 'aria-label': ariaLabel,\n}: ActionButtonProps) {\n const icon = getActionIcon(action, icons);\n if (href !== null) {\n return (\n <Link\n href={href}\n aria-label={ariaLabel}\n className={cx(styles.link, size === 'md' && styles.linkMd)}\n >\n {icon !== undefined ? <Icon icon={icon} size=\"sm\" /> : null}\n {action.label}\n </Link>\n );\n }\n return (\n <Button\n size={size}\n variant={action.destructive === true ? 'danger' : size === 'sm' ? 'ghost' : 'secondary'}\n {...(icon !== undefined ? { icon } : {})}\n isPending={isPending}\n isDisabled={isDisabled}\n aria-label={ariaLabel}\n onPress={onPress}\n >\n {action.label}\n </Button>\n );\n}\n"],"mappings":";;;;;;;;;AAwBA,SAAOgB,aAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAsB,MAAA,EAAAV,QAAAC,OAAAC,MAAAC,SAAAC,WAAAO,IAAAN,YAAAO,IAAAN,MAAAO,IAAA,cAAAC,cAAAN;CAKzB,MAAAJ,YAAAO,OAAAI,KAAAA,IAAA,QAAAJ;CACA,MAAAN,aAAAO,OAAAG,KAAAA,IAAA,QAAAH;CACA,MAAAN,OAAAO,OAAAE,KAAAA,IAAA,OAAAF;CAAW,IAAAG;CAAA,IAAAP,EAAA,OAAAT,UAAAS,EAAA,OAAAR,OAAA;EAGEe,KAAAlB,cAAcE,QAAQC,KAAK;EAACQ,EAAA,KAAAT;EAAAS,EAAA,KAAAR;EAAAQ,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAzC,MAAAQ,OAAaD;CACb,IAAId,SAAS,MAAI;EAKsB,MAAAgB,KAAAZ,SAAS,QAAQV,uBAAMuB;EAAO,IAAAC;EAAA,IAAAX,EAAA,OAAAS,IAAA;GAA9CE,KAAAzB,GAAGC,uBAAMyB,MAAOH,EAA8B;GAACT,EAAA,KAAAS;GAAAT,EAAA,KAAAW;EAAA,OAAAA,KAAAX,EAAA;EAAA,IAAAa;EAAA,IAAAb,EAAA,OAAAQ,MAAA;GAEzDK,KAAAL,SAASF,KAAAA,IAAY,oBAAC,MAAD;IAAYE;IAAW,MAAA;GAAI,CAAA,IAAhD;GAA0DR,EAAA,KAAAQ;GAAAR,EAAA,KAAAa;EAAA,OAAAA,KAAAb,EAAA;EAAA,IAAAc;EAAA,IAAAd,EAAA,OAAAT,OAAAwB,SAAAf,EAAA,OAAAK,aAAAL,EAAA,OAAAP,QAAAO,EAAA,QAAAW,MAAAX,EAAA,QAAAa,IAAA;GAL/DC,KAAA,qBAAC,MAAD;IACUrB;IACMY,cAAAA;IACD,WAAAM;IAHf,UAAA,CAKKE,IACAtB,OAAMwB,KANN;;GAOEf,EAAA,KAAAT,OAAAwB;GAAAf,EAAA,KAAAK;GAAAL,EAAA,KAAAP;GAAAO,EAAA,MAAAW;GAAAX,EAAA,MAAAa;GAAAb,EAAA,MAAAc;EAAA,OAAAA,KAAAd,EAAA;EAAA,OAPPc;CAOO;CAME,MAAAL,KAAAlB,OAAMyB,gBAAiB,OAAvB,WAAyCnB,SAAS,OAAT,UAAA;CAAqC,IAAAc;CAAA,IAAAX,EAAA,QAAAQ,MAAA;EAClFG,KAAAH,SAASF,KAAAA,IAAT,EAAAE,KAAiC,IAAjC,CAAiC;EAACR,EAAA,MAAAQ;EAAAR,EAAA,MAAAW;CAAA,OAAAA,KAAAX,EAAA;CAAA,IAAAa;CAAA,IAAAb,EAAA,QAAAT,OAAAwB,SAAAf,EAAA,QAAAK,aAAAL,EAAA,QAAAJ,cAAAI,EAAA,QAAAL,aAAAK,EAAA,QAAAN,WAAAM,EAAA,QAAAH,QAAAG,EAAA,QAAAS,MAAAT,EAAA,QAAAW,IAAA;EAH3CE,KAAA,oBAAC,QAAD;GACUhB;GACG,SAAAY;GAA8E,GAClFE;GACMhB;GACCC;GACAS,cAAAA;GACHX;GAERH,UAAAA,OAAMwB;EATJ,CAAA;EAUEf,EAAA,MAAAT,OAAAwB;EAAAf,EAAA,MAAAK;EAAAL,EAAA,MAAAJ;EAAAI,EAAA,MAAAL;EAAAK,EAAA,MAAAN;EAAAM,EAAA,MAAAH;EAAAG,EAAA,MAAAS;EAAAT,EAAA,MAAAW;EAAAX,EAAA,MAAAa;CAAA,OAAAA,KAAAb,EAAA;CAAA,OAVTa;AAUS"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ListActionEvent, ListActionPreview } from '../types';
|
|
1
|
+
import type { ListActionEvent, ListActionPreview } from '../types.js';
|
|
2
2
|
/** Whether an action needs a confirmation: it asks for one, or some selected items are skipped. */
|
|
3
3
|
export declare function needsConfirmation(event: ListActionEvent): boolean;
|
|
4
4
|
/** The dry run of a query selection: in progress, or done with the backend's count. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { messages } from "../messages.js";
|
|
2
2
|
import Actions_module_default from "./Actions.module.js";
|
|
3
|
+
import { c } from "react/compiler-runtime";
|
|
3
4
|
import { Button, Dialog, Spinner, usePanneauIntl } from "@panneau/ui";
|
|
4
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
//#region src/actions/ConfirmDialog.tsx
|
|
@@ -21,27 +22,52 @@ function needsConfirmation(event) {
|
|
|
21
22
|
* message with `{count}`), or default ones, and how many selected items will be skipped: those of
|
|
22
23
|
* the current page that don't allow it, or the backend's count for every item matching a query.
|
|
23
24
|
*/
|
|
24
|
-
function ConfirmDialog(
|
|
25
|
+
function ConfirmDialog(t0) {
|
|
26
|
+
const $ = c(42);
|
|
27
|
+
const { event, preview: t1, onConfirm, onCancel } = t0;
|
|
28
|
+
const preview = t1 === void 0 ? null : t1;
|
|
25
29
|
const intl = usePanneauIntl();
|
|
26
30
|
if (event === null) return null;
|
|
27
31
|
const { action, count } = event;
|
|
28
32
|
const loading = preview?.status === "loading";
|
|
29
33
|
const skipped = preview?.status === "done" ? preview.skipped : event.skipped.length;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
let T0;
|
|
35
|
+
let t10;
|
|
36
|
+
let t2;
|
|
37
|
+
let t3;
|
|
38
|
+
let t4;
|
|
39
|
+
let t5;
|
|
40
|
+
let t6;
|
|
41
|
+
let t7;
|
|
42
|
+
let t8;
|
|
43
|
+
let t9;
|
|
44
|
+
if ($[0] !== action.confirm || $[1] !== action.destructive || $[2] !== action.label || $[3] !== count || $[4] !== event || $[5] !== intl || $[6] !== loading || $[7] !== onCancel || $[8] !== onConfirm) {
|
|
45
|
+
const confirm = typeof action.confirm === "object" ? action.confirm : {};
|
|
46
|
+
const values = {
|
|
47
|
+
count,
|
|
48
|
+
action: action.label
|
|
49
|
+
};
|
|
50
|
+
T0 = Dialog;
|
|
51
|
+
t4 = true;
|
|
52
|
+
if ($[19] !== onCancel) {
|
|
53
|
+
t5 = (open) => {
|
|
54
|
+
if (!open) onCancel();
|
|
55
|
+
};
|
|
56
|
+
$[19] = onCancel;
|
|
57
|
+
$[20] = t5;
|
|
58
|
+
} else t5 = $[20];
|
|
59
|
+
t6 = "alertdialog";
|
|
60
|
+
t7 = false;
|
|
61
|
+
t8 = "sm";
|
|
62
|
+
t9 = confirm.title !== void 0 ? formatDefinitionMessage(intl, confirm.title, values) : intl.formatMessage(messages.confirmTitle, { action: action.label });
|
|
63
|
+
let t11;
|
|
64
|
+
if ($[21] !== event || $[22] !== onConfirm) {
|
|
65
|
+
t11 = () => onConfirm(event);
|
|
66
|
+
$[21] = event;
|
|
67
|
+
$[22] = onConfirm;
|
|
68
|
+
$[23] = t11;
|
|
69
|
+
} else t11 = $[23];
|
|
70
|
+
t10 = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
|
|
45
71
|
variant: "ghost",
|
|
46
72
|
onPress: onCancel,
|
|
47
73
|
children: confirm.cancelLabel ?? intl.formatMessage(messages.cancel)
|
|
@@ -49,13 +75,55 @@ function ConfirmDialog({ event, preview = null, onConfirm, onCancel }) {
|
|
|
49
75
|
variant: action.destructive === true ? "danger" : "primary",
|
|
50
76
|
autoFocus: true,
|
|
51
77
|
isDisabled: loading,
|
|
52
|
-
onPress:
|
|
78
|
+
onPress: t11,
|
|
53
79
|
children: confirm.confirmLabel ?? action.label
|
|
54
|
-
})] })
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
80
|
+
})] });
|
|
81
|
+
t2 = Actions_module_default.message;
|
|
82
|
+
t3 = confirm.message !== void 0 ? formatDefinitionMessage(intl, confirm.message, values) : intl.formatMessage(messages.confirmMessage, values);
|
|
83
|
+
$[0] = action.confirm;
|
|
84
|
+
$[1] = action.destructive;
|
|
85
|
+
$[2] = action.label;
|
|
86
|
+
$[3] = count;
|
|
87
|
+
$[4] = event;
|
|
88
|
+
$[5] = intl;
|
|
89
|
+
$[6] = loading;
|
|
90
|
+
$[7] = onCancel;
|
|
91
|
+
$[8] = onConfirm;
|
|
92
|
+
$[9] = T0;
|
|
93
|
+
$[10] = t10;
|
|
94
|
+
$[11] = t2;
|
|
95
|
+
$[12] = t3;
|
|
96
|
+
$[13] = t4;
|
|
97
|
+
$[14] = t5;
|
|
98
|
+
$[15] = t6;
|
|
99
|
+
$[16] = t7;
|
|
100
|
+
$[17] = t8;
|
|
101
|
+
$[18] = t9;
|
|
102
|
+
} else {
|
|
103
|
+
T0 = $[9];
|
|
104
|
+
t10 = $[10];
|
|
105
|
+
t2 = $[11];
|
|
106
|
+
t3 = $[12];
|
|
107
|
+
t4 = $[13];
|
|
108
|
+
t5 = $[14];
|
|
109
|
+
t6 = $[15];
|
|
110
|
+
t7 = $[16];
|
|
111
|
+
t8 = $[17];
|
|
112
|
+
t9 = $[18];
|
|
113
|
+
}
|
|
114
|
+
let t11;
|
|
115
|
+
if ($[24] !== t2 || $[25] !== t3) {
|
|
116
|
+
t11 = /* @__PURE__ */ jsx("p", {
|
|
117
|
+
className: t2,
|
|
118
|
+
children: t3
|
|
119
|
+
});
|
|
120
|
+
$[24] = t2;
|
|
121
|
+
$[25] = t3;
|
|
122
|
+
$[26] = t11;
|
|
123
|
+
} else t11 = $[26];
|
|
124
|
+
let t12;
|
|
125
|
+
if ($[27] !== intl || $[28] !== loading || $[29] !== skipped) {
|
|
126
|
+
t12 = loading ? /* @__PURE__ */ jsx("div", {
|
|
59
127
|
className: Actions_module_default.skipped,
|
|
60
128
|
children: /* @__PURE__ */ jsx(Spinner, {
|
|
61
129
|
size: "sm",
|
|
@@ -65,8 +133,37 @@ function ConfirmDialog({ event, preview = null, onConfirm, onCancel }) {
|
|
|
65
133
|
}) : skipped > 0 ? /* @__PURE__ */ jsx("p", {
|
|
66
134
|
className: Actions_module_default.skipped,
|
|
67
135
|
children: intl.formatMessage(messages.confirmSkipped, { count: skipped })
|
|
68
|
-
}) : null
|
|
69
|
-
|
|
136
|
+
}) : null;
|
|
137
|
+
$[27] = intl;
|
|
138
|
+
$[28] = loading;
|
|
139
|
+
$[29] = skipped;
|
|
140
|
+
$[30] = t12;
|
|
141
|
+
} else t12 = $[30];
|
|
142
|
+
let t13;
|
|
143
|
+
if ($[31] !== T0 || $[32] !== t10 || $[33] !== t11 || $[34] !== t12 || $[35] !== t4 || $[36] !== t5 || $[37] !== t6 || $[38] !== t7 || $[39] !== t8 || $[40] !== t9) {
|
|
144
|
+
t13 = /* @__PURE__ */ jsxs(T0, {
|
|
145
|
+
isOpen: t4,
|
|
146
|
+
onOpenChange: t5,
|
|
147
|
+
role: t6,
|
|
148
|
+
isDismissable: t7,
|
|
149
|
+
size: t8,
|
|
150
|
+
title: t9,
|
|
151
|
+
footer: t10,
|
|
152
|
+
children: [t11, t12]
|
|
153
|
+
});
|
|
154
|
+
$[31] = T0;
|
|
155
|
+
$[32] = t10;
|
|
156
|
+
$[33] = t11;
|
|
157
|
+
$[34] = t12;
|
|
158
|
+
$[35] = t4;
|
|
159
|
+
$[36] = t5;
|
|
160
|
+
$[37] = t6;
|
|
161
|
+
$[38] = t7;
|
|
162
|
+
$[39] = t8;
|
|
163
|
+
$[40] = t9;
|
|
164
|
+
$[41] = t13;
|
|
165
|
+
} else t13 = $[41];
|
|
166
|
+
return t13;
|
|
70
167
|
}
|
|
71
168
|
//#endregion
|
|
72
169
|
export { ConfirmDialog, needsConfirmation };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmDialog.js","names":["_Fragment","styles"],"sources":["../../src/actions/ConfirmDialog.tsx"],"sourcesContent":["import type { IntlShape } from 'react-intl';\n\nimport { Button, Dialog, Spinner, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from '../messages';\nimport type { ListActionEvent, ListActionPreview } from '../types';\nimport styles from './Actions.module.css';\n\n/** Formats an ICU message of the definition (`{count, plural, …}`) in the locale. */\nfunction formatDefinitionMessage(\n intl: IntlShape,\n message: string,\n values: Record<string, unknown>,\n) {\n try {\n return String(\n intl.formatters\n .getMessageFormat(message, intl.locale)\n .format(values as Record<string, string | number>),\n );\n } catch {\n return message;\n }\n}\n\n/** Whether an action needs a confirmation: it asks for one, or some selected items are skipped. */\nexport function needsConfirmation(event: ListActionEvent): boolean {\n const { confirm } = event.action;\n return (confirm !== undefined && confirm !== false) || event.skipped.length > 0;\n}\n\n/** The dry run of a query selection: in progress, or done with the backend's count. */\nexport type ConfirmPreview = { status: 'loading' } | ({ status: 'done' } & ListActionPreview);\n\nexport interface ConfirmDialogProps {\n /** The action to confirm, or `null` when the dialog is closed. */\n event: ListActionEvent | null;\n /**\n * What the backend told about a query selection. Its count of skipped items replaces the\n * count of the current page; while it loads, the dialog says so and can't be confirmed.\n */\n preview?: ConfirmPreview | null;\n onConfirm: (event: ListActionEvent) => void;\n onCancel: () => void;\n}\n\n/**\n * Asks before running an action (decision 0017): the action's `confirm` title and message (an ICU\n * message with `{count}`), or default ones, and how many selected items will be skipped: those of\n * the current page that don't allow it, or the backend's count for every item matching a query.\n */\nexport function ConfirmDialog({ event, preview = null, onConfirm, onCancel }: ConfirmDialogProps) {\n const intl = usePanneauIntl();\n if (event === null) {\n return null;\n }\n const { action, count } = event;\n const loading = preview?.status === 'loading';\n const skipped = preview?.status === 'done' ? preview.skipped : event.skipped.length;\n const confirm = typeof action.confirm === 'object' ? action.confirm : {};\n const values = { count, action: action.label };\n return (\n <Dialog\n isOpen\n onOpenChange={(open) => {\n if (!open) {\n onCancel();\n }\n }}\n role=\"alertdialog\"\n isDismissable={false}\n size=\"sm\"\n title={\n confirm.title !== undefined\n ? formatDefinitionMessage(intl, confirm.title, values)\n : intl.formatMessage(messages.confirmTitle, { action: action.label })\n }\n footer={\n <>\n <Button variant=\"ghost\" onPress={onCancel}>\n {confirm.cancelLabel ?? intl.formatMessage(messages.cancel)}\n </Button>\n <Button\n variant={action.destructive === true ? 'danger' : 'primary'}\n autoFocus\n isDisabled={loading}\n onPress={() => onConfirm(event)}\n >\n {confirm.confirmLabel ?? action.label}\n </Button>\n </>\n }\n >\n <p className={styles.message}>\n {confirm.message !== undefined\n ? formatDefinitionMessage(intl, confirm.message, values)\n : intl.formatMessage(messages.confirmMessage, values)}\n </p>\n {loading ? (\n <div className={styles.skipped}>\n <Spinner\n size=\"sm\"\n label={intl.formatMessage(messages.confirmChecking)}\n showLabel\n />\n </div>\n ) : skipped > 0 ? (\n <p className={styles.skipped}>\n {intl.formatMessage(messages.confirmSkipped, { count: skipped })}\n </p>\n ) : null}\n </Dialog>\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ConfirmDialog.js","names":["IntlShape","Button","Dialog","Spinner","usePanneauIntl","messages","ListActionEvent","ListActionPreview","styles","formatDefinitionMessage","intl","message","values","Record","String","formatters","getMessageFormat","locale","format","needsConfirmation","event","confirm","action","undefined","skipped","length","ConfirmPreview","status","ConfirmDialogProps","preview","onConfirm","onCancel","ConfirmDialog","t0","$","_c","t1","count","loading","T0","t10","t2","t3","t4","t5","t6","t7","t8","t9","destructive","label","open","title","formatMessage","confirmTitle","t11","cancelLabel","cancel","confirmLabel","confirmMessage","t12","confirmChecking","confirmSkipped","t13","_c","_Fragment","styles"],"sources":["../../src/actions/ConfirmDialog.tsx"],"sourcesContent":["import type { IntlShape } from 'react-intl';\n\nimport { Button, Dialog, Spinner, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from '../messages';\nimport type { ListActionEvent, ListActionPreview } from '../types';\nimport styles from './Actions.module.css';\n\n/** Formats an ICU message of the definition (`{count, plural, …}`) in the locale. */\nfunction formatDefinitionMessage(\n intl: IntlShape,\n message: string,\n values: Record<string, unknown>,\n) {\n try {\n return String(\n intl.formatters\n .getMessageFormat(message, intl.locale)\n .format(values as Record<string, string | number>),\n );\n } catch {\n return message;\n }\n}\n\n/** Whether an action needs a confirmation: it asks for one, or some selected items are skipped. */\nexport function needsConfirmation(event: ListActionEvent): boolean {\n const { confirm } = event.action;\n return (confirm !== undefined && confirm !== false) || event.skipped.length > 0;\n}\n\n/** The dry run of a query selection: in progress, or done with the backend's count. */\nexport type ConfirmPreview = { status: 'loading' } | ({ status: 'done' } & ListActionPreview);\n\nexport interface ConfirmDialogProps {\n /** The action to confirm, or `null` when the dialog is closed. */\n event: ListActionEvent | null;\n /**\n * What the backend told about a query selection. Its count of skipped items replaces the\n * count of the current page; while it loads, the dialog says so and can't be confirmed.\n */\n preview?: ConfirmPreview | null;\n onConfirm: (event: ListActionEvent) => void;\n onCancel: () => void;\n}\n\n/**\n * Asks before running an action (decision 0017): the action's `confirm` title and message (an ICU\n * message with `{count}`), or default ones, and how many selected items will be skipped: those of\n * the current page that don't allow it, or the backend's count for every item matching a query.\n */\nexport function ConfirmDialog({ event, preview = null, onConfirm, onCancel }: ConfirmDialogProps) {\n const intl = usePanneauIntl();\n if (event === null) {\n return null;\n }\n const { action, count } = event;\n const loading = preview?.status === 'loading';\n const skipped = preview?.status === 'done' ? preview.skipped : event.skipped.length;\n const confirm = typeof action.confirm === 'object' ? action.confirm : {};\n const values = { count, action: action.label };\n return (\n <Dialog\n isOpen\n onOpenChange={(open) => {\n if (!open) {\n onCancel();\n }\n }}\n role=\"alertdialog\"\n isDismissable={false}\n size=\"sm\"\n title={\n confirm.title !== undefined\n ? formatDefinitionMessage(intl, confirm.title, values)\n : intl.formatMessage(messages.confirmTitle, { action: action.label })\n }\n footer={\n <>\n <Button variant=\"ghost\" onPress={onCancel}>\n {confirm.cancelLabel ?? intl.formatMessage(messages.cancel)}\n </Button>\n <Button\n variant={action.destructive === true ? 'danger' : 'primary'}\n autoFocus\n isDisabled={loading}\n onPress={() => onConfirm(event)}\n >\n {confirm.confirmLabel ?? action.label}\n </Button>\n </>\n }\n >\n <p className={styles.message}>\n {confirm.message !== undefined\n ? formatDefinitionMessage(intl, confirm.message, values)\n : intl.formatMessage(messages.confirmMessage, values)}\n </p>\n {loading ? (\n <div className={styles.skipped}>\n <Spinner\n size=\"sm\"\n label={intl.formatMessage(messages.confirmChecking)}\n showLabel\n />\n </div>\n ) : skipped > 0 ? (\n <p className={styles.skipped}>\n {intl.formatMessage(messages.confirmSkipped, { count: skipped })}\n </p>\n ) : null}\n </Dialog>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Action } from '@panneau/protocol';
|
|
2
|
-
import type { ListItem } from '../types';
|
|
3
|
-
import { type ActionIcons } from './icons';
|
|
2
|
+
import type { ListItem } from '../types.js';
|
|
3
|
+
import { type ActionIcons } from './icons.js';
|
|
4
4
|
export interface RowActionsProps {
|
|
5
5
|
item: ListItem;
|
|
6
6
|
/** The label of the item, for the accessible names of its actions. */
|
|
@@ -3,10 +3,10 @@ import { messages } from "../messages.js";
|
|
|
3
3
|
import Actions_module_default from "./Actions.module.js";
|
|
4
4
|
import { getActionIcon } from "./icons.js";
|
|
5
5
|
import { ActionButton } from "./ActionButton.js";
|
|
6
|
+
import { c } from "react/compiler-runtime";
|
|
6
7
|
import { IconButton, Menu, MenuItem, MenuTrigger, usePanneauIntl } from "@panneau/ui";
|
|
7
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
import { Ellipsis } from "lucide-react";
|
|
9
|
-
import { c } from "react/compiler-runtime";
|
|
10
10
|
//#region src/actions/RowActions.tsx
|
|
11
11
|
/** The actions of a row: buttons, then an overflow menu. */
|
|
12
12
|
function RowActions(t0) {
|