The board-open self-heal is broadened from the #6484 list-unbind alone to a
shared repair set (models/lib/boardRepair.js planner + server/lib/repairBoardData.js):
- #6484: lists wrongly bound to a swimlane -> cleared back to board-wide, so the
list stops "disappearing" from the other swimlanes;
- cards with no swimlaneId (null/''/missing), which never render in the Swimlanes
view -> assigned to the board's first swimlane;
- orphaned cards whose swimlaneId points at a DELETED swimlane (invisible cards)
-> reassigned to the first swimlane. A card on an existing but archived swimlane
is NOT treated as orphaned.
The same repair set now runs in BOTH places:
- Board open: boardBody.js maybeRepairBoard -> boardRepairNeeded / repairBoardData
(server/methods/repairBoardData.js), once per board, admin-gated, fire-and-forget.
- MongoDB <-> FerretDB v1 (SQLite) text migration: migrateTextDatabase runs
repairAllBoards() on the live database BEFORE copying, so the migrated copy is
clean too. It reports a new "repairing" phase (boardsDone/boardsTotal/repaired).
Both flows drive ONE shared progress dashboard (migrationProgress), now:
- mounted app-wide (defaultLayout) so it shows for an Admin Panel database
migration as well as a board-open repair;
- fed from the DB-migration status poll (attachments.js driveMigrationDashboard);
- styled in WeKan blue (#2980b9) instead of the old purple/green;
- branded with the configured Product name (from the earlier commit).
Tests: tests/boardRepair.test.cjs (planner + server/migration/dashboard source
guards, 11 checks) and the updated tests/listUnbindRepair.test.cjs pass.
Thanks to xet7 !
(Arabic and its variants, Persian/Farsi, Hebrew, Uyghur, Uzbek-Arabic and
Yiddish — the languages flagged `rtl: true` in `imports/i18n/languages.js`).
Previously only some pages flipped. The root `<html>` element now gets a
reactive `dir="rtl"`/`dir="ltr"` attribute that follows the chosen language, so
the whole UI mirrors at once. To make this work on every page rather than a
handful, all directional component CSS was converted to CSS logical properties
(`margin-left`→`margin-inline-start`, `left:`→`inset-inline-start:`,
`text-align: left`→`text-align: start`, `float: left`→`float: inline-start`,
and the mirror-image right/end variants) across 48 stylesheets, which flip
automatically with `dir`. Horizontal-centering rules using
`left: 50%` + `transform: translate(-50%, …)` were intentionally kept physical,
since those already center correctly in both directions. The calendar view also
renders RTL. Thanks to xet7 and Claude.
- Tests for the RTL UI. A fast, server-less `tests/rtl.test.js` (run with
`node tests/rtl.test.js`) checks that exactly the expected languages are
flagged `rtl: true`, that the direction helper maps each language to the right
`dir` value, that the root `<html>` and the client keep `dir` in sync, and —
as a regression guard — that component CSS keeps using logical properties
(no physical `margin-left`/`float: left`/bare `left:` offsets sneak back in).
A Playwright browser spec `tests/playwright/specs/18-rtl-layout.e2e.js` drives
the app in both English (LTR) and Arabic (RTL) and asserts, on the boards list,
board view, card details, my-cards / due-cards / global-search, the admin
settings page and the login page, that the direction is correct, the
translated text is visible, and leading-edge content (the boards menu, the
first board list) sits on the correct side. Thanks to xet7 and Claude.
- Fixed the "Meteor unit tests" CI job hanging until its 45-minute timeout. The
workflow set `TEST_WATCH: '0'`, but meteortesting:mocha computes
`testWatch: TEST_WATCH || …` and the string `'0'` is truthy in JavaScript, so
it turned on watch mode and the process never exited. Removing the env var lets
`meteor test --once` finish and exit with the correct status.
Thanks to xet7 and Claude !
Fixes#6136,
fixes#3376,
fixes#884