Wekan
Open source kanban board application built with Meteor
Alternative to: trello
v10.42
2026-07-27v10.42 2026-07-27 WeKan ® release
This release fixes the following bugs:
Every popup had 10px of empty space above it that nothing asked for. Thanks to xet7.
The space above the first row of Board Settings, Board View, Member Settings,
Sort Cards, Change Watch, Change Visibility and Swimlane Actions — and above
the Title field of Rename Board — was much larger than the space beside it.
None of it came from popup.css: peopleBody.css and translationBody.css
each carried a bare .content-wrapper { margin-top: 10px }, and
.content-wrapper is not a settings class at all — the only element in WeKan
with that class is the scrolling body of a POPUP, so those two strays pushed
the content of every popup in the app down by 10px. They are gone, and the gap
that is left is 6px under the header plus the content’s 12px of padding = the
same 18px the content has beside it. Change Visibility and Change Watch also
lay their rows out as three left-aligned columns now — icon, name, description
— with the check mark of the active row in a track of its own, so it can no
longer push that row’s description out of line with the others.
tests/popupSpacing.test.cjs pins both, and fails again if any stylesheet
styles a popup-internal class without saying which popup.
The board bar centers its items, and the hamburger sits where its space middles. Thanks to xet7.
The second header bar centred its items inside a content box that had 7px of
padding above and none below, so everything sat half that distance high — most
visibly the board title, the tallest item in the row. The button groups then
carried a 3px top margin, which is a shift and not centring, so they hung below
the title’s centre line. The padding is symmetric now, wrapped rows are
separated by row-gap instead of that margin, and the title centres on its own
text rather than on a line box far taller than it. The sidebar hamburger had
2px of margin on one side and 8px on the other, which left an empty strip
between it and the end of the bar; equal margins put it in the middle of the
space between its divider and that edge.
Every upload threw in getFileStrategy, so no new file was mime-checked. Thanks to xet7.
From the dev-server log, on a plain attachment upload: [onAfterUpload] filename hardening failed: TypeError: Cannot read properties of undefined (reading 'gridFsFileId'). getFileStrategy read
fileObj.versions[versionName].meta.gridFsFileId to decide the storage, and a
freshly uploaded file has no meta on its version — only a GridFS one does —
so that read threw on EVERY upload. onAfterUpload catches and logs, so the
upload succeeded and looked fine while the two things that hook does were
silently skipped for every new file: detecting the real mime type and
correcting the stored filename from it. All three optional places are read
defensively now, and the decision is unchanged where the data is there.
Migrated images show in the card view again. Thanks to S0QR2 and xet7.
Reported after upgrading from WeKan 6: an attached image is visible in board
view, downloads correctly from the card, and yet the card view shows an empty
white box that cannot be maximized — while cards created after the upgrade are
fine. The card view does not look at the file, it looks at the flags
Meteor-Files writes at upload time (if(isImage) img … else span= extension),
and an attachment that came through a migration can arrive without them, and
often without extension or type either. The download button worked because
a download needs no flag. models/lib/attachmentKind.js is now the one place
that derives the kind — from the mime type where the document has one, in any
of the fields that have carried it, and from the file name where it does not; a
flag the document states is believed, and the name is consulted only when no
type is stated. The gallery, the “add cover” menu and the viewer all ask it,
and a startup repair writes the same answer back to the documents so the REST
API and the exports agree with the screen. tests/attachmentKind.test.cjs pins
the rules.
and has the following developer-facing changes:
Two test-harness fixes the newest run found. Thanks to xet7.
The node suites got four assertions further and stopped in the same file: two
more cpuExec expectations still spelled the qemu-wrapped command as a bare
name, which cpu-exec resolves to an absolute path now. And WebKit failed
33-board-domains with “Unexpected userId after login” — the admin’s id, when
the test had just switched to the non-admin: loginWithToken logged the new
user in over a session that was still someone else’s, so the poll could not
tell “not landed yet” from “landed on the wrong user”. It logs the previous
user out first and waits for an empty session, with a 15s settle deadline for a
loaded three-browser run.
cpu-exec hands qemu-user a path it can open, and its test stops assuming the machine. Thanks to xet7.
First real run of the node suites — they had never run anywhere until the “Run
ALL tests” change — and cpuExec.test.cjs failed, which is what that change
was for. Two real things behind it. qemu-user does not search PATH: it opens
the file it is given, so a bare command name (cpu-exec --features x86_64=avx mongod …) reached qemu as a relative path that does not exist and qemu exited
1 having run nothing — on exactly the CPU this helper exists for. cpu-exec
resolves the name with type -P first and hands over an absolute path; an
absolute path is passed through as before. And the test asked for “no qemu”
with PATH=/usr/bin:/bin, which is only true on a machine without qemu-user
installed; it now builds a PATH holding exactly the tools cpu-exec uses and
nothing else, so the case is the same everywhere.
Thanks to above GitHub users for their contributions and translators for their translations.