Repository navigation
Commit 1ed3360
feat(ui): record-mode currency — each record shows its own currency; ISO 4217 code select pre-filled with the organization currency; no cross-currency totals; Studio currency section (#27340)
epic:#8345#1 · os-bill · session_01Utp6CbTZrFqRYNgjSaSbN5
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wg9oTskgBVZmtxXLAEh251Cb)_
Fixes #27188
⛔ not released alone — R1: pairs with #27184, #27186, #27187, #27188
(one Version Packages release)
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么:** record 模式的金额按每条记录自己的币种显示(列表、表单、详情、仪表盘、甘特提示);币种码字段变成 ISO 4217
分组搜索下拉,「可用」组含组织币种和该对象已用过的币种,新建时预填组织币种;列表筛选里 record 金额条件带必填币种选择,生成「金额条件 且
币种 = C」;列表页脚与非按币种分组的合计不再跨币种相加;Studio 字段编辑器新增币种模式、币种字段选择和「创建币种字段」;分享链接页的
record 金额也按记录自己的币种显示;按币种分组的分析结果(仪表盘表格、报表表格及其导出、Studio 数据集预览)每行按该行币种格式化。
- **为什么改:** 没有这一步,record 字段会显示租户币种符号,比今天更错(ADR-0144 D9:R1 必含)。
- **风险与回滚:** 只影响声明 `currencyMode: 'record'` 的字段和声明 ISO 4217
值域的文本字段;dynamic / fixed 字段行为不变(原有测试全过)。回滚即 revert 本 PR。
- **先看:** `ui/packages/i18n/src/currency.ts`(解析器,record
分支)、`ui/packages/components/src/custom/filterRecordCurrency.ts`(筛选配对)、`ui/packages/components/src/renderers/form/usedCurrencyCodes.ts`(已用币种查询)、`ui/packages/plugin-grid/src/recordCurrencyAggregates.ts`(合计规则)。
- **两分钟验证:** `cd ui && pnpm exec vitest run
packages/fields/src/__tests__/recordCurrency.faces-27188.test.tsx`,应见三行
$ / € / ¥,无币种的行显示纯数字。
- **需要你做的:** 无,席位落地(#27268 已合并)。
## What changes
ADR-0144 D2 (the record currency lives in a sibling code field), D6 (raw
aggregates over a record-mode amount stand only inside one currency) and
D8 rule 4 (the form pre-fills the organization currency; the stored
value is always explicit), on the renderer side.
- **Resolver** (`@object-ui/i18n`). `resolveFieldCurrency(field,
tenantDefault, record?)` gains an optional record. Under `currencyMode:
'record'` it reads only `record[currencyConfig.currencyField]`; no
record or a blank code resolves to `undefined`, so the face shows a
plain number. It never falls back to the tenant default, a node-level
`currency` or a stray `defaultCurrency`. `dynamic` / `fixed` are
unchanged. New `recordCurrencyField(field)` names the pointer;
`FieldCurrencyConfig` types the three modes.
- **Faces that hold the record now pass it.** `CurrencyCellRenderer` and
the formula cell (the grid already hands `dependentValues={row}`),
`CurrencyField` (symbol, minor-unit decimals and spinner step follow the
selected code), the form renderer (hands the live record to the
`currency` and `formula` widgets, `RECORD_CURRENCY_WIDGET_TYPES`), the
grid's mobile card, the record page's summary chips, the dashboard table
cell and record drawer (`FieldMeta.currencyConfig`, copied only for
record mode), and Gantt tooltips.
- **Code field.** A `text` field declaring `valueDomain:
'iso_4217_currency'` renders `CurrencyCodeField`: a searchable select
grouped "Available" (home currency, then rated, then the codes in use)
and "All currencies (ISO 4217)", offering only codes
`isValueDomainMember('iso_4217_currency', code)` accepts. Re-selecting
the selected code keeps it (no click-to-clear). The picker is
`CurrencyCodePicker` in `@object-ui/components`, shared with the filter
row below.
- **Used codes** (`@object-ui/components` form renderer,
`usedCurrencyCodes.ts`). For every ISO 4217 code field on a form with an
`objectName`, the renderer asks `dataSource.queryGroupHeaders(object,
compileListViewGroupQuery(grouped by the code field))` once, keyed on
content, and hands the distinct stored codes down on the field's own
metadata as `usedCurrencyCodes`. No widget-contract key. All five
plugin-form hosts already put `objectName` on the form schema, so this
one seam covers them. A data source without `queryGroupHeaders` is not
asked (`aggregate` may degrade to a full fetch); a failed read hands
nothing down. Either way the picker offers home + rated + the record's
own code.
- **Filters** (`@object-ui/components` FilterBuilder,
`@object-ui/plugin-list`). A builder field entry may carry
`currencyField` (the list sets it from `currencyConfig` for record-mode
amounts). A value-comparing row on such an amount draws a required
currency picker, defaulting to `localization.currency`. The builder
emits the code condition as a companion row of the same flat group, `{
id: '<row id>::currency', field: <code field>, operator: 'equals',
value: C }`, so the group lowers to `amount op X AND code = C`
everywhere it is lowered (`convertFilterGroupToAST` gives `['and',
['amount','>',100], ['currency_code','=','USD']]`) and stored filters
keep the `ViewFilterRule` shape. The companion is drawn as the picker,
never as a row, and goes when its amount row goes, switches to a
non-pairing field, or switches to a presence operator. A paired group
cannot be toggled to OR, because under OR the pair would split; a stored
OR group shows why. Opening a stored filter emits nothing (a stored
amount row without a code shows a blank, invalid picker until the next
edit). The toolbar's filter count does not count companions.
- **Create forms** (`@object-ui/plugin-form`).
`SeedContext.homeCurrency`: a code field that some record-mode amount
points at, with no declared default, opens on `localization.currency`.
Wired into ObjectForm, DrawerForm, ModalForm, TabbedForm and WizardForm
(`SplitForm` is retired on `main`, #27159). Edit forms are not seeded,
so opening a record never rewrites its stored code.
- **Totals** (`@object-ui/plugin-grid`). The footer draws no sum / avg /
min / max for a record-mode amount; counts stand. Group-header
aggregations keep those only when the grid is grouped by the amount's
code field (`honestGroupAggregations`, applied before both the server
header query and client bucketing). The home field is a `dynamic` amount
and totals as before.
- **Studio** (`@object-ui/app-shell`). A currency field, or a formula
returning `currency`, gets a currency section (`CurrencyConfigField`):
mode, the fixed code, and under `record` a `currencyField` picker
listing only the object's `text` + ISO 4217 fields, with "Create
currency field", which appends `currency_code` (`type: 'text'`,
`valueDomain: 'iso_4217_currency'`, `required: true`) and sets the
pointer in one write. A mode switch keeps only the keys that mode reads.
- **Share links** (`@objectstack/types`, `@object-ui/console`; R1 rider
from #27268's contract review). The resolve answer's field projection
(`buildShareLinkResolveAnswer`) carried only `currencyMode` and
`defaultCurrency`, so a shared record-mode amount rendered as a plain
number. A currency field's projected `currencyConfig` now also carries
`currencyField`, only when the answer's `record` carries that code
field, so a link that redacts the code field discloses neither the code
nor the field's name and the amount shows as a plain number. The
shared-record page passes the shared record to the currency face as
`dependentValues`, so the amount shows in its own record's currency.
- **Dataset answers** (`@object-ui/core`, `@object-ui/plugin-dashboard`,
`@object-ui/plugin-report`, `@object-ui/app-shell`; R1 rider from
#27338's contract review). A grouped analytics answer over a
`record`-mode amount marks its measure column with
`AnalyticsResult.fields[].currencyField`, naming the result column that
holds each row's code (#27338). The readers passed only
`fields[].currency`, so those columns rendered as plain numbers. New
`measureCellCurrency(field, row)` returns that row's code when the
column carries `currencyField`, nothing for a row without one, and the
column's declared `currency` otherwise, so every other column formats
byte for byte as before. It reads `currencyField` structurally (`(field
as { currencyField?: unknown }).currencyField`): #27338's contract is
not on `main` yet, so the spec type does not carry the key. That passes
type-check, and it can switch to the spec type once #27338 lands. The
dashboard `table` widget's body cells, the report table's body cells and
its export snapshot, and the Studio dataset preview read it off the RAW
row (`state.rows[i]`, before `relabelDimensions`). Totals and cross-tab
cells pass no row and so draw no symbol, since they may add several
currencies. `chart-series.ts` reads no currency at all (only the numeral
`format`), so it has nothing to switch, and a chart axis has one unit.
- **i18n.** `fields.currencyCode.*` in all eleven locale packs;
`designer.field.currency.*` in the studio namespace (en, zh).
File surface beyond the Claim's list, accepted by the epic PM:
`ui/packages/plugin-grid`, `ui/packages/components`; also
`ui/packages/plugin-form`, `ui/packages/plugin-detail`,
`ui/packages/plugin-gantt` (one resolver call each, plus the form
seeding), and `ui/packages/plugin-list` (the list filter's
`currencyField` and filter count).
## Tests
- `i18n/src/__tests__/resolveFieldCurrency.recordMode-27188.test.ts` —
the record-mode truth table.
- `fields/src/__tests__/recordCurrency.faces-27188.test.tsx` — cells in
USD / EUR / JPY, no-code rows plain, the amount box's symbol and step
(USD 0.01, JPY 1, KWD 0.001), the code select's groups and domain
filter, `TextField` routing.
- `plugin-form/src/__tests__/recordCurrencySeed-27188.test.ts` —
seeding, unset setting, author default and caller record win.
- `plugin-grid/src/__tests__/recordCurrencyAggregates-27188.test.tsx` —
footer refuses money aggregates over record mode, counts stand, home
field sums; group aggregations by grouping field.
-
`plugin-dashboard/src/__tests__/recordFields.recordCurrency-27188.test.tsx`
— dashboard cells per row.
- `app-shell/.../CurrencyConfigField.recordMode-27188.test.tsx` — mode
switch, candidates, and the create shortcut's output parses under
`ObjectSchema`.
-
`components/src/renderers/form/__tests__/form-used-currency-codes-27188.test.tsx`
— the query shape, the distinct domain-valid read, one ask per object
across re-renders, no ask without an object or the capability, a failed
read.
-
`components/src/__tests__/filter-builder-record-currency-27188.test.tsx`
— the pairing rules, one picker per paired row, a new row on the home
currency, removal, the stored blank picker emitting nothing, the AND
lock and the OR notice.
-
`plugin-list/src/__tests__/convertFilterGroupToAST.recordCurrency-27188.test.ts`
— the pair lowers to `amount op X AND code = C`.
- `packages/types/src/share-link-resolve-answer.test.ts` gains: the
pointer is projected when the record carries the code field, and a
redacted code field is never named.
- `console/src/pages/SharedRecordPage.recordCurrency-27188.test.tsx` — a
shared record-mode amount shows its record's currency (EUR, then JPY),
and a hidden code field leaves a plain number.
- `core/src/utils/__tests__/dataset-format.recordCurrency-27188.test.ts`
— `measureCellCurrency`: per-row code, no code / no row gives no symbol,
a column without `currencyField` keeps `currency`; two rows of one
column format as `$1,234.50` and `€1,234.50`.
- `app-shell/.../previews/DatasetPreview.measureLocale.test.tsx` gains:
a record-mode column renders `$1,234.50` and `€99.00` in one table.
-
`plugin-dashboard/src/__tests__/DatasetWidget.recordCurrency-27188.test.tsx`
— the table widget formats USD, EUR and a code-less row (plain), and the
grand total has no symbol.
-
`plugin-report/src/__tests__/DatasetReportRenderer.measureLocale.test.tsx`
gains: the grouped report table formats USD, EUR and a code-less row
(plain), and the grand total has no symbol.
- `fields/.../recordCurrency.faces-27188.test.tsx` gains: the used codes
off `field.usedCurrencyCodes` appear in "Available" after the home
currency.
## Acceptance notes
- **Seat ruling: A/A** (epic PM, on the two open questions of the first
report). (1) The form reads the used codes once per object and passes
them on the field metadata, with no widget-contract key. (2) The filter
row gets a required currency picker defaulting to the organization
currency, and the builder emits `amount op X AND code = C`. Both are
built here.
- **Rated group is a seam.** `ratedCurrencyCodes()` in
`CurrencyCodeField.tsx` returns nothing until `sys_exchange_rate` ships
(R2, #27185).
- **Used codes, where asked.** The read rides the form renderer, the
seam every form host already reaches with `objectName`, rather than five
host-level copies. It is a per-mount read: a code first used after the
form opened shows up on the next open.
- **Filter scope.** The pairing is the list's filter builder
(`FilterBuilder` + `ListView`). The sharing-rule criteria editor
(`FilterConditionField`, stored as a Mongo-style object) is not paired:
it re-ids rows on every read, so a code condition there stays a row the
author writes.
- **No organization currency.** With `localization.currency` unset a new
pair's code is blank and the picker is marked invalid; the list's
lowering drops a blank row, so that filter compares the amount alone
until a code is picked.
- **Minor units.** The amount box reads the existing
`currencyDisplayWidth` / `currencyFractionDigits` reader (CLDR via
`Intl`), which `CURRENCY_FRACTION_DIGITS` mirrors by construction (its
header); no second table.
- **Chart tooltips, follow-on.** A chart over a grouped record-mode
answer still shows plain numbers in its tooltips. `chart-series.ts`
reads no currency at all (only the numeral `format`), and a value axis
has one unit, so per-row currency there is a follow-on, not part of R1's
table surfaces.
- **Home field display** (`homeAmount`) is #27196's.
- **Metric tiles** already show a plain number for a record-mode
aggregate (the resolver has no record); the build-time refusal is
#27187's.
## Verification
Head `554bd578` on `a9b2b97d`, which regenerates
`packages/spec/authorable-surface/data.json` on the merged tree (the
result is byte-identical to `main`'s), on `24055cf0`, a merge commit
bringing in `main` at `f7188b56` after #27268 landed as `41452103` (no
rebase). The diff against `main` is this card's own: 70 files, none
under `packages/spec`. Two conflicts:
- `ui/packages/i18n/src/currency.ts`. `main`'s side is #27268's final
file, byte-identical to the one this branch had already reconciled, so
this branch's side is kept. Under `record` mode the resolver reads the
row's code when the caller passes the row; a call with no record still
resolves to `undefined`, which #27268's own
`resolveFieldCurrency.test.ts` cases pin.
- `ui/packages/plugin-form/src/SplitForm.tsx`. `main` retired it
(#27159), so the deletion stands, along with this card's seeding call in
it.
`554bd578` moves `measureCellCurrency` above `formatDimensionValue`'s
docblock, which it had orphaned. It is a doc-only move.
`check:generated` (spec) passes at this head. ADR-0144 citations (D2,
D3, D6, D8 rules 3 and 4, D9) were re-read against the landed
`docs/adr/0144-…md` and hold.
<details><summary>Landing verification at
<code>554bd578</code></summary>
- Builds: `@objectstack/spec`, `@objectstack/types`, and the ui closure
of app-shell, console and plugin-report, exit 0. `@objectstack/spec
check:generated` exit 0.
- Tests, all exit 0 under `os-verify-lock`:
- the targeted ui set plus the Studio, census, #8415, dataset-format,
dataset preview, dashboard table and report table files: 55 files, 855
passed;
- every `plugin-form/src` suite: 210 files, 2343 passed, 1 skipped;
- every `core/src` suite after the docblock move: 218 files, 4133
passed, 27 skipped;
- share-link runtime, types and console: 12, 9 and 22 passed.
- Type-check exit 0: `@object-ui/` i18n, fields, components,
plugin-form, plugin-grid, plugin-list, plugin-dashboard, plugin-detail,
plugin-gantt, plugin-report, core, app-shell, console, and
`@objectstack/types`.
- Gates: `dispatch-gates --commands` on this card's 70 paths derives no
family the earlier runs had not. The 34 local re-runs exit 0; the rest
are CI's.
</details>
<details><summary>Targeted tests — 49 files, 786 tests, exit 0</summary>
```
cd ui && pnpm exec vitest run --maxWorkers=2 (every *27188* test above, #27268's resolveFieldCurrency suites, every components filter-builder suite, form-data-source-wiring, form-dependent-values, the plugin-list convertFilterGroupToAST suites, filter-operator-ast-parity and filter-count suites, and the currency neighbours: currencyMode.faces-10422, CurrencyField.minorUnits, TextField.maxLength-10179, optionDefaultSeed-11914, useColumnSummary.currencyMode-10422, recordFields.currencyConfig-10463, ObjectFieldInspector.valueDomain-7597)
Test Files 49 passed (49)
Tests 786 passed (786)
os-verify-lock: VERDICT command-exit 0
```
Before the merge, the neighbouring-package run (i18n, components form
renderer and custom, fields widgets, plugin-list filter suites) was 328
files, 3544 passed, 30 skipped.
</details>
<details><summary>Type-check and lint</summary>
`pnpm --filter @object-ui/PKG type-check` exit 0 at `ad386034` for i18n,
fields, components, plugin-form, plugin-grid, plugin-list,
plugin-dashboard, plugin-detail, plugin-gantt, app-shell, after building
their dependency closure. `pnpm exec eslint` over every ui file this
card touches: 0 errors.
</details>
<details><summary>Ablations at <code>ad386034</code> — three, each red
then restored</summary>
- Resolver record branch, `ui/packages/i18n/src/currency.ts`:
`currencyMode === 'record'` → `'ABLATED'` (blob `82ae7ac6` →
`c78a363b`): 7 failed / 8 passed across the i18n record-mode suite and
the fields faces suite.
- Used codes hand-off,
`ui/packages/components/src/renderers/form/form.tsx`:
`withUsedCurrencyCodes(field.field || field, …)` → `field.field ||
field` (blob `12d5c6b5` → `18cbb6d6`): 1 failed / 6 passed.
- Filter pairing,
`ui/packages/components/src/custom/filterRecordCurrency.ts`:
`pairedCurrencyField` answers `undefined` (blob `025b1560` →
`d78defb9`): 9 failed / 4 passed across the builder suite and the AST
lowering.
Each restored by `ablation-replace.mjs`: blob == HEAD, `git diff HEAD`
empty.
</details>
<details><summary>Share-link rider at <code>8bcaa1bc</code></summary>
- Tests: `@objectstack/runtime` `share-links-field-projection.test.ts`
12 passed; `@objectstack/types` `share-link-resolve-answer.test.ts` 9
passed; console `SharedRecordPage.recordCurrency-27188`,
`SharedRecordPage-27121`, `shared-record-shape` 22 passed. All exit 0
under `os-verify-lock`.
- Type-check: `@objectstack/types` and `@object-ui/console` exit 0.
eslint over the five files: 0 errors.
- Ablation, console page: `dependentValues={record}` →
`dependentValues={undefined}` in `SharedRecordFields.tsx` (blob
`e4ce54ff` → `88b99e73`): 2 failed / 1 passed. Restored: blob == HEAD.
- Ablation, projection: the `currencyField` spread → `false ? … : {}` in
`share-link-resolve-answer.ts` (blob `8c7a3bd5` → `57379712`): 1 failed
/ 8 passed. Restored: blob == HEAD.
</details>
<details><summary>CI fixes at <code>66a421cc</code> and
<code>c36aa49e</code></summary>
CI's Test UI at `8bcaa1bc` failed one test:
`ui/packages/types/src/__tests__/filter-builder-condition-id-8415.test.ts`
reads `removeCondition`'s id filter verbatim, and this card had widened
it to also drop the companion. The line is back to the pinned form. The
companion still goes with its amount row, because `handleChange` runs
`syncRecordCurrencyRows`, which drops a companion whose amount row is
gone. The "removing the amount row removes its code condition" case
covers this.
- Tests: the #8415 pin plus every components `__tests__` and
`custom/__tests__` suite, 255 files, 2431 passed, 7 skipped, exit 0
under `os-verify-lock`.
- Type-check: `@object-ui/components` exit 0. eslint: 0 errors.
CI's Test UI at `8bcaa1bc` also failed
`ui/examples/schema-catalog/test/form-field-channel-census-12130.test.tsx`,
which measures every key the form-field channel reads by name. This card
adds two reads: the form's used-codes hand-off (`usedCurrencyCodes.ts`)
reads the entry's `field` stash and `valueDomain`, and the currency-code
widget reads `valueDomain` off its carrier. `usedCurrencyCodes.ts` joins
the `field` row's readers. `valueDomain` gets a RUNTIME-ONLY ledger row:
it is object-field metadata (ADR-0144 D2) the code field takes from the
object, so it is ledgered rather than declared on `FormFieldSchema`.
- Tests: the census and its effects file, 2 files, 120 passed, exit 0
under `os-verify-lock`.
</details>
<details><summary>Studio and #27268's record-mode refusals</summary>
#27268 refuses `defaultCurrency` under `currencyMode: 'record'`, and
`currencyField` has `.min(1)`.
The Studio currency section never writes either refused shape.
`switchCurrencyMode` drops `defaultCurrency` on the switch to `record`,
the pointer picker deletes the key rather than writing `''`, and "Create
currency field" writes a fresh `{ currencyMode: 'record', currencyField
}`. A new test drives the whole path through the inspector: a fixed EUR
amount, a switch to Record, then a picked pointer. It asserts the saved
config and parses the saved object with `ObjectSchema`.
- Ablation: `switchCurrencyMode` carries `prev.defaultCurrency` into
`record` (blob `ad4d29d0` → `8cd4f3de`): 2 failed / 3 passed. Restored:
blob == HEAD.
- Tests: the targeted ui set plus the Studio, census and #8415 files, 51
files, 831 passed. Spec `currency-config-record-mode.test.ts`: 15
passed. Share-link runtime, types and console: 12, 9 and 22 passed. All
exit 0 under `os-verify-lock`.
- Type-check: i18n, fields, components, plugin-list, app-shell and
console exit 0.
- Gates: the 27 local re-runs, plus the 8 families `dispatch-gates
--commands` newly derives at this head (`check:adr-anchors`,
`bash32-floor`, `cli-command-ids`, `entry-guard`, `parse-guard`,
`pnpm-filter-targets`, `pnpm-flag-spellings`, `scripts-symbol-anchors`),
exit 0 each.
</details>
<details><summary>Dataset-answer rider at
<code>7d062908</code></summary>
- Ablation: `measureCellCurrency` always answers the column's `currency`
(blob `488643d0` → `da6fa0c1`): 4 failed / 9 passed, one red case in
each of the three files (core, preview, dashboard table). Restored: blob
== HEAD.
- Tests: every suite under `core/src/utils/__tests__/`,
`app-shell/.../metadata-admin/previews/` and
`plugin-dashboard/src/__tests__/`: 433 files, 5275 passed, 6 skipped,
exit 0 under `os-verify-lock`.
- Type-check: `@object-ui/core`, `@object-ui/plugin-dashboard`,
`@object-ui/app-shell` exit 0. eslint over the six files: 0 errors.
- Gates: `dispatch-gates --commands` derives no new family at this head.
The 34 local re-runs exit 0.
Report table at `3e2eb1d0`:
- Ablation: the report's `fmt` reads `measureField(measure)?.currency`
instead of `measureCellCurrency(measureField(measure), row)` (blob
`8f61bf2d` → `631d266c`): 1 failed / 10 passed. Restored: blob == HEAD.
- Tests: every `plugin-report/src` suite, 30 files, 278 passed, 7
skipped, exit 0 under `os-verify-lock`.
- Type-check `@object-ui/plugin-report` exit 0. eslint: 0 errors. No new
gate family. The 34 local re-runs exit 0.
</details>
<details><summary>Derived gates — 34 local runs, exit 0 each</summary>
Re-run locally at each head: the families `dispatch-gates --commands`
matches by this card's paths, plus `check:nul-bytes`,
`check:cross-package-test-inputs`, `check:doc-authoring`,
`check:issue-citations`, `check:type-check-coverage`,
`check:keyed-text-bounds`, `check:role-word`, `check:adr-anchors`,
`check:bash32-floor`, `check:cli-command-ids`, `check:entry-guard`,
`check:parse-guard`, `check:pnpm-filter-targets`,
`check:pnpm-flag-spellings`, `check:scripts-symbol-anchors`, and
`@objectstack/spec check:generated`. The rest are CI's.
</details>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01Utp6CXtadYa5QXb2PbXPev
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CXtadYa5QXb2PbXPev)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 556f323 commit 1ed3360
70 files changed
Lines changed: 2548 additions & 73 deletions
File tree
- .changeset
- packages/types/src
- ui
- apps/console/src/pages
- examples/schema-catalog/test
- packages
- app-shell/src/views/metadata-admin
- inspectors
- previews
- components/src
- __tests__
- custom
- renderers/form
- __tests__
- core/src/utils
- __tests__
- fields/src
- __tests__
- widgets
- i18n/src
- __tests__
- locales
- namespaces/studio
- plugin-dashboard/src
- __tests__
- plugin-detail/src
- plugin-form/src
- __tests__
- plugin-gantt/src
- plugin-grid/src
- __tests__
- plugin-list/src
- __tests__
- plugin-report/src
- __tests__
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | | - | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
36 | 39 | | |
37 | 40 | | |
38 | 41 | | |
| |||
52 | 55 | | |
53 | 56 | | |
54 | 57 | | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
55 | 64 | | |
56 | 65 | | |
57 | 66 | | |
| |||
109 | 118 | | |
110 | 119 | | |
111 | 120 | | |
112 | | - | |
| 121 | + | |
113 | 122 | | |
114 | 123 | | |
115 | 124 | | |
116 | 125 | | |
117 | 126 | | |
118 | 127 | | |
119 | 128 | | |
120 | | - | |
| 129 | + | |
121 | 130 | | |
122 | 131 | | |
123 | 132 | | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
124 | 137 | | |
125 | 138 | | |
126 | 139 | | |
| |||
142 | 155 | | |
143 | 156 | | |
144 | 157 | | |
| 158 | + | |
| 159 | + | |
145 | 160 | | |
146 | 161 | | |
147 | 162 | | |
148 | | - | |
| 163 | + | |
149 | 164 | | |
150 | 165 | | |
151 | 166 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
105 | | - | |
| 105 | + | |
| 106 | + | |
106 | 107 | | |
107 | 108 | | |
108 | 109 | | |
| |||
146 | 147 | | |
147 | 148 | | |
148 | 149 | | |
149 | | - | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
150 | 157 | | |
151 | 158 | | |
152 | 159 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
119 | 119 | | |
120 | 120 | | |
121 | 121 | | |
122 | | - | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
123 | 127 | | |
124 | 128 | | |
125 | 129 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
281 | 281 | | |
282 | 282 | | |
283 | 283 | | |
| 284 | + | |
284 | 285 | | |
285 | 286 | | |
286 | 287 | | |
| |||
310 | 311 | | |
311 | 312 | | |
312 | 313 | | |
313 | | - | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
314 | 317 | | |
315 | 318 | | |
316 | 319 | | |
317 | 320 | | |
318 | 321 | | |
319 | 322 | | |
320 | 323 | | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
321 | 329 | | |
322 | 330 | | |
323 | 331 | | |
| |||
0 commit comments