feat(18-01): money list column, danger record actions, preview Edit rule and table kit (task 2)

- columns.yaml type: money with currency or currencyFrom (exactly one),
  never searchable, not sortable by default; every list row carries the
  currencyFrom column's value under its own key; the schema serves
  currency and currencyFrom on the column
- pact.AdminRecordAction.Danger, served as danger on cabana.RecordAction
  (absent when false); RecordActions.vue passes it to the confirm dialog
- CellValue money kind through formatMoney with the row's code, the em
  dash when empty and the amount alone without a code; DataTable aligns
  money headers and cells to the right
- PreviewView renders Edit only when a registered value field allows
  update (F6)
- main.css .summer-table* and .summer-stat__note kit classes (F7) over
  --c-* variables; cabana README kit rows
- fixture record actions void (danger) and resend; TestMoneyListCompile,
  TestMoneyListSmoke and TestRecordActionDangerSmoke; regenerated OpenAPI
  and TS types; rebuilt dist; lists-and-filters and admin-controllers docs
This commit is contained in:
Jakub Zych
2026-10-13 11:22:36 +02:00
parent 20385e53ee
commit 0c8605123e
29 changed files with 615 additions and 56 deletions

View File

@@ -13,7 +13,7 @@ import { FIELD_SCOPE, FORM_SESSION, createUploadGate } from '../components/form/
import FormTabs from '../components/form/FormTabs.vue'
import PreviewField from '../components/form/PreviewField.vue'
import RecordActions from '../components/form/RecordActions.vue'
import { RELATION_MANAGER } from '../components/form/registry'
import { RELATION_MANAGER, isRegisteredField } from '../components/form/registry'
import {
DEFAULT_TAB,
contextAllows,
@@ -70,6 +70,13 @@ const fields = computed<FormField[]>(() =>
(schema.value?.fields ?? []).filter((field) => contextAllows(field, 'preview') && !hidden.has(field.type)),
)
// The Edit button renders only when the form holds at least one value field
// the SPA can edit whose context allows update (UI-SPEC F6): a record whose
// form shows only partials has nothing to edit and no primary button.
const hasEditableField = computed(() =>
(schema.value?.fields ?? []).some((field) => isRegisteredField(field) && contextAllows(field, 'update')),
)
// The same tabs as the form; a tab with no preview-visible field never
// appears, because tabs are built from the visible fields only.
const tabs = computed<TabItem[]>(() => {
@@ -290,7 +297,7 @@ void load()
@gone="onGone"
/>
<Button
v-if="!failed"
v-if="!failed && hasEditableField"
variant="primary"
data-action="edit"
:icon="Pencil"