Skip to content
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .changeset/13015-undo-partial-failures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@object-ui/plugin-grid': patch
'@object-ui/types': minor
'@object-ui/i18n': minor
---

An import undo that leaves rows unreverted now says so in the Import Wizard (objectui#13015).

The undo route runs its reversal writes under the object's declared controls, so a hook or rule can refuse a row. The server then answers with `success: false` and one `failures` entry per row it did not revert. Each entry carries the app's own refusal sentence. The job stays undoable for exactly those rows. The wizard used to ignore the answer and only reported a thrown error, so a partial undo showed nothing.

- **Both lists that run Undo show it.** In the History list and on the cancelled-result screen, a partial answer reports how many rows were not undone and that undoing again retries only those rows. It lists each refusal sentence the answer carries. Rows refused with the same sentence share one line, and after ten distinct sentences the rest are counted. Undo stays offered, because the re-read job is still undoable. The object's open lists still refetch, because the undo reverted the other rows. A full undo is unchanged.
- **A thrown undo in the History list shows its message again.** The list's reload cleared the error slot the undo had just written to, in the same tick, so that message never appeared. The undo outcome now has a slot of its own.
- **`@object-ui/types`: `ImportJobUndoResult` is the spec's `UndoImportJobResponse`, bound by reference.** It was a hand-written copy that lacked `failures`. It now carries the required `failures` array of `{ id, action: 'delete' | 'restore', code, error }`. `@object-ui/types` now requires `@objectstack/spec` `^18.0.0-next.5`, the first published release that declares `failures`.
- **`@object-ui/i18n`:** the ten packs gain the `grid.import.undoPartial` count family.

BREAKING (`@object-ui/types`), for a custom `DataSource` whose `undoImportJob` resolves to the old shape: it must now return `failures` (an empty array for a full undo). `@object-ui/data-objectstack` already returns the server's answer unchanged. The bump is `minor` by this repo's release model: objectui's major follows the `@objectstack` family major, and its own breaking changes ship as `minor` with the breaking semantics stated here.

Clause-②: yes (narrowing): `ImportJobUndoResult`, exported from `@object-ui/types`, gains `failures`, and the new pack keys widen `@object-ui/i18n`'s `TranslationKeys` (the widening). `failures` is now required of a custom `DataSource`'s `undoImportJob` answer (the narrowing; see BREAKING above).
7 changes: 7 additions & 0 deletions packages/i18n/src/locales/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,13 @@ const ar = {
undoing: "جارٍ التراجع…",
undoConfirm: "هل تريد التراجع عن هذا الاستيراد؟ ستُحذف السجلات التي أنشأها وتُستعاد السجلات التي حدّثها إلى قيمها السابقة.",
reverted: "تم التراجع",
undoPartial: "لم يتم التراجع عن {{count}} صف(صفوف). التراجع مرة أخرى يعيد محاولة هذه الصفوف فقط.",
undoPartial_zero: "لم يتم التراجع عن {{count}} صف. التراجع مرة أخرى يعيد محاولة هذه الصفوف فقط.",
undoPartial_one: "لم يتم التراجع عن {{count}} صف. التراجع مرة أخرى يعيد محاولة هذا الصف فقط.",
undoPartial_two: "لم يتم التراجع عن صفّين ({{count}}). التراجع مرة أخرى يعيد محاولة هذين الصفّين فقط.",
undoPartial_few: "لم يتم التراجع عن {{count}} صفوف. التراجع مرة أخرى يعيد محاولة هذه الصفوف فقط.",
undoPartial_many: "لم يتم التراجع عن {{count}} صفًا. التراجع مرة أخرى يعيد محاولة هذه الصفوف فقط.",
undoPartial_other: "لم يتم التراجع عن {{count}} صف. التراجع مرة أخرى يعيد محاولة هذه الصفوف فقط.",
jobStatus: {
pending: "قيد الانتظار",
running: "قيد التنفيذ",
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,9 @@ const de = {
undoing: "Wird rückgängig gemacht…",
undoConfirm: "Diesen Import rückgängig machen? Dabei erstellte Datensätze werden gelöscht und aktualisierte Datensätze auf ihre vorherigen Werte zurückgesetzt.",
reverted: "Rückgängig gemacht",
undoPartial: "{{count}} Zeilen wurden nicht rückgängig gemacht. Erneutes Rückgängigmachen wiederholt nur diese Zeilen.",
undoPartial_one: "{{count}} Zeile wurde nicht rückgängig gemacht. Erneutes Rückgängigmachen wiederholt nur diese Zeile.",
undoPartial_other: "{{count}} Zeilen wurden nicht rückgängig gemacht. Erneutes Rückgängigmachen wiederholt nur diese Zeilen.",
jobStatus: {
pending: "Ausstehend",
running: "Läuft",
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,9 @@ const en = {
undoing: 'Undoing…',
undoConfirm: 'Undo this import? Records it created will be deleted and records it updated will be restored to their previous values.',
reverted: 'Undone',
undoPartial: '{{count}} rows were not undone. Undo again to retry only those rows.',
undoPartial_one: '{{count}} row was not undone. Undo again to retry only that row.',
undoPartial_other: '{{count}} rows were not undone. Undo again to retry only those rows.',
jobStatus: {
pending: 'Pending',
running: 'Running',
Expand Down
4 changes: 4 additions & 0 deletions packages/i18n/src/locales/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,10 @@ const es = {
undoing: "Deshaciendo…",
undoConfirm: "¿Deshacer esta importación? Los registros que creó se eliminarán y los que actualizó se restaurarán a sus valores anteriores.",
reverted: "Deshecha",
undoPartial: "{{count}} filas no se deshicieron. Al deshacer de nuevo, solo se reintentan esas filas.",
undoPartial_one: "{{count}} fila no se deshizo. Al deshacer de nuevo, solo se reintenta esa fila.",
undoPartial_many: "{{count}} de filas no se deshicieron. Al deshacer de nuevo, solo se reintentan esas filas.",
undoPartial_other: "{{count}} filas no se deshicieron. Al deshacer de nuevo, solo se reintentan esas filas.",
jobStatus: {
pending: "Pendiente",
running: "En ejecución",
Expand Down
4 changes: 4 additions & 0 deletions packages/i18n/src/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,10 @@ const fr = {
undoing: "Annulation…",
undoConfirm: "Annuler cet import ? Les enregistrements créés seront supprimés et les enregistrements mis à jour seront rétablis à leurs valeurs précédentes.",
reverted: "Annulé",
undoPartial: "{{count}} lignes n'ont pas été annulées. Annuler à nouveau ne réessaie que ces lignes.",
undoPartial_one: "{{count}} ligne n'a pas été annulée. Annuler à nouveau ne réessaie que cette ligne.",
undoPartial_many: "{{count}} de lignes n'ont pas été annulées. Annuler à nouveau ne réessaie que ces lignes.",
undoPartial_other: "{{count}} lignes n'ont pas été annulées. Annuler à nouveau ne réessaie que ces lignes.",
jobStatus: {
pending: "En attente",
running: "En cours",
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,9 @@ const ja = {
undoing: "取り消し中…",
undoConfirm: "このインポートを取り消しますか?作成されたレコードは削除され、更新されたレコードは以前の値に戻されます。",
reverted: "取り消し済み",
undoPartial: "{{count}} 行を取り消せませんでした。もう一度取り消すと、これらの行だけを再試行します。",
undoPartial_one: "{{count}} 行を取り消せませんでした。もう一度取り消すと、この行だけを再試行します。",
undoPartial_other: "{{count}} 行を取り消せませんでした。もう一度取り消すと、これらの行だけを再試行します。",
jobStatus: {
pending: "待機中",
running: "実行中",
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,9 @@ const ko = {
undoing: "되돌리는 중…",
undoConfirm: "이 가져오기를 되돌릴까요? 생성된 레코드는 삭제되고 업데이트된 레코드는 이전 값으로 복원됩니다.",
reverted: "되돌림",
undoPartial: "{{count}}개 행을 되돌리지 못했습니다. 다시 되돌리면 이 행만 다시 시도합니다.",
undoPartial_one: "{{count}}개 행을 되돌리지 못했습니다. 다시 되돌리면 이 행만 다시 시도합니다.",
undoPartial_other: "{{count}}개 행을 되돌리지 못했습니다. 다시 되돌리면 이 행만 다시 시도합니다.",
jobStatus: {
pending: "대기 중",
running: "실행 중",
Expand Down
4 changes: 4 additions & 0 deletions packages/i18n/src/locales/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,10 @@ const pt = {
undoing: "Desfazendo…",
undoConfirm: "Desfazer esta importação? Os registros criados serão excluídos e os registros atualizados voltarão aos valores anteriores.",
reverted: "Desfeita",
undoPartial: "{{count}} linhas não foram desfeitas. Ao desfazer novamente, só essas linhas serão tentadas de novo.",
undoPartial_one: "{{count}} linha não foi desfeita. Ao desfazer novamente, só essa linha será tentada de novo.",
undoPartial_many: "{{count}} de linhas não foram desfeitas. Ao desfazer novamente, só essas linhas serão tentadas de novo.",
undoPartial_other: "{{count}} linhas não foram desfeitas. Ao desfazer novamente, só essas linhas serão tentadas de novo.",
jobStatus: {
pending: "Pendente",
running: "Em execução",
Expand Down
5 changes: 5 additions & 0 deletions packages/i18n/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,11 @@ const ru = {
undoing: "Отмена…",
undoConfirm: "Отменить этот импорт? Созданные им записи будут удалены, а обновлённые — восстановлены к прежним значениям.",
reverted: "Отменён",
undoPartial: "Не удалось отменить {{count}} строк. Повторная отмена затронет только эти строки.",
undoPartial_one: "Не удалось отменить {{count}} строку. Повторная отмена затронет только эту строку.",
undoPartial_few: "Не удалось отменить {{count}} строки. Повторная отмена затронет только эти строки.",
undoPartial_many: "Не удалось отменить {{count}} строк. Повторная отмена затронет только эти строки.",
undoPartial_other: "Не удалось отменить {{count}} строки. Повторная отмена затронет только эти строки.",
jobStatus: {
pending: "Ожидает",
running: "Выполняется",
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,9 @@ const zh = {
undoImport: '撤销导入',
undoing: '撤销中…',
reverted: '已撤销',
undoPartial: '{{count}} 行未能撤销。再次撤销只会重试这些行。',
undoPartial_one: '{{count}} 行未能撤销。再次撤销只会重试这一行。',
undoPartial_other: '{{count}} 行未能撤销。再次撤销只会重试这些行。',
undoConfirm: '撤销此次导入?它新建的记录将被删除,它更新的记录将恢复为之前的值。',
},
bulk: {
Expand Down
Loading
Loading