[4.117.0]
Update wekan to 9.80
Full Changelog
Admin Panel Domains table: pagination, column sort and search (like the Board Table view): The Admin Panel > People > Domains table loaded every domain (aggregated from all users) into the browser at once, with a fixed order and no search. It now behaves like the Board Table view: the server aggregates the domains and returns only one small page, so the whole list is never sent to the browser. You can order by the Domain or Users column (click the header to toggle ascending / descending, with a / indicator) and filter with a search box; prev/next controls page through the results. The search + sort + slice runs in the new pure, unit-tested models/lib/domainTablePage.js behind a new getDomainsWithUserCountsPage admin method (server/models/users.js), and the domainGeneral template (client/components/settings/peopleBody.{jade,js,css}) is now self-contained and fetches only the current page. Covered by tests/domainTablePage.test.cjs. Thanks to xet7.
Verified and added a regression test for the board-invitation email language: Confirmed that a board-invitation email is localised in the existing recipient's own profile language, or when the invitee is a new account created by the invite in the inviter's profile language, defaulting to en (en.i18n.json) when none is set. The behaviour was already correct; the language choice is now extracted into the pure, unit-tested models/lib/inviteEmailLanguage.js used by inviteUserToBoard, and locked in by tests/inviteEmailLanguage.test.cjs. Thanks to xet7.
Linked-card minicard now shows the cover image of the real card: A linked card (created by "Link card to this card") on one board did not show the cover image of the real card it points at on another board, even though the card's other fields did. A linked card is only a placeholder its real content lives on the card at linkedId and every other minicard getter resolves through the real card (getTitle/getReceived/getDue/), but the cover helpers read this.coverId directly, and a linked card has no coverId of its own. The real card's cover attachment is already published to the linking board (see the "linked cards" / "attachments for linked cards" children of the board publication), so this was purely a client-side resolution gap. Card.cover() and the minicard cover() helper now resolve the cover id through the real card via the pure, unit-tested models/lib/linkedCardCover.js; normal cards are unaffected. Covered by tests/linkedCardCover.test.cjs. Thanks to 32Dexter and xet7.
Fix date-picker calendar stays fully visible when opened low on a scrolled page: Opening a date field (due/start/end date, or a date custom field) low on the screen showed the calendar popup extending past the visible area, and because the pop-over is position: absolute (document coordinates) scrolling to reach it moved the calendar along with the page, so the full calendar could never be seen (the workaround was to close it, drag the field to the center and reopen). Popup._getOffset computed the space above/below the opener and the clamped top from the opener's DOCUMENT offset mixed with the VIEWPORT height, ignoring the page scroll, so on a scrolled page the anchored popup landed outside the visible viewport. The geometry now runs in viewport coordinates (subtracting the page scroll) and clamps the popup fully within the visible viewport, then converts back to document coordinates for the absolute style; when the page is not scrolled the output is unchanged. Extracted the math into the pure, unit-tested client/lib/popupOffset.js, used by client/lib/popup.js. Covered by tests/popupOffset.test.cjs. Thanks to MarcusDger and xet7.