Compare commits

..
3273 Commits
Author SHA1 Message Date
NotAlexNoyle 6e4c0539af Exclude CODEOWNERS from language statistics 2026-10-31 16:52:22 -04:00
NotAlexNoyle b8fcef2fd4 Add CODEOWNERS (one staff approval) 2026-10-31 16:52:21 -04:00
NotAlexNoyle 4e2e6adc73 Fix card details import 2026-06-13 11:54:24 -04:00
NotAlexNoyle 091541a960 Hide minicard completion checkbox 2026-06-13 11:52:03 -04:00
github-actions[bot] 967b8482d3 Bump versions for v9.42 2026-06-13 14:38:34 +00:00
Lauri Ojansivu cb43837c32 Updated ChangeLog. 2026-06-13 17:31:44 +03:00
Lauri Ojansivu 899617bd4d Greatly improved import from Trello to WeKan.
- Attachments now import. Trello attachment URLs require OAuth to download, so
  WeKan could not fetch them. The Trello import page now has two separate file
    fields: a **.json** field for a single Trello board, and a
    **.zip** field for a package produced by the
    [Trello Card Attachments Downloader](https://github.com/wekan/trello-attachments-downloader).
    The .zip may contain one *or more* board .json files together with each
    board's attachments in a board-name subfolder. The .zip is uploaded over HTTP
    and processed entirely on the server (the attachment bytes never travel over
    the realtime WebSocket, which previously overflowed the connection and made
    the page flicker): WeKan detects every board .json, matches each board to its
    attachment subfolder by name, streams each file straight into the Default
    file storage, imports all boards, then opens All Boards. The upload is guarded
    against abuse — it rejects oversized uploads, zip bombs (too many files or too
    much uncompressed data, per-file size caps) and unsafe entry paths (absolute
    paths or `..` traversal), and never overwrites existing files (stored under
    generated ids). The importer also reads attachments from `card.attachments`
    (newer Trello exports), not only from the action log, and uses the correct
    Meteor-Files insert API (the previous calls were no-ops on Meteor 3). Single
    board imports (the .json file or the pasted JSON, after the map-members step)
    now run through the same server-side HTTP path rather than the realtime
    `importBoard` method, so a heavy import can no longer drop the WebSocket and
    get retried in an endless loop (the page flickering with "Invalid frame
    header" / repeated "logged out" errors). When importing only a single board
    .json and you have saved Trello API key and token, WeKan uses them on the
    server to download that board's attachments, background image, member
    avatars and card stickers from Trello (a .json export often omits stickers;
    avatars only fill in mapped users who have none — an existing avatar is never
    overwritten); each download is best-effort and a failure never aborts the
    import. After a single-board import the new board's data is subscribed and
    loaded before opening it, so it shows its swimlanes, lists and cards
    immediately instead of needing a browser page reload (the HTTP import, unlike
    the old realtime method, does not push the written documents to the client by
    itself).
  - Import Trello-only card features: stickers (shown as Font Awesome icons on
    minicards and the card detail), card cover (color or attachment), card
    location (name, address, coordinates with an OpenStreetMap link), and the
    due-date "complete" checkbox shown on the minicard. Trello's two named
    sticker packs are renamed and highlighted (the icon keeps its normal colour)
    so they stay distinct: the "taco" pack becomes "mascot" with an underlined
    icon, and the "pete" pack becomes "computer" with a ring around the icon,
    e.g. "pete-ghost" imports as "computer ghost" with a Snapchat-ghost icon.
    Several named stickers that used to share an icon now get their own Font
    Awesome 4.7 icon (mascot active => heartbeat, pixel => qrcode, proto =>
    flask, embarrassed => meh-o, clean => bath, computer shipped => truck).
  - Live Trello API import: paste your Trello API key and token on the Trello
    import page to list all your Trello workspaces and boards, then import all
    or selected boards together with their attachments (downloaded
    server-side). Imported boards are placed under a personal workspace named
    after their Trello workspace, created by name if it does not exist, under an
    optional parent workspace you choose. The API client respects Trello's rate
    limits: it spaces out requests, honours `Retry-After` on HTTP 429, retries
    transient 5xx and network errors with capped exponential backoff, and
    reports a clear error on an invalid key/token (401). After a successful API
    import you are taken to the All Boards page where the new boards appear.
  - The live API import runs as a background job on the server: you can navigate
    away and come back to the Trello import page to watch progress, see
    per-board results, and read the full error log. Errors are shown in a
    selectable text box with a one-click "Copy to clipboard" button (and you can
    still select and copy just part of the text) so they are easy to share when
    fixing issues. If the import stops on a fatal API error (invalid token, or
    rate limit still failing after retries) you can fix the cause and Resume
    from where it left off, and a server restart leaves the job paused for
    resuming rather than lost. You can also Cancel the import, or Cancel and
    delete the boards already imported, to start the whole process over cleanly.
  - You can optionally save your Trello API key and token with the Save and
    Delete buttons on the import page. When saved, they are stored only on the
    server, never sent back to the browser, and are reused automatically when
    you list workspaces or import (so you do not have to paste them again); a
    "saved" indicator is shown, Save can overwrite them with new values, and
    Delete clears them from the database. If you do not save them, they are kept
    only in server memory for the running import and re-supplied when you resume.
  - Larger Trello JSON exports can be selected as a file instead of pasted.
  - Keep imported usernames for later mapping. Imported members that match an
    existing WeKan user (by username, or by a previously recorded imported
    username) are mapped automatically, and the imported username is remembered
    on that user so future imports map too. Members with no matching WeKan user
    are no longer lost: their usernames are kept on the board, so an admin can
    map them to real users later in Admin Panel / People (Imported Usernames),
    without having to map everyone up front at import time.
  Thanks to xet7 and Claude.
- Board background images can now be stored in WeKan. A new `backgrounds` file
  storage directory is created alongside `attachments` and `avatars` (using the
  current default storage backend), and Board menu → Board backgrounds lets a
  board admin upload background images, set one as the active board background,
  download, and delete them. Board export now includes the board's background
  images and re-imports them, and a Trello board's background image is
  downloaded and stored on import (so it keeps working even if the original
  Trello URL later changes). Thanks to xet7 and Claude.
- Stickers can be added to and removed from cards directly in WeKan, chosen from
  a set of Font Awesome icons similar to Trello's stickers (previously stickers
  only arrived via Trello import). The picker also includes every "mascot"
  (underlined) and "computer" (ringed) highlighted sticker that a Trello import
  can produce — generated from the same icon mapping the importer uses — so any
  imported sticker can also be added by hand. Stickers show on the minicard and
  in the card detail. Thanks to xet7 and Claude.
- The Trello-style "complete" checkbox (mark a card complete/incomplete,
  independent of the due date) is shown as an animated green checkbox to the
  left of the card title, both on the minicard and in the opened card, with
  "Mark as complete" / "Mark as incomplete" tooltips. It uses the same animated
  checkbox style as Admin Panel / Settings / Announcements and is vertically
  centered with the title text, and the two stay in sync. The minicard and the
  opened-card checkboxes use the same checked style (the board theme's colour, or
  green when no theme is set), so they always look identical. Subtask checkboxes
  and the card-detail custom-field checkbox now use the same animated checkbox as
  checklist items (they previously used static square icons), so every checkbox
  on a card animates consistently. Thanks to xet7 and Claude.
- Cards can now have multiple locations, similar to multiple members. The card
  detail shows a Location section (after Labels and Stickers) listing each
  location with its name, address and an OpenStreetMap link, with an "Add
  location" button to add more and a button to edit or remove each one. A single
  location imported from Trello keeps working and is shown in the same list. The
  Add/Edit location popup can also detect a location from any map link (Google
  Maps, OpenStreetMap, Bing Maps, Apple Maps, or generic `?q=`/`?ll=` links):
  paste the link, press "Detect", and the latitude, longitude and (when present)
  the place name/address are filled in automatically. The popup also has an
  "Open map links at" setting (OpenStreetMap by default, or Google/Bing/Apple
  Maps) saved to the user profile, controlling which map service the location
  "Open in map" links use. Thanks to xet7 and Claude.
- The opened card now docks to the top of the window, overlaying the global and
  board header bars, instead of opening downward from the clicked minicard, and
  it can be dragged all the way to the top without its top hiding behind those
  bars. (At 100% zoom the board wrapper no longer sets a `transform: scale(1)`,
  which had made it the containing block for the fixed card and trapped it below
  the headers.) Thanks to xet7 and Claude.

Fixes #5727,
fixes #2457,
fixes #5818,
fixes #755
2026-06-13 17:19:51 +03:00
Lauri Ojansivu 2757bfb365 Updated translations. 2026-06-13 17:18:06 +03:00
Lauri Ojansivu 1ed942bb8a Updated translations. 2026-06-13 09:09:57 +03:00
Lauri Ojansivu 179157ccd2 Updated translations. 2026-06-13 07:45:56 +03:00
Lauri Ojansivu 3e36b931a6 Updated translations. 2026-06-13 06:57:06 +03:00
Lauri Ojansivu c9e60847d0 Updated translations. 2026-06-13 06:35:09 +03:00
Lauri Ojansivu 4d83dc0c05 Updated translations. 2026-06-13 05:45:53 +03:00
Lauri Ojansivu 995965d157 Updated translations. 2026-06-13 03:01:17 +03:00
Lauri Ojansivu 15fbb314b0 Updated ChangeLog. 2026-06-12 20:21:35 +03:00
Lauri Ojansivu 68e0032c6d Fix Board Export/Import error.
Fix import/clone of inconsistent board JSON so the newest WeKan can import
board exports from any newer or older WeKan version. A syntactically valid
export can still be internally inconsistent (a board member whose user
account was deleted is no longer in the export's `users`, cards pointing at a
missing `listId`, orphaned checklists, or a missing `lists` array). Such
exports previously failed import as "error-json-malformed" or silently
dropped data (cards with an undefined list never rendered). The importer now
skips dangling user references in the member mapper (client
`wekanMembersMapper`, server `wekanmapper` used by board cloning, and
`WekanCreator`), falls back to the first imported list — creating one default
list when the export has none — for cards with a dangling `listId`, and skips
orphaned checklists whose card is missing. The importer remains
version-agnostic: it never reads `_format`, normalizes old `id` vs `_id`
fields, and ignores the source `boardId`.
Added `tests/wekanCreator.inconsistent.test.js` covering these cases.

Thanks to titver968, xet7 and Claude !

Fixes #6371
2026-06-12 20:15:56 +03:00
Lauri Ojansivu cffca535b5 Updated ChangeLog. 2026-06-12 19:49:13 +03:00
Lauri Ojansivu b2d2632e3b Fix Wrong card number after Import.
Thanks to titver968, xet7 and Claude !

Fixes #6372
2026-06-12 19:49:13 +03:00
Lauri Ojansivu 119379d4b4 Updated translations. 2026-06-12 19:49:13 +03:00
github-actions[bot] c434f83dfc Bump versions for v9.41 2026-06-11 22:17:23 +00:00
Lauri Ojansivu 1527f364b1 Updated ChangeLog. 2026-06-12 01:13:32 +03:00
Lauri Ojansivu 5779d94d78 Updated translations. 2026-06-12 01:12:38 +03:00
Lauri Ojansivu 096a3dc46b Add pagination and search to Admin Panel / Reports. Fix pagination at Admin Panel / Organizations and Teams.
Thanks to xet7 and Claude !
2026-06-12 01:12:38 +03:00
github-actions[bot] c883f31d35 Bump versions for v9.40 2026-06-11 18:35:38 +00:00
Lauri Ojansivu 1fa9714d4e Updated ChangeLog. 2026-06-11 21:30:00 +03:00
Lauri Ojansivu 53b64ee222 Fix releasing Helm Charts.
Thanks to xet7 and Claude !
2026-06-11 21:30:00 +03:00
github-actions[bot] e4b8396a3b Bump versions for v9.39 2026-06-11 18:19:21 +00:00
Lauri Ojansivu 8cf7e83493 Updated ChangeLog. 2026-06-11 21:15:15 +03:00
Lauri Ojansivu 68220f944b Fix building Docker image.
Thanks to xet7 and Claude !
2026-06-11 21:12:31 +03:00
github-actions[bot] fc4d84574e Bump versions for v9.38 2026-06-11 17:52:20 +00:00
Lauri Ojansivu 2989e1d5b1 Prepare v9.38 release 2026-06-11 20:47:00 +03:00
Lauri Ojansivu 5844e20d55 Fix Incorrect link in invite email.
Thanks to sbaecker, xet7 and Claude !

Fixes #6349
2026-06-11 20:44:25 +03:00
Lauri Ojansivu 2376237b6e Updated ChangeLog. 2026-06-11 20:23:48 +03:00
Lauri Ojansivu bcf55bdc3a Fix Admin Panel/People View is broken.
Thanks to titver968, xet7 and Claude !

Fixes #6370
2026-06-11 20:17:51 +03:00
Lauri Ojansivu ac44706461 Updated ChangeLog. 2026-06-11 20:04:04 +03:00
Lauri Ojansivu 928db8d675 Fix Docker image is broken.
Thanks to titver968, planet-goldfish, xet7 and Claude !

Fixes #6369
2026-06-11 20:04:04 +03:00
github-actions[bot] 5c9407f729 Bump versions for v9.37 2026-06-11 14:34:36 +00:00
Lauri Ojansivu 93f50a7fb3 Prepare v9.37 release 2026-06-11 17:27:45 +03:00
Lauri Ojansivu 39d84f8fe8 Update release website script version numbering.
Thanks to xet7 and Claude !
2026-06-11 17:25:12 +03:00
Lauri Ojansivu d369a3614a [Fixed BoardBleed: broken access control lets any authenticated user move their Cards/Lists/Swimlanes into a private board they are not a member of (cross-board write via collection allow rule)](https://github.com/wekan/wekan/security/advisories/GHSA-gm7v-pc38-53jr)
(CWE-284, CWE-639). WeKan boards are membership-scoped, but the DDP collection write
policies for Cards, Lists and Swimlanes (`server/permissions/cards.js`,
`server/permissions/lists.js`, `server/permissions/swimlanes.js`) authorized an update by
checking only the CURRENT (pre-update) `boardId` of the document — i.e. the attacker's own
source board — and never validated the NEW `boardId` supplied in the update modifier.
Because every logged-in user can create a board where they are admin, an attacker could take
a document they own and, in a single `/cards/update`, `/lists/update` or `/swimlanes/update`
DDP call, `$set` its `boardId` (plus `swimlaneId`/`listId`) to a victim's private board: the
allow rule saw the attacker's own source board, approved the write, and the document was
relocated into a board the attacker is not a member of and cannot even read. This let an
unprivileged user inject arbitrary cards/lists/swimlanes (attacker-controlled titles,
descriptions, assignees, etc.) into any private board by id, defeating board-level access
control. The REST API for the same operation
(`PUT /api/boards/:boardId/lists/:listId/cards/:cardId` with `newBoardId`) was not affected
because it correctly calls `Authentication.checkBoardWriteAccess(req.userId, newBoardId)` on
the destination board; only the DDP allow/deny layer was vulnerable. Fixed by adding a
`denyCrossBoardMove` helper in `server/lib/utils.js` and a `Cards.deny`/`Lists.deny`/
`Swimlanes.deny` `update` rule on each collection that rejects any update whose modifier
`$set`s a `boardId` on which the caller does not have write access, so a cross-board move is
only allowed into a destination board where the user is an active write-capable member.
Affected Wekan v9.35 and earlier.

Thanks to 0xzap, xet7 and Claude.
2026-06-11 17:13:06 +03:00
Lauri Ojansivu 078ab4125e Release scripts: Fix Launchpad build Snap.
Thanks to xet7 and Claude !
2026-06-11 06:34:54 +03:00
github-actions[bot] 3f0dc8b7be Bump versions for v9.36 2026-06-11 02:25:57 +00:00
Lauri Ojansivu c020e09aff Release scripts: Removed build-mac-amd64 that does work.
Thanks to xet7 and Claude !
2026-06-11 05:15:37 +03:00
Lauri Ojansivu b0c007d44f Updated GitHub workflows.
Thanks to xet7 and Claude !
2026-06-11 01:50:08 +03:00
github-actions[bot] b777ee2a12 Bump versions for v9.36 2026-06-10 21:19:30 +00:00
Lauri Ojansivu b328cae552 Prepare v9.36 release 2026-06-11 00:10:49 +03:00
Lauri Ojansivu 5357bb47c3 Updated release scripts.
Thanks to xet7 and Claude !
2026-06-10 23:49:17 +03:00
Lauri Ojansivu 447877733b Updated dependencies.
Thanks to developers of dependencies !
2026-06-10 22:23:27 +03:00
Lauri Ojansivu feb491f8d4 Updated ChangeLog. 2026-06-10 21:48:16 +03:00
Lauri Ojansivu 8f59d76a4e Update release scripts, trying to fix GitHub Actions builds.
Thanks to xet7 and Claude !
2026-06-10 21:46:00 +03:00
Lauri Ojansivu 3a52565ab4 Updated ChangeLog. 2026-06-10 19:42:32 +03:00
Lauri Ojansivu 08ae61161c Fixed TokenBleed: unauthenticated login-token minting via un-awaited auth check in
`POST /api/createtoken/:userId`](https://github.com/wekan/wekan/blob/main/CHANGELOG.md)
(CWE-863, CWE-287). `Authentication.checkUserId` in `server/authentication.js` is an
`async` function, so its 401 (undefined `userId`) and 403 (not an admin) throws become
rejected promises rather than synchronous exceptions. The REST handlers in
`server/models/users.js` and `server/models/boards.js` called it without `await` inside a
plain synchronous `try/catch`, which cannot catch a rejected promise, so the failed check
never stopped execution. `POST /api/createtoken/:userId` then went on to mint and return a
usable login token for any user ID in the URL — including an admin — with no credentials at
all (unauthenticated account takeover). The same detached-rejection bypass also affected
`GET /api/users`, `GET /api/users/:userId`, `PUT /api/users/:userId`, `POST /api/users/`,
`DELETE /api/users/:userId`, `POST /api/deletetoken`, `GET /api/boards`,
`GET /api/boards_count`, `DELETE /api/boards/:boardId`, `GET /api/users/:userId/boards` and
`POST /api/boards/:boardId/copy`. Fixed by awaiting every async `Authentication` check (and
making the two non-`async` handlers `async`) so a failed check rejects before any privileged
code runs. The same un-awaited pattern in the board/card/Excel/PDF export handlers
(`models/export.js`, `models/exportExcel.js`, `models/exportExcelCard.js`, `models/exportPDF.js`,
which were backstopped by `exporter.canExport()`) and in the checklist-create handler
(`server/models/checklists.js`) was given the same await pass. Affected Wekan v9.35 and earlier.

Thanks to Zion Boggan, xet7 and Claude.
2026-06-10 19:39:05 +03:00
Lauri Ojansivu 1835245943 Updated translations 2026-06-10 18:37:30 +03:00
Lauri Ojansivu 83de473e4e Updated ChangeLog. 2026-06-10 18:32:03 +03:00
Lauri Ojansivu a532ee7f14 Fix tests.
Thanks to xet7 and Claude !
2026-06-10 18:29:58 +03:00
Lauri Ojansivu f00b265b34 Updated ChangeLog. 2026-06-10 14:35:12 +03:00
Lauri Ojansivu 2931cc990f Add more API and fix API.
Thanks to xet7 and Claude !

Fixes #5998,
fixes #5897,
fixes #5846,
fixes #5819,
fixes #5813,
fixes #4815,
fixes #4811,
fixes #3062,
fixes #4743
2026-06-10 14:33:15 +03:00
Lauri Ojansivu 25a4672d6d Update build scripts.
Thanks to xet7 !
2026-06-10 11:57:04 +03:00
Lauri Ojansivu 969a4016ee Update rebuild-wekan.sh Node.js version 2026-06-10 11:25:06 +03:00
Lauri Ojansivu 5c2d7079ce Updated ChangeLog. 2026-06-08 22:06:29 +03:00
Lauri Ojansivu d1c71d0526 Updated Code of Conduct.
Thanks to xet7 !
2026-06-08 22:04:32 +03:00
Lauri Ojansivu 1fa2ab0146 Updated ChangeLog. 2026-06-08 21:24:52 +03:00
Lauri Ojansivu 26a03f4845 Improved CONTRIBUTING.md .
Thanks to xet7 !
2026-06-08 21:23:22 +03:00
Lauri Ojansivu 58bfad3adf Updated ChangeLog. 2026-06-08 20:46:29 +03:00
Lauri Ojansivu f1c2f1f40f Improved Security Advisory process.
Thanks to xet7 !
2026-06-08 20:43:54 +03:00
Lauri Ojansivu 7d3e8eb89f Updated ChangeLog. 2026-06-07 01:00:36 +03:00
Lauri Ojansivu 3fe8f602c8 Fix LDAP_SYNC_ADMIN_GROUPS so that admin status sync and group/role sync no longer require LDAP_GROUP_FILTER_ENABLE=true,
which only controls the login restriction filter.

Thanks to titver968, xet7 and Claude.

Fixes #6352
2026-06-07 00:58:46 +03:00
Lauri Ojansivu d87eed36a0 Updated ChangeLog. 2026-06-07 00:48:16 +03:00
Lauri Ojansivu 9cc0660410 Fix MultiSelect, so that it's possible to click select checkbox or minicard to select.
Thanks to xet7 and Claude !
2026-06-07 00:45:56 +03:00
Lauri Ojansivu 58ff88890d Updated ChangeLog. 2026-06-06 23:07:26 +03:00
Lauri Ojansivu 77d60b21a1 Fix Admin Panel / Reports icons and spacing.
Thanks to xet7 !
2026-06-06 23:05:12 +03:00
Lauri Ojansivu 9df2db0314 Updated translations. 2026-06-06 22:51:30 +03:00
Lauri Ojansivu 91839cf3ef Updated translations. 2026-06-06 22:39:05 +03:00
Lauri Ojansivu 74f2352387 v9.35 2026-06-06 10:54:38 +03:00
Lauri Ojansivu f299ca1285 Updated translations. 2026-06-06 10:29:24 +03:00
Lauri Ojansivu f47e67b5b4 Fixed Move Attachments and Avatars.
Thanks to xet7 and Claude !

Fixes #6364
2026-06-06 10:19:03 +03:00
Lauri Ojansivu fe16b94c1e Updated ChangeLog. 2026-06-06 09:59:16 +03:00
Lauri Ojansivu b77b62bfa2 Ask to install npm dependencies before running tests.
Thanks to xet7 and Claude !
2026-06-06 09:57:06 +03:00
Lauri Ojansivu 43d8bf1b92 Updated ChangeLog. 2026-06-06 09:31:39 +03:00
Lauri Ojansivu dca9427bfb New features:
- **Admin Panel / Attachments: the MongoDB GridFS page notes how to make legacy
  files visible.** A translatable line under the "MongoDB GridFS Storage" title
  reminds admins: "To have attachments and avatars visible, move them from
  CollectionFS to any other Storage." Thanks to Claude.
- **Admin Panel / Attachments: the Google Cloud Storage page now documents the
  required bucket permission.** A note under the "GCS Storage" title explains that
  the service account needs the **Storage Object Admin** role
  (`roles/storage.objectAdmin`) on the bucket (Cloud Console → Cloud Storage →
  Buckets → your bucket → Permissions → Grant access → add the service account →
  role "Storage Object Admin"), and that the bucket must exist in the same
  project — otherwise "Test connection" fails with `storage.objects.list denied`.
  Thanks to Claude.
- **Admin Panel / Attachments: a "Save" button next to the Enabled / Read toggles
  at the top of each cloud storage.** S3, Azure and Google Cloud Storage now have
  a Save button directly below the "[ ] Enabled  [ ] Read" row, so those toggles
  can be saved without scrolling to the bottom of the (now quite long) storage
  page. It saves the same way as the existing bottom Save button — the server
  merges that provider's config and preserves secrets left blank — and the bottom
  Save button is kept. (Filesystem and GridFS have only a Read toggle, which
  already saves the instant it is toggled, so they need no button.) Thanks to Claude.

Fixes:

- **Admin Panel / Attachments: "Run MongoDB compact" now actually compacts the
  database.** MongoDB refuses `compact` on an active replica-set primary unless
  `force: true` is given, so every collection failed with "will not run compact
  on an active replica set primary … use force:true to force" — and because the
  usual Meteor setup is a single-node replica set (only a primary, no
  secondaries), nothing was compacted at all and no disk space was reclaimed. The
  primary is now compacted with `force: true` (secondaries are still compacted
  without it, so the primary stays available while they run), so the GridFS
  collections are actually rewritten and freed space is returned to the
  filesystem. Thanks to Claude.
- **Admin Panel / Attachments: clearer cloud "Test connection" errors, and cloud
  config inputs are trimmed.** Testing an Azure/GCS/S3 connection used to report a
  single generic `Incomplete configuration or adapter not installed` even when the
  real problem was specific — e.g. Azure rejecting the config with `Invalid URL`
  (a stray space/newline in the account name, or a bad endpoint / connection
  string). `testCloudConnection` now reports the actual cause: adapter not
  installed, required fields missing, the adapter's own configuration error (such
  as `Invalid URL`), or the real `listFiles` error (auth failure, container not
  found, …). It also pre-validates the config and gives an actionable message
  before the adapter turns it into a cryptic error — e.g. for Azure it explains
  that the **Storage account name** must be just the account name (3–24 lowercase
  letters/numbers, e.g. `wekanstorage`, not a full `https://…` URL and with no
  spaces), or that the **Connection string** is malformed; and when Azure still
  returns `Invalid URL` the message appends which field to check. In addition, all
  cloud-storage text fields are now trimmed when read from the form, so
  leading/trailing whitespace from copy-paste no longer produces an invalid URL.

Thanks to xet7 and Claude.
2026-06-06 09:28:05 +03:00
Lauri Ojansivu 7f17616b75 Updated translations. 2026-06-06 09:23:15 +03:00
Lauri Ojansivu 4a9dcdd0ef Updated translations. 2026-06-06 08:41:23 +03:00
Lauri Ojansivu a1a4176ffb Updated ChangeLog. 2026-06-06 07:30:45 +03:00
Lauri Ojansivu a86a087915 New features:
- **Admin Panel / Attachments: "Calculate file counts" on every storage backend,
  shown right below the "Read" toggle.** Azure Blob Storage and Google Cloud
  Storage now have a "Calculate file counts" button (new `getAzureStorageStats` /
  `getGcsStorageStats` methods) that reports how many attachments and avatars are
  stored on that backend, matching what Filesystem, MongoDB GridFS and S3 already
  offer. The count is read from the stored file metadata (fast, no cloud API
  calls). The S3 button was also moved up to sit directly under its "Read"
  checkbox, so all backends are consistent. Thanks to Claude.
- **Admin Panel / Attachments: bilingual, self-documenting cloud-storage fields
  (S3, Azure and Google Cloud Storage).** Each cloud-storage setting now guides
  the admin from top to bottom with both English and translated text, so it is
  easy to follow along while clicking through the provider's Cloud Console:
  - the field **label** uses the provider's own console wording in English
    (e.g. *Access key ID*, *Secret access key*, *Storage account key*,
    *Service account key (JSON)*), with the translated label shown below it;
  - a literal **example** of what the value should look like
    (e.g. `eu-west-1`, an example bucket name / endpoint / connection string),
    which is intentionally not translated;
  - a short **description** of the value, in English and then translated;
  - the **Cloud Console menu path** showing exactly where to find or create the
    value (e.g. *AWS Console → IAM → Users → your user → Security credentials →
    Access keys → Create access key*; *Azure Portal → Storage accounts → your
    account → Access keys → key1*; *Google Cloud Console → IAM & Admin →
    Service accounts → … → Keys → Add key → Create new key → JSON*), again in
    English and then translated.
  The provider field names, examples and menu paths are kept in English so they
  match what the Cloud Console actually shows, while the descriptions and menu
  paths are also translatable; section titles, the enable/read/force-path-style
  checkboxes and the Test/Save buttons remain fully translated. Thanks to Claude.
- **Admin Panel / Attachments / Move Attachment: "Repair file locations" button
  and a persistent "last move" message.** The new **Repair file locations** button
  scans all attachments and avatars and finds any whose recorded storage
  (`versions.<v>.storage` / `path` / `meta.gridFsFileId`) no longer matches where
  the binary actually is — left inconsistent by an interrupted or failed move —
  and fixes the database to point at the real location: it detects the binary in
  GridFS (by the `metadata.fileId` stamped on upload, recovering files whose
  GridFS id reference was lost) or on the filesystem (using the storage
  strategy's own thorough path resolution, so the repair agrees with what a real
  download/move would find even when `versions.<v>.path` is stale), then corrects
  `storage`, `path` and `meta.gridFsFileId` accordingly. Cloud-stored files are
  left untouched, and files found nowhere are reported as "Not found". The scan is
  streamed (memory-safe) and shows a per-scope searched / repaired / not-found
  summary. Separately, after a move finishes the page now keeps showing
  the last move operation — source → destination (scope) and the date/time as
  `YYYY-MM-DD HH:MM:SS` — so it is clear what was last done. Thanks to Claude.

 New fixes:

- **Fixed moving attachments to S3 (and other cloud storage) failing and
  crashing the server.** Uploading to S3 failed two ways, each of which crashed
  the whole server because the rejection was unhandled and SyncedCron treats
  those as fatal. The `@tweedegolf/sab-adapter-amazon-s3` adapter uploaded with a
  `PutObjectCommand` whose `Body` was a live stream: (1) with no `ContentLength`
  the AWS SDK fell back to a chunked signed upload that needs a decoded content
  length, which was undefined for a stream of unknown size — `Invalid value
  "undefined" for header "x-amz-decoded-content-length"`; and (2) if the socket
  dropped mid-upload (`socket hang up`), the SDK's body-stream promise rejected
  unhandled. Fixed by uploading the file as a complete in-memory **buffer**
  (`addFileFromBuffer`) instead of a live stream: a buffer has a known length (no
  content-length error) and no socket-bound stream to re-reject. The cloud upload
  promise now never rejects — any failure is captured and exposed via
  `waitUntilStored()`, which `moveToStorage` checks inside a try/catch so a failed
  upload leaves the source file intact and is logged cleanly. (Files are moved one
  at a time, so peak memory is one file.) Thanks to Claude.
- **Fixed `TypeError: Cannot read properties of undefined (reading 'on')` when
  moving attachments between Meteor-Files/GridFS and Filesystem.** If a file's
  source binary was missing at its recorded location (e.g. a file left
  half-moved by an earlier interrupted run — storage says "gridfs" but the
  GridFS id reference is gone, or a filesystem path that no longer exists),
  `getReadStream()`/`getWriteStream()` returned `undefined` and `moveToStorage`
  (and `copyFile`) called `.on()` on it, throwing. Both now detect a missing
  read/write stream, log a clear message (which file, version, from→to storage,
  and why), **skip that file and leave the source intact** so no data is lost,
  and continue with the rest. Use the new "Repair file locations" button to fix
  the underlying inconsistent records. Thanks to Claude.
- **Fixed moving attachments/avatars from CollectionFS to Meteor-Files crashing
  the server, hanging the Admin Panel move at "File 1 / N", and leaving broken
  avatars.** Three problems in Admin Panel / Attachments / Move Attachment:
  - **Server crash on the first file** (`uncaughtException: TypeError: Cannot read
    properties of undefined (reading '_id')` at
    `AttachmentStoreStrategyGridFs.writeStreamFinished`). The current mongodb
    driver's GridFS `GridFSBucketWriteStream` `'finish'` event no longer passes
    the stored file document, so `finishedData._id` threw and killed the process
    (which is also why the move appeared stuck at "File 1 / 4" — the background
    job died mid-file and its persisted status was frozen). The GridFS strategy
    now reads the uploaded file id from the write stream itself (`gridFSFile._id`
    / `id`), the `'finish'` handler is wrapped so it can never crash the process,
    and a startup reconciliation clears a stale "running" move status left by a
    crashed run so the UI un-sticks and a new move can be started.
  - **Broken avatar after migrating avatars.** The bulk move only repointed card
    cover references (`cards.coverId`); a user's `profile.avatarUrl` still pointed
    at the deleted legacy `/cfs/files/avatars/<oldId>` URL, so the avatar rendered
    broken. The move now repoints `profile.avatarUrl` to the migrated avatar
    (`remapReferences` handles avatars), and migrated files stamp
    `meta.migratedFromId` so references can be repaired to the **exact** new file.
    The startup repair in `server/models/users.js` (previously a no-op: it
    string-replaced the URL prefix while keeping the now-deleted id and never
    saved the document) now points each affected user's avatar at their migrated
    Meteor-Files avatar — matched precisely by `meta.migratedFromId`, otherwise
    strictly by `userId` (newest migrated avatar first), so a user can only ever
    be given their own avatar, never another user's.
  - **`ObjectID` deprecation warning** from `models/lib/grid/createObjectId.js`
    (`MongoInternals.NpmModule.ObjectID` → `ObjectId`).

Thanks to Claude and xet7 !
2026-06-06 07:21:59 +03:00
Lauri Ojansivu f9ace4cde9 Updated translations. 2026-06-06 06:47:36 +03:00
Lauri Ojansivu 4677324425 Updated translations. 2026-06-06 05:23:18 +03:00
Lauri Ojansivu 7e5852c62c Updated ChangeLog. 2026-06-06 04:23:25 +03:00
Lauri Ojansivu e01f99eb52 Fix Dropdown list cannot be created with values.
**Fixed Dropdown custom field options not being addable / saving as empty.**
Creating a "Dropdown" custom field showed the "List Options" box, but pressing
Enter (or typing and saving) never added any option, and on the card the only
selectable value was `(none)`. The custom-fields sidebar component was migrated
from `BlazeComponent` to a plain `Template`, but the template still iterates the
options with `{{#each dropdownItems.get}}` — under BlazeComponent that resolved
to the instance's `dropdownItems` ReactiveVar, whereas a plain Template does not
expose instance variables to the template, so the list rendered nothing. Because
the options were never rendered as inputs, `getDropdownItems()` then overwrote
the ReactiveVar with the empty DOM on save and every entered value was dropped.
Fixed by re-adding the missing `dropdownItems` helper (returning the ReactiveVar),
matching the pattern the other migrated templates already use. Thanks to Claude.

**Fixed `Exception in global helper _` when opening the Create Custom Field
popup (and any translation containing a literal `%`).** i18n is configured with
a global sprintf post-processor (`postProcess: ["sprintf"]`), so every
translation is run through `i18next-sprintf-postprocessor`. The help text
`custom-field-stringtemplate-format` (`"Format (use %{value} as placeholder)"`)
contains a literal `%{value}` that sprintf cannot parse, so `vsprintf` threw and
crashed the global Blaze `_` translation helper — breaking that popup and any
string (in any language, including user translation overrides) that contains a
stray `%`. `TAPi18n.__` now retries without the sprintf post-processor when it
throws, returning the raw string (so `%{value}` is shown literally) instead of
crashing.

Thanks to rouceto1 and Claude.

Fixes #6357
2026-06-06 04:19:03 +03:00
Lauri Ojansivu 8ff9a41f2d Updated ChangeLog. 2026-06-06 04:14:25 +03:00
Lauri Ojansivu 075e86b00e **Fixed new checklists (and checklist items) on a newly added card not being
visible until logout/login.** The `board` publication batched checklists,
checklist items, comments and attachments into board-level cursors filtered by
`cardId: { $in: cardIds }`, where `cardIds` was a one-time snapshot. In
`reywood:publish-composite` a child cursor only re-runs when its parent (the
board) document changes, so the snapshot never refreshed when a card was added
— a checklist on a card created after subscribing matched no published card and
only appeared on the next subscribe (logout/login). This was a regression from
the "Optimized board loading" change, which had replaced the original reactive
per-card child cursors with these batched snapshots. Fixed by **denormalizing a
`boardId` field onto `Checklists` and `ChecklistItems`** so they can be
published with a single board-level cursor filtered by `boardId` — one cursor
per collection (keeping the load optimization) that still reacts to checklists
on newly added cards, because a new checklist is created already carrying the
board's id. `boardId` is set on insert (server `before.insert` hooks, plus
explicitly in the Trello/WeKan board importers, which use `direct.insert` and
bypass hooks), re-derived when a checklist/item or its card moves to another
card (`before.update` on `cardId`) or the card moves to another board
(`Cards.after.update` cascade), and backfilled for existing data by an
idempotent startup migration. New `{ boardId: 1 }` indexes were added on both
collections. Comments and attachments instead remain reactive as per-card
children of the cards cursor. Assigned-only board members still only receive
checklists for cards assigned to them (the board-level cursor falls back to the
assigned cards' ids for those roles).

Thanks to ahlgrimma and Claude !

Fixes #6361
2026-06-06 04:02:48 +03:00
Lauri Ojansivu f20080a603 Updated translations. 2026-06-06 03:26:10 +03:00
Lauri Ojansivu 3594d75b5d Updated ChangeLog. 2026-06-06 03:13:31 +03:00
Lauri Ojansivu 72767ad9a7 - Fixed SyncedCron crash.
**Fixed deleting archived lists (or many cards) crashing the server with
  `SyncedCron: Fatal error encountered (unhandledRejection): TypeError: Cannot
  read properties of undefined (reading 'boardId')` at
  `server/models/checklistItems.js`.** Deleting a list cascades into removing its
  cards, and each card's checklists, checklist items, comments and attachments
  (`cardRemover` in `models/cards.js`). `Cards.before.remove` called `cardRemover`
  **without `await`** (and was not `async`), so the card document was deleted
  first and the cascade then ran with the parent card already gone; the
  `ChecklistItems.before.remove` / `Checklists.before.remove` hooks dereferenced
  the now-undefined card (`card.boardId`) and threw, and because the promise was
  unhandled, SyncedCron caught the rejection and tore down all running cron jobs.
  Fixed by making `Cards.before.remove` `async` and awaiting `cardRemover` (so
  sub-items are removed while the card still exists), and the REST card-delete
  handler now runs `cardRemover` before removing the card. As defense in depth,
  every card-activity hook and helper that looked up a card and used its
  `boardId` / `listId` / `swimlaneId` now skips (with a warning) when the parent
  card — or, for checklist-completion activities, the parent checklist — is
  missing, instead of throwing: `before.remove` on checklist items and
  checklists, `Checklists.after.insert`, the `Cards.before.update` timing
  activity, and the shared `itemCreation` / `publishCheckActivity` /
  `publishChekListCompleted` / `publishChekListUncompleted` / `commentCreation`
  helpers (matching the guards already present in
  `server/models/cardComments.js`).

Thanks to titver968 and Claude !

Fixes #6366
2026-06-06 03:10:13 +03:00
Lauri Ojansivu 7db386fda3 Updated ChangeLog. 2026-06-06 02:55:55 +03:00
Lauri Ojansivu 39f3c89b0a Fixed upgrade crash.
Thanks to poc-sm and Claude !

Fixes #6367
2026-06-06 02:53:58 +03:00
Lauri Ojansivu 15a598525f Updated ChangeLog. 2026-06-06 02:10:21 +03:00
Lauri Ojansivu d30803276d - **Fixed Admin Panel / Attachments / Move Attachment doing nothing / crashing.**
Several issues in the bulk move:
- The GridFS source matcher required `meta.gridFsFileId` to be *absent*, but
  Meteor-Files always sets it, so selecting "MongoDB Meteor-Files" matched zero
  files and "nothing happened". The matcher now recognizes real GridFS files
  (`versions.*.storage === 'gridfs'` or a `meta.gridFsFileId` reference), and a
  "nothing to move" message is shown when a source is empty instead of silently
  doing nothing.
- Moving files crashed the whole server with
  `FilesCollection#findOne() not available in server` — `ReactiveCache.getAttachment`
  used a synchronous `findOne()`; it now uses `findOneAsync()`. The background
  job is also hardened so a single failing file is skipped instead of crashing
  the server via an unhandled rejection.
- The attachment **copy** API now honours the admin API upload limits (it
  previously skipped them).
- **Fixed the "MongoDB Meteor-Files" file-count statistic** in Admin Panel /
  Attachments, which counted *every* attachment metadata document (so files on
  the Filesystem were wrongly reported as being in GridFS). It now counts only
  attachments actually stored in GridFS, consistent with the move tool. Also
  renamed the mislabeled "Mongo-Files" column to "Meteor-Files". Thanks to Claude.
- **Unified attachment/avatar storage migration: move any → any.** Admin Panel /
  Attachments / Move Attachment can now move **Attachments, Avatars, or both**,
  from **any source to any destination** across Filesystem, Meteor-Files GridFS,
  Cloud (S3/Azure/GCS) and legacy CollectionFS GridFS. The default source is
  "All Read-enabled storages" (every backend whose Read flag is enabled and whose
  settings work), so everything can be consolidated into one destination in a
  single run. All metadata is preserved (board / swimlane / list / card / user /
  uploaded date / name / type / size), attachment cover references
  (`cards.coverId`) are remapped when an id changes, and the legacy source is
  deleted only after the new copy is verified. Thanks to Claude.
- **Legacy CollectionFS GridFS is now a first-class storage backend** (read,
  migrate-from, and export-to) for both attachments and avatars, via the new
  `models/lib/collectionFsStore.js` (binary keyed by `copies.<coll>.key` in the
  `cfs_gridfs.<coll>` bucket, metadata in `cfs.<coll>.filerecord`). Thanks to Claude.
- **The storage strategy layer is now collection-aware.** `moveToStorage` and the
  GridFS/Cloud strategies previously hard-coded the `Attachments` collection, so
  moving avatars to GridFS/cloud would have updated the wrong collection. The
  factory now carries its collection (`Attachments` or `Avatars`), so **avatars
  can be stored in Meteor-Files GridFS and cloud**, not only on the filesystem.
  Attachment behavior is unchanged. Thanks to Claude.
- **Read legacy CollectionFS attachments and avatars in place** (without
  migrating). The backward-compatibility layer
  (`models/lib/attachmentBackwardCompatibility.js`) was broken — it looked up the
  GridFS binary by the filerecord `_id` and by filename instead of by
  `ObjectId(copies.<coll>.key)`, so legacy files were never found. It is fixed and
  generalized for attachments and avatars. Legacy attachments now appear in the
  card attachment gallery (new `legacyBoardAttachments` publication) and stream
  from the `cfs_gridfs.attachments` bucket, and legacy avatars
  (`/cfs/files/avatars/<id>` URLs) are served from the `cfs_gridfs.avatars`
  bucket instead of redirecting to a 404.

Thanks to Claude.
2026-06-06 02:06:16 +03:00
Lauri Ojansivu be63a357dd Updated ChangeLog. 2026-06-05 23:47:19 +03:00
Lauri Ojansivu c71a97cba2 **Fixed OpenAPI REST API documentation generation**, which had been broken
since after WeKan v7.93 and only generated docs for the `login`/`register`
endpoints (2 operations) instead of the full API. The Meteor 3 migration moved
the REST routes from `models/*.js` (`JsonRoutes.add(...)`) into
`server/models/*.js` (`WebApp.handlers.get/post/put/delete(...)`) and
introduced optional chaining (`?.`) that the `esprima` Python parser cannot
read, so `openapi/generate_openapi.py` silently skipped every route file.
The generator now understands both routing styles, scans both `models/` and
`server/models/`, downlevels modern JS syntax so files parse, handles the
`type: Array` SimpleSchema idiom, and `releases/rebuild-docs.sh` works directly
with Python 3.12.x (PEP 668). The generated `public/api/wekan.yml` /
`wekan.html` now cover the full API again (89 operations / 61 paths).
Thanks to Claude.

**Documented the attachment / file REST API in the OpenAPI docs** — file
upload, download, info, listing a board's files, copy, move and delete (the
`/api/attachment/*` endpoints registered via `WebApp.handlers.use()`, which the
generator cannot auto-discover) are now documented in `openapi/extra_paths.yml`
and injected into the generated docs, including their authentication and
permission requirements. Thanks to Claude.

**Security: attachment write operations in the REST/DDP API now require board
write access, not just membership (CWE-862, CWE-639).** Both attachment API
implementations (`server/routes/attachmentApi.js` HTTP routes and
`server/attachmentApi.js` Meteor methods) gated upload / copy / move / delete
on `board.hasMember()`, which is true for any active member regardless of role.
This let read-only, comment-only, no-comments, worker and assigned-only board
members add, copy, move and delete attachments through the API — actions the UI
forbids for those roles. They now require board write access (global site
admins still allowed); read operations (download / list / info) keep
membership-level access. Added security tests in
`server/lib/tests/attachmentApi.tests.js`. Thanks to Claude.

**The attachment copy API now honours the admin "Admin Panel / Attachments"
API transfer limits.** Copying an attachment creates a new attachment but
skipped the `apiUploadBlocked` / `apiUploadMaxBytes` checks that upload
enforces; copy now respects them in both API implementations. Thanks to Claude.

**SVG image uploads are now sanitized instead of rejected.** Uploaded SVGs
(attachments and avatars) are cleaned in place in `onAfterUpload` via the new
`models/lib/sanitizeSvg.js`, which removes JavaScript (`<script>`, inline
`on*=` event handlers, `javascript:`/`vbscript:` URIs, `<foreignObject>` /
`<iframe>` / `<object>` / `<embed>` and similar active content) and XML loops
(`<!DOCTYPE>` / `<!ENTITY>` entity-expansion / XXE constructs and
`<?xml-stylesheet?>`), so SVG images can be uploaded safely.

Thanks to Claude.
2026-06-05 23:44:04 +03:00
Lauri Ojansivu 357de728c0 Fix [CloneBleed](https://wekan.fi/hall-of-fame/clonebleed/) and other security issues. Added more security tests to test suite.
Thanks to dizconnectz for the coordinated disclosure, and Claude.
2026-06-05 21:40:24 +03:00
Lauri Ojansivu db3c0c18f9 Updated ChangeLog. 2026-06-05 19:09:11 +03:00
Lauri Ojansivu 45706292e7 Updated translations. 2026-06-05 19:08:57 +03:00
Lauri Ojansivu 29b3f52e50 Updated to Meteor 3.5-rc.1 .
Thanks to Meteor developers !
2026-06-05 19:04:12 +03:00
Lauri Ojansivu f81a0d1537 Merge pull request #6365 from italojs/main
Update DDP transport and reactivity order for multi-tenant deployment
2026-06-05 18:57:44 +03:00
Lauri Ojansivu e613e8763b Updated Docker Meteor 3 settings. Part 2.
Thanks to italojs and xet7 !

Related https://github.com/meteor/meteor/pull/14112#issuecomment-4595290396
2026-06-02 00:03:27 +03:00
Lauri Ojansivu 3d17810293 Updated Docker Meteor 3 settings.
Thanks to italojs and xet7 !

Related https://github.com/meteor/meteor/pull/14112#issuecomment-4595290396
2026-06-02 00:00:22 +03:00
Lauri Ojansivu 1871873da0 Caddyfile: Separate websocket port not required.
Thanks to italojs !

Related https://github.com/meteor/meteor/pull/14112#issuecomment-4596252210
2026-06-01 23:40:52 +03:00
Lauri Ojansivu 15b3213a4d Fix typos 2026-06-01 22:51:20 +03:00
Lauri Ojansivu 4265288417 Updates 2026-06-01 22:49:15 +03:00
Lauri Ojansivu a36d6f9326 Merge branch 'main' of github.com:wekan/wekan 2026-06-01 22:45:07 +03:00
Lauri Ojansivu 3c50f90b51 Add separate websocket port 2026-06-01 22:44:27 +03:00
italo jose 24a4b8e5ee Refactor MongoDB service entrypoint and command for improved readability 2026-06-01 16:22:46 -03:00
italo jose e676f96905 Update DDP transport and reactivity order for multi-tenant deployment; add docker-compose example 2026-06-01 15:54:54 -03:00
Lauri Ojansivu a903154ab2 Updated ChangeLog. 2026-05-31 14:38:24 +03:00
Lauri Ojansivu beedf2fefa Update Windows MongoDB.
Thanks to xet7 !
2026-05-31 14:36:32 +03:00
Lauri Ojansivu dee5711000 v9.34 2026-05-31 13:42:43 +03:00
Lauri Ojansivu e93c049e8c Updated translations. 2026-05-31 13:38:57 +03:00
Lauri Ojansivu fc10ce4259 Fix to not list all boards etc at Admin Panel / Attachments / Move Attachment.
Thanks to xet7 !
2026-05-31 13:35:34 +03:00
Lauri Ojansivu 2573034149 v9.33 2026-05-31 12:46:36 +03:00
Lauri Ojansivu a1fc2a91dc 9.33 2026-05-31 12:40:33 +03:00
Lauri Ojansivu e86c37e636 Updated translations. 2026-05-31 12:18:56 +03:00
Lauri Ojansivu 8b71386b90 Updated translations. 2026-05-31 11:51:31 +03:00
Lauri Ojansivu 2edef5b4ab Updated translations. 2026-05-31 11:50:10 +03:00
Lauri Ojansivu d2a25ae9a6 Updated ChangeLog. 2026-05-31 11:15:12 +03:00
Lauri Ojansivu 6f021aa387 Mobile / touch fixes (Fairphone 4 postmarketOS Firefox and Fairphone 4 Ubuntu Touch Morph browser; iPhone 12 Mini was already correct):
- Fixed one-finger drag-to-scroll not working in the All Boards view and the
  Calendar view on Fairphone 4 Firefox and Ubuntu Touch Morph. These browsers
  do not emit the synthetic mouse events the `@wekanteam/dragscroll` library
  relies on, so scrolling only worked in the Swimlanes/Lists views. Added a new
  native touch-scrolling helper `client/lib/dragscrollTouch.js` that scrolls the
  nearest `.dragscroll` container with a one-finger drag (iOS is skipped, since
  native momentum scrolling already works there), and added the `dragscroll`
  class to the All Boards list and the Calendar view.
- Fixed all text, buttons, the All Boards tables and the top bars (header and
  the second bar) rendering about 2x too large on Fairphone 4. `getMobileMode()`
  defaulted to mobile mode only for iPhone, so every other phone fell back to
  desktop mode, whose large desktop sizing looks oversized on a small phone
  screen. The default is now mobile mode for any phone-sized touch device
  (iPhone, Android/Mobile browsers, Ubuntu Touch, or a coarse-pointer touch
  screen with viewport width ≤ 800px); desktop browsers stay in desktop mode and
  the user's own Mobile/Desktop toggle still takes priority.
- Fixed not being able to reorder swimlanes and lists by dragging their drag
  handle on touch devices. The new touch-scroll helper was hijacking touches
  that started on a drag handle; `.handle` / `.ui-sortable-handle` elements are
  now excluded from touch-scrolling so dragging the handle reorders as expected.
- Fixed a card duplicating into two cards when it was dragged by its title-row
  drag handle while its Card Details panel was open. The card sortable in
  `client/components/lists/list.js` was re-initialized on every list re-render
  without first destroying the previous instance, so two `stop` handlers fired
  per drag. It now destroys any existing sortable before re-initializing, the
  same guard already used for swimlanes.

Attachment storage:

- Added configurable attachment storage backends in the admin panel: choose the
  default save storage and store attachments on the local filesystem, GridFS, or
  cloud object storage — S3-compatible (AWS S3, MinIO, Cloudflare R2, Backblaze
  B2, Wasabi, DigitalOcean Spaces), Azure Blob Storage, or Google Cloud Storage
  — via the `@tweedegolf/storage-abstraction` adapters (new
  `models/lib/cloudStorage.js`). Includes a "Test connection" action and
  English translations for the new settings.
- Added a server-side bulk attachment move (new `server/attachmentBulkMove.js`
  and `models/attachmentBulkMoveStatus.js`) that moves all attachments from one
  storage backend to another as a background job whose progress survives the
  admin navigating away from or closing the page.

Thanks to xet7.
2026-05-31 11:12:41 +03:00
Lauri Ojansivu d80afc7834 v9.32 2026-05-31 05:00:13 +03:00
Lauri Ojansivu d8975d21be Updated ChangeLog. 2026-05-31 04:22:36 +03:00
Lauri Ojansivu b0918686a2 Added "Test Playwright Chromium", "Test Playwright Firefox" and "Test
Playwright Webkit" menu options to `rebuild-wekan.sh` for running the
Playwright end-to-end test suite per browser.

Thanks to xet7.
2026-05-31 04:20:30 +03:00
Lauri Ojansivu 71c9e1b3ee Updated translations. 2026-05-31 02:41:32 +03:00
Lauri Ojansivu 10759d777b Updated ChangeLog. 2026-05-31 02:24:33 +03:00
Lauri Ojansivu c956ab5a4e Add User board access roles to Admin Panel / People / Roles.
A new global "Roles" tab in Admin Panel / People lets a site admin choose which
board roles are allowed to invite users to a board ("Allow Invite to Board").
Each board role has its own toggle — Board Admin, Normal, Worker, Comment only,
No comments, Only Assigned Normal, Only Assigned Comment, Read Only and Only
Assigned Read — plus an "All Board Members" master toggle that selects them all.
The policy is enforced server-side in the `inviteUserToBoard` and `searchUsers`
methods, and the add-member button in the board sidebar is shown only to roles
the policy allows. Global Admin Panel users (site admins) always have all rights
and cannot be restricted here; this is kept clearly distinct in code from the
per-board "Board Admin" role. Secure default: only Board Admin and Normal may invite.

Thanks to xet7.
2026-05-31 02:22:31 +03:00
Lauri Ojansivu f9b790668d Updated ChangeLog. 2026-05-31 00:39:21 +03:00
Lauri Ojansivu 0e5fef6f31 Fix GHSA-hc3x-hq3m-663q: Server-Side Request Forgery (SSRF) via webhook
integration URLs (CWE-918). Wekan's outgoing-webhook integrations let a board
admin store an arbitrary URL that is later fetched server-side, so a
caller-controlled URL pointing at an internal address (cloud metadata at
`http://169.254.169.254/latest/meta-data/`, loopback, RFC 1918 ranges, etc.)
could be used to reach internal services or exfiltrate data.

**Originally fixed at the delivery layer in v8.35 and v8.36** (the
[IntegrationBleed](https://wekan.fi/hall-of-fame/integrationbleed/) fixes).
[Fix IntegrationBleed (v8.35)](https://github.com/wekan/wekan/commit/2cd702f48df2b8aef0e7381685f8e089986a18a4)
routed webhook delivery in `server/notifications/outgoing.js` through
`fetchSafe` (`server/lib/ssrfGuard.js`), which validates the URL and blocks
private/loopback IPs, and
[Fix RebindBleed of IntegrationBleed (v8.36)](https://github.com/wekan/wekan/commit/92beaa313706bc26fbea7e1cc8cfaf836609e038)
hardened it further to resolve DNS once, pin the connection to the validated
IP, and block redirects — closing the actual request-time SSRF including DNS
rebinding.

**New in this release:** the missing input-side validation the advisory
requested, added at the REST write paths in `server/models/integrations.js`.
Those endpoints accepted webhook URLs without a robust check:
`POST /api/boards/:boardId/integrations` relied only on the schema's regex
`custom()` validator (no DNS resolution, blind to a hostname that resolves to
a private IP and to decimal/octal/IPv4-mapped-IPv6 encodings), and
`PUT /api/boards/:boardId/integrations/:intId` wrote the URL via
`Integrations.direct.updateAsync`, which bypasses schema validation entirely,
so updated URLs were never validated at the data layer. Both endpoints now run
the DNS-aware `validateAttachmentUrl()`
(`models/lib/attachmentUrlValidation.js`, the same validator already used for
attachment imports) before storing the URL, rejecting
private/loopback/link-local/reserved targets with HTTP 400. Together with the
v8.35/v8.36 `fetchSafe` delivery guard and the schema validator on
client-side inserts/updates, webhook URLs are now validated on every write
path and again at delivery.

Thanks to Claude.
2026-05-31 00:35:49 +03:00
Lauri Ojansivu 832265e091 Updated ChangeLog. 2026-05-31 00:27:54 +03:00
Lauri Ojansivu 8940a10397 Fix GHSA-7w2h-g83c-jqrp: Authorization bypass in copyBoard DDP method allows
any user to copy private boards (CWE-862). The `copyBoard` Meteor method in
`server/publications/boards.js` had no authorization check: any logged-in user
could copy any board by ID — including private boards they are not a member of —
cloning all cards, checklists, custom fields, labels and rules, while the
equivalent REST endpoint `POST /api/boards/:boardId/copy` correctly required
board admin. The method also looped over caller-supplied `properties`
(`for (const key in properties) board[key] = properties[key]`) and copied them
onto the new board, letting an attacker inject arbitrary fields such as
`members` (to add themselves as admin of the copy) or `permission: 'public'`
(to expose the copy to everyone). The member-level fix shipped in v9.09 as part
of the AuthBleed fixes (caller must be authenticated, board must exist, caller
must be a board member, and `members`/`permission` are stripped from
`properties` before the copy). This release tightens it further to full parity
with the REST endpoint: `copyBoard` now requires the caller to be a board admin
(`board.hasAdmin(this.userId)`, the same `{isActive:true, isAdmin:true}`
condition the REST API enforces via `checkAdminOrCondition`) rather than merely
a member.

Thanks to Claude.
2026-05-31 00:24:13 +03:00
Lauri Ojansivu 1e1d9586d7 Updated ChangeLog. 2026-05-31 00:14:42 +03:00
Lauri Ojansivu 305864f0c7 Fix GHSA-cv95-8h7c-2ffq: Missing authorization on OIDC Meteor methods allows privilege escalation to admin (CWE-269, CWE-862).
Six Meteor methods used internally by the OIDC login flow were registered as globally DDP-callable
with no authorization, while their non-OIDC counterparts require admin. `setCreateOrgFromOidc` and
`setOrgAllFieldsFromOidc` (`server/models/org.js`), `setCreateTeamFromOidc` and
`setTeamAllFieldsFromOidc` (`server/models/team.js`) let any authenticated user create/rename/
deactivate/modify arbitrary organizations and teams — including `orgAutoAddUsersWithDomainName` —
bypassing the admin-only restriction. Most critically, `groupRoutineOnLogin`
(`packages/wekan-oidc/oidc_server.js`) sets `isAdmin` from caller-supplied group data, so with
`PROPAGATE_OIDC_DATA` enabled any authenticated user could call it over DDP with
`{groups:[{isAdmin:true,forceCreate:true}]}` and promote themselves to global admin;
`boardRoutineOnLogin` could likewise add the caller to the default board. These six methods are only
ever invoked server-side (via `Meteor.callAsync`) during the OIDC handshake, where a fix that checks
`isAdmin`/`this.userId` would break legitimate group/admin propagation (the user is not yet logged in
or admin at that point). Fixed by rejecting any direct client/DDP invocation: a server-to-server
`Meteor.callAsync` runs with `this.connection === null`, whereas a client call has a non-null
connection, so each of the six methods now throws `not-authorized` when `this.connection !== null`.
The legitimate OIDC login flow is unaffected.

Thanks to alexwaira for the coordinated disclosure, and Claude.
2026-05-31 00:11:18 +03:00
Lauri Ojansivu d475214224 Updated ChangeLog. 2026-05-31 00:01:06 +03:00
Lauri Ojansivu 73204d4e0a Fix GHSA-mp7g-hj5q-gxhq: OIDC Account Takeover via Unconditional Email-Based Account Merge in
`Accounts.onCreateUser` hook (CWE-287).
The `onCreateUser` hook in `server/models/users.js` unconditionally merged an incoming OIDC login
into any existing Wekan account whose email **or** username matched the (attacker-controlled) OIDC
claims — no ownership check, no email-verification check, no notification. An attacker who could
present a matching `email`/`username` claim (trivial on self-hosted Keycloak/Authentik, where the
`email`/`email_verified` claims are attacker-settable) inherited the victim's `_id`, boards, cards,
attachments, API tokens and admin status, all during the attacker's own first OIDC login with no
victim interaction. Fixed to fail closed, mirroring `LDAP_MERGE_EXISTING_USERS`: matching is now by
email only (never username); auto-linking is opt-in via the new `OAUTH2_MERGE_EXISTING_USERS`
setting (OFF by default, so the default deployment never merges); even when enabled the OIDC
provider must assert `email_verified=true`; otherwise the OIDC login is rejected with
`oidc-email-already-in-use` instead of merging. The provider's `email_verified` claim is now
captured into the OIDC service data in `packages/wekan-oidc/oidc_server.js`.

Thanks to alexwaira for the coordinated disclosure, and Claude.
2026-05-30 23:59:03 +03:00
Lauri Ojansivu 533187d328 Updated ChangeLog. 2026-05-30 23:45:45 +03:00
Lauri Ojansivu 70db04a93f Fix GHSA-6733-4wgq-8xvr: Read-only board members could create/modify/delete Custom Fields
(privilege escalation via read-level authz on write operations, CWE-862).
All six mutating REST handlers in `server/models/customFields.js` (POST/PUT custom-fields,
POST/PUT/DELETE dropdown-items, DELETE custom-fields) called the read-level
`Authentication.checkBoardAccess` instead of the write-level `checkBoardWriteAccess`, letting a
board member with the read-only role (`isReadOnly` / `isReadAssignedOnly`) write Custom Field
data via the REST API when `WITH_API=true`. Replaced the check with `checkBoardWriteAccess` in
all six mutating handlers (the two GET handlers correctly stay on `checkBoardAccess`), mirroring
`lists.js`/`swimlanes.js`/`cards.js`.

Thanks to Wernerina for the coordinated disclosure, and Claude.
2026-05-30 23:44:00 +03:00
Lauri Ojansivu e8eae6a1fc Updated ChangeLog. 2026-05-30 23:40:13 +03:00
Lauri Ojansivu 8ea5a6a097 Fix regression from the avatar RCE fix GHSA-35j7-h385-2q9g: external antivirus scanner broken (asyncExec undefined)
The avatar RCE fix renamed `asyncExec` to `asyncExecFile` in `models/fileValidation.js`, but the
admin-configured external scanner command line still called the now-undefined `asyncExec`, throwing
`ReferenceError` (swallowed by the catch) and making every upload silently fail validation whenever
an external scanner was configured. Restored a shell-based `asyncExec` used only for that
admin-configured command line; MIME detection still uses the shell-free `asyncExecFile`.

Thanks to Claude !
2026-05-30 23:38:58 +03:00
Lauri Ojansivu e6a2314a1e Updated ChangeLog. 2026-05-30 23:27:52 +03:00
Lauri OjansivuandCopilot Autofix powered by AI 7836ce27e7 Potential fix for code scanning alert no. 417: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 23:25:23 +03:00
Lauri Ojansivu a5fc4a4893 Updated ChangeLog. 2026-05-30 23:24:25 +03:00
Lauri OjansivuandCopilot Autofix powered by AI 358d893c33 Potential fix for code scanning alert no. 35: Insecure randomness
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 23:22:44 +03:00
Lauri Ojansivu ae211b5adf Updated ChangeLog. 2026-05-30 23:21:15 +03:00
Lauri Ojansivu d0b2b5201e Delete calendar demos, so that CodeQL stops complaining.
Thanks to xet7 !
2026-05-30 23:19:27 +03:00
Lauri Ojansivu 0130858584 Updated ChangeLog. 2026-05-30 23:16:09 +03:00
Lauri OjansivuandCopilot Autofix powered by AI 6b923eb4c2 Potential fix for code scanning alert no. 419: Clear-text logging of sensitive information
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 23:10:33 +03:00
Lauri Ojansivu d033dad20f Updated ChangeLog. 2026-05-30 23:09:11 +03:00
Lauri OjansivuandCopilot Autofix powered by AI f882a14ee0 Potential fix for code scanning alert no. 418: Clear-text logging of sensitive information
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 23:07:26 +03:00
Lauri Ojansivu 990d06b8e1 Updated ChangeLog. 2026-05-30 23:06:32 +03:00
Lauri OjansivuandCopilot Autofix powered by AI b6564c81f1 Potential fix for code scanning alert no. 48: Clear-text logging of sensitive information
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 23:03:37 +03:00
Lauri Ojansivu 8df46d8512 Updated ChangeLog. 2026-05-30 23:02:15 +03:00
Lauri OjansivuandCopilot Autofix powered by AI 5072861687 Potential fix for code scanning alert no. 55: Incomplete string escaping or encoding
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 22:59:59 +03:00
Lauri Ojansivu 919bd9e29b Updated ChangeLog. 2026-05-30 22:56:34 +03:00
Lauri OjansivuandCopilot Autofix powered by AI c5e42607af Potential fix for code scanning alert no. 56: Incomplete string escaping or encoding
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 22:55:01 +03:00
Lauri Ojansivu e64e2c6d53 Updated ChangeLog. 2026-05-30 22:53:56 +03:00
Lauri OjansivuandCopilot Autofix powered by AI 36274f35f4 Potential fix for code scanning alert no. 57: Incomplete multi-character sanitization
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 22:51:07 +03:00
Lauri Ojansivu d5e717e9ce Updated ChangeLog. 2026-05-30 22:50:26 +03:00
Lauri OjansivuandCopilot Autofix powered by AI 13f78f6207 Potential fix for code scanning alert no. 58: Incomplete multi-character sanitization
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 22:48:37 +03:00
Lauri Ojansivu e7aedd9f6b Updated ChangeLog. 2026-05-30 22:48:02 +03:00
Lauri OjansivuandCopilot Autofix powered by AI fc76d0e576 Potential fix for code scanning alert no. 60: Useless regular-expression character escape
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 22:44:58 +03:00
Lauri Ojansivu a1b7194261 Updated ChangeLog. 2026-05-30 22:43:45 +03:00
Lauri OjansivuandCopilot Autofix powered by AI 66d15f6ab0 Potential fix for code scanning alert no. 67: Incomplete multi-character sanitization
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 22:38:16 +03:00
Lauri Ojansivu 561e62a05c Updated ChangeLog. 2026-05-30 22:31:04 +03:00
Lauri Ojansivu b4b81684e0 Fix Incomplete string escaping in jade.js.
Thanks to CodeQL !
2026-05-30 22:28:20 +03:00
Lauri Ojansivu 898f625f1f Updated ChangeLog. 2026-05-30 22:19:42 +03:00
Lauri Ojansivu 105199991f Fix Polynomial regex DoS in Jade parser, part 2: remove the redundant $ anchor
from the interpolation regex in `compiler.js` and bundled `jade.js`. The greedy
`[\s\S]*` already matches to end of string, so dropping `$` keeps the same match
while eliminating the backtracking that CodeQL alert `js/polynomial-redos` flagged.
Thanks to CodeQL.
2026-05-30 22:16:42 +03:00
Lauri Ojansivu 89be5c1f6e Updated ChangeLog. 2026-05-30 22:12:01 +03:00
Lauri Ojansivu ae671bc70a Fix Polynomial regex DoS in Jade parser.
Thanks to CodeQL.
2026-05-30 22:07:32 +03:00
Lauri Ojansivu 78e34b5522 Updated ChangeLog. 2026-05-30 22:03:49 +03:00
Lauri Ojansivu 42d79b3dcf Updated dependencies. Part 8.
Thanks to developers of dependencies !
2026-05-30 22:02:34 +03:00
Lauri Ojansivu 2d4178a281 Updated ChangeLog. 2026-05-30 21:58:58 +03:00
Lauri Ojansivu ac0e11e548 Updated dependencies. Part 7.
Thanks to developers of dependencies !
2026-05-30 21:56:54 +03:00
Lauri Ojansivu 0543cc42de Updated ChangeLog. 2026-05-30 20:52:24 +03:00
Lauri Ojansivu 06c803388b Updated dependencies. Part 6. Fork and update meteor-node-stubs.
Thanks to developers of dependencies !
2026-05-30 20:48:43 +03:00
Lauri Ojansivu 58b00162d9 Updated ChangeLog. 2026-05-30 20:34:03 +03:00
Lauri Ojansivu 08084d96e8 Updated dependencies. Part 5.
Thanks to developers of dependencies !
2026-05-30 20:32:58 +03:00
Lauri Ojansivu 8b63e84cba Updated ChangeLog. 2026-05-30 20:30:40 +03:00
Lauri Ojansivu a2e76f2cf0 Updated dependencies. Part 4.
Thanks to developers of dependencies !
2026-05-30 20:29:34 +03:00
Lauri Ojansivu 72f22d1235 Updated ChangeLog. 2026-05-30 20:26:47 +03:00
Lauri Ojansivu 76945ee5b5 Updated dependencies. Part 3.
Thanks to developers of dependencies !
2026-05-30 20:25:46 +03:00
Lauri Ojansivu d8b7d6e5f4 Updated ChangeLog. 2026-05-30 20:23:02 +03:00
Lauri Ojansivu 1369316401 Updated dependencies. Part 2.
Thanks to developers of dependencies !
2026-05-30 20:19:37 +03:00
Lauri Ojansivu 29b0cc1f86 Updated dependencies.
Thanks to developers of dependencies !
2026-05-30 20:07:17 +03:00
Lauri Ojansivu 74f422b523 Updated ChangeLog. 2026-05-30 20:00:13 +03:00
Lauri Ojansivu 0fefdeec4c Fix iOS Chrome jQuery event handler runtime error.
Thanks to xet7 !
2026-05-30 19:58:18 +03:00
Lauri Ojansivu b99e7979db Updated ChangeLog. 2026-05-30 13:50:30 +03:00
Lauri Ojansivu 64b43a42dd Fix typos.
Thanks to xet7 !
2026-05-30 13:49:23 +03:00
Lauri Ojansivu 9d35870863 Copy wepica style of hide/show password to WeKan login and register pages.
Thanks to Chostakovitch and xet7 !
2026-05-30 13:43:52 +03:00
Lauri Ojansivu 526580cbb6 Updated translations. 2026-05-30 09:05:04 +03:00
Lauri Ojansivu d3366ca7cd v9.31 2026-05-27 22:51:13 +03:00
Lauri Ojansivu 048a90f876 Updated ChangeLog. 2026-05-27 22:06:37 +03:00
Lauri Ojansivu abc24cf381 Fix typo.
Thanks to xet7 !
2026-05-27 22:05:13 +03:00
Lauri Ojansivu 9d21f19ab8 Updated translations. 2026-05-27 21:57:04 +03:00
Lauri Ojansivu 07a0072b87 Updated translations. 2026-05-27 21:52:56 +03:00
Lauri Ojansivu dbe5705b47 Updated translations. 2026-05-27 21:49:57 +03:00
Lauri Ojansivu 0ba3255382 Updated ChangeLog. 2026-05-27 20:56:32 +03:00
Lauri Ojansivu 2e34b2d004 Updated ChangeLog. 2026-05-27 20:54:15 +03:00
Lauri Ojansivu fc92b342ce Fix GHSA-g6vm-7757-pr88. Moved Attachment Storage options from board to Admin Panel. Changed API to use Expose Meteor user context to Express endpoints.
Thanks to Jan Kahmen of turingpoint GmbH for reporting GHSA-g6vm-7757-pr88 and xet7 for fixes and attachment improvements.

Thanks to nachocodoner about https://forums.meteor.com/t/expose-meteor-user-context-to-express-endpoints/64384.
2026-05-27 20:54:05 +03:00
Lauri Ojansivu 45c4afd22b Add Header Login. Part 2.
Fixes #4311,
fixes #2019
2026-05-27 20:51:44 +03:00
Lauri Ojansivu d9f1ecb834 Add Header Login.
Fixes #4311,
fixes #2019
2026-05-27 20:51:44 +03:00
Lauri Ojansivu a37190e0fc Add more tests. Fix tests.
Thanks to xet7 !
2026-05-27 20:51:44 +03:00
Lauri Ojansivu cd37c6c980 Merge pull request #6362 from harryadel/upgrade-meteor-3.5-beta.12
Upgrade Meteor to 3.5-beta.12
2026-05-27 20:51:34 +03:00
Harry Adel 316567f219 Upgrade Meteor to 3.5-beta.12 2026-05-27 18:51:15 +03:00
Lauri Ojansivu e5c61b32e3 Fix typos.
Thanks to xet7 !
2026-05-27 03:59:32 +03:00
Lauri Ojansivu a41d5ff2c0 Updated ChangeLog. 2026-05-26 23:26:15 +03:00
Lauri Ojansivu 769a139e70 Updated dependencies.
Thanks to developers of dependencies !
2026-05-26 23:25:21 +03:00
Lauri Ojansivu 7729d9f33e Updated ChangeLog. 2026-05-26 17:34:50 +03:00
Lauri Ojansivu 8e13f2bce9 Update dependencies and maintenance scripts.
Thanks to developers of dependencies !
2026-05-26 17:30:29 +03:00
Lauri Ojansivu 4e28ffef9c Merge pull request #6360 from wekan/dependabot/github_actions/docker/build-push-action-7.2.0
Bump docker/build-push-action from 7.1.0 to 7.2.0
2026-05-26 17:20:04 +03:00
Lauri Ojansivu d06a7a2c76 Merge pull request #6359 from wekan/dependabot/github_actions/docker/metadata-action-6.1.0
Bump docker/metadata-action from 6.0.0 to 6.1.0
2026-05-26 17:19:25 +03:00
Lauri Ojansivu 886f3bb840 Merge pull request #6358 from wekan/dependabot/github_actions/docker/login-action-4.2.0
Bump docker/login-action from 4.1.0 to 4.2.0
2026-05-26 17:18:42 +03:00
dependabot[bot] b501d7af33 Bump docker/build-push-action from 7.1.0 to 7.2.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 7.1.0 to 7.2.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/bcafcacb16a39f128d818304e6c9c0c18556b85f...f9f3042f7e2789586610d6e8b85c8f03e5195baf)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-26 02:04:21 +00:00
dependabot[bot] c3ea57986f Bump docker/metadata-action from 6.0.0 to 6.1.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/030e881283bb7a6894de51c315a6bfe6a94e05cf...80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-26 02:04:18 +00:00
dependabot[bot] 048947ea7e Bump docker/login-action from 4.1.0 to 4.2.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/4907a6ddec9925e35a0a9e82d7399ccc52663121...650006c6eb7dba73a995cc03b0b2d7f5ca915bee)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-26 02:04:16 +00:00
Lauri Ojansivu 7834a660a5 Updated translations. 2026-05-25 07:57:20 +03:00
Lauri Ojansivu eee7c49439 Updated ChangeLog. 2026-05-23 00:29:02 +03:00
Lauri Ojansivu dbab502be4 Update Windows docs.
Thanks to xet7 !
2026-05-23 00:27:49 +03:00
Lauri Ojansivu f4d5279a09 Updated ChangeLog. 2026-05-22 22:10:46 +03:00
Lauri Ojansivu c8430a8c14 Updated platforms.
Thanks to xet7 !
2026-05-22 22:09:46 +03:00
Lauri Ojansivu 63efa5d0f0 Updated ChangeLog. 2026-05-22 21:05:35 +03:00
Lauri Ojansivu 8cda80752f Ubuntu 26.04 based core26 beta can be at devel like beta channel, not yet candidate.
Thanks to xet7 !
2026-05-22 21:02:51 +03:00
Lauri Ojansivu abeb2d2477 v9.30 2026-05-22 20:34:06 +03:00
Lauri Ojansivu a7c74e8d8b v9.30 2026-05-22 20:29:27 +03:00
Lauri Ojansivu 4b7ed35300 Updated ChangeLog. 2026-05-22 19:54:03 +03:00
Lauri Ojansivu 6463a1ef87 Release scripts: Use locally cached files.
Thanks to xet7 !
2026-05-22 19:52:23 +03:00
Lauri Ojansivu f85dc3fa76 Updated ChangeLog. 2026-05-22 19:36:48 +03:00
Lauri Ojansivu fb05b1a847 Fix Snap LXD container to work when network already exists.
Thanks to xet7 !
2026-05-22 19:34:35 +03:00
Lauri Ojansivu 5b751217d5 Updated ChangeLog. 2026-05-22 19:32:43 +03:00
Lauri Ojansivu 07e6f663db Try to fix Snap build LXD container network Internet access.
Thanks to xet7 !
2026-05-22 19:30:30 +03:00
Lauri Ojansivu 23ed41bddf v9.29 2026-05-22 19:12:17 +03:00
Lauri Ojansivu 3e33c766d6 Updated dependencies.
Thanks to developers of dependencies !
2026-05-22 18:51:02 +03:00
Lauri Ojansivu 83078736f5 Try to fix Snap.
Thanks to xet7 !
2026-05-22 17:50:13 +03:00
Lauri Ojansivu 7ccb50e4f5 v9.28 2026-05-22 16:37:57 +03:00
Lauri Ojansivu 1032c9d9cf Updated ChangeLog. 2026-05-22 16:34:10 +03:00
Lauri Ojansivu ecbecc9d86 Try to fix Snap by using correct versions of dependencies.
Thanks to xet7 !
2026-05-22 16:32:35 +03:00
Lauri Ojansivu 797426335a Updated ChangeLog. 2026-05-22 16:26:11 +03:00
Lauri Ojansivu e7f2068105 Build scripts: Update arm64 build script.
Thanks to xet7 !
2026-05-22 16:24:41 +03:00
Lauri Ojansivu afc51165f4 v9.27 2026-05-22 16:15:00 +03:00
Lauri Ojansivu 87a6354e42 Docker: Do not include pebble to final Docker container, only use it when building.
Thanks to xet7 !
2026-05-22 15:53:28 +03:00
Lauri Ojansivu edc8c17e35 Updated ChangeLog. 2026-05-22 15:16:03 +03:00
Lauri Ojansivu 2a700f5690 Try to fix Snap.
Thanks to xet7 !
2026-05-22 15:15:00 +03:00
Lauri Ojansivu a6ce798862 Updated ChangeLog. 2026-05-22 14:21:40 +03:00
Lauri Ojansivu 30fd008310 Fix Snap local build.
Thanks to xet7 !
2026-05-22 14:19:33 +03:00
Lauri Ojansivu 3608d4b657 v9.26 2026-05-22 13:54:02 +03:00
Lauri Ojansivu 7c1ee7f161 Updated ChangeLog. 2026-05-22 13:44:46 +03:00
Lauri Ojansivu d978d626ae Use Ubuntu 26.04 base for amd64 and arm64 at Docker and Snap.
Thanks to xet7 !
2026-05-22 13:41:56 +03:00
Lauri Ojansivu 1059164255 Updated ChangeLog. 2026-05-22 13:09:31 +03:00
Lauri Ojansivu 741668a831 Try to fix Snap: Use local npm package cache to prevent local build timeout.
Thanks to xet7 !
2026-05-22 13:07:11 +03:00
Lauri Ojansivu 5f06ebfaec v9.25 2026-05-22 12:18:13 +03:00
Lauri Ojansivu b5e79b37ed Try to fix Snap.
Thanks to xet7 !
2026-05-22 12:11:07 +03:00
Lauri Ojansivu 7076ce5df3 v9.24 2026-05-22 11:35:23 +03:00
Lauri Ojansivu 3e00b2ccc2 Updated ChangeLog. 2026-05-22 11:26:06 +03:00
Lauri Ojansivu 5681592572 Fix Snap pidFilePath.
Thanks to csonkaoszimt and xet7 !

Fixes #6355
2026-05-22 11:22:53 +03:00
Lauri Ojansivu 87dcfdbff6 Updates ip address 2026-05-21 16:24:43 +03:00
Lauri Ojansivu b035bed3d8 v9.23 2026-05-21 15:58:29 +03:00
Lauri Ojansivu 94d032c847 Updated translations. 2026-05-21 15:54:37 +03:00
Lauri Ojansivu 347d30c3e0 Merge pull request #6350 from wekan/dependabot/npm_and_yarn/brace-expansion-5.0.6
Bump brace-expansion from 5.0.5 to 5.0.6
2026-05-21 15:49:17 +03:00
Lauri Ojansivu 720ef251ae Updated ChangeLog. 2026-05-21 15:48:20 +03:00
Lauri Ojansivu 24577ad2a9 Fix tests. Added Filter test. Part 4.
Thanks to xet7 !
2026-05-21 15:46:32 +03:00
Lauri Ojansivu 06cdd459db Fix Filter.
Thanks to hmeunier95 and xet7 !

Fixes #6351
2026-05-21 15:43:08 +03:00
Lauri Ojansivu fad217db8a Added script to revert git add.
Thanks to xet7 !
2026-05-21 10:45:34 +03:00
Lauri Ojansivu 4aeb3aa3d2 Fix No label and dates on any minicard.
Thanks to hmeunier95 and xet7 !

Fixes #6347
2026-05-21 10:08:41 +03:00
Lauri Ojansivu 8baa9124a6 Fix CRITICAL SECURITY ISSUE BFLABleed https://wekan.fi/hall-of-fame/bflableed/
Thanks to Fredrik Dietrichson and xet7 !
2026-05-21 09:33:25 +03:00
Lauri Ojansivu 1b1b04d083 Fix tests.
Thanks to xet7 !
2026-05-21 09:24:05 +03:00
dependabot[bot] 982f0b1cf5 Bump brace-expansion from 5.0.5 to 5.0.6
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 5.0.5 to 5.0.6.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v5.0.5...v5.0.6)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 5.0.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 17:34:27 +00:00
Lauri Ojansivu b5f3cbc38e Updated ChangeLog. 2026-05-18 05:09:25 +03:00
Lauri Ojansivu 28464685a7 Fix WeKan version update script.
Thanks to xet7 !
2026-05-18 05:08:04 +03:00
Lauri Ojansivu 3a6aa7dccd Updated ChangeLog. 2026-05-18 04:55:18 +03:00
Lauri Ojansivu 2cc30a85f2 Add local build cache, for npm packages and http downloads.
Thanks to xet7 !
2026-05-18 04:52:45 +03:00
Lauri Ojansivu c5ac0cf8ce v9.22 2026-05-18 04:10:17 +03:00
Lauri Ojansivu 95ad27e0df Fix minicard drag handle to be below minicard menu. Not at top of minicard menu anymore.
Thanks to xet7 !
2026-05-18 04:02:08 +03:00
Lauri Ojansivu b0e2674b11 Updated ChangeLog. 2026-05-18 03:44:07 +03:00
Lauri Ojansivu 46e67512ac Backup also attachments and avatars.
Thanks to xet7 !
2026-05-18 03:42:40 +03:00
Lauri Ojansivu 994ecf8ec0 Updated ChangeLog. 2026-05-18 03:24:06 +03:00
Lauri Ojansivu d486eb2a8f Added backup-all.sh script.
Thanks to xet7 !
2026-05-18 03:20:42 +03:00
Lauri Ojansivu 8f574799e2 Fixed path 2026-05-18 03:08:45 +03:00
Lauri Ojansivu 7496d994e1 Script to executeable. 2026-05-18 03:02:57 +03:00
Lauri Ojansivu ec728dabf6 Updated ChangeLog. 2026-05-18 02:46:57 +03:00
Lauri Ojansivu 2474ff15d6 Docs: Added link to Meteor Security.
Thanks to xet7 !
2026-05-18 02:44:40 +03:00
Lauri Ojansivu 53c205b4ce Updated ChangeLog. 2026-05-18 02:40:38 +03:00
Lauri Ojansivu 7b88f4c21a Use only oplog sockjs so that multitenancy works.
Thanks to xet7 !
2026-05-18 02:38:20 +03:00
Lauri Ojansivu 20368533a0 Added nocache header to Caddy, trying to fix showing correct page.
Thanks to xet7 !
2026-05-17 22:07:07 +03:00
Lauri Ojansivu ac7712f141 Updated ChangeLog. 2026-05-17 21:05:58 +03:00
Lauri Ojansivu 0b9d33cac4 Script for upgrading Docker WeKan from old version to new version.
Thanks to xet7 !
2026-05-17 21:04:08 +03:00
Lauri Ojansivu d4aca1c009 v9.21 2026-05-17 19:48:16 +03:00
Lauri Ojansivu a5ca6b7a79 Updated ChangeLog. 2026-05-17 19:43:01 +03:00
Lauri Ojansivu 964caabaaf Set default to changeStreams and uws.
Thanks to xet7 !
2026-05-17 19:41:55 +03:00
Lauri Ojansivu 9455646d66 Updated ChangeLog. 2026-05-17 19:35:53 +03:00
Lauri Ojansivu c2f67001d6 Fix sudden logouts.
Thanks to xet7 !
2026-05-17 19:33:54 +03:00
Lauri Ojansivu b57362c5e8 Updated ChangeLog. 2026-05-17 19:20:08 +03:00
Lauri Ojansivu d5d04728fb Added Docs for Meteor 3 Docker WeKan with ChangeStreams etc.
Thanks to xet7 !
2026-05-17 19:16:58 +03:00
Lauri Ojansivu b99e1ccc05 Updated ChangeLog. 2026-05-17 02:38:53 +03:00
Lauri Ojansivu 3390324c2a Updated Kin 2.0 Meta OS to Friend page.
Thanks to xet7 !
2026-05-17 02:34:55 +03:00
Lauri Ojansivu 5748475e8d Updated version scripts.
Thanks to xet7 !
2026-05-16 15:05:54 +03:00
Lauri Ojansivu accb51cc67 v9.20 2026-05-16 14:21:25 +03:00
Lauri Ojansivu f81fe11dae Added remaining MongoDB indexes and MongoDB settings.
Thanks to xet7 !
2026-05-16 14:16:37 +03:00
Lauri Ojansivu 5309e4863d Use oplog and sockjs as default. Not changeStreams and uws.
Thanks to xet7 !
2026-05-16 14:01:27 +03:00
Lauri Ojansivu f26a2ac9ad Added fallback so attachments and avatars can be at WRITABLE_PATH or WRITABLE_PATH/files.
Thanks to xet7 !
2026-05-16 13:46:56 +03:00
Lauri Ojansivu c37047d8ee Update build scripts.
Thanks to xet7 !
2026-05-16 13:45:47 +03:00
Lauri Ojansivu d5ca31a38b v9.19 2026-05-16 07:14:57 +03:00
Lauri Ojansivu 0958182306 Updated ChangeLog. 2026-05-16 07:06:46 +03:00
Lauri Ojansivu 9f979054de After register or login, redirect to All Boards page.
Thanks to bcook-konza and xet7 !

Fixes #6328
2026-05-16 07:04:30 +03:00
Lauri Ojansivu 86e671ea49 Updated ChangeLog. 2026-05-16 06:55:03 +03:00
Lauri Ojansivu 47794f799b Removed empty line from star board description at top bar of board, and added some space between icons and text.
Thanks to xet7 !
2026-05-16 06:52:42 +03:00
Lauri Ojansivu b6200c14fc Updated translations. 2026-05-16 06:30:10 +03:00
Lauri Ojansivu 53b0224cce Deleted old file. 2026-05-16 06:22:40 +03:00
Lauri Ojansivu f02e02b401 Updated ChangeLog. 2026-05-14 05:10:21 +03:00
Lauri Ojansivu 52ce4f6128 Fix Esc not work in an opened card when Keyboard Shortcuts enabled.
Thanks to mimZD and xet7 !

This is temporary fix, using click.
If sometime later browser protections prevents this
(like happened previously with click code),
fix this properly by extracting js-close-card-details() to function
and change to run that function directly, without using click.
2026-05-14 05:04:26 +03:00
Lauri Ojansivu a12e075780 Updated ChangeLog. 2026-05-14 04:41:40 +03:00
Lauri Ojansivu 597eb6b2bb Updated @wekanteam/html-to-markdown with Fix Some HTML tags should not get newlines when converted to markdown.
Fixes #6154

Add space after hashes, so that headings views correctly:
https://github.com/wekan/html-to-markdown/commit/3b254e1fa32b6067dd22789fbaab8d4742349bd6
2026-05-14 04:37:39 +03:00
Lauri Ojansivu ba953b57e5 Updated ChangeLog. 2026-05-14 04:17:41 +03:00
Lauri Ojansivu 3adf69bd4c Fix Change list inside of card should show only lists of current swimlane.
Thanks to mimZD and xet7 !

Fixes #6161

The two changes made:

- **[cardDetails.js](client/components/cards/cardDetails.js)**:
Added `currentSwimlaneListsSorted` helper that queries lists
filtered by the card's `swimlaneId`
(mirroring the logic in `dialogWithBoardSwimlaneList.js`),
sorted by `sort` field (left-to-right column order → top-to-bottom in dropdown).

- **[cardDetails.jade](client/components/cards/cardDetails.jade:300)**:
Changed `each currentBoard.lists` to `each currentSwimlaneListsSorted`
so the dropdown only shows lists belonging to the card's current swimlane.
The default swimlane edge case is handled: if the card is in the default swimlane, lists with `swimlaneId` of `null`, `''`, or the default swimlane ID are all included.
2026-05-14 04:14:04 +03:00
Lauri Ojansivu cb1c7da78c Updated ChangeLog. 2026-05-14 04:10:59 +03:00
Lauri Ojansivu 64bc774b1e Fix Labels are disappearing when you are filtering cards by label.
Thanks to hmeunier95 and xet7 !

Fixes #6265

**Fix 1 — [`models/cards.js:797`](models/cards.js)**
`labels()` called `this.board().labels` without a null guard.
If `board()` ever returns `undefined` (board not yet in minimongo,
or a card with a bad `boardId`), this throws silently in Blaze
and all label chips disappear. Now returns `[]` safely.

**Fix 2 — [`client/components/swimlanes/swimlanes.js:660`](client/components/swimlanes/swimlanes.js)**
In swimlane view, `Template.swimlane`'s `visible()` helper
called `list.cards()` **without** the current swimlane ID.
This meant a list in swimlane S2 was considered "non-empty"
(and therefore kept visible) if swimlane S1 had
a card matching the label filter — even though S2 itself
had zero matching cards. The list would appear in S2
but be completely empty, explaining
"some lists are empty even when they contain cards with the label."
Now passes `this._id` (the current swimlane) so
only that swimlane's cards are counted.
2026-05-14 04:06:20 +03:00
Lauri Ojansivu 172f3bb31b Updated ChangeLog. 2026-05-14 03:52:00 +03:00
Lauri Ojansivu 8183a645a1 Fix Remaining view: Drag board starts drag preview but drop is no-op.
Thanks to YosserDerbali and xet7 !

Fixes #6258

**Root cause:** When dragging a board in the Remaining view,
there were no visual cues indicating where to drop — users tried
dropping on other boards (which does nothing), not knowing
they need to drop on a workspace in the left sidebar.

**Changes made:**

1. **[boardsList.js](client/components/boards/boardsList.js)** —
   `dragstart .js-board`: On drag start, adds `.board-drag-hint`
   class to all workspace nodes and the Remaining menu item
   in the sidebar, visually signalling valid drop targets.
   New `dragend .js-board` cleans up the class.

2. **[boardsList.js](client/components/boards/boardsList.js)** —
   `boardWorkspaceDragHint()`: Updated tooltip
   from "Drag board: Remaining <-> Workspaces"
   to "Drag board to assign to Workspaces
   (drop on workspace in left sidebar)" —
   removes the ambiguous bidirectional arrow that implied reordering.

3. **[boardsList.css](client/components/boards/boardsList.css)**:
   Added green dashed border highlight for
   `.workspace-node.board-drag-hint` and
   `.js-select-menu.board-drag-hint` so valid drop targets
   light up during a board drag.

4. **[en.i18n.json](imports/i18n/data/en.i18n.json)**:
   Added `drag-board-to-workspace` key and
   updated `board-open-and-move-between-remaining-and-workspaces`
   to reflect the correct purpose (workspace assignment, not reordering).

This resolves the UX mismatch without implementing board reorder
(which carries regression risk).
The drag handle stays visible since it's genuinely functional
for workspace assignment — users just now get
a clear visual guide showing where to drop.
2026-05-14 03:46:06 +03:00
Lauri Ojansivu f69e543376 Updated ChangeLog. 2026-05-14 03:42:05 +03:00
Lauri Ojansivu fbce6e5e9b Fix Card pop-up menu content overflows viewport.
Thanks to aminsaidane and xet7 !

Fixes #6219

**Root cause:** [popup.css](client/components/main/popup.css)
had duplicate and conflicting rules at the bottom of the file.
Two rules were overriding the correct `cardDetailsActionsPopup`-specific fix:

1. `.pop-over:has(.pop-over-list) { max-height: 400px !important }` — had
   the same CSS specificity as `.pop-over[data-popup="cardDetailsActionsPopup"]`
   but appeared later, so it won, forcing the popup to 400px instead of 80vh.
2. `.pop-over .pop-over-list { max-height: 300px !important }` — forced each
   individual list element to independently scroll at 300px, which is wrong
   (the container should scroll, not each list).
3. There was an entire duplicate of the same block, adding the rules twice.

**What was removed:** The "STRONGER FIX" section and its duplicate (~55 lines),
which contained the conflicting `max-height: 400px` and `max-height: 300px` rules.

**What remains (and works correctly):**
- The `cardDetailsActionsPopup`-specific rules at lines 343–361
  (max-height: 80vh, scrollable content-wrapper)
- The general flex-column layout at the end that constrains all popups to
  `max-height: 90vh` with a fixed header and scrollable content area
- The `listActionsPopup`-specific rules
- The JS `_getOffset` in [popup.js](client/lib/popup.js:267) which
  already correctly calculates available space above/below the opener
  and passes `maxHeight` to the template
2026-05-14 03:37:08 +03:00
Lauri Ojansivu 5efb90640c Updated ChangeLog. 2026-05-14 03:34:42 +03:00
Lauri Ojansivu 93f90873e8 Fix Cards disappear from lists that has been minimized.
Thanks to robertjensen, harryadel and xet7 !

Fixes #6266,
fixes https://github.com/wekan/wekan/pull/6278

**Bug:** Cards disappear from lists that were previously minimized.

**Root cause** — [`client/components/lists/listBody.jade:2`](client/components/lists/listBody.jade):

```jade
template(name="listBody")
  unless collapsed    ← BUG: reads raw list.collapsed from MongoDB
```

`Template.listBody` has no `collapsed` helper defined in `listBody.js`.
In Blaze, when a helper isn't found, it falls through to
the raw data context — the list document from MongoDB.
So it reads `list.collapsed` directly from the database.

The parent template `list.jade` wraps `+listBody` with
its own `unless collapsed` that correctly uses
`Utils.getListCollapseState()`, which reads from the user's profile.
These two checks were reading from **different sources**.

**Failure sequence:**
1. Old WeKan versions (or a DB migration) stored `collapsed: true`
   directly on the list document in MongoDB
2. User clicks the expand arrow → `Utils.setListCollapseState(list, false)
   updates `profile.collapsedLists` only — it does **not** clear `list.collapsed`
   in MongoDB
3. `list.jade`'s helper sees `false` (from profile) → renders `+listBody`
4. `listBody.jade`'s `unless collapsed` reads the raw
   MongoDB field → still `true` → hides all cards, the add-card compose
   and the `.js-minicards` container (breaking drag-and-drop too)

**Fix:** Remove the redundant `unless collapsed` from `listBody.jade`.
The parent template already guards it with the correct
helper — if `listBody` is being rendered at all, the list is expanded.
The inner check was both redundant and broken.
2026-05-14 03:27:51 +03:00
Lauri Ojansivu 8b8a0c8458 Updated ChangeLog. 2026-05-14 03:10:06 +03:00
Lauri Ojansivu fc37c08687 Fix Not possible to change the tracking mode.
Thanks to hmeunier95 and xet7 !

Fixes #6267

In [boardHeader.js:429](client/components/boards/boardHeader.js),
the event handler uses `Template.currentData()` which returns
the popup template's data context — not the string from
the inner `with "watching"` / `with "tracking"` / `with "muted"` blocks.
It should use `this` instead, since `this` in a Blaze event handler
refers to the data context of the element that was clicked.
2026-05-14 03:06:34 +03:00
Lauri Ojansivu 933bd97393 Updated ChangeLog. 2026-05-14 02:57:27 +03:00
Lauri Ojansivu ed5304cd30 Fix Email notifications show "undefined" instead of username.
Thanks to apiccolim, Raawen-dev and xet7 !

Fixes #6280

**Fix 1 — [models/cards.js:2170](models/cards.js)**: Added `await` to `Cards.updateAsync()` in the `move()` method.

Without `await`, the card update was dispatched as a fire-and-forget Promise. In Meteor 3's AsyncLocalStorage-based DDP context, this can cause the collection hooks (`after.update`) to fire outside the original DDP method context, making `Meteor.userId()` return `null`. With `await`, the async chain is intact and the DDP userId context is preserved through to the hooks.

Also tightened the `UserPositionHistory` guard to `typeof Meteor.userId === 'function'` — the error log showed `TypeError: o.Meteor.userId is not a function` in certain bundle contexts, and this guard prevents that crash.

**Fix 2 — [server/rulesHelper.js](server/rulesHelper.js)**: Added `withUserId()` helper that sets `DDP._CurrentMethodInvocation` before calling `card.move()` from rule execution.

When automation rules trigger a card move, the code runs in a server-side callback with no active DDP method invocation. `CollectionHooks.getUserId()` → `Meteor.userId()` returns `null`, so the resulting activity gets `userId: null`, and the email shows `undefined`. Wrapping `card.move()` in `DDP._CurrentMethodInvocation.withValue({ userId: activity.userId }, ...)` restores the user context so hooks pick up the correct userId.

**Fix 3 — [server/notifications/email.js:37](server/notifications/email.js)**: Defensive fallback `const actorName = params.user || ''` instead of interpolating `params.user` directly.

If `params.user` is ever `undefined` (e.g., activity inserted without a userId from a migration or cron job), the template previously produced the literal string `"undefined moved card X to list Y"`. The fallback produces a blank actor name instead, which is less confusing and avoids the regression.
2026-05-14 02:53:31 +03:00
Lauri Ojansivu e6a3ce6772 Updated ChangeLog. 2026-05-14 02:36:11 +03:00
Lauri Ojansivu acc49aeccb Fix Broken card report.
Thanks to titver968 and xet7 !

Fixes #6293

This fix matches the pattern already used in [server/publications/boards.js:329-330](server/publications/boards.js:329-330).

**Root cause:** `ReactiveCache.getAttachments(..., true)` can return either:
- A FilesCollection cursor (`FileCursor`) which has a `.cursor` property holding the real Mongo cursor, OR
- A plain Mongo cursor with no `.cursor` property

The old code always accessed `.cursor`, which would be `undefined` when the result is already a plain cursor. `undefined` in the cursors array causes Meteor DDP to throw "Publish function returned an array of non-Cursors".

**Fix:** Extract the result first, then use `attachmentsResult.cursor || attachmentsResult` — exactly like `boards.js` already does — so it works regardless of which type is returned.
2026-05-14 02:32:09 +03:00
Lauri Ojansivu f19938b6bb Updated ChangeLog. 2026-05-14 02:10:07 +03:00
Lauri Ojansivu 997931e462 Fix Show Checklist on Minicard and make it editable at Minicard. Fix spurious minicard cover element.
Thanks to brlin-tw and xet7 !

Fixes #6301,
fixes #6315
2026-05-14 02:06:18 +03:00
Lauri Ojansivu e837c0948a Fix Boards Place Sorting.
Thanks to titver968 and xet7 !

Fixes #6294

**Bug:** When the jQuery sortable board-reordering code was replaced with HTML5 drag-and-drop (for workspace management), the board-to-board sorting was accidentally dropped. The `dragstart .js-board` handler only set `dataTransfer` data for workspace assignment — there were no `dragover`/`drop` handlers on `.js-board` elements to actually reorder boards.

**Fix in [boardsList.js](client/components/boards/boardsList.js):** Added four new event handlers after `dragstart .js-board`:

- `dragover .js-board` — allows drop (calls `preventDefault`) and shows a blue top/bottom border indicator based on cursor position relative to the target board's midpoint. Skips workspace drags by checking `dataTransfer.types`.
- `dragleave .js-board` — removes the visual indicator.
- `dragend .js-board` — cleans up all drag indicators on all boards.
- `drop .js-board` — determines drop position (before/after target), walks siblings to find the adjacent `.js-board` DOM elements, calls `Utils.calculateIndex()` to get a sort value, then saves it via `currentUser.setBoardSortIndex()` — matching exactly what the old jQuery sortable did.

**Fix in [boardsList.css](client/components/boards/boardsList.css):** Added `board-drag-over-top` and `board-drag-over-bottom` CSS classes with a 3px blue border to give visual feedback while dragging.
2026-05-14 01:29:59 +03:00
Lauri Ojansivu 361099b2cc Updated ChangeLog. 2026-05-13 23:35:27 +03:00
Lauri Ojansivu 5105cf6489 Fix Search cards should return more results.
Thanks to snowsky and xet7 !

Fixes #6332

Summary of 3 fixes:

**`server/publications/cards.js`** — three publications were returning the raw `{ cursors, sessionData }` object from `findCards()` instead of publishing correctly:
- `brokenCards` (line 907–909): now destructures and pushes `sessionData` via `this.added()`, returns `cursors`
- `nextPage` (line 919–921): same fix
- `previousPage` (line 931–933): same fix

**`client/lib/cardSearch.js`** — `getResults()` had two bugs:
- A `directCards` undefined variable reference (would throw a `ReferenceError` at runtime)
- A fallback when `sessionData` is null that queried `Cards` filtered by `dueAt` — completely unrelated to search, and likely the direct cause of "1 card shown" (whichever card had a due date in MiniMongo)

The replacement uses `Cards.find({ _id: { $in: this.sessionData.cards } })` to fetch all matching cards in a single query, which is both correct and avoids the per-ID `ReactiveCache` staleness issues. When `sessionData` is null (subscription not ready yet), it now returns an empty array rather than random due-date cards.
2026-05-13 23:32:21 +03:00
Lauri Ojansivu 01043096f3 Updated ChangeLog. 2026-05-13 23:28:26 +03:00
Lauri Ojansivu af86ea8785 Fix Sub-URL at ROOT_URL does not work.
Thanks to Meridiana and xet7 !

Fixes #6322

**[`client/00-startup.js`](client/00-startup.js)**

1. **Build chunks / language popup** — Sets `__webpack_public_path__` at module evaluation time (before any `import()` expressions run, which only happen inside `Meteor.startup` callbacks). Reads `window.__meteor_runtime_config__.ROOT_URL`, extracts the pathname (e.g. `/wekan`), and sets the prefix so rspack loads chunks from `/wekan/build-chunks/...` instead of `/build-chunks/...`.

2. **Service worker** — Replaces the hardcoded `/pwa-service-worker.js` path with `new URL('pwa-service-worker.js', Meteor.absoluteUrl()).pathname`, which automatically includes the context path.

**[`models/lib/universalUrlGenerator.js`](models/lib/universalUrlGenerator.js)**

3. **Attachment download links** — Added `getRootUrlPath()` which reads the pathname from ROOT_URL on the client (returns `''` on the server, where `WebApp.handlers` already strips the prefix before routing). `generateUniversalFileUrl` and `generateFallbackUrl` now prepend this prefix, so generated URLs are `/wekan/cdn/storage/attachments/...` instead of `/cdn/storage/attachments/...`.

**[`server/routes/universalFileServer.js`](server/routes/universalFileServer.js)**

4. **Redirect Location headers** — The `/attachments/` and `/avatars/` fallback routes issued relative-path redirects (`/cdn/storage/...`) that ignored the context path. They now use `Meteor.absoluteUrl(...)` which produces a correct absolute URL including the path prefix.
2026-05-13 23:25:19 +03:00
Lauri Ojansivu b32a14fbd5 Updated ChangeLog. 2026-05-13 23:19:15 +03:00
Lauri Ojansivu 14de1ac072 Fix Add Board / Import is not visible.
Thanks to titver968 and xet7 !

Fixes #6325
2026-05-13 23:18:45 +03:00
Lauri Ojansivu ddc3335854 Updated ChangeLog. 2026-05-13 23:10:12 +03:00
Lauri Ojansivu c01743b53a Fix Template "Board not Found" after being archieved, by always showing Template boards.
Thanks to WassimDhib and xet7 !

Fixes #4632
2026-05-13 23:07:45 +03:00
Lauri Ojansivu 508d7a80ef Updated ChangeLog. 2026-05-13 23:03:24 +03:00
Lauri Ojansivu 49ee49d2b8 Fix no due date notification email.
Thanks to JaumeFigueras and xet7 !

Fixes #6338

**Three bugs fixed:**

**1. `NOTIFY_DUE_DAYS_BEFORE_AND_AFTER=0` was silently ignored** ([cards.js:2842](models/cards.js))
- Old: `!(iValue > 0 && iValue < 15)` — `0 > 0` is false, so `0` was always rejected
- Also: `.filter(Boolean)` would strip the number `0` even if the condition was fixed (`Boolean(0) === false`)
- Fix: changed condition to `isNaN(iValue) || iValue < -14 || iValue > 14`, and filter to `.filter(v => v !== false)`

**2. `day=1` produced an empty date range** ([cards.js:2825](models/cards.js))
- Old: `args = [then(1), then(day), ...]` → for `day=1`, both bounds were the same timestamp → `$gte: tomorrow, $lt: tomorrow` → zero results
- Fix: `args = [then(1), then(day + 1), ...]` so `day=1` correctly queries `[tomorrow, day_after_tomorrow)`

**3. Crash on cards with deleted/missing users** ([cards.js:2799](models/cards.js))
- Old: `user.username` was accessed without checking if `user` was null — a single bad card would crash the entire nightly scan silently
- Fix: null-guard with a `continue` and a warning log

**Practical impact for the reporter:**
- `NOTIFY_DUE_DAYS_BEFORE_AND_AFTER=0` now works (today's due cards)
- `NOTIFY_DUE_DAYS_BEFORE_AND_AFTER=1` now works (cards due tomorrow)
- `NOTIFY_DUE_DAYS_BEFORE_AND_AFTER=2,0` now works for both values
- Negative values (e.g. `-1`) now also work for past-due notifications
2026-05-13 22:59:03 +03:00
Lauri Ojansivu 89999ab10f Updated ChangeLog. 2026-05-13 22:53:30 +03:00
Lauri Ojansivu 39effe9a0b Fix Clicking on a card does not open the card detail panel.
Thanks to gaetanquentin !

Fixes #6331
2026-05-13 22:50:21 +03:00
Lauri Ojansivu ad3a38e900 Updated ChangeLog. 2026-05-13 22:33:24 +03:00
Lauri Ojansivu b4742b84ab Try fix tests. 2026-05-13 22:32:38 +03:00
Lauri Ojansivu 9ddad24e2a Updated ChangeLog. 2026-05-13 22:19:49 +03:00
Lauri Ojansivu 9f3c216576 Fix Board visibility ist only private and cannot change it. Fix Public Board, Archive, and menus visibility.
Thanks to titver968 and xet7 !

Fixes #6333
2026-05-13 22:16:45 +03:00
Lauri Ojansivu 664c285cbb Updated ChangeLog. 2026-05-13 19:43:01 +03:00
Lauri Ojansivu 7fb2c3de7b Fix editing comments.
Thanks to dehnamaki and xet7 !

Fixes #6336
2026-05-13 19:41:21 +03:00
Lauri Ojansivu 24f4bfd5ad Try to fix tests. 2026-05-13 19:40:22 +03:00
Lauri Ojansivu 45595d95ab Updated ChangeLog. 2026-05-13 19:35:04 +03:00
Lauri Ojansivu 568ea35ed7 Try to fix tests. 2026-05-13 19:34:19 +03:00
Lauri Ojansivu 6243550c84 Updated ChangeLog. 2026-05-13 19:24:57 +03:00
Lauri Ojansivu 6650618682 Try to fix tests. 2026-05-13 19:23:06 +03:00
Lauri Ojansivu b26d9fa163 Updated ChangeLog. 2026-05-13 18:58:02 +03:00
Lauri Ojansivu 0c6acbfaa2 Try to fix Playwright tests at GitHub Actions. 2026-05-13 18:56:36 +03:00
Lauri Ojansivu af7323a0ab Updated ChangeLog. 2026-05-13 18:53:16 +03:00
Lauri Ojansivu 1950aff865 Fix LDAP Admin Sync.
Thanks to titver968 and xet7 !

Fixes #6343
2026-05-13 18:51:27 +03:00
Lauri Ojansivu 9013ffc5ad Updated ChangeLog. 2026-05-13 18:46:55 +03:00
Lauri Ojansivu 6d56d69ae3 Try to fix tests at GitHub Actions.
Thanks to xet7 !

Related #6334
2026-05-13 18:45:21 +03:00
Lauri Ojansivu 80f4b37337 Updated ChangeLog. 2026-05-13 18:29:22 +03:00
Lauri Ojansivu 0e287c9117 Try to fix Playwright tests at GitHub Actions.
Thanks to xet7 !

Related #6334
2026-05-13 18:27:35 +03:00
Lauri Ojansivu a3ed18294f Updated ChangeLog. 2026-05-13 18:17:44 +03:00
Lauri Ojansivu 8e4404ab49 Updated tests dependencies. 2026-05-13 18:16:38 +03:00
Lauri Ojansivu 8b6c459453 Revert not working PR 6337 Fix attachments API 500 error and upload crash.
Thanks to xet7 !
2026-05-13 18:14:42 +03:00
Lauri Ojansivu 8d6d409cc2 Updated ChangeLog. 2026-05-13 18:04:29 +03:00
Lauri Ojansivu 9962f2bd9b Fix Playwright tests.
Thanks to snowsky and xet7 !

Fixes #6334
2026-05-13 18:01:25 +03:00
Lauri Ojansivu 6c816e573d Updated ChangeLog. 2026-05-13 17:08:41 +03:00
Lauri Ojansivu 7f1dd16dfc rebuild-wekan.sh: At macOS, add paths to node@24.
Thanks to xet7 !
2026-05-13 17:06:35 +03:00
Lauri Ojansivu 09a5737e21 Updated dependencies. Part 2. 2026-05-13 17:05:14 +03:00
Lauri Ojansivu 7d94e575b7 Updated ChangeLog. 2026-05-13 16:58:53 +03:00
Lauri Ojansivu bfd554e65c Merge pull request #6344 from wekan/copilot/update-playwright-dependency-setup
Isolate Playwright from root node_modules to fix E2E Rspack bundling errors
2026-05-13 16:57:37 +03:00
Lauri Ojansivu a692f270da Merge pull request #6337 from KhaoulaMaleh/fix/error
Fix attachments API 500 error and upload crash
2026-05-13 16:53:52 +03:00
copilot-swe-agent[bot]andxet7 6999faced9 Isolate Playwright deps from root app to fix E2E Rspack errors
Agent-Logs-Url: https://github.com/wekan/wekan/sessions/16011cb0-2e0b-4045-9969-074a1dc40cbe

Co-authored-by: xet7 <15545+xet7@users.noreply.github.com>
2026-05-13 13:52:47 +00:00
copilot-swe-agent[bot] ea70df6805 Initial plan 2026-05-13 13:49:59 +00:00
Lauri Ojansivu 736fa07dca Revert removing GitHub Workflows, added them back, bugs were unrelated updates that are now done.
Thanks to xet7 !
2026-05-13 16:36:58 +03:00
Lauri Ojansivu 83a683435a Updates 2026-05-13 16:35:06 +03:00
Lauri Ojansivu 7efba64c39 Updated dependencies.
Thanks to developers of dependencies !
2026-05-13 16:31:18 +03:00
Lauri Ojansivu 79521baad8 Updated ChangeLog. 2026-05-13 15:48:16 +03:00
Lauri Ojansivu c1f0da1217 Fix Docker Compose missing dashes.
Thanks to C0rn3j, kichkasch and xet7 !

Fixes #6327
2026-05-13 15:38:11 +03:00
Lauri Ojansivu 8da4a2ad04 Deleted buggy GitHub Workflows.
Thanks to xet7 !
2026-05-12 16:27:22 +03:00
Lauri Ojansivu 6f8a502cf2 Merge pull request #6342 from wekan/dependabot/github_actions/actions/checkout-6 2026-05-12 09:32:24 +03:00
Lauri Ojansivu 98fc5d6ffc Merge pull request #6341 from wekan/dependabot/github_actions/actions/upload-artifact-7 2026-05-12 09:32:04 +03:00
Lauri Ojansivu 8a8469ac2a Merge pull request #6340 from wekan/dependabot/github_actions/actions/setup-node-6 2026-05-12 09:31:47 +03:00
Lauri Ojansivu 059fc979dc Merge pull request #6339 from wekan/dependabot/github_actions/actions/dependency-review-action-5 2026-05-12 09:31:25 +03:00
dependabot[bot] 21f2e2e6ef Bump actions/checkout from 4 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 03:02:18 +00:00
dependabot[bot] 82e5ce1d76 Bump actions/upload-artifact from 4 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 03:02:12 +00:00
dependabot[bot] b92292fe8f Bump actions/setup-node from 4 to 6
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 03:02:07 +00:00
dependabot[bot] 6b7cb473aa Bump actions/dependency-review-action from 4 to 5
Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 4 to 5.
- [Release notes](https://github.com/actions/dependency-review-action/releases)
- [Commits](https://github.com/actions/dependency-review-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/dependency-review-action
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 03:02:02 +00:00
KhaoulaMaleh ac2bacf42c attachement fix 2026-05-10 01:41:03 -11:00
Lauri Ojansivu 21c62c6b82 v9.18 2026-05-10 05:00:45 +03:00
Lauri Ojansivu 1a998f9ece Try to fix Parallel Snap paths.
Thanks to xet7 !
2026-05-10 04:54:05 +03:00
Lauri Ojansivu fd10c4c9ad Updated ChangeLog. 2026-05-10 01:28:25 +03:00
Lauri Ojansivu 8d73d2f575 Release Scripts: Include updating version at same script.
Thanks to xet7 !
2026-05-10 01:25:38 +03:00
Lauri Ojansivu 22b9930168 Build scripts: Not change firewall settings anymore. 2026-05-10 01:15:43 +03:00
Lauri Ojansivu 7337854bb7 v9.17 2026-05-10 00:39:14 +03:00
Lauri Ojansivu f6303840c5 Updated ChangeLog. 2026-05-10 00:27:47 +03:00
Lauri Ojansivu 31bcf947cb Try to fix Parallel Snap MongoDB ports.
Thanks to xet7 !
2026-05-10 00:25:02 +03:00
Lauri Ojansivu 0f8ff1f21c Updates 2026-05-09 23:02:26 +03:00
Lauri Ojansivu 61554fa53a v9.16 2026-05-09 22:52:25 +03:00
Lauri Ojansivu da4b40115d Updated ChangeLog. 2026-05-09 22:42:17 +03:00
Lauri Ojansivu c7f9c95596 Fix Parallel Snap MongoDB port and paths, that worked at WeKan 9.07 but later broke.
Thanks to xet7 !
2026-05-09 22:38:53 +03:00
Lauri Ojansivu 5c31adb314 Updated ChangeLog. 2026-05-09 22:06:23 +03:00
Lauri Ojansivu cea6aee038 Fixed uploading attachment to card.
Thanks to xet7 !
2026-05-09 22:05:01 +03:00
Lauri Ojansivu cb32b11586 Temporary fix to https://github.com/jamauro/offline/issues/27, waiting for new jam:offline version.
Thanks to xet7 !
2026-05-09 21:58:37 +03:00
Lauri Ojansivu d0de79cba2 Updated ChangeLog. 2026-05-09 20:56:26 +03:00
Lauri Ojansivu c52f2481d3 Fix login and register to not require page reload by adding router fallback.
Thanks to xet7 !

Fixes #6328
2026-05-09 20:52:33 +03:00
Lauri Ojansivu 690f49e60c Updated ChangeLog. 2026-05-09 13:49:45 +03:00
Lauri Ojansivu fa78267068 Merge pull request #6335 from wekan/dependabot/npm_and_yarn/fast-uri-3.1.2
Bump fast-uri from 3.1.1 to 3.1.2
2026-05-09 13:46:41 +03:00
dependabot[bot] e0391f7dd4 Bump fast-uri from 3.1.1 to 3.1.2
Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.1 to 3.1.2.
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](https://github.com/fastify/fast-uri/compare/v3.1.1...v3.1.2)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-09 05:42:13 +00:00
Lauri Ojansivu 0f6883bdf3 Updates 2026-05-08 04:40:19 +03:00
Lauri Ojansivu b5a406f8eb v9.15 2026-05-08 00:17:53 +03:00
Lauri Ojansivu 80ffbcd562 Updated ChangeLog. 2026-05-08 00:15:25 +03:00
Lauri Ojansivu 8715133868 Update release script to force include required file.
Thanks to xet7 !
2026-05-08 00:13:01 +03:00
Lauri Ojansivu 75cecab73f Updated ChangeLog. 2026-05-08 00:09:15 +03:00
Lauri Ojansivu f778707236 Fix to run code only if there is userId and user.
Thanks to xet7 !
2026-05-08 00:07:00 +03:00
Lauri Ojansivu b6b9d5b787 Updates 2026-05-07 22:06:27 +03:00
Lauri Ojansivu d19506d32f v9.14 2026-05-07 21:59:31 +03:00
Lauri Ojansivu 8349167a32 Snap Candidate: Reinitialize MongoDB ReplicaSet if it needs reconfig. When restoring, don't restore indexes.
Thanks to xet7 !
2026-05-07 21:54:17 +03:00
Lauri Ojansivu cf2bae0bfb Updates 2026-05-07 20:06:09 +03:00
Lauri Ojansivu eb75d60df1 v9.12 2026-05-07 20:00:39 +03:00
Lauri Ojansivu 57f1f9da5b Fix Snap Candidate: Wait for MongoDB to start before starting Node.js.
Thanks to xet7 !
2026-05-07 19:56:36 +03:00
Lauri Ojansivu c8c7230331 Updates 2026-05-07 19:56:06 +03:00
Lauri Ojansivu 7e193ef603 v9.11 2026-05-07 18:36:29 +03:00
Lauri Ojansivu 5b1cd3dc2f Fix Snap common directory path for Parallel Snap.
Thanks to xet7 !
2026-05-07 18:33:40 +03:00
Lauri Ojansivu b895a66e24 v9.10 2026-05-07 17:59:58 +03:00
Lauri Ojansivu 25dd4be3f8 v9.10 2026-05-07 17:56:53 +03:00
Lauri Ojansivu 6d70826b40 Updated ChangeLog. 2026-05-07 17:55:20 +03:00
Lauri Ojansivu 2dbe335b30 Merge pull request #6330 from KhaoulaMaleh/fix/attachement
Fix attachment cursor handling and await board access check
2026-05-07 17:42:42 +03:00
Lauri Ojansivu 9e94321c90 Updates 2026-05-07 17:20:56 +03:00
Lauri Ojansivu 6e07efdfa8 v9.09 2026-05-07 17:03:15 +03:00
Lauri Ojansivu 5c6aa15564 Updated ChangeLog. 2026-05-07 16:59:06 +03:00
Lauri Ojansivu 62c01725f9 Fixed CRITICAL SECURITY ISSUES of [AuthBleed](https://wekan.fi/hall-of-fame/authbleed/).
Thanks to Qiulin Deng and xet7 !
2026-05-07 16:54:51 +03:00
Lauri Ojansivu b404ac6068 Updated ChangeLog. 2026-05-07 16:10:02 +03:00
Lauri Ojansivu 4520a432c4 Updated GitHub Actions to build release bundles.
Thanks to xet7 !
2026-05-07 16:08:35 +03:00
Lauri Ojansivu aecdac5aca Updated ChangeLog. 2026-05-07 15:59:55 +03:00
Lauri Ojansivu f2d6695fdc Added Playwright Tests 2026-05-07: 16 specs. 306/306 passing.
Thanks to xet7 !
2026-05-07 15:57:42 +03:00
Lauri Ojansivu 5435753573 Updated ChangeLog. 2026-05-07 10:00:37 +03:00
Lauri Ojansivu 90cfc3f696 Docs: Clarified SECURITY.md . Part 2.
Thanks to xet7 !
2026-05-07 09:59:16 +03:00
Lauri Ojansivu 7b7e376ba2 Updated ChangeLog. 2026-05-07 09:57:34 +03:00
Lauri Ojansivu f347dc7d4d Docs: Clarified SECURITY.md .
Thanks to xet7 !
2026-05-07 09:55:43 +03:00
KhaoulaMaleh d174a4832e fix Accessing attachments 2026-05-06 18:03:20 -11:00
Lauri Ojansivu bc1cd58491 Updates 2026-05-04 22:08:56 +03:00
Lauri Ojansivu 86ade7f1f6 v9.08 2026-05-04 21:59:00 +03:00
Lauri Ojansivu f39f66192f Updated ChangeLog. 2026-05-04 21:54:28 +03:00
Lauri Ojansivu 330e0e3570 Upgrade to Meteor 3.5-beta.10, changeStreams, DDP_TRANSPORT=uws.
Thanks to Meteor developers !

Fixes #6307
2026-05-04 21:51:50 +03:00
Lauri Ojansivu a54f23e2ec Updated ChangeLog. 2026-05-03 19:52:49 +03:00
Lauri Ojansivu f7db51b457 Release scripts: Add Snap Store scripts to list and publish revisions to channels, because snapcraft.io website currently does not work.
Thanks to xet7 !
2026-05-03 19:49:42 +03:00
Lauri Ojansivu ebaa31c1e0 v9.07 2026-05-03 19:01:03 +03:00
Lauri Ojansivu 123417d931 Merge pull request #6324 from stegoh/main
Fix CleanDark theme: transparent list header, white popup text, no co…
2026-05-03 18:55:09 +03:00
Lauri Ojansivu d7b0441376 Updated ChangeLog. 2026-05-03 18:54:38 +03:00
Lauri Ojansivu a4c74a5980 Fix avatars rce.
Thanks to Trung Nguyen from CyStack Security and xet7 !
2026-05-03 18:36:15 +03:00
Stefan GohmannandClaude Sonnet 4.6 5e09f6b599 Fix CleanDark theme: transparent list header, white popup text, no column border
- Add !important to list header background/border overrides so they are
  not overridden by list.css rules that use !important
- Add !important to list background and border-left overrides to prevent
  the default #dedede background and 1px border from showing
- Add color overrides for pop-over-list links: white for CleanDark,
  dark for CleanLight, to counter the global color:#000 !important in
  popup.css (regression introduced with the popup overflow fixes)

Fixes #6168

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 08:56:24 +02:00
Lauri Ojansivu f2968f0235 Updates 2026-05-02 03:58:03 +03:00
Lauri Ojansivu fa8036aa3c v9.06 2026-05-02 03:55:32 +03:00
Lauri Ojansivu 7556b3ed8e Fix Snap Candidate attachments directory permissions at parallel snap file path /var/snap/wekan_SOMENAME/common/files/
Thanks to xet7 !
2026-05-02 03:46:05 +03:00
Lauri Ojansivu 786c9295a9 Docs: Updated manual parallel snap command.
Thanks to xet7 !
2026-05-02 03:15:24 +03:00
Lauri Ojansivu c1cc1e3e3d Updated ChangeLog. 2026-05-02 02:43:19 +03:00
Lauri Ojansivu 158f31ad4f Updates 2026-05-02 02:40:53 +03:00
Lauri Ojansivu 5e4319473e Updated ChangeLog. 2026-05-02 01:08:27 +03:00
Lauri Ojansivu 82c78ebd1e Docs: Added firewall config for Internet access from LXD Ubuntu container at Fedora Asahi Linux Remix, because building Linux arm64 version of WeKan.
Thanks to xet7 !
2026-05-02 01:03:35 +03:00
Lauri Ojansivu 628a49d84e Updated ChangeLog. 2026-05-02 00:43:36 +03:00
Lauri Ojansivu 3c8db21d2f Update docs lxc commands.
Thanks to xet7 !
2026-05-02 00:42:11 +03:00
Lauri Ojansivu 550f4a19cc v9.05 2026-05-02 00:21:46 +03:00
Lauri Ojansivu cd2c69f5f0 Fix Snap Candidate attachments WRITABLE_PATH for Parallel Snap installs. Part 2.
Thanks to xet7 !
2026-05-02 00:17:58 +03:00
Lauri Ojansivu cadd015d20 Fix Snap Candidate attachments WRITABLE_PATH for Parallel Snap installs.
Thanks to xet7 !
2026-05-02 00:04:26 +03:00
Lauri Ojansivu 5aa2219541 Updated ChangeLog. 2026-05-01 16:33:44 +03:00
Lauri Ojansivu 4e77df9ff5 Update version script and dependencies.
Thanks to xet7 !
2026-05-01 16:32:11 +03:00
Lauri Ojansivu b40e6caa4d v9.04 2026-05-01 14:17:01 +03:00
Lauri Ojansivu 2a3aa981d2 Upgrade to MongoDB 7.0.32 at Windows Bundle docs.
Thanks to MongoDB developers !
2026-05-01 14:14:06 +03:00
Lauri Ojansivu 653c61081a Update version script.
Thanks to xet7 !
2026-05-01 14:06:11 +03:00
Lauri Ojansivu cc3b5cb8c6 Updated ChangeLog. 2026-05-01 13:57:30 +03:00
Lauri Ojansivu df153dcc56 Revert Incomplete Fix "Show on Minicard" board card preference lost after upgrading from 8.74 to 8.98
Thanks to and xet7 !

Opens #6301
2026-05-01 13:56:16 +03:00
Lauri Ojansivu 5878c80fa6 Updated ChangeLog. 2026-05-01 13:47:46 +03:00
Lauri Ojansivu d04beea6f8 Fix: Added space between Card Number and Card Title at Minicard and Opened Card.
Thanks to xet7 !
2026-05-01 13:44:59 +03:00
Lauri Ojansivu d160d985c9 Updated ChangeLog. 2026-05-01 13:37:04 +03:00
Lauri Ojansivu f0a25358b4 Fix "Show on Minicard" board card preference lost after upgrading from 8.74 to 8.98 by changing back to original database field names without suffix OnMinicard.
Thanks to brlin-tw and xet7 !

Fixes #6301
2026-05-01 13:31:01 +03:00
Lauri Ojansivu 36e1753f89 Updated ChangeLog. 2026-05-01 12:53:45 +03:00
Lauri Ojansivu 9defe9681b Fix Cannot delete card checklist title, by removing "Delete" and "Convert to Card" that belong to Checklist Items only. Checklist Menu already has Delete Checklist.
Thanks to xet7 !

Fixes #5827
2026-05-01 12:49:08 +03:00
Lauri Ojansivu 2bb6999656 Updated ChangeLog. 2026-05-01 12:35:10 +03:00
Lauri Ojansivu 309b488861 Fix can not edit checklist title.
Thanks to xet7 !
2026-05-01 12:33:04 +03:00
Lauri Ojansivu 67192cf5c4 Updates 2026-04-30 02:36:05 +03:00
Lauri Ojansivu c84473ae43 v9.03 2026-04-29 00:57:29 +03:00
Lauri Ojansivu f6328937c9 Merge pull request #6321 from KhaoulaMaleh/fix/access
feat: add missing board‑attachments API endpoint (fix #6319)
2026-04-28 23:50:45 +03:00
KhaoulaMaleh 80db2517fd fixing access 2026-04-28 21:39:47 -11:00
Lauri Ojansivu 918bd0b6b5 Updated ChangeLog. 2026-04-28 20:41:20 +03:00
Lauri Ojansivu e22f422615 Update version script. Part 2.
Thanks to xet7 !
2026-04-28 20:40:19 +03:00
Lauri Ojansivu 1826f51664 Updated ChangeLog. 2026-04-28 20:37:12 +03:00
Lauri Ojansivu e547be9ab8 Update version script.
Thanks to xet7 !
2026-04-28 20:35:32 +03:00
Lauri Ojansivu 89140f1fee Updates 2026-04-28 20:08:08 +03:00
Lauri Ojansivu 1b57d09d0d v9.02 2026-04-28 20:01:39 +03:00
Lauri Ojansivu e7d67e3ddb Updated ChangeLog. 2026-04-28 19:42:34 +03:00
Lauri Ojansivu a4b5ac6c4e Fix mongodb in snap 9.01 on Ubuntu 24.04 crashes because of missing libcrypto.so.1.1 .
Thanks to sbaecker !

Fixes #6320
2026-04-28 19:39:35 +03:00
Lauri Ojansivu 9b22f9e157 Updates 2026-04-28 15:09:04 +03:00
Lauri Ojansivu 2ab0f59f13 v9.01 2026-04-28 13:48:23 +03:00
Lauri Ojansivu 611368abc6 Removed old file. 2026-04-28 13:06:15 +03:00
Lauri Ojansivu d3b3be2a52 Updated ChangeLog. 2026-04-28 12:59:50 +03:00
Lauri Ojansivu 11a2c95ea7 Fix Snap mongodb port wrong.
Thanks to xet7 !

Fixes #6316
2026-04-28 12:58:09 +03:00
Lauri Ojansivu 3e612c39b7 Updated ChangeLog. 2026-04-28 12:09:51 +03:00
Lauri Ojansivu 58de6bb737 Disable not working GitHub workflows.
Thanks to xet7 !
2026-04-28 12:03:16 +03:00
Lauri Ojansivu f6d8befb56 Moved website to separate repo. Moved docs2 back to docs.
Thanks to xet7 !
2026-04-28 11:59:16 +03:00
Lauri Ojansivu b49aa050e9 Removed charts, that are moved back to github.com/wekan/charts.
Thanks to xet7 !
2026-04-28 11:33:40 +03:00
Lauri Ojansivu 2ef8465e8d 9.00.0 2026-04-28 11:26:02 +03:00
Lauri Ojansivu 7878596608 9.00.0 2026-04-28 11:02:54 +03:00
Lauri Ojansivu 1f2f9f571e Updated ChangeLog. 2026-04-27 19:48:27 +03:00
Lauri Ojansivu 855cb86088 Docs: Updated s390x page.
Thanks to xet7 !
2026-04-27 19:45:56 +03:00
Lauri Ojansivu ed3cf96c6f Updated ChangeLog. 2026-04-27 08:32:23 +03:00
Lauri Ojansivu fdb477f351 Updated Docker platforms for what currently builds successfully.
Thanks to xet7 !
2026-04-27 08:30:08 +03:00
Lauri Ojansivu ac6cc1041a 9.00 2026-04-27 03:57:36 +03:00
Lauri Ojansivu 7d09a649ac Prepare v9.00 release 2026-04-27 03:38:04 +03:00
Lauri Ojansivu 040ed6e605 v9.00 2026-04-27 03:17:40 +03:00
Lauri Ojansivu d7e36f5157 Updated ChangeLog. 2026-04-27 03:03:47 +03:00
Lauri Ojansivu 1a08003834 Merge pull request #6314 from aminsaidane/fix/mycards-subscription
Fix/mycards subscription
2026-04-26 22:38:43 +03:00
Lauri Ojansivu 64bc6ea71c Updated ChangeLog. 2026-04-26 22:01:14 +03:00
Lauri Ojansivu ef4161889a Updated website.
Thanks to xet7 !
2026-04-26 21:59:13 +03:00
aminsaidane dd9d6083c0 fix:remove leftover code 2026-04-26 14:38:00 +01:00
aminsaidane 027b6a45a1 fix(myCards): fix subscription crash caused by non-cursor in publish return* 2026-04-26 14:32:30 +01:00
Lauri Ojansivu b717e5d7ad Updated ChangeLog. 2026-04-24 22:33:24 +03:00
Lauri Ojansivu 74965f5f95 Updated dependencies.
Thanks to developers of dependencies !
2026-04-24 22:32:25 +03:00
Lauri Ojansivu fa812faf6d Updated ChangeLog. 2026-04-24 22:06:50 +03:00
Lauri Ojansivu b459151798 Updated dependencies.
Thanks to developers of dependencies !
2026-04-24 22:05:36 +03:00
Lauri Ojansivu 73679919fb Updated ChangeLog. 2026-04-24 21:51:08 +03:00
Lauri Ojansivu 58b0ae29e1 Revert Fix MongoDB duplicate key error in notification_cleanup cron job.
Thanks to xet7 !
2026-04-24 21:50:18 +03:00
Lauri Ojansivu 773931a538 Updated ChangeLog. 2026-04-24 16:41:08 +03:00
Lauri Ojansivu 1ef814fe6b Merge pull request #6311 from Raawen-dev/fix-cron-5110-only
Fix MongoDB duplicate key error in notification_cleanup cron job (Issue #5110)
2026-04-24 16:33:34 +03:00
Lauri Ojansivu b010c687f3 Merge branch 'main' into fix-cron-5110-only 2026-04-24 16:33:18 +03:00
Lauri Ojansivu 05950fb287 Merge pull request #6310 from Raawen-dev/fix-popup-6221-only
Fix list actions popup overflow (Issue #6221)
2026-04-24 16:19:56 +03:00
RAWEN KHEFIFI 56a685983b Merge upstream/main into fix-cron-5110-only 2026-04-23 17:54:47 +01:00
RAWEN KHEFIFI 339c0a2bb7 Fix MongoDB duplicate key error in notification_cleanup cron job (#5110)
- Add check to remove existing cron job before adding
- Wrap job logic in try-catch for duplicate key errors
- Prevents E11000 error in cronHistory collection
2026-04-23 17:51:13 +01:00
RAWEN KHEFIFIandRaawen-dev a790453c9a Fix list actions popup overflow (#6221)
- Append CSS fix to existing popup.css
- Add max-height: 300px and overflow-y: auto to .pop-over-list
- Prevents list actions menu from overflowing viewport
- Tested working on Mac (Chrome/Firefox)

Co-authored-by: Raawen-dev <rawenkhefifi19@gmail.com>
2026-04-23 17:50:45 +01:00
RAWEN KHEFIFI 04eb8a8fbb Fix list actions popup overflow (Issue #6221)
- Add max-height: 300px to .pop-over-list
- Enable scrolling with overflow-y: auto
- Prevent popup from overflowing viewport
2026-04-23 15:42:05 +01:00
Lauri Ojansivu 4ab1bc9638 Updated ChangeLog. 2026-04-23 05:00:38 +03:00
Lauri Ojansivu 699b9a9c71 Update release and version scripts. 2026-04-23 04:59:20 +03:00
Lauri Ojansivu 3a203d274d Release scripts: Fix version detection.
Thanks to xet7 !
2026-04-23 03:46:25 +03:00
Lauri Ojansivu 887511fdda Updated ChangeLog. 2026-04-23 03:43:17 +03:00
Lauri Ojansivu 64f58455ff Update releases scripts.
Thanks to xet7 !
2026-04-23 03:41:59 +03:00
Lauri Ojansivu 5163ec0da2 Updated ChangeLog. 2026-04-23 01:59:52 +03:00
Lauri Ojansivu c47eb013b4 Fix UI hangs and data loss by disabling changeStreams, until there is new Meteor release that included bugfix to changeStreams.
Thanks to bcook-konza and italojs !

Fixes #6307
2026-04-23 01:55:13 +03:00
Lauri Ojansivu d4cbe12316 Updated translations. 2026-04-23 01:34:57 +03:00
Lauri Ojansivu 794222c85e Updated ChangeLog. 2026-04-23 01:26:56 +03:00
Lauri Ojansivu 675c661114 Updated HoF.
Thanks to xet7 !
2026-04-23 01:07:46 +03:00
Lauri Ojansivu 7700efde1f Update security.md etc.
Thanks to xet7 !
2026-04-23 00:44:47 +03:00
Lauri Ojansivu 16832124ce Updated dependencies.
Thanks to developers of dependencies !
2026-04-22 03:53:46 +03:00
Lauri Ojansivu bf5ca3d3eb Added back jam packages. Updated dependencies.
Thanks to xet7 !
2026-04-22 03:47:13 +03:00
Lauri Ojansivu 189b6cae84 Merge pull request #6306 from wekan/dependabot/github_actions/actions/deploy-pages-5
Bump actions/deploy-pages from 4 to 5
2026-04-21 09:08:55 +03:00
Lauri Ojansivu 9bf0114148 Merge pull request #6305 from wekan/dependabot/github_actions/docker/setup-buildx-action-4
Bump docker/setup-buildx-action from 3 to 4
2026-04-21 09:08:37 +03:00
Lauri Ojansivu 9f3bbb5ed2 Merge pull request #6304 from wekan/dependabot/github_actions/actions/upload-pages-artifact-5
Bump actions/upload-pages-artifact from 4 to 5
2026-04-21 09:08:15 +03:00
dependabot[bot] 85b981e1c7 Bump actions/deploy-pages from 4 to 5
Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 4 to 5.
- [Release notes](https://github.com/actions/deploy-pages/releases)
- [Commits](https://github.com/actions/deploy-pages/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/deploy-pages
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-20 22:22:25 +00:00
dependabot[bot] eb5ac8b7dd Bump docker/setup-buildx-action from 3 to 4
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-20 22:22:22 +00:00
dependabot[bot] 5ef32af248 Bump actions/upload-pages-artifact from 4 to 5
Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-pages-artifact/releases)
- [Commits](https://github.com/actions/upload-pages-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-pages-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-20 22:22:18 +00:00
Lauri Ojansivu 9cb5837e3e Updated ChangeLog. 2026-04-18 19:14:46 +03:00
Lauri Ojansivu 5ae9c2b7ac Merge pull request #6303 from Raawen-dev/first-fix
Fix Issue #6007: Add permission checks to list width method
2026-04-18 19:12:06 +03:00
RAWEN KHEFIFI 7d16fed34e Fix Issue #6007: Add permission checks to applyListWidth method
- Add user authentication check
- Add board membership verification
- Change update to updateAsync to fix server error
- List widths now persist after page refresh
2026-04-18 17:04:58 +01:00
Lauri Ojansivu db2701f1d7 Update release scripts. In Progress.
Thanks to xet7 !
2026-04-17 18:34:36 +03:00
Lauri Ojansivu 76818e2c98 Updated ChangeLog. 2026-04-17 15:02:27 +03:00
Lauri Ojansivu c4e084ffbb Fix MongoDB replicaset setup at docker-compose.yml.
Thanks to C0rn3j.

Fixes #6297
2026-04-17 14:59:24 +03:00
Lauri Ojansivu a10b28bf6a Updated ChangeLog. 2026-04-17 14:50:30 +03:00
Lauri Ojansivu 90c0110615 Merge pull request #6299 from snowsky/main
Update cards.js
2026-04-17 14:46:00 +03:00
Hao 73c594bb36 Update cards.js
Fix the error:

```
Exception from sub myCards id xxx TypeError: Promise.await is not a function
```
2026-04-16 18:40:58 -05:00
Lauri Ojansivu 903544c680 Prepare v8.99 release 2026-04-16 22:15:49 +03:00
Lauri Ojansivu 32e1ec9d22 Release scripts: Update versions.
Thanks to xet7 !
2026-04-16 22:11:57 +03:00
Lauri Ojansivu 3516a21329 Prepare v8.98 release 2026-04-16 21:00:29 +03:00
Lauri Ojansivu f6198dee30 Release scripts: Updated creating Helm Charts to docs/wekan and docs/charts.
Thanks to xet7 !
2026-04-16 20:57:46 +03:00
Lauri Ojansivu 13f14df880 Updated Helm Charts. 2026-04-16 20:36:37 +03:00
Lauri Ojansivu f3ae64cf21 Prepare v8.98 release 2026-04-16 19:55:20 +03:00
Lauri Ojansivu 1820804b9f Fix Helm Chart parts to docs/wekan and docs/charts.
Thanks to xet7 !
2026-04-16 19:53:24 +03:00
Lauri Ojansivu d3d76b12f7 Prepare v8.98 release 2026-04-16 17:12:56 +03:00
Lauri Ojansivu 51ad6ed99d Release scripts: use node:24-slim directly.
Thanks to xet7 !
2026-04-16 17:11:24 +03:00
Lauri Ojansivu 1c8cea9ada Prepare v8.98 release 2026-04-16 16:47:23 +03:00
Lauri Ojansivu a0c190137d Release scripts: Use 24-slim fallback.
Thanks to xet7 !
2026-04-16 16:45:37 +03:00
Lauri Ojansivu 83e1845290 Prepare v8.98 release 2026-04-16 16:19:55 +03:00
Lauri Ojansivu 052d8c1584 Release scripts: Require only newest version number when releasing.
Thanks to xet7 !
2026-04-16 16:18:11 +03:00
Lauri Ojansivu 7b0e2213cf Release scripts: Fix updating version numbers.
Thanks to xet7 !
2026-04-16 16:06:19 +03:00
Lauri Ojansivu 05e6d15478 Prepare v8.98 release 2026-04-16 15:47:05 +03:00
Lauri Ojansivu be0283381b Release scripts: Use latest available Node.js slim docker images when building.
Thanks to xet7 !
2026-04-16 15:47:05 +03:00
github-actions[bot] 379a92846e v8.98 2026-04-16 12:33:19 +00:00
Lauri Ojansivu bb6163a70f Prepare v8.98 release 2026-04-16 15:32:31 +03:00
Lauri Ojansivu 10f009f5b1 Release scripts: Fix indentation at release-all.yml.
Thanks to xet7 !
2026-04-16 15:30:13 +03:00
Lauri Ojansivu 19c882ed2f Prepare v8.98 release 2026-04-16 15:23:37 +03:00
Lauri Ojansivu e7cb6ac6f0 Updated ChangeLog. 2026-04-16 15:20:40 +03:00
Lauri Ojansivu 38e488ee4a Moved Helm Charts from helm directory to docs/wekan and docs/charts to be at wekan.fi/wekan and wekan.fi/charts.
Thanks to xet7 !
2026-04-16 15:18:14 +03:00
Lauri Ojansivu 589fa30fd1 Updated ChangeLog. 2026-04-16 15:05:44 +03:00
Lauri Ojansivu 64d351d835 Commented out requirement to update website manually.
Thanks to xet7 !
2026-04-16 15:04:19 +03:00
Lauri Ojansivu 4151ecb7e7 Release scripts: Update versions at wekan.fi/install/ as part of GitHub Actions builds.
Thanks to xet7 !
2026-04-16 15:01:10 +03:00
Lauri Ojansivu f4b5e5f07d Updated ChangeLog. 2026-04-16 14:51:42 +03:00
Lauri Ojansivu c1639ea589 Update markdown docs links from docs to docs2.
Thanks to xet7 !
2026-04-16 14:50:12 +03:00
Lauri Ojansivu 21b0ab064c Updated ChangeLog. 2026-04-16 14:38:32 +03:00
Lauri Ojansivu 1c0d8e9964 Moved docs to docs2, and wekan.fi to docs, to be able publish with GitHub Pages.
Thanks to xet7 !
2026-04-16 14:36:10 +03:00
Lauri Ojansivu 8a7949a8ab Updated ChangeLog. 2026-04-16 14:30:01 +03:00
Lauri Ojansivu 3c36db33e9 Moved website from repo wekan/wekan.fi to wekan/wekan/docs/wekan.fi .
Thanks to xet7 !
2026-04-16 14:28:15 +03:00
Lauri Ojansivu 59d0cfc457 Updated ChangeLog. 2026-04-16 14:06:21 +03:00
Lauri Ojansivu 72f6d96dbc Release scripts: Detect newest MongoDB 7.x stable version and update to use it.
Thanks to xet7 !
2026-04-16 14:03:51 +03:00
Lauri Ojansivu 49c81f5426 Updated ChangeLog. 2026-04-16 13:44:42 +03:00
Lauri Ojansivu 08ed1705b1 Release scripts: Update versions at website with release-website.sh script.
Thanks to xet7 !
2026-04-16 13:44:42 +03:00
Lauri Ojansivu 47088c30c0 Release scripts: Detect newest Node.js 24.x version.
Thanks to xet7 !
2026-04-16 13:44:42 +03:00
github-actions[bot] 539dbdc034 Helm chart 8.97.0 2026-04-16 10:43:18 +00:00
github-actions[bot] 129af0bad9 v8.97 2026-04-16 10:02:21 +00:00
Lauri Ojansivu a9d95dd6b7 Prepare v8.97 release 2026-04-16 13:01:42 +03:00
Lauri Ojansivu 6d0978d0ed Release Scripts: Clean GitHub Cache. Part 3.
Thanks to xet7 !
2026-04-16 13:00:39 +03:00
Lauri Ojansivu 13cdf08e22 Release Scripts: Clean GitHub Cache. Part 2.
Thanks to xet7 !
2026-04-16 12:56:52 +03:00
Lauri Ojansivu e59bc9cd86 Release Scripts: Clean GitHub Cache.
Thanks to xet7 !
2026-04-16 12:53:42 +03:00
Lauri Ojansivu 6478d27d1c Fix GitHub Actions builds.
Thanks to xet7 !
2026-04-16 12:49:37 +03:00
Lauri Ojansivu 76d1800ec7 Prepare v8.96 release 2026-04-16 12:46:15 +03:00
Lauri Ojansivu 03ba747bc0 Fix GitHub Actions builds.
Thanks to xet7 !
2026-04-16 12:43:35 +03:00
Lauri Ojansivu 9eb3889d51 Prepare v8.95 release 2026-04-16 12:33:53 +03:00
Lauri Ojansivu 5d4bc7a886 Updated ChangeLog. 2026-04-16 12:31:58 +03:00
Lauri Ojansivu 135af977af Helm Chart: Use current Finland time for created field at index.yaml for newest built Helm Chart release.
Thanks to xet7 !
2026-04-16 12:26:44 +03:00
Lauri Ojansivu 6dfe81cbcb Fix Cannot find module /build/main.js error in latest Docker image.
Thanks to s8321414 and xet7 !

Fixes #6291
2026-04-16 12:16:58 +03:00
Lauri Ojansivu 3ec2821058 Updated ChangeLog. 2026-04-16 12:04:27 +03:00
Lauri Ojansivu 1c5ac8efba Merge pull request #6292 from titver968/helm-improvements
helm: add single-node ReplicaSet support with auto MONGO_OPLOG_URL
2026-04-16 12:00:01 +03:00
titver968 ce7fa0e314 helm: add single-node ReplicaSet support with auto MONGO_OPLOG_URL
- mongodb.url template now appends ?replicaSet=<name> for single-replica
  setups when mongodb.replicaSet.name is set, eliminating the need for
  a secretEnv workaround
- New mongodb.oplog.url helper generates MONGO_OPLOG_URL automatically
  when a ReplicaSet is configured (single-node or multi-node)
- deployment.yaml injects MONGO_OPLOG_URL env var when the oplog URL
  helper produces a non-empty value
- values.yaml documents the replicaSet.name option with example config
2026-04-16 09:58:44 +02:00
github-actions[bot] 0f464b21a3 Helm chart 8.94.0 2026-04-16 02:34:48 +00:00
github-actions[bot] 7169da8dae v8.94 2026-04-16 02:15:31 +00:00
Lauri Ojansivu 0f56e2dfc3 Prepare v8.94 release 2026-04-16 05:14:48 +03:00
Lauri Ojansivu 1b086c80a7 Updated ChangeLog. 2026-04-16 05:12:42 +03:00
Lauri Ojansivu c27d5d0412 Updated dompurify.
Thanks to developers of dompurify !
2026-04-16 05:10:59 +03:00
Lauri Ojansivu 7b3043bf46 Updated ChangeLog. 2026-04-16 05:09:46 +03:00
Lauri Ojansivu da19160e87 Fix Can't start latest docker image because of MongoDB Index errors.
Thanks to s8321414 and xet7 !

Fixes #6290
2026-04-16 05:09:46 +03:00
github-actions[bot] 790a801f30 Helm chart 8.93.0 2026-04-16 02:07:36 +00:00
github-actions[bot] b08c66a483 v8.93 2026-04-16 01:48:41 +00:00
Lauri Ojansivu 524aa9124d Prepare v8.93 release 2026-04-16 04:48:01 +03:00
Lauri Ojansivu df85b5ac45 Updated ChangeLog. 2026-04-16 04:44:04 +03:00
Lauri Ojansivu c009ddc915 Fix SSO Login broken. Part 2.
Thanks to xet7 !

Fixes #6276
2026-04-16 04:44:04 +03:00
github-actions[bot] 5407e4533c Helm chart 8.92.0 2026-04-16 01:08:11 +00:00
github-actions[bot] 98088c7734 v8.92 2026-04-16 00:49:02 +00:00
Lauri Ojansivu 0d6fb33043 Prepare v8.92 release 2026-04-16 03:48:15 +03:00
Lauri Ojansivu 1dbad1b454 Updated ChangeLog. 2026-04-16 03:44:46 +03:00
Lauri Ojansivu 2c8a6c8ec6 GitHub Actions: Added missing sudo to snap build.
Thanks to xet7 !
2026-04-16 03:42:56 +03:00
Lauri Ojansivu 06b9946dd8 Updated ChangeLog. 2026-04-16 03:36:32 +03:00
Lauri Ojansivu dbcdf15244 Updated Helm Charts versions.
Thanks to xet7 !
2026-04-16 03:36:32 +03:00
github-actions[bot] 7e2067d0b1 v8.91 2026-04-16 00:21:29 +00:00
Lauri Ojansivu 7489f720ea Prepare v8.91 release 2026-04-16 03:02:50 +03:00
Lauri Ojansivu 140e844238 Updated Helm Chart URL at readme.
Thanks to xet7 !
2026-04-16 03:02:50 +03:00
Lauri Ojansivu de55d5afbe Fix building Snap at GitHub Actions.
Thanks to xet7 !
2026-04-16 03:02:50 +03:00
github-actions[bot] c5fccb52cc Helm chart 8.90.0 2026-04-15 23:50:03 +00:00
github-actions[bot] 507ca57a50 v8.90 2026-04-15 23:28:22 +00:00
Lauri Ojansivu b2e072e02c Prepare v8.90 release 2026-04-16 02:27:44 +03:00
Lauri Ojansivu 357f63d01f Release scripts: Moved more steps to GitHub Actions.
Thanks to xet7 !
2026-04-16 02:24:17 +03:00
Lauri Ojansivu e6422d842a Updated ChangeLog. 2026-04-16 02:02:33 +03:00
Lauri Ojansivu 99519af83a Changed ArtifactHub from wekan/charts repo to wekan/wekan repo.
Thanks to xet7 !
2026-04-16 02:00:47 +03:00
Lauri Ojansivu 514ce6ad24 Updated ChangeLog. 2026-04-16 01:52:33 +03:00
Lauri Ojansivu f57ce52198 Added GitHub Actions for Docker and Snap. Moved Helm Charts from charts repo to wekan repo.
Thanks to xet7 !
2026-04-16 01:49:42 +03:00
Lauri Ojansivu 2a9c921ba6 Updated ChangeLog. 2026-04-16 00:54:13 +03:00
Lauri Ojansivu 0dd924f148 Removed jam:offline jam:method jam:pub-sub, because they are not used, and they cause too much database usage.
Thanks to xet7 !
2026-04-16 00:50:58 +03:00
Lauri Ojansivu 678eb0896d v8.89 2026-04-15 23:01:39 +03:00
Lauri Ojansivu 233c1c8e81 Updated ChangeLog. 2026-04-15 22:57:58 +03:00
Lauri Ojansivu f6a851a3d8 Disable jam:offline keepAll BEFORE any collections are created. Part 2.
Thanks to xet7 !
2026-04-15 22:56:01 +03:00
Lauri Ojansivu 4fba9d7802 v8.88 2026-04-15 21:45:44 +03:00
Lauri Ojansivu d41ecb054c Updated ChangeLog. 2026-04-15 21:37:09 +03:00
Lauri Ojansivu ec0c1bc9af Disable jam:offline keepAll to prevent full-collection COLLSCAN queries and Ensure standard GridFS index on attachments.chunks for efficient chunk lookups.
Disable jam:offline keepAll to prevent full-collection COLLSCAN queries.
WeKan uses modifiedAt (not updatedAt) and archived (not deleted),
so the default offline sync generates queries on non-existent fields
causing massive collection scans on every sync cycle.

Ensure standard GridFS index on attachments.chunks for efficient chunk lookups.
Without this, queries like find({files_id: ObjectId}) do full collection scans.
2026-04-15 21:33:18 +03:00
Lauri Ojansivu 05b77d24fa v8.87 2026-04-15 17:39:22 +03:00
Lauri Ojansivu 4535303807 Updated ChangeLog. 2026-04-15 17:37:33 +03:00
Lauri Ojansivu f232fdc30b Merge pull request #6287 from FlorentDotMe/fix_quick-access-scroll
ui: enable the horizontal scroll in the quick access menu boards list
2026-04-15 17:36:24 +03:00
Lauri Ojansivu dab72d80dc Updated ChangeLog. 2026-04-15 17:35:55 +03:00
Lauri Ojansivu 6f83464b24 Merge pull request #6286 from FlorentDotMe/fix_rooturl-as-env-variable
improve handling of ROOT_URL as an environement variable
2026-04-15 17:34:48 +03:00
Lauri Ojansivu 41cd0a8925 Updated ChangeLog. 2026-04-15 17:34:35 +03:00
Lauri Ojansivu fc02a15753 Try to fix Snap.
Thanks to xet7 !
2026-04-15 17:31:09 +03:00
Florent Bervas bd9c5a058a improve handling of ROOT_URL as an environement variable 2026-04-15 13:47:28 +00:00
Lauri Ojansivu c1692cc6b9 v8.86 2026-04-15 16:29:44 +03:00
Florent Bervas 5259c09a5c ui: enable the horizontal scroll in the quick access menu boards list 2026-04-15 13:28:08 +00:00
Lauri Ojansivu 10f801d31b Try to fix Snap.
Thanks to xet7 !
2026-04-15 16:25:06 +03:00
Lauri Ojansivu 28d19db328 v8.85 2026-04-15 16:02:59 +03:00
Lauri Ojansivu 0e13bfc50e Try to fix Snap.
Thanks to xet7 !
2026-04-15 16:00:33 +03:00
Lauri Ojansivu 4f4aa22ca1 v8.84 2026-04-15 15:29:15 +03:00
Lauri Ojansivu 6bec01198d Updated ChangeLog. 2026-04-15 15:27:02 +03:00
Lauri Ojansivu 5dbceb43b4 Updated ChangeLog. 2026-04-15 15:17:14 +03:00
Lauri Ojansivu bc92978fa9 Try to fix Snap Candidate.
Thanks to xet7 !
2026-04-15 15:16:02 +03:00
Lauri Ojansivu 893f83b79e Updated ChangeLog. 2026-04-15 15:09:53 +03:00
Lauri Ojansivu bde23f6c4d Merge pull request #6284 from cloudron-io/oidc-login-fix
Use local content variable in error case
2026-04-15 15:05:53 +03:00
Johannes Zellner e6d4b38c64 Use local content variable in error case 2026-04-15 10:27:53 +02:00
Lauri Ojansivu 23264044e6 v8.83 2026-04-14 21:39:23 +03:00
Lauri Ojansivu d51a381a79 Updated ChangeLog. 2026-04-14 21:32:31 +03:00
Lauri Ojansivu da4459304f Changed start-wekan.sh and start-wekan.bat to not use Change Streams.
Thanks to xet7 !
2026-04-14 21:31:08 +03:00
Lauri Ojansivu 085699f202 Updated ChangeLog. 2026-04-14 01:12:42 +03:00
Lauri Ojansivu 2c43aa463a Release scripts: Fix Node.js 24.x download URL for Snap builds.
Thanks to xet7 !
2026-04-14 01:09:26 +03:00
Lauri Ojansivu 41db7b4ad1 Release scripts: Docker not for armhf, no official Node.js binary for it.
Thanks to xet7 !
2026-04-14 00:58:35 +03:00
Lauri Ojansivu d0a9fa9a71 Release scripts: Removed armhf, there is no official Node.js binary for it.
Thanks to xet7 !
2026-04-14 00:38:55 +03:00
Lauri Ojansivu ed0675aaff v8.82 2026-04-14 00:37:28 +03:00
Lauri Ojansivu cad8f58468 Merge pull request #6282 from wekan/dependabot/github_actions/docker/build-push-action-7.1.0
Bump docker/build-push-action from 7.0.0 to 7.1.0
2026-04-14 00:31:12 +03:00
Lauri Ojansivu 819d58cf31 Merge pull request #6281 from wekan/dependabot/github_actions/softprops/action-gh-release-3
Bump softprops/action-gh-release from 2 to 3
2026-04-14 00:30:43 +03:00
dependabot[bot] b951515e3e Bump docker/build-push-action from 7.0.0 to 7.1.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 7.0.0 to 7.1.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/d08e5c354a6adb9ed34480a06d141179aa583294...bcafcacb16a39f128d818304e6c9c0c18556b85f)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-13 21:24:10 +00:00
dependabot[bot] 4c3265bca5 Bump softprops/action-gh-release from 2 to 3
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-13 21:24:05 +00:00
Lauri Ojansivu 11672a13f7 Release scripts: Added script for deleting repo git tag.
Thanks to xet7 !
2026-04-14 00:19:15 +03:00
Lauri Ojansivu 9a8141a0eb v8.81 2026-04-14 00:16:28 +03:00
Lauri Ojansivu 5462fb0647 Release scripts: Comment out build for armhf because no official Node.js 24.x binaries exist for armhf (arm/v7).
Thanks to xet7 !
2026-04-14 00:10:51 +03:00
Lauri Ojansivu 6b74b8f770 v8.81 2026-04-13 22:57:32 +03:00
Lauri Ojansivu 99fff1a1a1 Updated ChangeLog. 2026-04-13 20:25:00 +03:00
Lauri Ojansivu 645f233b83 Merge pull request #6279 from kolaente/patch-1
fix(exporter): attachments always empty in board JSON export
2026-04-13 20:22:38 +03:00
kolaente 643e2738bd fix(exporter): attachments always empty in board JSON export 2026-04-13 18:15:48 +02:00
Lauri Ojansivu cd356a29ce Updated translations. 2026-04-13 17:16:10 +03:00
Lauri Ojansivu 341be982f9 Updated ChangeLog. 2026-04-13 17:14:21 +03:00
Lauri Ojansivu 2e7565f9eb Docs: Added History of Schema Migration Systems.
Thanks to xet7 !
2026-04-13 17:13:00 +03:00
Lauri Ojansivu 1637a9c938 Updated dependencies.
Thanks to developers of dependencies !
2026-04-13 17:11:04 +03:00
Lauri Ojansivu 67c2be1858 Updated ChangeLog. 2026-04-13 16:25:14 +03:00
Lauri Ojansivu b8d4c01e60 Updated ChangeLog. 2026-04-13 16:23:41 +03:00
Lauri Ojansivu e259ab86f7 Updated dependencies.
Thanks to developers of dependencies !
2026-04-13 16:23:41 +03:00
Lauri Ojansivu 029b3523cb Merge pull request #6275 from KhaoulaMaleh/fix/export
Fix: include historical comments and activities in board exports
2026-04-13 16:21:02 +03:00
KhaoulaMaleh f4657ad817 Fix: include historical comments and activities in board exports 2026-04-13 00:12:57 -11:00
Lauri Ojansivu 5efddff154 Updated translations. 2026-04-12 17:35:51 +03:00
Lauri Ojansivu 25efe93507 Updated ChangeLog. 2026-04-12 17:31:27 +03:00
Lauri Ojansivu a393e67ef8 Merge pull request #6262 from Raawen-dev/first-fix
Fix Issue #6069: Add migration for v7.95 due dates
2026-04-12 17:29:21 +03:00
Lauri Ojansivu 7f6758cbe9 Merge pull request #6268 from YosserDerbali/fix/board-drag-tooltip-clarification
Clarify board drag tooltip text in Remaining and Workspaces
2026-04-12 17:28:48 +03:00
Lauri Ojansivu c5644a3321 Updated ChangeLog. 2026-04-12 17:28:38 +03:00
Lauri Ojansivu 4fec03101f Updated ChangeLog. 2026-04-12 17:27:32 +03:00
Lauri Ojansivu 10fed0a85c Merge pull request #6271 from YosserDerbali/fix/readme-node-version-and-changes-made
Fix/readme node version and changes made
2026-04-12 17:25:51 +03:00
Lauri Ojansivu fff6316192 Updated ChangeLog. 2026-04-12 17:23:19 +03:00
Lauri Ojansivu 61623f50b1 Merge pull request #6273 from AymenHassini19/solve-white-container-“Link-Card”-dialog
Fix Link Card modal overflow in Docker environment
2026-04-12 17:21:59 +03:00
Lauri Ojansivu 9f626407cf Updated ChangeLog. 2026-04-12 17:20:26 +03:00
Lauri Ojansivu 3a51678495 Merge pull request #6272 from snowsky/fix-activities-not-showing
Fix activities are not showing
2026-04-12 17:14:02 +03:00
Aymen Hassini c730a0e733 Add missing Meteor test dependencies 2026-04-12 10:17:18 +01:00
Aymen Hassini 80a9971508 solving white container "Link Card" 2026-04-12 09:31:49 +01:00
Hao Wang 85788e1d7d Fix activities are not showing 2026-04-11 19:39:27 +00:00
Yosser Derbali 23680547ea docs: update README to Node.js 24.x and remove Rosetta mention 2026-04-11 14:30:04 +01:00
Yosser Derbali 9767ead9f3 docs: update README Node.js version and setup guidance 2026-04-10 22:26:16 +01:00
Yosser Derbali 910c9a7f1f docs: improve README with first-time setup guide and fix typos 2026-04-10 22:24:40 +01:00
Yosser Derbali 0bc6c6abb6 docs: fix typos and grammar in SECURITY.md
- Fix capitalization: 'About Money', 'QA About PubSub', etc.
- Add missing articles ('the', 'a')
- Fix spelling: 'Wordwide' -> 'Worldwide', 'logics' -> 'logic'
- Remove duplicate 'by' and extra spaces
- Fix grammar and sentence structure for clarity
- Improve consistency with WeKan capitalization
2026-04-10 22:24:40 +01:00
Yosser Derbali 6361e16dba Clarify board drag tooltip text 2026-04-10 18:21:04 +01:00
Lauri Ojansivu 8572cbd761 v8.80 2026-04-10 11:56:56 +03:00
Lauri Ojansivu 1c0b91c5f4 Updated translations. 2026-04-10 11:56:25 +03:00
Lauri Ojansivu 2ebefdd0bf Try to fix GitHub Actions builds with custom newer bcrypt.
Thanks to xet7 !
2026-04-10 11:53:09 +03:00
Lauri Ojansivu 29f1384945 v8.79 2026-04-09 16:00:52 +03:00
Lauri Ojansivu 334e569fda Updated translations. 2026-04-09 15:58:41 +03:00
Lauri Ojansivu 2d4170a9bf Fix 8.78: WeKan build Error: Could not find rspack config. Using MongoDB Change Streams at start-wekan.sh start-wekan.bat bundle, docker-compose.yml and Snap Candidate.
Thanks to nachocodoner and xet7 !

Fixes #6264
2026-04-09 15:42:05 +03:00
Lauri Ojansivu 6b2759f97d v8.78 2026-04-09 04:52:05 +03:00
Lauri Ojansivu adf4312e5a v8.77 2026-04-09 04:40:21 +03:00
Lauri Ojansivu b1707b8691 Upgraded to Meteor 3.5-beta.7
Thanks to Meteor developers !
2026-04-09 04:37:36 +03:00
Lauri Ojansivu 25dff3f2da v8.76 2026-04-09 04:19:51 +03:00
Lauri Ojansivu bc88c0dfc2 Fix GitHub Actions builds.
Thanks to xet7 !
2026-04-09 04:14:46 +03:00
Lauri Ojansivu 1ca2dfd1b1 v8.75 2026-04-09 03:58:01 +03:00
Lauri Ojansivu bdb9274485 Updated to Node.js 24.x at release scripts.
Thanks to xet7 !
2026-04-09 03:56:06 +03:00
Lauri Ojansivu 14f9ac39ad Upgraded to Meteor 3.5-beta.7 and Node.js 24.14.1. Now prefers MongoDB Change Streams at Snap Candidate and docker-compose.yml.
Thanks to Meteor developers and xet7 !
2026-04-09 03:44:58 +03:00
Lauri Ojansivu d4b52f7de9 Updated ChangeLog. 2026-04-09 02:19:44 +03:00
Lauri Ojansivu bdc65ec6f4 Merge pull request #6261 from KhaoulaMaleh/fix/translation-refinement
Refine translations
2026-04-08 23:30:39 +03:00
RAWEN KHEFIFI 74966a0bc7 Fix Issue #6069: Add migration for v7.95 due dates
- Add migration script to convert dueDate to dueAt
- Convert string dates to Date objects
- Add missing userId and members fields
- Fix invalid board/list/swimlane references

This fixes cards not appearing in Due Cards view after migration from v7.95 to v8.20
2026-04-08 16:44:19 +01:00
KhaoulaMaleh 7fb31cecd5 fix refinement 2026-04-08 00:45:27 -11:00
KhaoulaMaleh 317c82a9f0 fixed after review 2026-04-08 00:16:18 -11:00
KhaoulaMaleh 9b5c89d235 Enhance translations with new key:value pairs 2026-04-07 23:36:43 -11:00
Lauri Ojansivu c23e190e8e Updated ChangeLog. 2026-04-08 02:16:21 +03:00
Lauri Ojansivu 4a73371499 Merge pull request #6260 from KhaoulaMaleh/fix/Card_setting_checkbox
fixed Card settings checkboxes
2026-04-08 02:14:28 +03:00
KhaoulaMaleh 6f8af55489 fixed Card settings checkboxes 2026-04-08 00:04:48 -11:00
Lauri Ojansivu 2a05f62bf9 Updated ChangeLog. 2026-04-08 01:49:33 +03:00
Lauri Ojansivu d6eb1eb76f Merge pull request #6259 from KhaoulaMaleh/fix/enhance_translation
Enhance translations with new key:value pairs
2026-04-08 01:46:33 +03:00
Lauri Ojansivu 27542f3a51 v8.74 2026-04-08 00:34:49 +03:00
Lauri Ojansivu 0328e70d5f Fix can not save Card Data. Part 2.
Thanks to xet7 !

Fixes #6254
2026-04-08 00:31:40 +03:00
Lauri Ojansivu c46932ee30 v8.73 2026-04-07 23:18:14 +03:00
Lauri Ojansivu c7408ad8d1 Fix board and card activities. Part 2.
Thanks to xet7 !

Related #6252
2026-04-07 23:12:26 +03:00
Lauri Ojansivu 05dc8f8f93 Updated ChangeLog. 2026-04-07 22:01:59 +03:00
Lauri Ojansivu aea8c285c2 Fix Change list inside or card.
Thanks to mimZD and xet7 !

Fixes #6161
2026-04-07 22:00:11 +03:00
Lauri Ojansivu a859137971 Updated ChangeLog. 2026-04-07 21:53:11 +03:00
Lauri Ojansivu 08ebad0fe4 Fix Checklists add and Subtasks reorder. Fix Board Activity part 1.
Thanks to xet7 !

Related #6252
2026-04-07 21:49:26 +03:00
Lauri Ojansivu d54ebfa0e1 Updated ChangeLog. 2026-04-07 20:39:55 +03:00
Lauri Ojansivu 304a007d07 Fix Search All Boards result opened card missing Copy Card Link etc that can be used to open correct card.
Thanks bcook-konza and xet7 !

Fixes #6251
2026-04-07 20:35:20 +03:00
Lauri Ojansivu b6b58c9d95 Updated ChangeLog. 2026-04-07 20:10:38 +03:00
Lauri Ojansivu 7f0c42cca5 Fix Error in choosing member or assignee in a card.
Thanks to hmeunier95 and xet7 !

Fixes #6257
2026-04-07 20:08:04 +03:00
Lauri Ojansivu 9508d46ebd Updated ChangeLog. 2026-04-07 19:25:15 +03:00
Lauri Ojansivu bcbf4771ea Fix 8.72 Bug: LDAP login does not work. ReactiveCache is not defined.
Thanks to poc-sm and xet7 !

Fixes #6255
2026-04-07 19:23:06 +03:00
Lauri Ojansivu 9da5ec25c6 Updated ChangeLog. 2026-04-07 19:21:20 +03:00
Lauri Ojansivu 028b404377 Removed exclude-arch from rebuild-wekan.sh, it is not necessary anymore.
Thanks to xet7 !
2026-04-07 19:19:53 +03:00
Lauri Ojansivu 8da0f34ee6 Fix can not save Card Data.
Thanks to xet7 !

Fixes #6254
2026-04-07 19:17:35 +03:00
Lauri Ojansivu cac2628b19 Updated ChangeLog. 2026-04-07 11:40:46 +03:00
Lauri Ojansivu 9c69530256 Fix Link to Windows release doesn't work.
Thanks to hmeunier95 and xet7 !

Fixes #6253
2026-04-07 11:37:50 +03:00
Lauri Ojansivu 6e108358d7 v8.72 2026-04-07 10:44:37 +03:00
Lauri Ojansivu 87f592c67f Updated release scripts.
Thanks to xet7 !
2026-04-07 10:42:45 +03:00
Lauri Ojansivu fc95abd587 v8.72 2026-04-07 09:52:41 +03:00
Lauri Ojansivu ce3e51b147 Fix Impersonate User. Show/Edit Avatar at Admin Panel/People/People.
Thanks to ahlgrimma, DnT1mmer, robbagithub, norrig and xet7 !

Fixes #6226,
fixes #6101,
fixes #3327,
fixes #4748
2026-04-07 09:52:41 +03:00
Lauri Ojansivu bb48b23266 Merge pull request #6250 from wekan/dependabot/github_actions/docker/login-action-4.1.0
Bump docker/login-action from 4.0.0 to 4.1.0
2026-04-07 09:26:54 +03:00
Lauri Ojansivu fdf00e06f5 Merge pull request #6249 from wekan/dependabot/github_actions/actions/cache-5
Bump actions/cache from 4 to 5
2026-04-07 09:26:38 +03:00
Lauri Ojansivu 950b246da8 Merge pull request #6248 from wekan/dependabot/github_actions/actions/upload-artifact-7
Bump actions/upload-artifact from 4 to 7
2026-04-07 09:26:25 +03:00
Lauri Ojansivu 6ac0df8448 Merge pull request #6247 from wekan/dependabot/github_actions/actions/download-artifact-8
Bump actions/download-artifact from 4 to 8
2026-04-07 09:25:51 +03:00
dependabot[bot] 80ae3a18a8 Bump docker/login-action from 4.0.0 to 4.1.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/b45d80f862d83dbcd57f89517bcf500b2ab88fb2...4907a6ddec9925e35a0a9e82d7399ccc52663121)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 20:33:05 +00:00
dependabot[bot] 972bfb9677 Bump actions/cache from 4 to 5
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 20:33:01 +00:00
dependabot[bot] b1149e4d6e Bump actions/upload-artifact from 4 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 20:32:55 +00:00
dependabot[bot] 3cd2ba847b Bump actions/download-artifact from 4 to 8
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 20:32:49 +00:00
Lauri Ojansivu 8bf869654c Updated ChangeLog. 2026-04-06 05:09:38 +03:00
Lauri Ojansivu 3b98f862bc Fix Admin Panel / Version not showing name of MongoDB storage engine and status of MongoDB Oplog enabled.
Thanks to xet7 !
2026-04-06 05:05:19 +03:00
Lauri Ojansivu 9bc889e274 v8.71 2026-04-06 03:40:47 +03:00
Lauri Ojansivu 5df924f416 Fix: Added missing null check to notification.
Thanks to xet7 !
2026-04-06 03:35:28 +03:00
Lauri Ojansivu 5ef94b7079 v8.70 2026-04-06 02:43:39 +03:00
Lauri Ojansivu dfcaaf0ae7 Convert upsert calls to async in authentication.js .
Thanks to snowsky and xet7 !

Fixes https://github.com/wekan/wekan/pull/6243,
fixes https://github.com/wekan/wekan/pull/6245
2026-04-06 02:36:45 +03:00
Lauri Ojansivu 34e7ff532f v8.69 2026-04-06 01:32:30 +03:00
Lauri Ojansivu fbdfcead50 Try to fix Snap to start MongoDB OpLog correctly.
Thanks to xet7.
2026-04-06 01:28:46 +03:00
Lauri Ojansivu b8bbe4431b v8.68 2026-04-06 00:26:18 +03:00
Lauri Ojansivu 9e31666280 Try to fix Snap to start MongoDB OpLog correctly.
Thanks to xet7 !
2026-04-06 00:21:39 +03:00
Lauri Ojansivu 5846d9c9b0 v8.67 2026-04-05 23:22:53 +03:00
Lauri Ojansivu 7707a5b7fc Try to fix GitHub Actions release bundle builds.
Thanks to xet7.
2026-04-05 23:20:35 +03:00
Lauri Ojansivu 18c495940e v8.65 2026-04-05 23:11:32 +03:00
Lauri Ojansivu d3155d24c6 Try to fix GitHub Actions release bundle builds.
Thanks to xet7.
2026-04-05 23:09:36 +03:00
Lauri Ojansivu c0661506c4 Fix Docker Actions Test suite.
Thanks to xet7 !
2026-04-05 22:56:29 +03:00
Lauri Ojansivu fa2b34764f v8.64 2026-04-05 22:51:36 +03:00
Lauri Ojansivu 7a7909b49f Try to fix GitHub Actions release bundle builds.
Thanks to xet7 !
2026-04-05 22:49:33 +03:00
Lauri Ojansivu 17d3b3088f v8.63 2026-04-05 22:38:05 +03:00
Lauri Ojansivu 6a78a178e2 Try to fix GitHub Actions release bundle builds.
Thanks to xet7 !
2026-04-05 22:35:50 +03:00
Lauri Ojansivu 749de39e2a v8.62 2026-04-05 22:20:33 +03:00
Lauri Ojansivu cd55c0e12e Try to fix GitHub Actions bundle builds.
Thanks to xet7 !
2026-04-05 22:17:12 +03:00
Lauri Ojansivu d04037739e v8.61 2026-04-05 21:58:49 +03:00
Lauri Ojansivu f3a97b9938 Delete all GitHub Actions Caches, so that old stuff does not break builds.
Thanks to xet7 !
2026-04-05 21:55:09 +03:00
Lauri Ojansivu 104fbef37a Reverted disabling GitHub workflows. Still trying to fix them.
Thanks to xet7 !
2026-04-05 21:28:19 +03:00
Lauri Ojansivu 98b3dc71af Updated ChangeLog. 2026-04-05 21:15:52 +03:00
Lauri Ojansivu 7b28e4d589 Merge pull request #6246 from KhaoulaMaleh/fix/comment
Fix: Server crash during comment deletion
2026-04-05 21:14:09 +03:00
KhaoulaMaleh 57291dbe50 fixing deletion comment 2026-04-05 17:51:29 -11:00
Lauri Ojansivu 9f9eefce27 Updated ChangeLog. 2026-04-05 21:13:50 +03:00
Lauri Ojansivu af3361b35b Disabled not working GitHub workflows.
Thanks to xet7 !
2026-04-05 21:12:08 +03:00
Lauri Ojansivu 24d65e1e72 Disabled GitHub workflows that produce broken builds.
Thanks to xet7 !
2026-04-05 21:06:49 +03:00
Lauri Ojansivu 29922fca6a Updated ChangeLog. 2026-04-05 18:46:12 +03:00
Lauri Ojansivu 81319fc48b Updated Docker build script to check directories and repos exist.
Thanks to xet7 !
2026-04-05 18:44:07 +03:00
Lauri Ojansivu 28b7209407 v8.60 2026-04-05 18:14:31 +03:00
Lauri Ojansivu 0b59f87887 Updated Docker build script.
Thanks to xet7 !
2026-04-05 18:10:57 +03:00
Lauri Ojansivu b22df9e93d v8.59 2026-04-05 18:09:10 +03:00
Lauri Ojansivu 1fa72fd34a Fix Snap to use OpLog.
Thanks to xet7 !
2026-04-05 18:05:29 +03:00
Lauri Ojansivu a2f38e7494 Updated ChangeLog. 2026-04-05 17:41:52 +03:00
Lauri Ojansivu 30a1792c92 Fix docker-compose.yml to use OpLog.
Thanks to xet7 !
2026-04-05 17:40:01 +03:00
Lauri Ojansivu 3d70f24a78 v8.58 2026-04-05 16:45:54 +03:00
Lauri Ojansivu b3d14fb5e8 Updated build docs.
Thanks to xet7 !
2026-04-05 16:39:25 +03:00
Lauri Ojansivu 59956ca720 Try to fix .zip Bundle, Docker and Snap.
Thanks to xet7 !
2026-04-05 16:34:58 +03:00
Lauri Ojansivu aaf7690b9a v8.57 2026-04-05 15:18:00 +03:00
Lauri Ojansivu 9f549dfcd2 Try to fix Snap.
Thanks to xet7 !
2026-04-05 15:11:40 +03:00
Lauri Ojansivu f191392e3a v8.56 2026-04-05 07:36:06 +03:00
Lauri Ojansivu 56f26418ea Try to fix Snap.
Thanks to xet7 !
2026-04-05 07:33:22 +03:00
Lauri Ojansivu 118e0e5d5c v8.55 2026-04-05 06:58:46 +03:00
Lauri Ojansivu 264dcca42b Updated ChangeLog. 2026-04-05 06:48:47 +03:00
Lauri Ojansivu 73d69f4631 Updated dependencies.
Thanks to developers of dependencies !
2026-04-05 06:47:10 +03:00
Lauri Ojansivu 485b773338 Updated ChangeLog. 2026-04-05 06:39:23 +03:00
Lauri Ojansivu 8443e3511d Try to fix Snap.
Thanks to xet7 !
2026-04-05 06:38:16 +03:00
Lauri Ojansivu b2a349aec5 Updated ChangeLog. 2026-04-05 06:18:30 +03:00
Lauri Ojansivu faf8453c6d Fix Search All Boards.
Thanks to YosserDerbali and xet7 !

Fixes #6229,
fixes #6225
2026-04-05 06:13:53 +03:00
Lauri Ojansivu 7484c8cce3 Updated ChangeLog. 2026-04-05 01:34:55 +03:00
Lauri Ojansivu 2b02e7712e Fix Cards Reports is not working.
Thanks to titver968 and xet7 !

Fixes #6209
2026-04-05 01:32:04 +03:00
Lauri Ojansivu 8a3a7b19aa Updated ChangeLog. 2026-04-04 23:03:59 +03:00
Lauri Ojansivu 9fa6574c80 Docs: IMPORTANT: Do NOT npm audit fix --force, it breaks builds.
Thanks to xet7 !

Fixes #6224
2026-04-04 23:00:29 +03:00
Lauri Ojansivu 2bad17010c Docs: IMPORTANT: Do NOT npm audit fix --force, it breaks builds. 2026-04-04 22:59:16 +03:00
Lauri Ojansivu 4168385607 Updated ChangeLog. 2026-04-04 22:54:48 +03:00
Lauri Ojansivu c0aa1ef375 v8.54 2026-04-04 18:20:00 +03:00
Lauri Ojansivu 811b79b641 Revert v8.53 Refactor upsert calls to use async method.
Thanks to xet7 !
2026-04-04 18:17:26 +03:00
Lauri Ojansivu dab9755dd4 v8.53 2026-04-04 18:07:57 +03:00
Lauri Ojansivu 6863479c09 Updated ChangeLog. 2026-04-04 18:04:57 +03:00
Lauri Ojansivu e05eebb8b0 Merge pull request #6243 from snowsky/main
Refactor upsert calls to use async method
2026-04-04 18:02:03 +03:00
Hao 28ef0e6e89 Refactor upsert calls to use async method 2026-04-04 08:34:32 -05:00
Lauri Ojansivu 09e65ccac2 v8.52 2026-04-03 20:38:13 +03:00
Lauri Ojansivu 03e0cfdc15 Try to fix Docker and Snap.
Thanks to xet7 !
2026-04-03 20:35:54 +03:00
Lauri Ojansivu 7634cd6c2e v8.51 2026-04-03 20:26:08 +03:00
Lauri Ojansivu 4594711be4 Updated release scripts.
Thanks to xet7 !
2026-04-03 20:21:18 +03:00
Lauri Ojansivu c267933bf7 Updated ChangeLog. 2026-04-03 20:20:03 +03:00
Lauri Ojansivu edc6b18b5f Fix Bug: WeKan v8.50 WRITABLE_PATH.
Thanks to snowsky and xet7 !

Fixes #6242
2026-04-03 20:16:32 +03:00
Lauri Ojansivu 60657c6e94 v8.50 2026-04-03 04:40:19 +03:00
Lauri Ojansivu 3c189f9c7f Updated ChangeLog. 2026-04-03 04:32:15 +03:00
Lauri Ojansivu bf02c9a453 Updated dependencies.
Thanks to developers of dependencies.
2026-04-03 04:23:09 +03:00
Lauri Ojansivu e6b6cd3036 Updated ChangeLog. 2026-04-03 03:43:24 +03:00
Lauri Ojansivu 6e8589b1f9 Updated npm package @wekanteam/exceljs.
Thanks to xet7 !
2026-04-03 03:38:22 +03:00
Lauri Ojansivu 1354f84a70 Updated ChangeLog. 2026-04-03 00:31:11 +03:00
Lauri Ojansivu d07cf92f7c Merge pull request #6240 from snowsky/main
Fix indentation for release-all.yml workflow
2026-04-03 00:28:26 +03:00
Hao Wang e079644ed6 Fix indentation for release-all.yml workflow 2026-04-02 17:16:00 -04:00
Lauri Ojansivu 6b393178dc Updated translations. 2026-04-02 23:10:21 +03:00
Lauri Ojansivu 26e1c9ab69 Updated ChangeLog. 2026-04-01 00:57:36 +03:00
Lauri Ojansivu 145a17fee5 Uncommented build steps. Not yet tested are required dependencies included.
Thanks to xet7 !
2026-04-01 00:55:12 +03:00
Lauri Ojansivu ccc9301ed4 v8.49 2026-03-31 19:21:00 +03:00
Lauri Ojansivu f2e46d660f Updated ChangeLog. 2026-03-31 18:55:50 +03:00
Lauri Ojansivu 8b4676175c Try to fix Snap.
Thanks to xet7 !
2026-03-31 18:54:49 +03:00
Lauri Ojansivu e9a547c89b Updated ChangeLog. 2026-03-31 18:47:01 +03:00
Lauri Ojansivu d07fcceb6a Fix docker-compose.yml.
Thanks to xet7 !
2026-03-31 18:45:54 +03:00
Lauri Ojansivu 6b5002f314 Updated ChangeLog. 2026-03-31 18:21:50 +03:00
Lauri Ojansivu 5418ffd558 Merge pull request #6237 from kovacs-andras/main
fix: missing module '@meteorjs/reify/lib/runtime'
2026-03-31 18:17:38 +03:00
Andras Kovacs ea98afeb68 fix: missing module '@meteorjs/reify/lib/runtime' 2026-03-31 15:09:17 +02:00
Lauri Ojansivu be7d7e26fb v8.48 2026-03-31 05:56:09 +03:00
Lauri Ojansivu 56377aaf4c Updated release scripts. 2026-03-31 05:51:38 +03:00
Lauri Ojansivu 43601c5e3e Updated release scripts. 2026-03-31 05:31:29 +03:00
Lauri Ojansivu 1db7f3a57d v8.47 2026-03-31 05:04:33 +03:00
Lauri Ojansivu e58e99c285 Updated attachments and avatar path to be at WRITABLE_PATH/files/attachments etc.
Thanks to xet7 !
2026-03-31 05:00:17 +03:00
Lauri Ojansivu b38e25c9f1 v8.46 2026-03-31 04:32:57 +03:00
Lauri Ojansivu ce52b8a0ab Updated release scripts. 2026-03-31 04:29:23 +03:00
Lauri Ojansivu f7800846a5 Updated ChangeLog. 2026-03-31 04:00:52 +03:00
Lauri Ojansivu 02b75824e5 Updated docker-compose.yml to change from FerretDB/PostgreSQL to MongoDB.
Thanks to xet7 !
2026-03-31 03:59:07 +03:00
Lauri Ojansivu cf52c2f6e4 Updated ChangeLog. 2026-03-31 03:44:02 +03:00
Lauri Ojansivu 6bc68ba57b Updated release scripts.
Thanks to xet7 !
2026-03-31 03:42:19 +03:00
Lauri Ojansivu 5ec9cfa537 v8.45 2026-03-31 03:23:36 +03:00
Lauri Ojansivu 3457cab0b1 Updated ChangeLog. 2026-03-31 03:20:21 +03:00
Lauri Ojansivu 8349fb6b63 Updated release scripts. Added missing dependencies.
Thanks to xet7 !
2026-03-31 02:56:06 +03:00
Lauri Ojansivu 33267fa2e4 Try to fix Snap 2026-03-31 01:54:28 +03:00
Lauri Ojansivu 5c4130311a Try to fix Snap 2026-03-31 01:45:46 +03:00
Lauri Ojansivu ed718f083a Try to fix Snap 2026-03-31 01:40:40 +03:00
Lauri Ojansivu 2aa8ecfc39 Try to fix Snap 2026-03-31 01:35:24 +03:00
Lauri Ojansivu cdf1d3305b Try to fix Snap 2026-03-31 01:30:47 +03:00
Lauri Ojansivu fd58bb9e4d Try to fix Snap 2026-03-31 01:25:11 +03:00
Lauri Ojansivu 55ec0b5ff5 Try to fix Snap.
Thanks to xet7 !
2026-03-31 01:17:58 +03:00
Lauri Ojansivu e5c551f009 Docker registry Quay.io is currently read only, it's not possible to push newest WeKan Docker image to Quay.io
Thanks to xet7 !
2026-03-31 01:08:09 +03:00
Lauri Ojansivu 7666c6c0e1 Merge pull request #6235 from wekan/dependabot/github_actions/docker/login-action-4
Bump docker/login-action from 3 to 4
2026-03-31 00:58:41 +03:00
Lauri Ojansivu e6ccbfd3b8 Merge pull request #6234 from wekan/dependabot/github_actions/docker/setup-qemu-action-4
Bump docker/setup-qemu-action from 3 to 4
2026-03-31 00:58:23 +03:00
Lauri Ojansivu d8a2e06a95 Merge pull request #6233 from wekan/dependabot/github_actions/docker/build-push-action-7
Bump docker/build-push-action from 6 to 7
2026-03-31 00:58:06 +03:00
Lauri Ojansivu c38fa1c272 Merge pull request #6232 from wekan/dependabot/github_actions/actions/checkout-6
Bump actions/checkout from 4 to 6
2026-03-31 00:57:48 +03:00
Lauri Ojansivu 1a5e23617d Merge pull request #6231 from wekan/dependabot/github_actions/actions/setup-node-6
Bump actions/setup-node from 4 to 6
2026-03-31 00:57:22 +03:00
Lauri Ojansivu 87916c20bf Try to fix Snap. Part 2.
Thanks to xet7 !
2026-03-31 00:49:33 +03:00
Lauri Ojansivu 12c223d226 Try to fix Snap.
Thanks to xet7 !
2026-03-31 00:37:53 +03:00
dependabot[bot] 9ae2842fa4 Bump docker/login-action from 3 to 4
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 21:33:06 +00:00
dependabot[bot] 79853a2fb7 Bump docker/setup-qemu-action from 3 to 4
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 21:33:02 +00:00
dependabot[bot] ec1e383558 Bump docker/build-push-action from 6 to 7
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 21:32:59 +00:00
dependabot[bot] df067f01e8 Bump actions/checkout from 4 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 21:32:55 +00:00
dependabot[bot] 4b8cc0683e Bump actions/setup-node from 4 to 6
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 21:32:47 +00:00
Lauri Ojansivu f43b76c323 Updated release scripts.
Thanks to xet7 !
2026-03-31 00:07:19 +03:00
Lauri Ojansivu e90b2e384c Add release-all workflow for multi-platform builds
Add a GitHub Actions workflow for releasing all platforms, including version extraction, building bundles for multiple architectures, and creating a GitHub release.
2026-03-30 23:54:05 +03:00
Lauri Ojansivu 6125822cf7 Updated release scripts. 2026-03-30 23:53:23 +03:00
Lauri Ojansivu 4223c2a79f Updated release scripts.
Thanks to xet7 !
2026-03-30 23:39:29 +03:00
Lauri Ojansivu 7059cc244a v8.44 2026-03-30 22:36:22 +03:00
Lauri Ojansivu 5fc608e310 Updated ChangeLog. 2026-03-30 21:43:33 +03:00
Lauri Ojansivu 29550cbd93 Updated release scripts. Part 2.
Thanks to xet7 !
2026-03-30 21:42:24 +03:00
Lauri Ojansivu 35674a205b Updated ChangeLog. 2026-03-30 20:57:13 +03:00
Lauri Ojansivu a702596bee Updated release scripts.
Thanks to xet7 !
2026-03-30 20:53:20 +03:00
Lauri Ojansivu 02fef72e7e Updated ChangeLog. 2026-03-30 20:38:18 +03:00
Lauri Ojansivu d5c9e402ce Fix myCards crash.
Thanks to cristomoya !

Fixes #6202
2026-03-30 20:35:17 +03:00
Lauri Ojansivu b788d398b9 Fix globalSearch.
Thanks to snowsky !

Fixes #6230
2026-03-30 20:29:40 +03:00
Lauri Ojansivu 5c3b73e3b0 Updated ChangeLog. 2026-03-30 19:32:26 +03:00
Lauri Ojansivu 82f1de078f Updated dependencies.
Thanks to developers of dependencies !
2026-03-30 19:30:26 +03:00
Lauri Ojansivu ddc353023c Updated ChangeLog. 2026-03-30 18:54:44 +03:00
Lauri Ojansivu ef75b9ecac Always show all data, like Shared Lists that were before Per-Swimlanes lists, Orphaned Swimlanes/Lists/Cards etc.
Thanks to xet7 !
2026-03-30 18:46:27 +03:00
Lauri Ojansivu cf2b3e4fc9 From FerretDB/PostgreSQL back to MongoDB 7.x.
Thanks to xet7 !
2026-03-30 18:21:05 +03:00
Lauri Ojansivu cf21991a3f Updated translations. 2026-03-30 18:00:08 +03:00
Lauri Ojansivu 9e4f72e2a4 Updated Node.js at Windows docs 2026-03-28 01:04:30 +02:00
Lauri Ojansivu f7da243c9e Updated release scripts. Part 5.
Thanks to xet7 !
2026-03-28 00:49:32 +02:00
Lauri Ojansivu a71efd2668 v8.43 2026-03-28 00:37:33 +02:00
Lauri Ojansivu 6a23290584 Updated ChangeLog. 2026-03-27 23:25:02 +02:00
Lauri Ojansivu 0e59033ea6 Updated release scripts. Part 4.
Thanks to xet7 !
2026-03-27 23:24:02 +02:00
Lauri Ojansivu 186f7a6b82 Updated ChangeLog. 2026-03-27 23:21:41 +02:00
Lauri Ojansivu 5cf3bba68f Updated release scripts. Part 3.
Thanks to xet7 !
2026-03-27 23:19:55 +02:00
Lauri Ojansivu 4647ddc2b7 Updated ChangeLog. 2026-03-27 23:10:51 +02:00
Lauri Ojansivu 1ac708b0d9 Updated ChangeLog. 2026-03-27 22:49:43 +02:00
Lauri Ojansivu 07eb062474 Updated release scripts. Part 2.
Thanks to xet7 !
2026-03-27 22:45:52 +02:00
Lauri Ojansivu f660817627 Updated ChangeLog. 2026-03-27 20:55:15 +02:00
Lauri Ojansivu 0fdf45e847 Updated release scripts.
Thanks to xet7 !
2026-03-27 20:48:39 +02:00
Lauri Ojansivu 0c3cebd30a Merge pull request #6223 from YosserDerbali/fix/list-actions-popup-overflow-scroll
Fix/list actions popup overflow scroll
2026-03-27 20:47:09 +02:00
Yosser Derbali c589918989 Merge upstream/main and resolve popup.css conflict
- Keep upstream's cardDetailsActionsPopup styling
- Combine date picker container styling from both versions
- Ensure both list actions and card details popups work correctly
2026-03-27 19:42:25 +01:00
Yosser Derbali 256aa0a053 fix(popup): keep list actions popup inside viewport and scrollable 2026-03-27 19:17:00 +01:00
Lauri Ojansivu 67c56e41b0 Merge pull request #6222 from KhaoulaMaleh/fix/global-search
fix search: guard async methods in ReactiveCache and search publications
2026-03-27 20:16:52 +02:00
KhaoulaMaleh ade9e0f589 fix search: guard async methods in ReactiveCache and search publications 2026-03-27 18:36:32 -11:00
Lauri Ojansivu e14dfb9e7e Merge pull request #6220 from aminsaidane/fix/card-actions-popup-overflow
Fix card actions popup overflow
2026-03-27 20:15:36 +02:00
Lauri Ojansivu c26cc313fc Updated ChangeLog. 2026-03-27 19:22:45 +02:00
Lauri Ojansivu 55660e0e69 Updated dependencies. Part 2.
Thanks to developers of dependencies !
2026-03-27 19:20:27 +02:00
Lauri Ojansivu 3701544f6a Updated ChangeLog. 2026-03-27 19:04:28 +02:00
Lauri Ojansivu acfb081b90 Updated dependencies.
Thanks to developers of dependencies !
2026-03-27 19:02:42 +02:00
Lauri Ojansivu a30d7cabe3 Updated ChangeLog. 2026-03-27 18:59:12 +02:00
Lauri Ojansivu 517d148387 Moved Meteor 3 migration docs to docs/Upgrade/
Thanks to xet7 !
2026-03-27 18:56:43 +02:00
aminsaidane f8aec4de73 Fix card actions popup overflow
- Added max-height constraint to card details actions popup
- Ensured popup fits within viewport on all screen sizes
- Implemented scrollable content when menu exceeds viewport
- Used min(380px, 85vw) for responsive width sizing
- Prevents menu items from being cut off or hidden

Resolves card pop-up menu content overflow issue
2026-03-27 17:47:00 +01:00
Lauri Ojansivu e1b6cf6124 Updated translations 2026-03-27 18:37:27 +02:00
Lauri Ojansivu 1eac00e7fa Updated ChangeLog. 2026-03-27 18:18:24 +02:00
Lauri Ojansivu 278ed23440 Updated ChangeLog. 2026-03-27 18:15:31 +02:00
Lauri Ojansivu b42689a54d Fix attachment rename fails for clipboard uploads and keep extension metadata in sync.
Thanks to snowsky, YosserDerbali and xet7 !

Fixes #6203,
related https://github.com/wekan/wekan/pull/6217
2026-03-27 18:14:10 +02:00
Lauri Ojansivu 10bfa30458 Merge pull request #6218 from aminsaidane/fix/workspace-settings-modal-overflow
Fix workspace settings modal overflow
2026-03-27 18:09:37 +02:00
aminsaidane a0a1cda0a7 Fix workspace settings modal overflow
- Added top padding to popup content to prevent crowding
- Added max-height constraints for workspace actions popup
- Ensured modal fits within viewport on all screen sizes
- Implemented scrollable content when exceeding viewport
- Fixes issue with partially hidden controls in Workspace Settings modal

Closes #6200
2026-03-27 16:27:14 +01:00
Lauri Ojansivu 001af3fabd Updated translations. 2026-03-26 16:52:06 +02:00
Lauri Ojansivu c0316e9446 Merge pull request #6215 from KhaoulaMaleh/fix/csv-export
Fix: Clarify CSV export separator labels for i18n
2026-03-26 15:53:33 +02:00
KhaoulaMaleh d80a6e7e38 Fix: Clarify CSV export separator labels for i18n 2026-03-26 04:20:21 -11:00
Lauri Ojansivu 8d8d8f9cee Updated ChangeLog. 2026-03-26 01:45:40 +02:00
Lauri Ojansivu 0630d62ad0 Fix Set Color of Swimlane, List and Card.
Thanks to SVANNER, brlin-tw and xet7 !

Fixes #6207,
fixes #6212,
fixes #5660
2026-03-26 01:36:06 +02:00
Lauri Ojansivu c07b282dc9 Updated translations 2026-03-25 23:54:41 +02:00
Lauri Ojansivu 5aa39463b0 Updated ChangeLog. 2026-03-25 23:45:08 +02:00
Lauri Ojansivu f1e71247c7 Updated rebuild-wekan.sh for macOS 26.4.
Thanks to xet7 !
2026-03-25 23:40:47 +02:00
Lauri Ojansivu 419fb2535b Updated ChangeLog. 2026-03-25 21:57:25 +02:00
Lauri Ojansivu 23697d2a33 Fixed typo.
Thanks to YosserDerbali and xet7 !

Related https://github.com/wekan/wekan/pull/6210
2026-03-25 21:54:52 +02:00
Lauri Ojansivu 55edc7ef63 Updated ChangeLog. 2026-03-25 02:28:16 +02:00
Lauri Ojansivu c1e3ce64a7 Removed temporary debug logs.
Thanks to xet7 !
2026-03-25 02:26:52 +02:00
Lauri Ojansivu d34163402c Updated ChangeLog. 2026-03-25 01:40:03 +02:00
Lauri Ojansivu 5c5ed102ca Export Card to Excel. Part 3. Also, fixed uploading attachments.
Thanks to xet7 !

Fixes #5324
2026-03-25 01:37:42 +02:00
Lauri Ojansivu 0bbadfe9a6 Updated ChangeLog. 2026-03-24 21:53:49 +02:00
Lauri Ojansivu 21ab640686 Updated @meteorjs/rspack.
Thanks to Meteor developers!
2026-03-24 21:52:20 +02:00
Lauri Ojansivu a3f6d200ac Updated ChangeLog. 2026-03-24 21:41:58 +02:00
Lauri Ojansivu 701c10d618 Updated @meteorjs/rspack.
Thanks to Meteor developers!
2026-03-24 21:40:00 +02:00
Lauri Ojansivu 7f8de1f988 Updated ChangeLog. 2026-03-24 21:28:01 +02:00
Lauri Ojansivu 95ff8ef1f2 Updated dependencies of npm package @wekanteam/exceljs.
Thanks to xet7 !
2026-03-24 21:26:14 +02:00
Lauri Ojansivu 4eb885f88a Updated translations 2026-03-24 20:59:27 +02:00
Lauri Ojansivu 9a7a0b7271 Updated ChangeLog. 2026-03-24 20:57:26 +02:00
Lauri Ojansivu 4a8293f881 Fixed rebuild-wekan.sh to build WeKan correctly.
Thanks to xet7 !
2026-03-24 20:55:54 +02:00
Lauri Ojansivu 56ed341510 Updated ChangeLog. 2026-03-24 20:44:53 +02:00
Lauri Ojansivu 7584afda6d Upgraded to Meteor 3.4, Node.js 22.22, MongoDB 7.x, here related fixes.
Thanks to harryadel and xet7 !
2026-03-24 20:39:21 +02:00
Harry Adel bbb8f8e51d Merge branch 'main' into meteor-3-migration
# Conflicts:
#	.meteor/packages
#	.meteor/versions
#	models/attachments.js
#	models/boards.js
#	models/server/ExporterExcelCard.js
#	package-lock.json
2026-03-24 02:22:57 +02:00
Harry Adel ddd873c7a0 Fix client runtime regressions after Meteor 3 migration 2026-03-24 01:51:20 +02:00
Harry Adel 63ce45c538 Split shared models from Meteor 3 server runtime 2026-03-24 01:50:39 +02:00
Harry Adel 8ffc0cb5ff Centralize client boot and rspack package loading 2026-03-24 01:50:25 +02:00
Lauri Ojansivu ce95907778 v8.42 2026-03-23 20:07:35 +02:00
Lauri Ojansivu 4ed3250352 Updated ChangeLog. 2026-03-23 20:04:28 +02:00
Lauri Ojansivu 2dce7a84cd Fix SSO login is broken.
Thanks to sbaecker, vladimirdulov and xet7 !

Fixes #6204
2026-03-23 20:00:26 +02:00
Lauri Ojansivu b9631659f7 Updated version. 2026-03-23 18:36:04 +02:00
Lauri Ojansivu 405cf3efa3 v8.41 2026-03-23 18:34:52 +02:00
Lauri Ojansivu 462b3801ee Updated translations. 2026-03-23 18:31:51 +02:00
Lauri Ojansivu 7ec42880f0 Updated ChangeLog. 2026-03-23 18:29:17 +02:00
Lauri Ojansivu 3d6797a305 Fixed Board lost its member list or permissions.
Thanks to marylinereumont, AymenHassini19, muabila and xet7 !

Fixes #6198
2026-03-23 18:25:38 +02:00
Lauri Ojansivu 065fe35b6a Updated translations. 2026-03-23 11:39:51 +02:00
Lauri Ojansivu 4a4e4135ab Updated ChangeLog. 2026-03-23 11:28:22 +02:00
Lauri Ojansivu e388d18aad Merge pull request #6199 from KhaoulaMaleh/fix/cards
Fix: prevent cards from disappearing after dragging in List view
2026-03-23 11:25:00 +02:00
KhaoulaMaleh 60d9698343 Fix: prevent cards from disappearing after dragging in List view 2026-03-23 03:44:28 -11:00
Lauri Ojansivu a7c9f7aa17 Updated ChangeLog. 2026-03-22 22:17:51 +02:00
Lauri Ojansivu 7de1b04ebc Export Card to Excel. Part 2.
Thanks to xet7 !

Fixes #5324
2026-03-22 22:15:33 +02:00
Lauri Ojansivu 024ec23b7f Updated ChangeLog. 2026-03-22 19:47:08 +02:00
Lauri Ojansivu 7b2128b356 Fixed 2nd new card should not have text of 1st card, it should be empty.
Thanks to xet7 !
2026-03-22 19:41:44 +02:00
Lauri Ojansivu 6d54b826e8 Merge pull request #6197 from harryadel/use-email-sendAsync
Replace Email.send with Email.sendAsync
2026-03-22 19:12:47 +02:00
Lauri Ojansivu 30c4010512 Merge pull request #6196 from harryadel/remove-meteorhacks-aggregate
Remove unused meteorhacks:aggregate for Meteor 3.0 migration
2026-03-22 19:11:40 +02:00
Lauri Ojansivu c4c8446fc2 Merge pull request #6195 from harryadel/migrate-communitypackages
Replace useraccounts packages with communitypackages alternatives
2026-03-22 19:10:55 +02:00
Lauri Ojansivu c374c87c08 Updated translations 2026-03-22 19:09:21 +02:00
Harry Adel 8486bb1e87 Fix load order: two-stage entry points with require() bootstrap
ES module import statements are hoisted and evaluated in dependency-graph
order, not textual order. This means `import '/imports/collectionHelpers'`
being first in the file does NOT guarantee it runs first.

Fix: Split entry points into two stages:
- main.js: uses require() only (sequential, not hoisted)
  1. require('/imports/collectionHelpers') — loads collection2, SimpleSchema
  2. require('./imports') — loads all app code
- imports.js: contains all the import statements (safe because
  collectionHelpers has already fully loaded via require())

This pattern guarantees attachSchema/SimpleSchema/helpers are available
before ANY model file evaluates, regardless of circular dependency chains.
2026-03-22 19:03:11 +02:00
Harry Adel 655f44919a Fix attachSchema: convert collectionHelpers to pure require()
The root cause: import statements are hoisted and trigger evaluation
chains that reach model files (via reactiveCache circular deps)
BEFORE collection2 has patched Mongo.Collection.prototype.attachSchema.

Fix: Convert collectionHelpers.js to use ONLY require() calls.
require() is NOT hoisted — each call completes synchronously before
the next, guaranteeing collection2 fully loads before any model
file can run.
2026-03-22 18:59:09 +02:00
Harry Adel 17ea7978f0 Fix attachSchema: require collection2 directly in settings.js
settings.js is loaded early via circular dependency chain before
the entry point's hoisted imports finish. Add explicit require()
for aldeed:collection2 to ensure attachSchema is available.
2026-03-22 18:56:37 +02:00
Harry Adel b518946c41 Centralize collection2/SimpleSchema setup in collectionHelpers shim
Move all collection infrastructure into imports/collectionHelpers.js:
- Import aldeed:collection2 (provides attachSchema on Mongo.Collection)
- Import and set SimpleSchema as global
- Register denyUpdate/denyInsert as allowed schema extensions
- Provide Collection.helpers() shim

This ensures collection2 is loaded before any model file uses
attachSchema, regardless of circular dependency import ordering.
2026-03-22 18:54:01 +02:00
Harry Adel ca8a4af354 Fix SimpleSchema v2: add missing parent object declarations
SimpleSchema v2.0 requires explicit parent object declarations for
dot-notation sub-keys:
- settings.js: Add mailServer as Object parent for mailServer.* sub-keys
- watchable.js: Add watchers as [Object] parent for watchers.$.* sub-keys
2026-03-22 18:51:30 +02:00
Harry Adel 1682f8834d Fix denyUpdate/denyInsert: register as allowed SimpleSchema extensions
aldeed:simple-schema v2.0 no longer includes denyUpdate/denyInsert as
built-in properties. Register them via SimpleSchema.extendOptions() in:
- settings.js (first model loaded via circular dep chain)
- client/main.js and server/main.js (for all other models)
2026-03-22 18:42:53 +02:00
Harry Adel eac472c54b Fix SimpleSchema: use default import (not named export)
aldeed:simple-schema v2.0 uses `export default SimpleSchema`, not
a named export. Fix all import/require sites:
- settings.js: require().default
- attachmentStorageSettings.js: import default
- client/main.js, server/main.js: import default for global
2026-03-22 18:41:31 +02:00
Harry Adel 3a873559f8 Fix settings.js: use require() for ALL deps to prevent import hoisting
ES module import statements are hoisted above all code, so placing
Settings = new Mongo.Collection() between imports has no effect.
Convert ALL imports to require() so the collection definition
truly executes first, breaking the circular dependency.
2026-03-22 18:36:32 +02:00
Harry Adel aec6779601 Fix SimpleSchema not defined: import explicitly + set global
- settings.js: Import SimpleSchema explicitly from aldeed:simple-schema
  before attachSchema call (breaks circular dep ordering)
- client/main.js, server/main.js: Set SimpleSchema as global for the
  29 other model files that use it without importing
2026-03-22 18:30:38 +02:00
Harry Adel 973d9eccae Fix runtime errors: circular dependency in settings.js, fibers in users.js
- settings.js: Break circular import (settings → ReactiveCache → i18n →
  translation → ReactiveCache → settings) by defining Settings collection
  before require() calls instead of after import statements
- users.js: Make Users.after.insert hook async for template container
  creation (already committed fibers/future removal)
- fileStoreStrategy.js: Remove duplicate sanitizeFilename (already committed)
- wekanCreator.js: Fix forEach→for...of for await (already committed)
2026-03-22 18:27:41 +02:00
Harry Adel 7468b30001 Fix build errors: fibers/future, duplicate sanitizeFilename, forEach await
- users.js: Replace fibers/future pattern with async/await using
  insertAsync/updateAsync for template container creation
- fileStoreStrategy.js: Remove duplicate sanitizeFilename declaration
- wekanCreator.js: Convert attachments.forEach to for...of loop
  so await works inside the iteration body
2026-03-22 18:24:07 +02:00
Harry Adel e68cb5f32f Meteor 3.4 migration: Flip release to METEOR@3.4
Update .meteor/release from METEOR@2.16 to METEOR@3.4.
This activates Node 22, Express 5, async collection APIs,
MongoDB driver 6.x, and the Rspack bundler integration.
2026-03-22 17:58:34 +02:00
Harry Adel a157ae5d1c Meteor 3.4 migration: Module restructuring + Rspack setup
Create explicit entry points required by Meteor 3.4's Rspack bundler:

- client/main.js: imports all client code (models, components, jade
  templates, libraries, config, startup)
- server/main.js: imports all server code (models, methods, publications,
  routes, migrations, notifications, cron, auth)
- rspack.config.js: configures meteor-jade-loader for .jade files
- package.json: adds meteor.mainModule pointing to entry files
- .gitignore: adds Rspack build artifact directories
2026-03-22 17:58:04 +02:00
Harry Adel 620e5ce9dc Meteor 3.4 migration: Convert remaining sync methods to async
Convert all remaining Meteor.methods with sync collection calls:
- users.js: deleteWorkspace → async with findOneAsync/updateAsync
- userPositionHistory.js: 3 methods → async with insertAsync/fetchAsync
- attachmentStorageSettings.js: 4 methods → findOneAsync/insertAsync/upsertAsync
- org.js, team.js, translation.js: insert → insertAsync
- boards.js: acceptInvite + collection hooks → updateAsync
- settings.js: sendInvitation → updateAsync/insertAsync
- import.js: importBoard/cloneBoard → async with await creator.create()
- attachments.js: onAfterUpload → async with findOneAsync/updateAsync
2026-03-22 17:50:31 +02:00
Harry Adel 2e3fbf25db Meteor 3.4 migration: Convert allow/deny callbacks to async
Meteor 3.x supports async allow/deny callbacks. Convert all 25 sync
allow/deny callbacks across 23 model files to use async/await with
findOneAsync/fetchAsync instead of sync findOne/find().fetch().

Also converts helper functions in server/lib/utils.js:
- allowIsBoardMemberWithWriteAccessByCard -> async
- allowIsBoardMemberByCard -> async
- canUpdateCard (cards.js) -> async
- permissionHelper.allow (integrations.js) -> async
2026-03-22 17:44:29 +02:00
Harry Adel e8fee653c3 Meteor 3.4 migration: Phases 0-3
Phase 0 - Pre-migration cleanup:
- Remove msavin:usercache (unused), es5-shim, http@2.0.0, fibers
- Replace Meteor.wrapAsync in counters.js, exporter.js, attachmentUrlValidation.js
- Replace meteorhacks:subs-manager with Meteor.subscribe in 6 client files

Phase 1 - Create meteor-jade-loader:
- Custom Rspack/webpack loader for .jade templates
- Extracts mquandalle:jade-compiler pipeline (lexer, parser, transpiler)
- Bundles Meteor vendor packages (htmljs, html-tools, blaze-tools, spacebars-compiler)

Phase 2 - Package version bumps & replacements:
- Remove mquandalle:jade, dburles:collection-helpers, aldeed:simple-schema
- Remove communitypackages:picker (Meteor 3 bundles Express)
- Replace simple:json-routes -> communitypackages:json-routes
- Replace simple:rest-accounts-password -> communitypackages:rest-accounts-password
- Add collection-helpers shim at imports/collectionHelpers.js
- Convert Picker.route() to WebApp.handlers.get() in export files + sandstorm.js
- Add api.versionsFrom(['2.16', '3.0']) to all 9 custom packages
- Remove version pins from .meteor/packages

Phase 3 - Express 5 migration:
- Rename WebApp.connectHandlers -> WebApp.handlers (20 occurrences)
- Rename WebApp.rawConnectHandlers -> WebApp.rawHandlers (5 occurrences)
- Convert regexp route patterns to Express 5 named params in attachmentApi.js, avatarServer.js
2026-03-22 17:17:48 +02:00
Harry Adel 0d3f3474d1 Merge remote-tracking branch 'fork/use-email-sendAsync' into meteor-3-migration 2026-03-22 15:07:38 +02:00
Harry Adel 6ecb6bdaa7 Merge remote-tracking branch 'fork/remove-meteorhacks-aggregate' into meteor-3-migration 2026-03-22 15:07:33 +02:00
Harry Adel 738655d380 Use Email.sendAsync in SMTP test and update docs
Replace Email.send with await Email.sendAsync in the SMTP test email
method and update the documentation example to match.
2026-03-22 03:21:11 +02:00
Harry Adel 3f0eb227ec Await email calls in notifications and rules
Add missing await to EmailLocalization.sendEmail() calls and replace
fallback Email.send with Email.sendAsync in the notification email
handler and rules helper. The notification handler runs inside an
async setTimeout callback where the missing await meant email errors
were unhandled promise rejections instead of being caught.
2026-03-22 03:20:51 +02:00
Harry Adel 409a624e33 Await email calls in invitation code
Add missing await to EmailLocalization.sendEmail() calls and replace
fallback Email.send with Email.sendAsync in board invitation and
registration invitation flows. Without await, promise rejections from
failed email sends were silently swallowed instead of being caught
by the surrounding try/catch blocks.
2026-03-22 03:20:26 +02:00
Harry Adel 1b02184482 Use Email.sendAsync in email localization wrapper
Email.sendAsync is available since Meteor 2.16 (email@2.2.5).
The synchronous Email.send is just a wrapper around it via
Promise.await. Switch to the async version directly since
sendEmail() is already an async function.
2026-03-22 03:19:54 +02:00
Harry AdelandClaude Opus 4.6 f88e6671a2 Remove unused meteorhacks:aggregate package for Meteor 3.0 migration
The only aggregation usage (metrics.js) already calls rawCollection().aggregate()
directly — the native MongoDB driver method — not the monkey-patched method from
this package. Convert to async/await (replacing Promise.await) for Meteor 3.0
Fibers removal compatibility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 03:02:09 +02:00
Harry Adel 073c297490 Remove unused meteorhacks:aggregate package for Meteor 3.0 migration
The only aggregation usage (metrics.js) already calls rawCollection().aggregate()
directly — the native MongoDB driver method — not the monkey-patched method from
this package. Convert to async/await (replacing Promise.await) for Meteor 3.0
Fibers removal compatibility.
2026-03-22 03:02:09 +02:00
Harry Adel e92578d41d Remove dead useraccounts-core reference from stacksmith build
The sed command targeting packages/meteor-useraccounts-core/package.js
referenced a local package directory that no longer exists.
2026-03-22 02:43:16 +02:00
Harry Adel 0644aeb70e Replace useraccounts packages with communitypackages alternatives
Migrate from the unmaintained useraccounts:* packages to the
community-maintained communitypackages:* drop-in replacements:

- useraccounts:core -> communitypackages:core@2.0.3
- useraccounts:unstyled -> communitypackages:unstyled@2.0.1
- useraccounts:flow-routing-extra -> communitypackages:flow-routing@2.1.0

Also clean up .meteor/packages:
- Remove unused coffeescript and spacebars packages
- Unpin ecmascript and standard-minifier-js versions
2026-03-22 02:43:10 +02:00
Lauri Ojansivu 456bda1169 v8.40 2026-03-21 21:28:34 +02:00
Lauri Ojansivu 4b83a3f861 Updated translations 2026-03-21 21:23:49 +02:00
Lauri Ojansivu 7e18526ed1 Updated translations 2026-03-21 21:14:28 +02:00
Lauri Ojansivu ffef908c8d Updated ChangeLog. 2026-03-21 21:02:03 +02:00
Lauri Ojansivu be5bdbe314 Export Card to Excel and related fixes. Part 1.
Thanks to xet7 !

Fixes #5324
2026-03-21 20:57:07 +02:00
Lauri Ojansivu 6d0f869309 v8.39 2026-03-21 15:35:20 +02:00
Lauri Ojansivu bfd0f9d0e4 Updated translations 2026-03-21 15:32:05 +02:00
Lauri Ojansivu ee9b5a0d25 Updated ChangeLog. 2026-03-21 15:25:48 +02:00
Lauri Ojansivu 445746fd7f Updated ChangeLog. 2026-03-21 15:23:28 +02:00
Lauri Ojansivu ac33d8012b Delete workspace. Part 2.
Thanks to xet7 !

Fixes #6157
2026-03-21 15:18:02 +02:00
Lauri Ojansivu 8513b2e456 Delete workspace etc. In Progress.
Thanks to xet7 !

Related #6157
2026-03-21 11:32:56 +02:00
Lauri Ojansivu 26d393f8ee Fix open lock from all button position at Admin Panel/People/People.
Thanks to xet7 !
2026-03-21 10:33:06 +02:00
Lauri Ojansivu bee322cb2e v8.38 2026-03-21 02:28:01 +02:00
Lauri Ojansivu bf209bfdd7 Updated ChangeLog. 2026-03-21 00:12:24 +02:00
Lauri Ojansivu 0e410b6d7a Fix List of users is empty, some translations not visible, count of orgs/teams/people, theme of some buttons, New org/team to be leftmost column.
Thanks to xet7 !

Fixes #6194
2026-03-21 00:11:08 +02:00
Lauri Ojansivu 2e4e3b1a06 Updated ChangeLog. 2026-03-20 18:15:56 +02:00
Lauri Ojansivu 7ed26f437d Updated CONTRIBUTING.md 2026-03-20 18:07:33 +02:00
Lauri Ojansivu e50b9f211d Updated CONTRIBUTING.md 2026-03-20 18:05:05 +02:00
Lauri Ojansivu e705df6634 Updated CONTRIBUTING.md 2026-03-20 18:01:38 +02:00
Lauri Ojansivu e669a9fe64 Updated CONTRIBUTING.md 2026-03-20 17:57:41 +02:00
Lauri Ojansivu 6249af041c Updated CONTRIBUTING.md 2026-03-20 17:53:23 +02:00
Lauri Ojansivu a4a4fc1cf2 Merge branch 'main' of github.com:wekan/wekan 2026-03-20 17:51:45 +02:00
Lauri Ojansivu 6acc7c95ff Updated CONTRIBUTING.md and SECURITY.md 2026-03-20 17:50:38 +02:00
Lauri Ojansivu 3d75e905d1 v8.37 2026-03-20 15:03:36 +02:00
Lauri Ojansivu 55bc0ed411 Updated ChangeLog. 2026-03-20 15:00:07 +02:00
Lauri Ojansivu 37142f3bb9 Fix card save does not work.
Thanks to comunidadplayasdetijuana, Janfy and xet7 !

Fixes #6192
2026-03-20 14:56:59 +02:00
Lauri Ojansivu c11aa2a194 Updated translations. 2026-03-20 07:47:40 +02:00
Lauri Ojansivu 9da7adad95 v8.36 2026-03-20 00:40:50 +02:00
Lauri Ojansivu 69277d4b24 Updates 2026-03-20 00:36:05 +02:00
Lauri Ojansivu 2e157501c3 Updated ChangeLog. 2026-03-20 00:12:40 +02:00
Lauri Ojansivu 610849ab0b Add remaining features of Copy and Move of Swimlanes, Lists and Cards.
Thanks to xet7 !
2026-03-20 00:10:13 +02:00
Lauri Ojansivu b966607070 Updated ChangeLog. 2026-03-19 22:51:46 +02:00
Lauri Ojansivu d0c44bded8 Fix Copy Card and Move Card.
Thanks to BlobbyBob and xet7 !

Fixes #6169
2026-03-19 22:49:22 +02:00
Lauri Ojansivu c79f5be07a Updated translations. 2026-03-19 22:48:10 +02:00
Lauri Ojansivu baab46a3fb Updated ChangeLog. 2026-03-19 22:08:18 +02:00
Lauri Ojansivu 92beaa3137 Fix RebindBleed of IntegrationBleed.
Thanks to Rodolphe GHIO and xet7 !
2026-03-19 22:07:07 +02:00
Lauri Ojansivu f03d0ddf30 Updated ChangeLog. 2026-03-19 21:32:35 +02:00
Lauri Ojansivu 4dea702ff2 Fixed adding label and select color causes color not checkmarked and wrong color choosed.
Thanks to xet7 !
2026-03-19 21:29:09 +02:00
Lauri Ojansivu 7e55b83a7b Updated translations. 2026-03-19 21:22:54 +02:00
Lauri Ojansivu 259f3776d2 Updated ChangeLog. 2026-03-19 21:18:41 +02:00
Lauri Ojansivu 2f07eb7097 Fixed add remove checklist and checklist item.
Thanks to xet7 !
2026-03-19 21:17:14 +02:00
Lauri Ojansivu 6d6247d449 Updated ChangeLog. 2026-03-19 20:24:02 +02:00
Lauri Ojansivu c3f66cce55 Updated flatted.
Thanks to developers of flatted !
2026-03-19 20:22:51 +02:00
Lauri Ojansivu 8ee178dd89 Updated ChangeLog. 2026-03-19 20:16:05 +02:00
Lauri Ojansivu d01d7fbcc9 Merge pull request #6191 from harryadel/remove-raix-handlebar-helpers
Remove raix:handlebar-helpers, replace with native Blaze helpers
2026-03-19 20:14:57 +02:00
Harry Adel 252b95f661 Remove raix:handlebar-helpers, replace with native Blaze helpers
Replace the raix:handlebar-helpers package with inline Blaze helper
registrations for operator helpers ($eq, $neq, $gt, $lt, $gte, $lte,
$and, $or, $not, $in, $nin, $). This removes an external dependency
while preserving the same template helper API.

Also removes the unused ui@1.0.13 package pin.
2026-03-19 18:08:02 +02:00
Lauri Ojansivu 89f262feae Updated translations 2026-03-19 17:19:23 +02:00
Lauri Ojansivu 7167f53270 Updated ChangeLog. 2026-03-19 17:16:52 +02:00
Lauri Ojansivu c989c21d4f Fixed view, restore and delete of Archived Cards, Lists and Swimlanes. If delete list, it does not delete card of that list that was archived before archive list.
Thanks to xet7 !
2026-03-19 17:12:44 +02:00
Lauri Ojansivu 5d83d4c239 Updated translations. 2026-03-19 09:52:35 +02:00
Lauri Ojansivu 94089f9505 Updated ChangeLog. 2026-03-19 09:42:59 +02:00
Lauri Ojansivu 872dd578c8 Fixed Add after list to add after selected list. Added Confirm to Archive List and Archive Swimlane.
Thanks to xet7 !
2026-03-19 09:40:47 +02:00
Lauri Ojansivu fba00535fa Updated ChangeLog. 2026-03-19 08:10:15 +02:00
Lauri Ojansivu ccd23f6cde Fixed crash at sign-up page, when registering new user, happened after some PR.
Thanks to xet7 !
2026-03-19 08:07:42 +02:00
Lauri Ojansivu 7a1db4e040 Updated ChangeLog. 2026-03-19 07:56:48 +02:00
Lauri Ojansivu 7d0a422714 Removed not needed input fields from GitHub Bug report issue template.
Thanks to xet7 !
2026-03-19 07:55:01 +02:00
Lauri Ojansivu e411a4fd8e Updated ChangeLog. 2026-03-19 07:49:19 +02:00
Lauri Ojansivu 77b57d8233 Merge pull request #6190 from harryadel/remove-underscore
Replace underscore with native JavaScript utilities
2026-03-19 07:48:09 +02:00
Lauri Ojansivu d14005a183 Updated ChangeLog. 2026-03-19 07:47:44 +02:00
Lauri Ojansivu 0c29fa3cbe Fixed crash when IFTTT Rules archived card, but cards etc are not visible at archive yet. Fixed "Add After List" to show lists only from current Swimlane.
Thanks to xet7 !
2026-03-19 07:44:34 +02:00
Harry Adel 60bc1d55f4 Remove underscore from .meteor/packages
All application code now uses native JavaScript equivalents.
underscore remains as a transitive dependency of
raix:handlebar-helpers in .meteor/versions.
2026-03-18 22:39:34 +02:00
Harry Adel bcadc517c3 Remove underscore dependency from wekan-ldap package
- Remove import _ from 'underscore'
- _.reduce -> .reduce()
- _.map on objects -> Object.entries().forEach() (argument order swap)
- _.isEmpty -> manual null/length check
- _.isObject -> typeof check
- _.find -> .includes()
- _.last -> .at(-1)
- _.size -> Object.keys().length
- _.debounce -> inline debounce function
- Remove api.use('underscore') from package.js
2026-03-18 22:39:29 +02:00
Harry Adel eb4cb341c6 Remove underscore dependency from wekan-oidc package
- _.pick -> Object.fromEntries/Object.entries filter
- _.extend -> Object.assign (including on Error objects)
- _.pluck -> .map()
- Remove api.use('underscore') from package.js
2026-03-18 22:39:20 +02:00
Harry Adel 331bc2d1b9 Replace underscore with native JS in server and shared files
- server/publications: _.findWhere -> findWhere() helper
- server/notifications: _.clone -> spread operator
- server/rulesHelper: _.min/_.max -> Math.min/Math.max
- server/lib/utils: _.some/_.contains -> .some()/.includes()
- imports/reactiveCache: _.groupBy/_.indexBy -> helpers
- config/router: _.each on object -> Object.entries().forEach()
- sandstorm: _.pluck/_.values -> .map()/Object.values()
2026-03-18 22:39:14 +02:00
Harry Adel b5782c7b86 Replace underscore with native JS in models
Largest changes in cards.js (~76 calls), boards.js (~38 calls),
and activities.js (~31 calls). Key patterns:

- _.contains -> .includes() with null guards where needed
- _.findWhere/_.where -> findWhere()/where() helpers
- _.pluck -> .map()
- _.union -> [...new Set()]
- _.extend -> Object.assign()
- _.each on objects -> Object.entries().forEach() (argument order swap)
- _.debounce -> debounce() helper
- _.groupBy/_.indexBy -> groupBy()/indexBy() helpers
- _.clone -> spread operator
- _.sortBy -> [...arr].sort()
- Type checks -> native typeof
2026-03-18 22:39:06 +02:00
Harry Adel 01bb5a930d Replace underscore with native JS in client components
- _.contains -> .includes()
- _.filter -> .filter()
- _.pluck -> .map()
- _.findWhere -> findWhere() helper
- _.union -> [...new Set()]
- _.every/.some -> .every()/.some()
- _.once -> once() helper
- _.uniq with property -> uniqBy() helper
- _.sortBy -> [...arr].sort()
- _.chain().groupBy() -> groupBy() helper
- _.each -> .forEach()
- _.isNumber -> typeof x === 'number'
2026-03-18 22:38:56 +02:00
Harry Adel 1bb657b073 Replace underscore with native JS in client utility files
- _.has -> Object.hasOwn
- _.isString -> typeof x === 'string'
- _.isUndefined -> x === undefined
- _.sortBy -> [...arr].sort()
- _.any -> .some()
- _.range -> Array.from()
- _.times -> for loop
2026-03-18 22:38:44 +02:00
Harry Adel 740f39e17c Add native JS collection helpers to replace underscore utilities
Add findWhere, where, uniqBy, groupBy, indexBy, debounce, and once
helper functions in imports/lib/collectionHelpers.js. These provide
null-safe replacements for underscore methods that have no clean
native one-liner equivalent. Expose them on the Utils global for
client-side usage.
2026-03-18 22:38:37 +02:00
Lauri Ojansivu e34e4b8404 Updated ChangeLog. 2026-03-18 22:07:29 +02:00
Lauri Ojansivu e6fbfa87f0 Fix more Rules buttons styling.
Thanks to xet7 !
2026-03-18 22:06:25 +02:00
Lauri Ojansivu a31de9e1a0 Updated ChangeLog. 2026-03-18 22:02:13 +02:00
Lauri Ojansivu a3ac219503 Changed colors of Add Rule and Back buttons from black to theme color.
Thanks to xet7 !
2026-03-18 22:00:10 +02:00
Lauri Ojansivu 5af4a5395b Updated ChangeLog. 2026-03-18 21:42:29 +02:00
Lauri Ojansivu d2168aca3d Removed empty space at top of list header.
Thanks to xet7 !
2026-03-18 21:41:08 +02:00
Lauri Ojansivu 6148d96b9a Updated ChangeLog. 2026-03-18 21:20:41 +02:00
Lauri Ojansivu b6a6180dc3 Fix can not close opened card.
Thanks to xet7 !
2026-03-18 21:18:58 +02:00
Lauri Ojansivu 6edd3c77ec Updated ChangeLog. 2026-03-18 20:57:38 +02:00
Lauri Ojansivu 36741d7ae5 Fix Error reading default file .well-known/assetlinks.json.default.
Thanks to gre3x and xet7 !

Fixes #6189
2026-03-18 20:55:44 +02:00
Lauri Ojansivu 507b196101 Updated ChangeLog. 2026-03-18 20:24:15 +02:00
Lauri Ojansivu 6fc1cb9127 Fix List drag handle missing.
Thanks to FK-PATZ3 and xet7 !

Fixes #6185
2026-03-18 20:22:25 +02:00
Lauri Ojansivu b3ae3871f2 Updated ChangeLog. 2026-03-18 18:38:00 +02:00
Lauri Ojansivu 1f6b5ed0e3 Fix version not visible.
Thanks to FK-PATZ3 and xet7 !

Related #6185
2026-03-18 18:36:12 +02:00
Lauri Ojansivu ab5fe6411a Updated ChangeLog. 2026-03-18 18:07:10 +02:00
Lauri Ojansivu 5dd3209ee8 Updated ChangeLog. 2026-03-18 18:04:50 +02:00
Lauri Ojansivu fccefcaa6c Updated to MongoDB 7.0.31 at Snap Candidate.
Thanks to MongoDB developers !
2026-03-18 18:03:11 +02:00
Lauri Ojansivu 98249dda8e Updated translations. 2026-03-18 18:02:47 +02:00
Lauri Ojansivu 26732d4f6e Updated ChangeLog. 2026-03-16 03:07:22 +02:00
Lauri Ojansivu 9a6319772e Merge pull request #6187 from KhaoulaMaleh/bugfix/6165-card-search-results
Fix #6165: Improve global search relevance and add exact-field operators
2026-03-16 02:58:27 +02:00
Lauri Ojansivu 2547967113 Merge pull request #6188 from harryadel/fix/list-add-card-and-sort-persistence
Fix list add-card actions and sort persistence
2026-03-16 02:56:04 +02:00
Harry Adel f436525f20 Fix list add-card actions and sort persistence 2026-03-16 01:49:53 +02:00
KhaoulaMaleh 7b3f7b8e6b fix search relevance 2026-03-15 04:56:25 -11:00
Lauri Ojansivu a3dece58fb Updated ChangeLog. 2026-03-14 18:58:41 +02:00
Lauri Ojansivu a159856628 Updated flatted.
Thanks to developers of flatted !
2026-03-14 18:57:43 +02:00
Lauri Ojansivu 7fb6e2a5d9 Added docs about If you get "Board not Found" after archieving Template Board.
Thanks to marcuskki and xet7 !

Related #4632
2026-03-13 20:53:17 +02:00
Lauri Ojansivu 0cdae9def1 Updated ChangeLog. 2026-03-13 20:52:55 +02:00
Lauri Ojansivu 63df6cb197 Updated dependencies.
Thanks to developers of dependencies !
2026-03-13 20:51:44 +02:00
Lauri Ojansivu 55d2d0843a Updated ChangeLog. 2026-03-12 04:49:38 +02:00
Lauri Ojansivu 7e378be1d8 Fix Add List popup to not open after adding new board or there being no lists at all.
Thanks to xet7 !
2026-03-12 04:39:51 +02:00
Lauri Ojansivu 89f86caf69 Replaced incompatible file-type with mime-type.
Thanks to xet7 !
2026-03-12 04:29:49 +02:00
Lauri Ojansivu 9604598a79 Updates 2026-03-12 04:12:21 +02:00
Lauri Ojansivu 90d9805abf Updated ChangeLog. 2026-03-12 04:12:21 +02:00
Lauri Ojansivu 0deb7ab641 Updated file-type.
Thanks to developers of file-type.
2026-03-12 04:12:21 +02:00
Lauri Ojansivu 230f954571 Updated ChangeLog. 2026-03-12 04:12:21 +02:00
dependabot[bot] e3f739e5d9 Bump docker/login-action from 3.7.0 to 4.0.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.7.0 to 4.0.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/c94ce9fb468520275223c153574b00df6fe4bcc9...b45d80f862d83dbcd57f89517bcf500b2ab88fb2)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-12 04:12:21 +02:00
dependabot[bot] 6b75bfcb0c Bump docker/metadata-action from 5.10.0 to 6.0.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.10.0 to 6.0.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/c299e40c65443455700f0fdfc63efafe5b349051...030e881283bb7a6894de51c315a6bfe6a94e05cf)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-12 04:12:21 +02:00
dependabot[bot] db47ed5430 Bump docker/build-push-action from 6.19.2 to 7.0.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.19.2 to 7.0.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/10e90e3645eae34f1e60eeb005ba3a3d33f178e8...d08e5c354a6adb9ed34480a06d141179aa583294)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-12 04:12:21 +02:00
KhaoulaMaleh 48361b2047 fixed linked card swimlane routing 2026-03-12 04:12:21 +02:00
Harry Adel 6953cc0670 Update PDF export models
Clean up exportPDF and ExporterCardPDF server-side code to align
with the BlazeComponent removal changes.
2026-03-08 11:13:17 +02:00
Harry Adel 477e1c89e5 Migrate rules, activities, and remaining components to Template
Convert all remaining BlazeComponent-based components to native Meteor
Template pattern: activities, comments, all rules actions/triggers,
swimlanes, users, gantt, import, and main utility components.
2026-03-08 11:13:17 +02:00
Harry Adel bae23f9ed8 Migrate sidebar and settings components from BlazeComponent to Template
Convert sidebar, sidebarArchives, sidebarCustomFields, sidebarFilters,
sidebarSearches, and all settings panel components to use native Meteor
Template.onCreated/helpers/events pattern.
2026-03-08 11:04:53 +02:00
Harry Adel d3625db755 Migrate card components from BlazeComponent to Template
Convert cardDetails, cardCustomFields, cardDate, cardTime,
cardDescription, attachments, checklists, labels, minicard,
resultCard, and subtasks to use native Meteor Template pattern.
2026-03-08 11:04:53 +02:00
Harry Adel d9e2e8f97e Migrate board and list components from BlazeComponent to Template
Convert boardBody, boardHeader, boardsList, boardArchive,
originalPositionsView, list, listBody, and listHeader to use
native Meteor Template.onCreated/helpers/events pattern.
2026-03-08 11:04:53 +02:00
Harry Adel f1625ad1f5 Migrate client library code from BlazeComponent to Template pattern
Convert popup, inlinedform, multiSelection, spinner, cardSearch,
datepicker, and dialog helper libraries to use native Meteor
Template.onCreated/helpers/events instead of BlazeComponent.
Update reactiveCache to remove BlazeComponent dependency.
2026-03-08 11:04:53 +02:00
Harry Adel 012947c076 Convert HTML templates to Jade and update template markup
Replace Spacebars .html templates with Jade equivalents for
originalPositionsView and originalPosition. Add new Jade template
for inlinedCardDescription. Update existing Jade templates to
reflect the BlazeComponent-to-Template migration changes.
2026-03-08 11:04:53 +02:00
Harry Adel 3b6f6fa80a Replace BlazeComponent mixins with standalone utility modules
Delete the old Mixins global and BlazeComponent-based InfiniteScrolling
mixin. Add standalone replacements:
- client/lib/infiniteScrolling.js: plain scroll-based pagination helper
- client/lib/currentCard.js: centralized current card resolution
- client/components/forms/datepicker.js: extracted date picker logic
2026-03-08 11:04:53 +02:00
Harry Adel 2848b1a38a Remove peerlibrary:blaze-components package and clean up config
Remove the blaze-components Meteor package and its peer dependencies
from .meteor/packages and .meteor/versions. Clean up related ESLint
globals (BlazeComponent, Mixins, InlinedForm, ReactiveTabs).
2026-03-08 11:04:53 +02:00
Lauri Ojansivu 53a0beffee Updates 2026-03-06 17:21:52 +02:00
Lauri Ojansivu 4cb99c6014 Updates 2026-03-06 17:16:50 +02:00
Lauri Ojansivu e485168169 Updates 2026-03-06 17:03:44 +02:00
Lauri Ojansivu 44a083e095 Updates 2026-03-06 17:00:40 +02:00
Lauri Ojansivu 1bd3363708 Updated ChangeLog. 2026-03-06 01:04:05 +02:00
Lauri Ojansivu ca87e5c3cf v8.35 2026-03-05 22:35:43 +02:00
Lauri Ojansivu 2cd702f48d Fix IntegrationBleed.
Thanks to Rodolphe GHIO and xet7 !
2026-03-05 21:26:22 +02:00
Lauri Ojansivu 97b0c392be Updated ChangeLog. 2026-03-05 17:30:35 +02:00
Lauri Ojansivu 274f1309c3 Fixed unable to delete Avatar, with Meteor 3 compatible avatar and attachments fixes.
Thanks to inDane and xet7 !

Fixes #6160
2026-03-05 17:27:33 +02:00
Lauri Ojansivu 326f9bed84 Updated ChangeLog. 2026-03-05 14:54:52 +02:00
Lauri Ojansivu 9f79a8b6ed Updated dompurify.
Thanks to xet7 !
2026-03-05 14:53:45 +02:00
Lauri Ojansivu 98eda7f49f Updated ChangeLog. 2026-03-05 14:47:17 +02:00
Lauri Ojansivu 5fe0b737c2 Updated translations 2026-03-05 14:40:25 +02:00
Lauri Ojansivu c29e92de1c Merge pull request #6175 from harryadel/remove-templates-tabs-package
Replace templates:tabs package with inline Blaze implementation
2026-03-05 14:38:19 +02:00
Lauri Ojansivu e9507d37cf Merge pull request #6174 from harryadel/replace-mongo-counter-package
Replace konecty:mongo-counter with inline implementation
2026-03-05 14:37:30 +02:00
Lauri Ojansivu 3454ab0278 Merge pull request #6173 from harryadel/fix-filescollection-findOneAsync
Fix FilesCollection findOneAsync errors for Avatars and Attachments
2026-03-05 14:37:02 +02:00
Lauri Ojansivu cfc9abea99 Merge pull request #6172 from wekan/dependabot/github_actions/actions/upload-artifact-7
Bump actions/upload-artifact from 6 to 7
2026-03-05 14:36:38 +02:00
Lauri Ojansivu 8e68bb6343 Merge pull request #6171 from wekan/dependabot/github_actions/meteorengineer/setup-meteor-3
Bump meteorengineer/setup-meteor from 2 to 3
2026-03-05 14:36:26 +02:00
Lauri Ojansivu 69ab456ed2 Merge pull request #6170 from wekan/dependabot/github_actions/actions/download-artifact-8
Bump actions/download-artifact from 7 to 8
2026-03-05 14:36:08 +02:00
Harry Adel 441b2b7c0d Merge branch 'main' into remove-templates-tabs-package 2026-03-05 05:32:28 +02:00
Harry Adel 81d3a08b9b Replace templates:tabs Atmosphere package with inline Blaze implementation
Drop the templates:tabs dependency as part of Meteor 3.0 migration prep.
The package is replaced by a lightweight inline basicTabs/tabContent
template pair with identical API, so no consumer template changes needed.
2026-03-05 05:31:35 +02:00
Harry Adel 3ebeac6b30 Replace konecty:mongo-counter with inline implementation
Remove the konecty:mongo-counter Meteor package dependency and replace
it with a minimal inline incrementCounter function using raw MongoDB
findOneAndUpdate. Also exports an async version for future Meteor 3.0
migration. No data migration needed — uses the same next_val field.
2026-03-05 05:16:40 +02:00
Harry Adel fa2f36b76b Merge branch 'main' into fix-filescollection-findOneAsync 2026-03-05 05:02:29 +02:00
Harry Adel 8b1e1dd92a Fix FilesCollection findOneAsync errors for Avatars and Attachments
FilesCollection from ostrio:files does not have findOneAsync. Use
the sync findOne method instead, matching the client-side cache.
2026-03-05 05:00:18 +02:00
dependabot[bot] 31614e58f2 Bump actions/upload-artifact from 6 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 22:16:39 +00:00
dependabot[bot] 9ff15562d9 Bump meteorengineer/setup-meteor from 2 to 3
Bumps [meteorengineer/setup-meteor](https://github.com/meteorengineer/setup-meteor) from 2 to 3.
- [Release notes](https://github.com/meteorengineer/setup-meteor/releases)
- [Commits](https://github.com/meteorengineer/setup-meteor/compare/v2...v3)

---
updated-dependencies:
- dependency-name: meteorengineer/setup-meteor
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 22:16:34 +00:00
dependabot[bot] 8c4f432e0c Bump actions/download-artifact from 7 to 8
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 22:16:30 +00:00
Lauri Ojansivu d34a886cac Back to package-lock.json format 1.
Thanks to xet7 !
2026-03-02 19:50:03 +02:00
Lauri Ojansivu 3ee4d1cace Merge pull request #6167 from wekan/dependabot/npm_and_yarn/minimatch-3.1.5
Bump minimatch from 3.1.3 to 3.1.5
2026-03-02 12:01:44 +02:00
Lauri Ojansivu ff7729fc35 Updated ChangeLog. 2026-03-01 00:12:15 +02:00
Lauri Ojansivu 7127862bea Optimized board loading.
Thanks to xet7 !

Fixes #6146
2026-03-01 00:10:09 +02:00
Lauri Ojansivu 4a8037047a Updated ChangeLog. 2026-02-28 23:50:27 +02:00
Lauri Ojansivu 9b3ecd795f Commented out Admin Panel/Settings/Migrations related menu option and code to speed up WeKan.
Thanks to xet7 !

Fixes #6146
2026-02-28 23:46:09 +02:00
dependabot[bot] cc06f515ce Bump minimatch from 3.1.3 to 3.1.5
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.1.3 to 3.1.5.
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.3...v3.1.5)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-28 21:31:56 +00:00
Lauri Ojansivu d57c5f736f Updated dependencies.
Thanks to developers of dependencies !
2026-02-28 23:30:33 +02:00
Lauri Ojansivu cf8c82b3fb Updated translations 2026-02-28 17:17:28 +02:00
Lauri Ojansivu f73bcfd134 Updated translations. 2026-02-25 12:45:03 +02:00
Lauri Ojansivu 3e400820e5 Merge pull request #6162 from harryadel/chore/fullcalendar-npm-moment-migration
fullcalendar npm moment migration
2026-02-25 12:34:44 +02:00
Harry Adel b6f9eac37e Add missing calendar translation keys for today day week and month 2026-02-24 23:44:04 +02:00
Harry Adel 7b443b7bfc Refine calendar toolbar labels and style create-card modal controls consistently 2026-02-24 23:43:58 +02:00
Harry Adel 8dafc774d8 Use template-bound autorun in wekan-fullcalendar to prevent Blaze current view errors 2026-02-24 23:43:53 +02:00
Harry Adel 2fe490ec3d Record FullCalendar post-Meteor-3.0 upgrade guidance in migration guide 2026-02-24 23:14:27 +02:00
Harry Adel d25da91e0b Document FullCalendar v5 wrapper usage and non-jQuery refetch flow 2026-02-24 23:07:07 +02:00
Harry Adel 1b74fd8d4e Migrate wekan-fullcalendar to npm FullCalendar v5 and remove Meteor moment package 2026-02-24 23:07:05 +02:00
Lauri Ojansivu d796c4d9bb Updates 2026-02-23 13:42:38 +02:00
Lauri Ojansivu 8787ce84ac Updates 2026-02-22 14:14:21 +02:00
Lauri Ojansivu 33e0c08adc v8.34 2026-02-20 00:35:29 +02:00
Lauri Ojansivu a34c2f35a6 Fix Notifications from not allowed Boards.
Thanks to FK-PATZ3 and xet7 !

Fixes #6103
2026-02-20 00:30:17 +02:00
Lauri Ojansivu 6903e12112 Updated ChangeLog. 2026-02-19 23:50:02 +02:00
Lauri Ojansivu 62216e36c1 Fix GHSL-2026-045_Wekan.
Thanks to GHSL and xet7 !
2026-02-19 23:47:56 +02:00
Lauri Ojansivu 73eb98c57a Fix GHSL-2026-044_Wekan.
Thanks to GHSL and xet7.
2026-02-19 23:40:56 +02:00
Lauri Ojansivu 1ee9b2e917 Fix GHSL-2026-037_Wekan.
Thanks to GHSL and xet7.
2026-02-19 23:36:44 +02:00
Lauri Ojansivu 8c00adc6b8 Fix GHSL-2026-036_Wekan.
Thanks to GHSL and xet7 !
2026-02-19 23:31:01 +02:00
Lauri Ojansivu 1c8667eae8 Fix GHSL-2026-035_Wekan.
Thanks to GHSL and xet7 !
2026-02-19 23:25:39 +02:00
Lauri Ojansivu f0deed448a Updated ChangeLog. 2026-02-19 23:19:36 +02:00
Lauri Ojansivu 06d418b12b Fix createWorkspace Meteor method fails with "Expected string, got undefined"
Thanks to TheBoysenBuilds and xet7 !

Fixes #6150
2026-02-19 23:17:53 +02:00
Lauri Ojansivu f6f16608dd Updated ChangeLog. 2026-02-19 23:08:54 +02:00
Lauri Ojansivu 8816c886cf Moved meteor-reactive-cache to npmjs.com @wekanteam/meteor-reactive-cache https://github.com/wekan/meteor-reactive-cache.
Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/6139
2026-02-19 23:05:15 +02:00
Lauri Ojansivu 6192c19fde Updated ChangeLog. 2026-02-19 22:27:06 +02:00
Lauri Ojansivu f463198e40 Updated dependencies.
Thanks to developers of dependencies !
2026-02-19 22:24:45 +02:00
Lauri Ojansivu ed907f8c61 Removed duplicate code.
Thanks to xet7 !
2026-02-19 22:24:25 +02:00
Lauri Ojansivu 55d2a5d15c Updates 2026-02-19 22:13:44 +02:00
Lauri Ojansivu 6168356ad2 Updated ChangeLog. 2026-02-19 22:11:58 +02:00
Lauri Ojansivu 71b1a0381f Merge pull request #6156 from wekan/dependabot/npm_and_yarn/tar-7.5.9
Bump tar from 7.5.7 to 7.5.9
2026-02-19 22:03:19 +02:00
dependabot[bot] 640629f69c Bump tar from 7.5.7 to 7.5.9
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.7 to 7.5.9.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.7...v7.5.9)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-19 20:02:55 +00:00
Lauri Ojansivu cde5af62cf Merge pull request #6151 from wekan/dependabot/npm_and_yarn/ajv-8.18.0
Bump ajv from 6.12.6 to 8.18.0
2026-02-19 22:01:37 +02:00
dependabot[bot] d016e66938 Bump ajv from 6.12.6 to 8.18.0
Bumps [ajv](https://github.com/ajv-validator/ajv) from 6.12.6 to 8.18.0.
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.6...v8.18.0)

---
updated-dependencies:
- dependency-name: ajv
  dependency-version: 8.18.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-19 20:01:17 +00:00
Lauri Ojansivu 5be23f61d0 Merge pull request #6155 from KhaoulaMaleh/updates
Fix calendar
2026-02-19 22:01:09 +02:00
Lauri Ojansivu a0c918c646 Merge pull request #6153 from harryadel/fix/cron-migration-async-job
Fix unhandled Promise rejection in cron migration job callback
2026-02-19 21:59:38 +02:00
Lauri Ojansivu 1d910b8a89 Merge pull request #6139 from harryadel/feature/reactive-cache-async-migration
Migrate @wekanteam/meteor-reactive-cache
2026-02-19 21:58:37 +02:00
Lauri Ojansivu c042eeb07e Merge pull request #6149 from wekan/dependabot/github_actions/docker/build-push-action-6.19.2
Bump docker/build-push-action from 6.18.0 to 6.19.2
2026-02-19 21:57:40 +02:00
KhaoulaMaleh afd40b21f1 Merge branch 'updates' of https://github.com/KhaoulaMaleh/wekan into updates 2026-02-19 01:21:56 -11:00
Harry Adel f40a00ef0e Update lock files 2026-02-19 00:34:15 +02:00
Harry Adel e77be37450 Use sync code in allow/deny for 2.x 2026-02-19 00:26:47 +02:00
Harry Adel 15f979f08a Fix unhandled Promise rejection in cron migration job callback
The createCronJob method's job callback was not async and did not await
this.runMigrationStep(step), causing the returned Promise to float.
When runMigrationStep threw, the unhandled rejection triggered
quave:synced-cron's global handler which called process.exit(0),
crashing the app on startup.
2026-02-18 22:41:16 +02:00
Lauri Ojansivu c8beb6018f Updated ChangeLog. 2026-02-18 21:14:56 +02:00
Harry Adel f934aea2a5 Return data on client (sync) and Promise on server (async) naturally, without wrapping in an extra Promise 2026-02-18 18:24:55 +02:00
KhaoulaMaleh 3d69c33caf Fix calendar 2026-02-18 00:36:58 -11:00
Harry Adel 2b15a8ff09 Fix merge problem 2026-02-17 17:46:24 +02:00
Harry Adel 5212f3beb3 Merge branch 'main' into feature/reactive-cache-async-migration 2026-02-17 16:45:06 +02:00
dependabot[bot] 4f45ebef84 Bump docker/build-push-action from 6.18.0 to 6.19.2
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.18.0 to 6.19.2.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/263435318d21b8e681c14492fe198d362a7d2c83...10e90e3645eae34f1e60eeb005ba3a3d33f178e8)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.19.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-16 20:37:22 +00:00
Lauri Ojansivu 8afdcd7a4c v8.33 2026-02-15 22:14:56 +02:00
Lauri Ojansivu 8ba18a971e Updated translations. 2026-02-15 22:13:54 +02:00
Lauri Ojansivu c47d443dcf Updated ChangeLog. 2026-02-15 21:55:32 +02:00
Lauri Ojansivu b5a13f0206 Admin Panel/Settings/Layout, for PWA: Custom head meta, link, icons, assetlinks.json, site.webmanifest.
Thanks to xet7 !
2026-02-15 21:49:55 +02:00
Lauri Ojansivu dace6b78c0 Fix typos 2026-02-15 18:29:38 +02:00
Lauri Ojansivu 29c5d6fbb3 Updated ChangeLog. 2026-02-15 17:21:43 +02:00
Lauri Ojansivu bebea9efea Updated dependencies.
Thanks to developers of dependencies !
2026-02-15 17:19:05 +02:00
Lauri Ojansivu 5a5eaec340 Merge pull request #6115 from harryadel/wekan-ldap-async-migration
Migrate wekan-ldap to async API for Meteor 3.0
2026-02-14 03:55:59 +02:00
Harry Adel 217cd7bcb6 Use ldapts instead ldapjs
We're using ldapts v4.2.6 because Wekan is on 2.16
2026-02-13 18:45:59 +02:00
Harry Adel 6bf60c496b Merge branch 'main' into wekan-ldap-async-migration 2026-02-13 17:11:16 +02:00
Lauri Ojansivu 68fb0a81e3 v8.32 2026-02-13 08:29:44 +02:00
Lauri Ojansivu 779f014fc5 Updated ChangeLog. 2026-02-13 08:26:21 +02:00
Lauri Ojansivu 4c5da0254a Updated ChangeLog. 2026-02-13 08:23:47 +02:00
Lauri Ojansivu fed2e9dd4e Updated to MongoDB 7.0.30 at Snap Candidate.
Thanks to MongoDB developers !
2026-02-13 08:22:29 +02:00
Lauri Ojansivu 3e8c2e98e7 Updated ChangeLog. 2026-02-13 07:42:18 +02:00
Lauri Ojansivu 0db7ab2eaa Merge pull request #6114 from harryadel/wekan-accounts-cas-async-migration
Migrate wekan-accounts-cas to async API for Meteor 3.0
2026-02-13 07:19:46 +02:00
Lauri Ojansivu 66ccba9267 Merge pull request #6112 from harryadel/wekan-accounts-sandstorm-async-migration
Migrate wekan-accounts-sandstorm to async API for Meteor 3.0
2026-02-13 07:18:57 +02:00
KhaoulaMaleh 0951c37536 fix the hour notation 2026-02-12 02:56:21 -11:00
Khaoula Maleh 1870c256b6 Merge branch 'main' into updates 2026-02-11 15:13:00 -11:00
Harry Adel 117a00c996 Migrate sandstorm.js to async 2026-02-12 03:35:40 +02:00
Harry Adel dd798b4c13 Update versions 2026-02-12 03:35:27 +02:00
Harry Adel b6ceef6775 Missing awaits 2026-02-12 03:29:31 +02:00
Harry Adel 89ce2f825d Merge branch 'main' into wekan-accounts-sandstorm-async-migration 2026-02-12 03:12:21 +02:00
Harry Adel eaf2d3fbb3 Final touches
- Removed underscore dependency and replaced it with a native solution
- Added ecmascript
- Update versions in .meteor
2026-02-12 02:50:29 +02:00
Harry Adel 91eb206ed5 Merge branch 'main' into wekan-accounts-cas-async-migration 2026-02-12 02:36:13 +02:00
Lauri Ojansivu eab8d7e2fc Updates 2026-02-11 21:19:12 +02:00
Lauri Ojansivu 4d65e214c3 Updated translations 2026-02-11 15:41:43 +02:00
Lauri Ojansivu 4d80dab633 Merge pull request #6111 from harryadel/wekan-oidc-async-migration
Migrate wekan-oidc to async API for Meteor 3.0
2026-02-11 15:17:51 +02:00
Lauri Ojansivu 8e1a800c31 Updated translations. 2026-02-10 08:19:28 +02:00
Harry Adel af30a00af2 Add missing imports 2026-02-09 20:16:57 +02:00
Harry Adel b52a337d36 Asyncif createObject and updateObject 2026-02-09 20:16:45 +02:00
Harry Adel 0f4ff6e30e Fix bugs 2026-02-09 19:52:10 +02:00
Lauri Ojansivu ffe7bb6ce5 v8.31 2026-02-08 01:40:14 +02:00
Lauri Ojansivu fc33f10e9b Updated ChangeLog. 2026-02-08 01:37:37 +02:00
Lauri Ojansivu f8aa487e91 Fix Copy Card and Move Card.
Thanks to xet7 !

Fixes #6119
2026-02-08 01:35:31 +02:00
Lauri Ojansivu 77041e0d74 v8.30 2026-02-08 00:56:35 +02:00
Lauri Ojansivu 1fd2468af6 Updated ChangeLog. 2026-02-08 00:51:03 +02:00
Lauri Ojansivu 1b8b8d2eef Reverted New UI Design of WeKan v8.29 and added more fixes and performance improvements.
Thanks to xet7 !
2026-02-08 00:48:39 +02:00
Lauri Ojansivu d152d8fc1b v8.29 2026-02-07 20:52:05 +02:00
Lauri Ojansivu 473f8640d0 Updated ChangeLog. 2026-02-07 20:46:02 +02:00
Lauri Ojansivu 6acdee51b6 Updated translations. 2026-02-07 20:42:56 +02:00
Lauri Ojansivu 537ea369bf Merge pull request #6133 from wekan/copilot/fix-merge-conflicts-pr-6131
Resolve merge conflicts for PR #6131 UI improvements
2026-02-07 18:36:31 +02:00
copilot-swe-agent[bot]andxet7 dba265aaef Fix merge conflict markers and logic bugs found in code review
Co-authored-by: xet7 <15545+xet7@users.noreply.github.com>
2026-02-07 16:33:00 +00:00
copilot-swe-agent[bot]andxet7 97dd5d2064 Resolve merge conflicts by accepting PR #6131 changes
Co-authored-by: xet7 <15545+xet7@users.noreply.github.com>
2026-02-07 16:30:08 +00:00
copilot-swe-agent[bot] dc0b68ee80 Initial plan 2026-02-07 16:26:45 +00:00
KhaoulaMaleh 93ebae78b8 Fix #6118: Raise minimum list width from 100 to 270 in existing configurable system 2026-02-06 22:23:28 -11:00
Lauri Ojansivu 9610d8f883 Updated ChangeLog. 2026-02-07 05:47:13 +02:00
Lauri Ojansivu 631c250f40 Fix move and copy popup duplicate view.
Thanks to mimZD and xet7 !

Fixes #6102
2026-02-07 05:44:34 +02:00
Lauri Ojansivu 5836e50e69 Updated ChangeLog. 2026-02-07 04:32:51 +02:00
Lauri Ojansivu 0a92e896f8 Fix Notifications from not allowed Boards.
Thanks to FK-PATZ3 and xet7 !

Fixes #6103
2026-02-07 04:31:24 +02:00
Lauri Ojansivu d6f9626a10 Updated ChangeLog. 2026-02-07 04:21:08 +02:00
Lauri Ojansivu 0ae9865fcb Added missing linefeeds.
Thanks to xet7 !
2026-02-07 04:19:05 +02:00
Lauri Ojansivu 0987154a7f Removed extra file. 2026-02-07 04:12:10 +02:00
Lauri Ojansivu cb6d487cbd Updated ChangeLog. 2026-02-07 03:54:07 +02:00
Lauri Ojansivu 55710835fe Fix No Add Card + etc.
Thanks to mimZD and xet7 !

Fixes #6108
2026-02-07 03:52:16 +02:00
Lauri Ojansivu c7b46c86c3 Updated ChangeLog. 2026-02-07 01:59:20 +02:00
Lauri Ojansivu 4456bc1360 Fixed extra space at RTL need margin.
Thanks to mimZD and xet7 !

Fixes #6099
2026-02-07 01:57:28 +02:00
Lauri Ojansivu 41c417fda0 Updated ChangeLog. 2026-02-07 01:09:24 +02:00
Lauri Ojansivu 345f9ec223 v8.28 2026-02-05 06:52:44 +02:00
Lauri Ojansivu 8bae45add3 Updated ChangeLog. 2026-02-05 06:31:37 +02:00
Lauri Ojansivu 6c2e2f271d Updated meteor-node-stubs.
Thanks to Meteor developers !
2026-02-05 06:29:48 +02:00
Lauri Ojansivu 90b0c47c41 Updated translations. 2026-02-05 06:02:08 +02:00
Lauri Ojansivu 79e9dadc38 Updated ChangeLog. 2026-02-05 06:00:10 +02:00
Lauri Ojansivu 404dd0735d Merge pull request #6126 from harryadel/fix/issue-6105-copy-move-remaining
Await async setDone before closing popup in copy/move dialogs
2026-02-05 05:45:00 +02:00
Harry Adel 30458c617e Guard against null newCard after cross-board copy
After a cross-board copy, ReactiveCache.getCard(newCardId) can return
null if the publication update hasn't reached the client yet. The card
is already created with a valid sort position server-side, so the
client-side repositioning is safely skippable.
2026-02-05 02:39:39 +02:00
Harry Adel e8b9a3a163 Fix Card.copy() mutating source card and normalize customFields
Card.copy() mutated `this` directly (boardId, labelIds, customFields,
etc.), corrupting the cached source card object and causing intermittent
failures on repeated copy operations. Now works on a shallow copy.

Also normalizes customFields to [] when it's not an array (e.g. legacy
{} data in the database), preventing "Custom fields must be an array"
schema validation errors on both copy and move operations.
2026-02-05 02:28:15 +02:00
Harry Adel d68ad47de6 Await async setDone before closing popup in copy/move dialogs
The click handler called setDone() without await then immediately
called Popup.back(2), destroying the popup template while the async
operation was still running. This caused unhandled promise rejections
and made errors invisible to the user.
2026-02-05 02:28:00 +02:00
Lauri Ojansivu 10cef2f254 Updated translations. 2026-02-05 00:26:07 +02:00
Lauri Ojansivu 8c252163c9 Updated ChangeLog. 2026-02-05 00:00:59 +02:00
Lauri Ojansivu c31758960f Fixed Jade syntax at header.
Thanks to xet7 !
2026-02-04 23:55:35 +02:00
Aymen Hassini ef32a72b4b improve cardDetails.css 2026-02-04 15:25:50 +01:00
Lauri Ojansivu 7dbebed6db Merge pull request #6122 from wekan/dependabot/github_actions/docker/login-action-3.7.0
Bump docker/login-action from 3.6.0 to 3.7.0
2026-02-04 03:49:03 +02:00
dependabot[bot] dda22ddb50 Bump docker/login-action from 3.6.0 to 3.7.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.6.0 to 3.7.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/5e57cd118135c172c3672efd75eb46360885c0ef...c94ce9fb468520275223c153574b00df6fe4bcc9)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 3.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-03 02:16:13 +00:00
Lauri Ojansivu 42d1b1c725 Updated ChangeLog. 2026-02-02 20:47:11 +02:00
Lauri Ojansivu e16e3aac2d Merge pull request #6121 from KhaoulaMaleh/updates
fixed text truncation
2026-02-02 20:42:52 +02:00
KhaoulaMaleh 19237ca7ce fixed text truncation 2026-02-02 19:29:08 -11:00
Harry Adel 71eb01e233 Update ReactiveCache call sites to use async/await for Meteor 3.0
Part 3 of ReactiveCache async migration:
- Add await before all ReactiveCache.getX() calls
- Make functions containing ReactiveCache calls async
- Convert forEach/map/filter loops with async callbacks to for...of
- Update model helpers, Meteor methods, JsonRoutes handlers
- Update collection hooks (.before/.after insert/update/remove)
- Update .allow() callbacks to async

Files updated across models/ and server/ directories:
- Model files: cards, boards, lists, swimlanes, activities, users,
  checklists, checklistItems, customFields, attachments, integrations,
  cardComments, settings files, creators, exporters, and more
- Server files: publications, methods, notifications, routes, migrations
2026-02-01 00:54:38 +02:00
Lauri Ojansivu bb12311e2f v8.27 2026-01-31 20:51:19 +02:00
Harry Adel 2f6e34c5f5 Make ReactiveCache async for Meteor 3.0 compatibility
- Convert all ReactiveCacheServer methods to async
  - findOne() → findOneAsync()
  - find().fetch() → find().fetchAsync()
  - Meteor.user() → Meteor.userAsync()
- Convert ReactiveCache facade methods to async
  - Server path uses await for async operations
  - Client path returns sync Minimongo result (wrapped in Promise)

This prepares the codebase for Meteor 3.0 where MongoDB
operations are async.
2026-01-31 20:50:40 +02:00
Harry Adel e241e27ca1 Add local fork of meteor-reactive-cache package
- Clone @wekanteam/meteor-reactive-cache to npm-packages/
- Add .meteorignore to exclude npm-packages from Meteor
- Update package.json to use local file path

This allows direct modification of the package for Meteor 3.0
async migration while maintaining publishability to npm.
2026-01-31 20:46:05 +02:00
Lauri Ojansivu bbd9fd838b Merge pull request #6120 from harryadel/fix/issue-6105-async-copy-card
Fix async/await in copy/move card operations
2026-01-31 20:36:12 +02:00
Harry Adel 35715ef2a3 Propagate async/await to List.copy(), Swimlane.copy() and callers
Since Card.copy() is now async, all callers in the copy chain need to
be updated to properly await the async operations:

- Make List.copy() async and await card.copy() in loop
- Make Swimlane.copy() async and await list.copy() in loop
- Fix mutateSelectedCards() to support async callbacks and method calls
- Make template copy event handler async in listBody.js

This also fixes the copySelection feature which was passing a callback
to mutateSelectedCards() but the function only supported method names.
2026-01-31 19:46:22 +02:00
Harry Adel 14de981ac3 Fix async/await in copy/move card operations
The mapCustomFieldsToBoard() method is async but was being called without
await in copy() and move() methods. This caused a Promise to be assigned
to customFields instead of the actual array, failing MongoDB schema
validation on cross-board operations.

Changes:
- Make copy() method async and await mapCustomFieldsToBoard()
- Add await in move() for mapCustomFieldsToBoard()
- Make copyCard() server method async and await card.copy()
- Add null check in mapCustomFieldsToBoard() for cards without custom fields
- Update client to use Meteor.callAsync for server-only copyCard method

Fixes #6105
2026-01-31 19:45:43 +02:00
Lauri Ojansivu 88b35a6415 Updated ChangeLog. 2026-01-31 10:42:09 +02:00
Lauri Ojansivu b55e1bbd40 Updated MongoDB to 7.0.29 at Windows install docs.
Thanks to MongoDB developers.
2026-01-31 10:40:16 +02:00
Lauri Ojansivu 520304d560 v8.26 2026-01-31 09:44:57 +02:00
Lauri Ojansivu be1ad7d041 Updated ChangeLog. 2026-01-31 09:29:59 +02:00
Lauri Ojansivu f73eab23f9 Fix Bug: Rules view translation not is not shown correctly.
Thanks to cactus7as and xet7 !

Fixes #6117
2026-01-31 09:27:49 +02:00
Lauri Ojansivu 9c2f782f84 Updated ChangeLog. 2026-01-31 09:22:24 +02:00
Lauri Ojansivu 0b891464b9 Fix Card copy menu is not displayed.
Thanks to xet7 !

Fixes #6105
2026-01-31 09:20:24 +02:00
Lauri Ojansivu 03439d1bcc Updated dependencies.
Thanks to developers of dependencies !
2026-01-31 09:16:02 +02:00
Lauri Ojansivu 6e9c8a174f Merge branch 'harryadel-wekan-accounts-lockout-async-migration' 2026-01-30 19:07:41 +02:00
Lauri Ojansivu ef84d798b5 Updated translations 2026-01-30 19:05:58 +02:00
Lauri Ojansivu a76f40a4d0 Updated ChangeLog. 2026-01-30 19:05:58 +02:00
Lauri Ojansivu 537e25df93 Spreadsheet vs Kanban, version 2.
Thanks to xet7 !
2026-01-30 19:05:58 +02:00
Lauri Ojansivu 0764b46a02 Updated ChangeLog. 2026-01-30 19:05:58 +02:00
Lauri Ojansivu b0f983dfa9 Added Docs: Spreadsheet vs Kanban.
Thanks to xet7 !
2026-01-30 19:05:58 +02:00
Lauri Ojansivu a3c7269d9e Updated translations 2026-01-30 00:00:39 +02:00
Lauri Ojansivu dc94618c26 Updated ChangeLog. 2026-01-29 22:53:13 +02:00
Lauri Ojansivu 37d0daee59 Spreadsheet vs Kanban, version 2.
Thanks to xet7 !
2026-01-29 22:51:57 +02:00
Lauri Ojansivu 9225b61225 Updated ChangeLog. 2026-01-29 22:43:11 +02:00
Lauri Ojansivu a0a8d0186c Added Docs: Spreadsheet vs Kanban.
Thanks to xet7 !
2026-01-29 22:41:42 +02:00
Harry Adel 11dab6680d Update .meteor/versions 2026-01-29 21:31:19 +02:00
Harry Adel b431600d32 Migrate accounts-lockout server files to async for Meteor 3.0
- lockedUsers.js: async getLockedUsers, unlockUser, unlockAllUsers
- lockoutSettings.js: async reloadAccountsLockout with findOneAsync
- accounts-lockout-config.js: async startup with findOneAsync
- models/lockoutSettings.js: upsert → upsertAsync
2026-01-29 21:29:56 +02:00
Harry Adel fb79ccaa55 Replace slugify with limax and fix sync operations 2026-01-29 21:01:39 +02:00
Harry Adel fa3966e1f7 Replace Npm.require with ES imports 2026-01-29 20:59:19 +02:00
Harry Adel 81c81ff4aa Replace Npm.require(fs) with ES import 2026-01-29 20:57:49 +02:00
Harry Adel 788406c217 Migrate wekan-accounts-sandstorm from HTTP to fetch 2026-01-29 20:45:50 +02:00
Harry Adel 49a272d6c0 Migrate wekan-oidc from HTTP to fetch 2026-01-29 20:45:00 +02:00
Harry Adel 0fcdf47545 Migrate wekan-oidc to async API for Meteor 3.0 2026-01-29 20:16:12 +02:00
Harry Adel 65ce948bb0 Migrate wekan-accounts-lockout to async API for Meteor 3.0 2026-01-29 20:12:00 +02:00
Harry Adel 5d6014d496 Migrate wekan-accounts-sandstorm to async API for Meteor 3.0 2026-01-29 20:05:51 +02:00
Harry Adel 6e48988118 Migrate wekan-accounts-cas to async API for Meteor 3.0
- Remove Fiber dependency (Npm.require('fibers'))
- Use Meteor.bindEnvironment for WebApp handler
- Convert login handler to async with findOneAsync
- Bump version 0.1.0 → 0.2.0
2026-01-29 20:03:10 +02:00
Harry Adel 7d56dca80b Migrate wekan-ldap to async API for Meteor 3.0
- Replace Meteor.wrapAsync with native Promises
- Convert all sync methods to async
- Use async DB operations (findOneAsync, updateAsync)
- Bump version 0.0.2 → 0.1.0
2026-01-29 19:58:23 +02:00
Lauri Ojansivu eb0c9ac1e6 Updates 2026-01-29 14:27:27 +02:00
Lauri Ojansivu 752bd501bc Updated ChangeLog. 2026-01-29 13:27:37 +02:00
Lauri Ojansivu 542ec7b78b Updated ChangeLog. 2026-01-28 22:27:37 +02:00
Lauri Ojansivu 218855eebf Merge pull request #6106 from AymenHassini19/fix/member-settings-scroll-overflow
Reduce Member Settings Overflow for Better UI
2026-01-28 22:25:10 +02:00
Aymen Hassini f4a449b4ab Partially Fix Member Settings Scroll Overflow 2026-01-28 14:58:44 +01:00
Lauri Ojansivu 8ce77880bd v8.25 2026-01-28 14:02:55 +02:00
Lauri Ojansivu ac70fe2848 Updated to MongoDB 7.0.29 at Snap Candidate.
Thanks to developers of MongoDB !
2026-01-28 13:54:10 +02:00
Lauri Ojansivu 7ff174cf66 Revert multi-CPU Snap, will try it later.
Thanks to xet7 !
2026-01-28 13:27:08 +02:00
Lauri Ojansivu a419d831a4 Fix Filebleed of Floppybleed.
Thanks to Luke Hebenstreit Twitter lheben_ and xet7 !
2026-01-28 13:20:28 +02:00
Lauri Ojansivu 7ad04f4535 Most Unicode Icons back to Font Awesome 4.7 for better accessibility. Less always visible buttons, More at ☰ Men.
Thanks to xet7 !
2026-01-28 13:02:02 +02:00
Lauri Ojansivu 440f553de0 Fix autofocus.
Thanks to xet7 !
2026-01-28 12:55:22 +02:00
Lauri Ojansivu c29ff995b3 Updated translations. 2026-01-28 12:42:47 +02:00
Lauri Ojansivu dee71b652d Updated translations. 2026-01-27 19:07:26 +02:00
Lauri Ojansivu 7a76cac80c Updated ChangeLog. 2026-01-24 09:13:15 +02:00
Lauri Ojansivu 3e0ecea0c9 Updated ChangeLog. 2026-01-24 07:36:11 +02:00
Lauri Ojansivu 60846a4495 Deleted extra docker-compose.yml-arm64, because docker-compose.yml should work at amd64/arm64/s390x.
Thanks to xet7 !
2026-01-24 07:34:57 +02:00
Lauri Ojansivu 15eba12e91 Updated ChangeLog. 2026-01-24 07:28:03 +02:00
Lauri Ojansivu 98e5adfba8 File content moved to releases/docker-build.sh
Thanks to xet7 !
2026-01-24 07:27:02 +02:00
Lauri Ojansivu 422514e907 Updated ChangeLog. 2026-01-24 07:26:30 +02:00
Lauri Ojansivu b2c7c7f55b Docker and Snap for Linux amd64/arm64/s390x. Part 3.
Thanks to xet7 !
2026-01-24 07:25:02 +02:00
Lauri Ojansivu 82097d622b Updated ChangeLog. 2026-01-24 06:45:13 +02:00
Lauri Ojansivu e72019fa55 Docker image for Linux amd64/arm64/s390x. Part 2.
Thanks to xet7 !
2026-01-24 06:43:13 +02:00
Lauri Ojansivu 38711f0a29 Docker image for Linux amd64/arm64/s390x.
Thanks to xet7 !
2026-01-24 06:37:28 +02:00
Lauri Ojansivu be6635c2a3 Updated ChangeLog. 2026-01-24 06:03:19 +02:00
Lauri Ojansivu d298ab7486 Updated Dockerfile.
Thanks to xet7 !
2026-01-24 06:01:51 +02:00
Lauri Ojansivu c912542223 Updated ChangeLog. 2026-01-24 05:29:32 +02:00
Lauri Ojansivu bf5d50e8a9 Updated FerretDB 2 / PostgreSQL docs location. Part 3.
Thanks to xet7 !
2026-01-24 05:28:25 +02:00
Lauri Ojansivu 4a5cfaf929 Updated ChangeLog. 2026-01-24 05:27:39 +02:00
Lauri Ojansivu 0ede9d6d93 Updated FerretDB 2 / PostgreSQL docs location. Part 2.
Thanks to xet7 !
2026-01-24 05:26:23 +02:00
Lauri Ojansivu 1bf4bf1f30 Updated ChangeLog. 2026-01-24 05:24:53 +02:00
Lauri Ojansivu 710d522e06 Updated FerretDB 2 / PostgreSQL docs location.
Thanks to xet7 !
2026-01-24 05:23:29 +02:00
Lauri Ojansivu ba4f4af29b Updated ChangeLog. 2026-01-24 05:17:22 +02:00
Lauri Ojansivu 2f25f47d0b Updated code counts.
Thanks to xet7 !
2026-01-24 05:15:32 +02:00
Lauri Ojansivu 59c6003fe1 Updated ChangeLog. 2026-01-24 03:24:17 +02:00
Lauri Ojansivu 4b0cd22bf7 v8.24 2026-01-24 03:11:14 +02:00
Lauri Ojansivu 3aca142770 Updated ChangeLog. 2026-01-24 03:04:43 +02:00
Lauri Ojansivu 256990b95c Updated ChangeLog. 2026-01-24 02:55:59 +02:00
Lauri Ojansivu 537ad1eff3 Merge pull request #6096 from harryadel/fix-autofocus
List on body for global onRendered
2026-01-24 02:54:09 +02:00
Lauri Ojansivu 2217a27757 Merge pull request #6095 from harryadel/remove-idmontie-migrations
Remove idmontie:migrations
2026-01-24 02:53:52 +02:00
Harry Adel 55abe2ee75 Remove idmontie:migrations 2026-01-24 02:39:27 +02:00
Harry Adel 70825d3425 List on body for global onRendered 2026-01-24 02:38:25 +02:00
Lauri Ojansivu 7f1bb73b75 Updated translations 2026-01-24 02:08:46 +02:00
Lauri Ojansivu 8b362a4165 Updated ChangeLog. 2026-01-24 02:06:36 +02:00
Lauri Ojansivu 25eedd187e Merge pull request #6093 from harryadel/createIndex-migration
Migrate createIndex to createIndexAsync
2026-01-24 02:04:35 +02:00
Lauri Ojansivu ff9f29d12d Merge pull request #6088 from harryadel/autofocus-migration
Remove mquandalle:autofocus
2026-01-24 02:04:21 +02:00
Harry Adel 42968d4c15 Merge branch 'main' into autofocus-migration 2026-01-24 01:58:25 +02:00
Harry Adel ca2083c858 Migrate createIndex to createIndexAsync 2026-01-24 01:55:29 +02:00
Lauri Ojansivu de0ff4002e Updated ChangeLog. 2026-01-24 01:52:48 +02:00
Lauri Ojansivu d0dc206ffc Merge pull request #6087 from harryadel/speakingurl-to-limax
Replace ongoworks:speakingurl with limax
2026-01-24 01:51:52 +02:00
Lauri Ojansivu 02d2ba2b6b Updated ChangeLog. 2026-01-24 01:51:30 +02:00
Lauri Ojansivu 904211dba5 Merge branch 'harryadel-collection-mutations-migrations' 2026-01-24 01:49:15 +02:00
Lauri Ojansivu 1d374db0f3 Meteor 2.16 2026-01-24 01:40:30 +02:00
Harry Adel e0249493d0 Fix swimlanes 2026-01-23 22:28:59 +02:00
Harry Adel 47f067e38e Merge branch 'main' into collection-mutations-migrations 2026-01-23 22:14:33 +02:00
Harry Adel 3b36d61698 Merge branch 'main' into speakingurl-to-limax 2026-01-22 15:01:29 +02:00
Lauri Ojansivu 60ecddfce4 Updated ChangeLog. 2026-01-22 02:19:46 +02:00
Lauri Ojansivu cc8b771eb4 Secure Sandbox for VSCode at Debian 13 amd64. Part 2.
Thanks to xet7 !
2026-01-22 02:18:25 +02:00
Lauri Ojansivu f503b7f517 Updated ChangeLog. 2026-01-22 02:10:32 +02:00
Lauri Ojansivu 639ac9549f Secure Sandbox for VSCode at Debian 13 amd64.
Thanks to xet7 !
2026-01-22 02:06:29 +02:00
Lauri Ojansivu 839098c884 Updated translations. 2026-01-21 23:48:15 +02:00
Harry Adel d8495ab08f Remove mquandalle:autofocus 2026-01-21 20:03:40 +02:00
Harry Adel 53a314af65 Downgrade limax to 4.1.0 2026-01-21 19:45:23 +02:00
Harry Adel 2d0c4f5bd8 Replace ongoworks:speakingurl with limax 2026-01-21 19:39:01 +02:00
Harry Adel 94a3575e2c Replace mquandalle:collection-mutations with collection helpers 2026-01-21 19:22:54 +02:00
Lauri Ojansivu aca661583d v8.23 2026-01-21 15:09:38 +02:00
Lauri Ojansivu ca79fcb7e9 Updated ChangeLog. 2026-01-21 14:16:44 +02:00
Lauri Ojansivu 04bfa0e6ba Updated dependencies.
Thanks to developers of dependencies !
2026-01-21 14:15:01 +02:00
Lauri Ojansivu 3f8059baad Updated translations. 2026-01-21 14:11:40 +02:00
Lauri Ojansivu b803d5336e Updated ChangeLog. 2026-01-21 13:41:24 +02:00
Lauri Ojansivu 7b72fcaee1 Merge pull request #6085 from wekan/dependabot/npm_and_yarn/tar-7.5.6
Bump tar from 7.5.3 to 7.5.6
2026-01-21 13:36:05 +02:00
Lauri Ojansivu c56bdb84d2 Merge pull request #6084 from harryadel/migrate-to-publish-composite
Replace cottz:publish-relations with reywood:publish-composite
2026-01-21 13:35:07 +02:00
dependabot[bot] ccc0d16b52 Bump tar from 7.5.3 to 7.5.6
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.3 to 7.5.6.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.3...v7.5.6)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-21 11:34:28 +00:00
Lauri Ojansivu f38e3624cf Merge pull request #6083 from harryadel/remove-kadira-dochead
Remove kadira:dochead
2026-01-21 13:33:50 +02:00
Lauri Ojansivu 8586fa8ce0 Merge pull request #6082 from harryadel/mousetrap-migration
Replace mousetrap
2026-01-21 13:33:09 +02:00
Harry Adel a5444e08ab Replace cottz:publish-relations with reywood:publish-composite 2026-01-21 07:52:04 +02:00
Harry Adel f9e584e13c Remove kadira:dochead 2026-01-21 07:36:17 +02:00
Harry Adel c795dfe96b Replace mousetrap 2026-01-21 07:03:46 +02:00
Lauri Ojansivu a528a411da Updated translations. 2026-01-21 01:02:14 +02:00
Lauri Ojansivu d96b8942e7 Updated ChangeLog. 2026-01-21 00:58:19 +02:00
Lauri Ojansivu a31a615da6 Fix DB migration from 8.19 to 8.21 stuck forever.
Thanks to MaccabeeY and xet7 !

Fixes #6078
2026-01-21 00:56:42 +02:00
Lauri Ojansivu e177bf54e2 Updated ChangeLog. 2026-01-20 20:49:28 +02:00
Lauri Ojansivu ce55f0d8f4 Fixed newly created "Default" swimlane are displayed as "key 'default (LOCALE)' returned an object instead of string".
Thanks to brlin-tw and xet7 !

Fixes #6064
2026-01-20 20:44:57 +02:00
Lauri Ojansivu 320b76aec4 Updated translations. 2026-01-20 20:03:24 +02:00
Lauri Ojansivu 5d86bcce6d Updated ChangeLog. 2026-01-20 19:59:53 +02:00
Lauri Ojansivu 0b9f23bd4a Merge branch 'harryadel-synced-cron-migration' 2026-01-20 19:57:34 +02:00
Harry Adel 526251397e Migrate from percolate:synced-cron to quave:synced-cron 2026-01-20 17:56:52 +02:00
Lauri Ojansivu 997b9a7c76 v8.22 2026-01-20 02:51:55 +02:00
Lauri Ojansivu bfebee5949 Updated translations. 2026-01-20 02:44:35 +02:00
Lauri Ojansivu bd899b2bf2 Updated ChangeLog. 2026-01-20 02:35:03 +02:00
Lauri Ojansivu ad511bd137 Fixed Add member and @mentions.
Thanks to xet7 !

Fixes #6076,
fixes #6077
2026-01-20 02:28:32 +02:00
Lauri Ojansivu 603a65ef17 v8.21 2026-01-18 21:18:03 +02:00
Lauri Ojansivu 2fa490d83d Fix DB migration from 8.19 to 8.20 is in a loop.
Thanks to MaccabeeY and xet7 !

Fixes #6072
2026-01-18 20:27:23 +02:00
Lauri Ojansivu a787bcddf3 Security Fix 14: RulesBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 20:18:38 +02:00
Lauri Ojansivu 91a936e07d Security Fix 13: LinkedBoardActivitiesBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 20:13:25 +02:00
Lauri Ojansivu 4ce181d172 Security Fix 12: FixDuplicateBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 20:07:12 +02:00
Lauri Ojansivu 0f5a9c3877 Security Fix 11: CardPubSubBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 20:00:37 +02:00
Lauri Ojansivu 545566f566 Security Fix 10: BoardTitleRESTBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 19:55:48 +02:00
Lauri Ojansivu 8c0b4f79d8 Security Fix 9: ListWIPBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 19:50:29 +02:00
Lauri Ojansivu c413a7e860 Security Fix 8: MoveStorageBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 19:45:44 +02:00
Lauri Ojansivu 053bf1dfb7 Security Fix 7: AttachmentMigrationBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 19:39:50 +02:00
Lauri Ojansivu 146905a459 Security Fix 6: SyncLDAPBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 19:36:28 +02:00
Lauri Ojansivu 55576ec177 Security Fix 5: PositionHistoryBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 19:29:58 +02:00
Lauri Ojansivu cc35dafef5 Security Fix 4: MigrationBleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 19:24:07 +02:00
Lauri Ojansivu 251d49eea9 Security Fix 3: Checklist REST Bleed.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 19:13:14 +02:00
Lauri Ojansivu cabfeed9a6 Security Fix 2: Orgs Teams permissions checks.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-18 19:08:28 +02:00
Lauri Ojansivu b4b90b1c41 Updated ChangeLog. 2026-01-18 15:24:30 +02:00
Lauri Ojansivu d337afd5d3 Fixed "Copy card link to clipboard" icon often not working.
Thanks to brlin-tw and xet7 !

Fixes #6068
2026-01-18 15:21:33 +02:00
Lauri Ojansivu 4473ca09f6 Updated ChangeLog. 2026-01-17 19:42:21 +02:00
Lauri Ojansivu d30192f7f9 Show password at Login and Register pages.
Thanks to xet7 !

Fixes #6070
2026-01-17 19:40:07 +02:00
Lauri Ojansivu 7291617a77 Updated ChangeLog. 2026-01-17 17:43:30 +02:00
Lauri Ojansivu 95da8966fe Updated dependencies.
Thanks to developers of dependencies !
2026-01-17 17:42:27 +02:00
Lauri Ojansivu db7ffc98fa Updated ChangeLog. 2026-01-17 17:33:39 +02:00
Lauri Ojansivu cb43a41b0c Updated translations. 2026-01-17 17:28:10 +02:00
Lauri Ojansivu a7e29b92bf Merge pull request #6072 from harryadel/meteor-2.16
Update 2.16
2026-01-17 13:10:20 +02:00
Lauri Ojansivu 4899330b6e Merge pull request #6071 from wekan/dependabot/npm_and_yarn/multi-5983a32967
Bump tar and @mapbox/node-pre-gyp
2026-01-17 13:09:43 +02:00
Harry Adel c56bc0be7f Update to 2.16 2026-01-16 23:18:29 +02:00
dependabot[bot] fd8ce39990 Bump tar and @mapbox/node-pre-gyp
Bumps [tar](https://github.com/isaacs/node-tar) to 7.5.3 and updates ancestor dependency [@mapbox/node-pre-gyp](https://github.com/mapbox/node-pre-gyp). These dependencies need to be updated together.


Updates `tar` from 6.2.1 to 7.5.3
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v6.2.1...v7.5.3)

Updates `@mapbox/node-pre-gyp` from 1.0.11 to 2.0.3
- [Release notes](https://github.com/mapbox/node-pre-gyp/releases)
- [Changelog](https://github.com/mapbox/node-pre-gyp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mapbox/node-pre-gyp/compare/v1.0.11...v2.0.3)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.3
  dependency-type: indirect
- dependency-name: "@mapbox/node-pre-gyp"
  dependency-version: 2.0.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-16 21:17:58 +00:00
Harry Adel f9ed63ac76 Remove kadira:flow-router 2026-01-16 23:17:50 +02:00
Lauri Ojansivu 641d4c2f7f Updated ChangeLog. 2026-01-16 22:50:27 +02:00
Lauri Ojansivu 980510d71a Updated Linux s390x bundle build script.
Thanks to xet7 !
2026-01-16 22:48:43 +02:00
Lauri Ojansivu 07001a229d Updated ChangeLog. 2026-01-16 22:15:37 +02:00
Lauri Ojansivu e2ec50730f Update Linux arm64 bundle build script.
Thanks to xet7 !
2026-01-16 22:14:07 +02:00
Lauri Ojansivu 20884cf6c7 Updated ChangeLog. 2026-01-16 21:02:44 +02:00
Lauri Ojansivu f0118d52e9 Updated Windows Bundle build .bat script.
Thanks to xet7 !
2026-01-16 21:01:29 +02:00
Lauri Ojansivu d4e922eed4 Updated ChangeLog. 2026-01-16 19:53:36 +02:00
Lauri Ojansivu b88b27689a Updated Docker build command.
Thanks to xet7 !
2026-01-16 19:52:07 +02:00
Lauri Ojansivu a29733be9c v8.20 2026-01-16 19:43:46 +02:00
Lauri Ojansivu 33e0a82967 Updated translations. 2026-01-16 19:17:05 +02:00
Lauri Ojansivu 13b5b170b6 Updated translations. 2026-01-14 23:57:35 +02:00
Lauri Ojansivu e2f2090da1 Updated ChangeLog. 2026-01-14 23:45:34 +02:00
Lauri Ojansivu eabb6a239d Fix New Board Permissions: NormalAssignedOnly, CommentAssignedOnly, ReadOnly, ReadAssignedOnly. Part 1.
Thanks to nazim-oss and xet7 !

Related #6060
2026-01-14 23:43:11 +02:00
Lauri Ojansivu 2f59e42024 Updated ChangeLog. 2026-01-14 21:13:31 +02:00
Lauri Ojansivu 20b5e2ab8f Fix mentions and notifications drawer.
Thanks to xet7 !

Fixes #6062,
fixes #6003,
fixes #5996,
fixes #5720,
fixes #5911,
fixes #5792,
fixes #5163,
fixes #4431,
fixes #4126,
fixes #3363,
fixes #3150
2026-01-14 21:02:10 +02:00
Lauri Ojansivu 0d5dd3082c Updated ChangeLog. 2026-01-14 19:12:53 +02:00
Lauri Ojansivu 5cb712bee4 Added back feature: Toggle Drag Handles. Improved positions of Add List etc buttons.
Thanks to xet7 !
2026-01-14 19:10:51 +02:00
Lauri Ojansivu 00793c39f8 Updated ChangeLog. 2026-01-14 16:31:01 +02:00
Lauri Ojansivu e37220cde6 Updated translations. 2026-01-14 16:19:15 +02:00
Lauri Ojansivu dd20988b1c Updated translations. 2026-01-14 01:29:03 +02:00
Lauri Ojansivu 32785376d8 Updated ChangeLog. 2026-01-14 01:20:50 +02:00
Lauri Ojansivu 4a39bcc6ee Merge branch 'harryadel-routing-layer-migration' 2026-01-14 01:12:30 +02:00
Lauri Ojansivu 984a2dcec1 Some fixes to make WeKan working after Meteor 3 related router upgrades.
Thanks to xet7 !
2026-01-14 01:11:42 +02:00
Lauri Ojansivu c8bdb95b38 Updated ChangeLog. 2026-01-14 01:00:59 +02:00
Lauri Ojansivu e89f4d260c Fixed Change Avatar. Improved Admin Panel: People columns order, selected tab background color.
Thanks to xet7 !
2026-01-14 01:00:59 +02:00
Lauri Ojansivu eca42f32bb Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu 6ad9770bb6 Changed find.sh to not search from translations, because I'm trying to find code, not translations.
Thanks to xet7 !
2026-01-14 01:00:58 +02:00
Lauri Ojansivu 5b47340b76 Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu 69f54dddaf Removed extra pipe character from UI.
Thanks to xet7 !
2026-01-14 01:00:58 +02:00
Lauri Ojansivu b3cb47ac47 Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu 69e2ad1007 Add back button texts to Filter, Search, Board View and MultiSelection.
Thanks to audiocrush and xet7 !

Fixes #6066
2026-01-14 01:00:58 +02:00
Lauri Ojansivu 40784b2054 Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu ab49e09da6 Removed extra list borders.
Thanks to TDSCDMA and xet7 !

Related #6063
2026-01-14 01:00:58 +02:00
Lauri Ojansivu 6ed8e54dac Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu c80d1aae4c Swimlane drag button position improvements.
Thanks to TDSCDMA and xet7 !

Related #6063
2026-01-14 01:00:58 +02:00
Lauri Ojansivu a62b3c6ce0 Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu 8a0568ce01 Updated GitHub issue templates. Part 3.
Thanks to xet7 !
2026-01-14 01:00:58 +02:00
Lauri Ojansivu c740474145 Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu 4a373b45e1 Updated GitHub issue templates. Part 2.
Thanks to xet7 !
2026-01-14 01:00:58 +02:00
Lauri Ojansivu 32733023ca Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu 0ffb0fa24f Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu b5177e3870 Added FerretDB2/PostgreSQL Docs. Part 4.
Thanks to juri_ at WeKan Libera.Chat IRC and xet7 !
2026-01-14 01:00:58 +02:00
Lauri Ojansivu c326e58d5e Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu 4d4046986f Updated GitHub issue templates.
Thanks to xet7 !
2026-01-14 01:00:58 +02:00
Lauri Ojansivu 36cbd3a606 Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu 715d47dd2c Added FerretDB2/PostgreSQL Docs. Part 3.
Thanks to juri_ at WeKan Libera.Chat IRC and xet7 !
2026-01-14 01:00:58 +02:00
Lauri Ojansivu 71d84f58a4 Updated ChangeLog. 2026-01-14 01:00:58 +02:00
Lauri Ojansivu 306305a95c Docs: Added s390x firewall info.
Thanks to xet7 !
2026-01-14 01:00:58 +02:00
Lauri Ojansivu 2bc9fa1629 Updated ChangeLog. 2026-01-14 01:00:57 +02:00
Lauri Ojansivu fd45ae2a62 Added FerretDB2/PostgreSQL Docs. Part 2.
Thanks to juri_ at WeKan Libera.Chat IRC and xet7 !
2026-01-14 01:00:57 +02:00
Lauri Ojansivu 46100cfd1d Updated ChangeLog. 2026-01-14 01:00:57 +02:00
Lauri Ojansivu 1d62322b3c Added FerretDB2/PostgreSQL Docs.
Thanks to juri_ at WeKan Libera.Chat IRC and xet7 !
2026-01-14 01:00:57 +02:00
Lauri Ojansivu d784d2b633 Updated ChangeLog. 2026-01-14 00:42:51 +02:00
Lauri Ojansivu 07186e12a9 Fixed Change Avatar. Improved Admin Panel: People columns order, selected tab background color.
Thanks to xet7 !
2026-01-14 00:41:35 +02:00
Harry Adel 0635a663f0 Remove pwix:blaze-layout 2026-01-14 00:13:21 +02:00
Lauri Ojansivu dcd8d80b9d Updated ChangeLog. 2026-01-13 22:52:51 +02:00
Lauri Ojansivu 58ae2b6c68 Changed find.sh to not search from translations, because I'm trying to find code, not translations.
Thanks to xet7 !
2026-01-13 22:50:39 +02:00
Lauri Ojansivu c76a569fb0 Updated ChangeLog. 2026-01-13 22:38:52 +02:00
Lauri Ojansivu 66e79d2df7 Removed extra pipe character from UI.
Thanks to xet7 !
2026-01-13 22:35:36 +02:00
Lauri Ojansivu fc06ae1000 Updated ChangeLog. 2026-01-13 22:26:45 +02:00
Lauri Ojansivu dac7e17500 Add back button texts to Filter, Search, Board View and MultiSelection.
Thanks to audiocrush and xet7 !

Fixes #6066
2026-01-13 22:24:02 +02:00
Lauri Ojansivu 8f51fcd65a Updated ChangeLog. 2026-01-13 21:26:21 +02:00
Lauri Ojansivu a4f8faa48e Removed extra list borders.
Thanks to TDSCDMA and xet7 !

Related #6063
2026-01-13 21:22:39 +02:00
Lauri Ojansivu b5ab917dfb Updated ChangeLog. 2026-01-13 20:23:08 +02:00
Lauri Ojansivu 376a30f8a9 Swimlane drag button position improvements.
Thanks to TDSCDMA and xet7 !

Related #6063
2026-01-13 20:20:33 +02:00
Harry Adel 9ebf4d2426 Migrate routing layer from deprecated kadira packages to modern alternatives
- Remove deprecated kadira:flow-router, kadira:blaze-layout, arillo:flow-router-helpers
- Add ostrio:flow-router-extra (modern, actively maintained)
- Add pwix:blaze-layout (maintained fork of kadira:blaze-layout)
- Convert all 22 BlazeLayout.render() calls to this.render() in route actions
- Maintain full backward compatibility with existing FlowRouter API
- All route definitions remain functional without syntax changes
- Build compilation succeeds without errors

This migration prepares Wekan for Meteor 3.0 compatibility by replacing
9-year-old deprecated routing packages with modern alternatives.

Next phase: Schema and async collection methods migration
2026-01-13 19:46:32 +02:00
Lauri Ojansivu 42c14faf41 Updated ChangeLog. 2026-01-13 16:39:45 +02:00
Lauri Ojansivu 4a658dc02a Updated GitHub issue templates. Part 3.
Thanks to xet7 !
2026-01-13 16:38:12 +02:00
Lauri Ojansivu f250cba405 Updated ChangeLog. 2026-01-13 16:35:28 +02:00
Lauri Ojansivu cf6e691498 Updated GitHub issue templates. Part 2.
Thanks to xet7 !
2026-01-13 16:33:58 +02:00
Lauri Ojansivu 5b2e6511b0 Updated ChangeLog. 2026-01-13 16:30:33 +02:00
Lauri Ojansivu 52a9514536 Updated ChangeLog. 2026-01-13 16:23:12 +02:00
Lauri Ojansivu ffd37b9fd9 Added FerretDB2/PostgreSQL Docs. Part 4.
Thanks to juri_ at WeKan Libera.Chat IRC and xet7 !
2026-01-13 16:21:44 +02:00
Lauri Ojansivu e2b80652a5 Updated ChangeLog. 2026-01-13 16:13:44 +02:00
Lauri Ojansivu bd37b88e4d Updated GitHub issue templates.
Thanks to xet7 !
2026-01-13 16:12:01 +02:00
Lauri Ojansivu a0adc54a08 Updated ChangeLog. 2026-01-13 03:52:46 +02:00
Lauri Ojansivu 9431b2d530 Added FerretDB2/PostgreSQL Docs. Part 3.
Thanks to juri_ at WeKan Libera.Chat IRC and xet7 !
2026-01-13 03:50:52 +02:00
Lauri Ojansivu 594ef40f2e Updated ChangeLog. 2026-01-12 15:26:44 +02:00
Lauri Ojansivu aacdcea37b Docs: Added s390x firewall info.
Thanks to xet7 !
2026-01-12 15:25:11 +02:00
Lauri Ojansivu 309a456a0d Updated ChangeLog. 2026-01-12 03:55:35 +02:00
Lauri Ojansivu f198421f10 Added FerretDB2/PostgreSQL Docs. Part 2.
Thanks to juri_ at WeKan Libera.Chat IRC and xet7 !
2026-01-12 03:54:41 +02:00
Lauri Ojansivu fa0460b1f0 Updated ChangeLog. 2026-01-12 02:24:36 +02:00
Lauri Ojansivu 9fb1aeb827 Added FerretDB2/PostgreSQL Docs.
Thanks to juri_ at WeKan Libera.Chat IRC and xet7 !
2026-01-12 02:21:03 +02:00
Lauri Ojansivu 59ad67c08c Updated translations. 2026-01-09 18:49:54 +02:00
Lauri Ojansivu ec57618c98 Updated translations. 2026-01-06 00:20:33 +02:00
Lauri Ojansivu 3b378961b0 Updated ChangeLog. 2026-01-06 00:16:48 +02:00
Lauri Ojansivu cbb1cd78de Security Fix 1: There was not enough permission checks. Moved migrations to Admin Panel/Settings/Cron.
Thanks to [Joshua Rogers](https://joshua.hu) of [Aisle Research](https://aisle.com) and xet7.
2026-01-06 00:15:16 +02:00
Lauri Ojansivu d6834d0287 Updated ChangeLog. 2026-01-05 21:49:52 +02:00
Lauri Ojansivu a9a89b501a Published @wekanteam npm packages to npmjs.com .
Thanks to xet7 !
2026-01-05 21:31:54 +02:00
Lauri Ojansivu 7de4385160 Updated dependencies.
Thanks to developers of dependencies !
2026-01-05 19:19:56 +02:00
Lauri Ojansivu 7ac5a2bba5 Updated translations. 2026-01-05 18:23:26 +02:00
Lauri Ojansivu e0af5db1a9 Merge pull request #6056 from brlin-tw/patch-nonascii-attachment-download-error
WIP: AI: Fix attachment download error with non-ASCII filenames (#6055)
2026-01-04 20:06:06 +02:00
Lauri Ojansivu 87cd07dec7 Merge pull request #6059 from wekan/dependabot/npm_and_yarn/multi-8d39329a2d
Bump qs
2026-01-04 20:05:38 +02:00
dependabot[bot] e80f8e5121 Bump qs
Bumps [qs](https://github.com/ljharb/qs) to 6.14.0 and updates ancestor dependency . These dependencies need to be updated together.


Updates `qs` from 6.14.0 to 6.14.0
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.14.0...v6.14.0)

Updates `qs` from 6.13.0 to 6.14.1
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.14.0...v6.14.0)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.14.0
  dependency-type: indirect
- dependency-name: qs
  dependency-version: 6.14.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-01 13:35:17 +00:00
Lauri Ojansivu 2325a5c532 Updated translations 2025-12-30 12:19:55 +02:00
Lauri Ojansivu b1db262b37 Updated ChangeLog. 2025-12-30 12:01:28 +02:00
GitHub Copilot 2e564bd076 Fix attachment download error with non-ASCII filenames
Fixes #6055.

Signed-off-by: Buo-ren Lin (OSSII) <buoren.lin@ossii.com.tw>
2025-12-30 17:54:29 +08:00
Lauri Ojansivu e09e9114aa v8.19 2025-12-29 21:54:10 +02:00
Lauri Ojansivu efd91a8f72 Updated translations. 2025-12-29 21:49:37 +02:00
Lauri Ojansivu fbfde81bc8 Opened card Checklist menu: Hide finished tasks. Show Checklist at Minicard.
Thanks to C0rn3j and xet7 !

Fixes #6019,
fixes #5567,
fixes #2984
2025-12-29 21:42:19 +02:00
Lauri Ojansivu cf62807ad5 Fix Unable to delete Checklist. Added confirm delete to Checklist and Chekclist Item.
Thanks to C0rn3j and xet7 !

Fixes #6020
2025-12-29 19:42:20 +02:00
Lauri Ojansivu 2d87ba18b3 Fix move card last selection is gone.
Thanks to mimZD and xet7 !

Fixes #6046
2025-12-29 19:17:06 +02:00
Lauri Ojansivu 74f1dfde72 Fix copy move card at board and MultiSelect to have numbered target of board, card above or below. Added MultiSelect change color.
Thanks to mimZD and xet7 !

Fixes #6045
2025-12-29 19:09:45 +02:00
Lauri Ojansivu db4b04d837 Fix find.sh work with spaces, for example: ./find.sh "Some text"
Thanks to xet7 !
2025-12-29 18:46:05 +02:00
Lauri Ojansivu 0b0e16c3ea Security Fix 10: LDAP filter injection in LDAP auth.
Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec !
2025-12-29 17:13:32 +02:00
Lauri Ojansivu 1d16955b6d Security Fix 9: Attachment upload not scoped to card/board relationship.
Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec !
2025-12-29 17:06:22 +02:00
Lauri Ojansivu 6dfa3beb2b Security Fix 8: Attachments publication leaks metadata without auth.
Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec !
2025-12-29 17:03:02 +02:00
Lauri Ojansivu 5cd875813f Security Fix 7: Checklist create IDOR: cardId not verified against boardId.
Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec !
2025-12-29 16:58:26 +02:00
Lauri Ojansivu 08a6f084eb Security Fix 6: Checklist delete IDOR: checklist not verified against board/card.
Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec !
2025-12-29 16:54:04 +02:00
Lauri Ojansivu 181f837d8c Security Fix 5: Read-only roles can still update cards.
Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec !
2025-12-29 16:47:11 +02:00
Lauri Ojansivu 198509e760 Security Fix 4: Cross-board card move without destination authorization.
Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec !
2025-12-29 16:39:23 +02:00
Lauri Ojansivu 67cb47173c Security Fix 3: Card comment author spoofing (IDOR) via API.
Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec !
2025-12-29 16:34:00 +02:00
Lauri Ojansivu 7ed76c180e Security Fix 2: Private-only board setting can be bypassed.
Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec !
2025-12-29 16:29:01 +02:00
Lauri Ojansivu f244a43771 Security Fix 1: IDOR in setCreateTranslation. Non-admin could change Custom Translation.
Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec.
2025-12-29 16:20:17 +02:00
Lauri Ojansivu 48e856fca2 Updated translations. 2025-12-29 16:12:37 +02:00
Lauri Ojansivu 7d83cb3d0b Updated ChangeLog. 2025-12-29 15:31:26 +02:00
Lauri Ojansivu 3af3c9a89d Converted Gantt from js to Jade. Part 2.
Thanks to xet7 !
2025-12-29 15:26:16 +02:00
Lauri Ojansivu 2d3bef9033 Converted Gantt from js to Jade.
Thanks to xet7 !
2025-12-29 15:17:27 +02:00
Lauri Ojansivu ce9afbcaca Updated ChangeLog. 2025-12-29 10:07:47 +02:00
Lauri Ojansivu ba79d5389d Updated ChangeLog. 2025-12-29 07:27:48 +02:00
Lauri Ojansivu 2f4c40c1db Updated translations. 2025-12-29 07:25:26 +02:00
Lauri Ojansivu 6c9e8a4aa8 Merge pull request #6052 from Chostakovitch/6048-dnd-lists
Merge list component methods with same name
2025-12-29 07:19:35 +02:00
Lilou 223c38c50d Set sortable methods of lists only once 2025-12-29 02:45:48 +01:00
Lilou c1981dee9b Merge list component methods with same name
Probably results in inconsistant behavior (which one overwrites the other?)
2025-12-29 01:48:33 +01:00
Lauri Ojansivu 45b3373145 Updated ChangeLog. 2025-12-28 23:45:21 +02:00
Lauri Ojansivu 54a566cfb1 Merge pull request #6050 from Chostakovitch/6049-announcements
Re-add JS closing class to unicode close announcement symbol
2025-12-28 23:40:28 +02:00
Lilou 5a51c2940a Re-add JS closing class to unicode close announcement symbol 2025-12-28 21:54:39 +01:00
Lauri Ojansivu 7232070bd1 Updated ChangeLog. 2025-12-28 20:38:34 +02:00
Lauri Ojansivu 33ab8920ca v8.18 2025-12-28 20:32:44 +02:00
Lauri Ojansivu db4d47cc52 Updated ChangeLog. 2025-12-28 20:21:44 +02:00
Lauri Ojansivu e210c9973b Upgraded MongoDB to 7.0.28 to fix mongobleed at Snap Candidate.
Thanks to developers of MongoDB !
2025-12-28 19:59:36 +02:00
Lauri Ojansivu 98d05ce545 Updated translations 2025-12-25 08:47:55 +02:00
Lauri Ojansivu 9268d80974 Updated translations. 2025-12-25 08:46:43 +02:00
Lauri Ojansivu 1a221a6967 Updated translations. 2025-12-23 16:06:21 +02:00
Lauri Ojansivu a039bb1066 Per-User and Board-level data save fixes. Part 3.
Thanks to xet7 !
2025-12-23 09:03:41 +02:00
Lauri Ojansivu 90a7a61904 Updates 2025-12-23 08:03:04 +02:00
Lauri Ojansivu 58e970d685 Per-User and Board-level data save fixes. Part 2.
Thanks to xet7 !
2025-12-23 08:01:30 +02:00
Lauri Ojansivu edf0f3c05b Updated translations 2025-12-23 07:54:57 +02:00
Lauri Ojansivu 5bbf5e0dac Updated ChangeLog. 2025-12-23 07:52:46 +02:00
Lauri Ojansivu 414b8dbf41 Per-User and Board-level data save fixes. Per-User is collapse, width, height. Per-Board is Swimlanes, Lists, Cards etc.
Thanks to xet7 !

Fixes #5997
2025-12-23 07:49:37 +02:00
Lauri Ojansivu 2e0e1e56b5 Updated translations. 2025-12-23 06:59:50 +02:00
Lauri Ojansivu 546dcdf1de Updated ChangeLog. 2025-12-23 06:58:30 +02:00
Lauri Ojansivu 58f4884ad6 Collapse Swimlane, List, Opened Card. Opened Card window X and Y position can be moved freely from drag handle. Fix some dragging not possible. Fix iPhone Safari.
Thanks to xet7 !

Fixes #6040,
fixes #6027,
fixes #6021,
fixes #6002
2025-12-23 06:47:02 +02:00
Lauri Ojansivu 95d1625a9f Updated translations. 2025-12-23 01:45:40 +02:00
Lauri Ojansivu 05fbdd559f Updated ChangeLog. 2025-12-23 01:32:50 +02:00
Lauri Ojansivu 300b653ea3 Right top User Settings / Grey Icons. Also fixed Change Language popup.
Thanks to xet7 !
2025-12-23 01:31:02 +02:00
Lauri Ojansivu 1808ea7384 fix(jade): simplify rules headers and conditions; add helpers to expose ruleName safely 2025-12-22 23:35:30 +02:00
Lauri Ojansivu 4408eae158 feat: grey unicode icons without UI freezes 2025-12-22 23:26:30 +02:00
Lauri Ojansivu a68993d099 perf(unicode-icons): replace body-wide scans with added-nodes observer; prevent unresponsiveness while greying icons 2025-12-22 23:26:30 +02:00
Lauri Ojansivu ecfb0f0fdf Manually merged fixes from seve12.
Thanks to seve12 !

Related https://github.com/wekan/wekan/pull/5967
2025-12-22 23:18:01 +02:00
Lauri Ojansivu fc3bb962f7 Updated translations. 2025-12-22 23:01:14 +02:00
Lauri Ojansivu 23630a4c67 Updated translations. 2025-12-22 22:49:53 +02:00
Lauri Ojansivu b0a7fea724 Updated translations. 2025-12-22 22:41:05 +02:00
Lauri Ojansivu 47bbd5b4a8 Updated ChangeLog. 2025-12-22 22:25:41 +02:00
Lauri Ojansivu a7400dca45 More translations. Added support page to Admin Panel / Settings / Layout.
Thanks to xet7 !
2025-12-22 22:24:35 +02:00
Lauri Ojansivu 4227377449 Updated ChangeLog. 2025-12-22 21:46:14 +02:00
Lauri Ojansivu c1168d181b New Board Permissions: NormalAssignedOnly, CommentAssignedOnly, ReadOnly, ReadAssignedOnly.
Thanks to xet7 !

Fixes #1122,
fixes #6033,
fixes #3300
2025-12-22 21:45:09 +02:00
Lauri Ojansivu 21fb8e9164 Updated ChangeLog. 2025-12-22 21:08:53 +02:00
Lauri Ojansivu e569c2957e Number of cards per list and sum of custom number field in list head.
Thanks to xet7 !

Fixes #3796
2025-12-22 21:06:44 +02:00
Lauri Ojansivu 4292302c3c Updated ChangeLog. 2025-12-22 17:02:20 +02:00
Lauri Ojansivu f34e4c0e36 Gantt chart view to one board view menu Swimlanes/Lists/Calendar/Gantt.
Thanks to xet7 !

Fixes #2870
2025-12-22 16:51:10 +02:00
Lauri Ojansivu 1790918006 Updated translations. 2025-12-22 06:06:47 +02:00
Lauri Ojansivu 400eb81206 Updated Mac docs for Applite
Thanks to xet7 !
2025-12-18 01:58:53 +02:00
Lauri Ojansivu e07e461e48 Updates 2025-12-17 14:58:38 +02:00
Lauri Ojansivu 451e9f7870 Updates 2025-12-17 14:57:11 +02:00
Lauri Ojansivu 3c57840340 Updates 2025-12-17 14:53:41 +02:00
Lauri Ojansivu 2cbf64da33 Updates 2025-12-17 14:43:30 +02:00
Lauri Ojansivu 3ef0a3e685 Updates 2025-12-17 14:41:26 +02:00
Lauri Ojansivu 9ebdc82d46 Updates 2025-12-17 14:39:57 +02:00
Lauri Ojansivu fe4b36b85d Fix migration instructions from Snap to Docker
Corrected instructions for migrating from Snap to Docker, ensuring clarity on file paths and environment variables.
2025-12-17 14:37:37 +02:00
Lauri Ojansivu b7ff370561 Fix backup command for WeKan database
Corrected command in backup instructions to create directory before moving files.
2025-12-17 14:34:30 +02:00
Lauri Ojansivu 5686c92e05 Revise backup and upgrade instructions for Docker Wekan
Updated notes on Docker commands and migration steps.
2025-12-17 14:33:39 +02:00
Lauri Ojansivu 784c5c6b0c Update Backup.md 2025-12-17 14:27:43 +02:00
Lauri Ojansivu 30541260f0 Update Backup.md to reflect related topics 2025-12-17 14:25:15 +02:00
Lauri Ojansivu 59fc756a0b Revise WeKan Snap upgrade and backup instructions
Updated the WeKan Snap upgrade instructions, including backup steps and Caddy configuration.
2025-12-17 14:24:17 +02:00
Lauri Ojansivu 4e346c0ab7 Update Backup.md with migration instructions
Added instructions for handling board settings and migrations after starting Wekan.
2025-12-17 14:07:01 +02:00
Lauri Ojansivu 19fa12bb26 Update backup instructions for Docker and Snap
Updated docker-compose command to use 'docker compose' syntax and added note about Snap upgrade.
2025-12-17 14:00:35 +02:00
Lauri Ojansivu e669b1b9c7 Updated backup docs for docker upgrades 2025-12-17 13:57:17 +02:00
Lauri Ojansivu f24e4a4ce3 Added docs about Mac Homebrew. 2025-12-17 11:13:15 +02:00
Lauri Ojansivu 8b5430acb8 Added Mac docs about Homebrew GUI Applite.
Thanks to xet7 !
2025-12-17 11:10:57 +02:00
Lauri Ojansivu 614cb44b55 Updated translations. 2025-12-16 21:56:51 +02:00
Lauri Ojansivu 0ce8e8b74d Merge pull request #6043 from wekan/dependabot/github_actions/actions/cache-5
Bump actions/cache from 4 to 5
2025-12-16 05:47:09 +02:00
Lauri Ojansivu 4ea53af76e Merge pull request #6042 from wekan/dependabot/github_actions/actions/download-artifact-7
Bump actions/download-artifact from 6 to 7
2025-12-16 05:46:50 +02:00
Lauri Ojansivu 016f17d663 Merge pull request #6041 from wekan/dependabot/github_actions/actions/upload-artifact-6
Bump actions/upload-artifact from 5 to 6
2025-12-16 05:46:26 +02:00
dependabot[bot] 07f69950a7 Bump actions/cache from 4 to 5
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 20:13:04 +00:00
dependabot[bot] cec625607d Bump actions/download-artifact from 6 to 7
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 20:13:00 +00:00
dependabot[bot] a290c7b34b Bump actions/upload-artifact from 5 to 6
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 20:12:55 +00:00
Lauri Ojansivu 5b77ac1b44 Updated translations 2025-12-11 03:33:17 +02:00
Lauri Ojansivu 41c635afb5 Merge pull request #6029 from MialLewis/add_archive_card_to_api
Add archive card to api
2025-12-04 11:58:44 +02:00
Lauri Ojansivu adbf729cb2 Merge pull request #6032 from wekan/dependabot/github_actions/docker/metadata-action-5.10.0
Bump docker/metadata-action from 5.9.0 to 5.10.0
2025-12-04 11:58:02 +02:00
dependabot[bot] 88ea716d63 Bump docker/metadata-action from 5.9.0 to 5.10.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.9.0 to 5.10.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/318604b99e75e41977312d83839a89be02ca4893...c299e40c65443455700f0fdfc63efafe5b349051)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 5.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 23:35:03 +00:00
Mial Lewis 003a07ebce change restore to unarchive 2025-11-27 22:00:43 +00:00
Mial Lewis d3c237bc66 fix more indenting 2025-11-27 08:29:36 +00:00
Mial Lewis bac0fa81fc correce indent 2025-11-27 08:27:38 +00:00
Mial Lewis a42915614a add restore to wekan.yml 2025-11-27 08:25:59 +00:00
Mial Lewis 5ff9bf331f add restore to api 2025-11-27 08:23:56 +00:00
Mial Lewis 36d7b0f8a7 correct return values 2025-11-27 00:52:28 +00:00
Mial Lewis 67c8a98f20 add route to wekan.yml 2025-11-27 00:05:53 +00:00
Mial Lewis a81a603031 update bool to boolean 2025-11-26 23:59:00 +00:00
Mial Lewis e30ce78053 add archive card to api 2025-11-26 23:57:49 +00:00
Lauri Ojansivu 3d70de94c6 Merge pull request #6028 from wekan/dependabot/github_actions/actions/checkout-6
Bump actions/checkout from 5 to 6
2025-11-26 18:04:09 +02:00
Lauri Ojansivu 1b6e8797ec Feature: Grey Icons. This makes WeKan very slow. Not recommended.
Thanks to xet7 !
2025-11-25 04:33:42 +02:00
dependabot[bot] 70975c2944 Bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 20:03:19 +00:00
Lauri Ojansivu 960e2126b4 Updated ChangeLog. 2025-11-21 03:02:41 +02:00
Lauri Ojansivu 3db1305e58 Updated build script for Linux arm64 bundle.
Thanks to xet7 !
2025-11-21 02:44:50 +02:00
Lauri Ojansivu f16780b5e3 Updated translations. 2025-11-19 09:34:57 +02:00
Lauri Ojansivu 37a3065f3c Updated translations. 2025-11-15 16:35:31 +02:00
Lauri Ojansivu 7ff1649d89 Updated security.md 2025-11-14 07:47:31 +02:00
Lauri Ojansivu a39ae31b45 Merge pull request #6012 from wekan/dependabot/github_actions/docker/metadata-action-5.9.0 2025-11-13 17:19:00 +02:00
dependabot[bot] 6302a48221 Bump docker/metadata-action from 5.8.0 to 5.9.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.8.0 to 5.9.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/c1e51972afc2121e065aed6d45c65596fe445f3f...318604b99e75e41977312d83839a89be02ca4893)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 5.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 20:02:19 +00:00
Lauri Ojansivu c277bee9d2 Merge pull request #6009 from brlin-tw/patch-issue-6008
Fix Broken Strikethroughs in Markdown to HTML conversion.
2025-11-10 04:58:29 +02:00
Buo-ren Lin (OSSII) c5f5ce126d Fix Broken Strikethroughs in Markdown to HTML conversion.
Allow the s tag to be rendered.

Fixes #6008.

Signed-off-by: Buo-ren Lin (OSSII) <buoren.lin@ossii.com.tw>
2025-11-10 10:49:26 +08:00
Lauri Ojansivu 0004ae716b v8.17 2025-11-06 04:00:04 +02:00
Lauri Ojansivu 7f53dfac3c Updated ChangeLog. 2025-11-06 03:33:46 +02:00
Lauri Ojansivu 18003900c2 Fix Worker Permissions does not allow for cards to be moved. - v8.15.
Thanks to xet7 !

Fixes #5990
2025-11-06 03:31:14 +02:00
Lauri Ojansivu fe104791b5 Updated ChangeLog. 2025-11-06 03:08:51 +02:00
Lauri Ojansivu 6244657ca5 Fix Workspaces at All Boards to have correct count of remaining etc, while starred also at Starred/Favorites.
Thanks to xet7 !
2025-11-06 03:06:16 +02:00
Lauri Ojansivu 46866dac85 Updated ChangeLog. 2025-11-06 02:46:52 +02:00
Lauri Ojansivu c829c073cf Remove not working Bookmark menu option.
Thanks to xet7 !
2025-11-06 02:44:30 +02:00
Lauri Ojansivu 0772ca4036 Updated ChangeLog. 2025-11-06 02:36:10 +02:00
Lauri Ojansivu 581733d605 Fix Regression - Show calendar popup at set due date.
Thanks to xet7 !

Fixes #5978
2025-11-06 02:32:34 +02:00
Lauri Ojansivu b02af27ac3 Updated ChangeLog. 2025-11-06 01:06:19 +02:00
Lauri Ojansivu 20af0a2ef5 Try to fix Edit Custom Fields button not working. Removed duplicate option from Boards Settings.
Thanks to xet7 !

Fixes #5988
2025-11-06 01:04:20 +02:00
Lauri Ojansivu c58ab5b07d Updated ChangeLog. 2025-11-06 00:37:42 +02:00
Lauri Ojansivu e5e711c938 Fix Card emoji issues.
Thanks to xet7 !

Fixes #5995
2025-11-06 00:35:49 +02:00
Lauri Ojansivu 42594abe4e Updated ChangeLog. 2025-11-06 00:30:08 +02:00
Lauri Ojansivu 0afbdc95b4 Feature: Workspaces, at All Boards page.
Thanks to xet7 !
2025-11-06 00:26:35 +02:00
Lauri Ojansivu 16a74bb748 Updated ChangeLog. 2025-11-05 20:51:44 +02:00
Lauri Ojansivu 8711b476be Fix star board.
Thanks to xet7 !
2025-11-05 20:50:28 +02:00
Lauri Ojansivu df9fba4765 Updated translations. 2025-11-05 20:26:29 +02:00
Lauri Ojansivu 7d27139aa9 Updated ChangeLog. 2025-11-05 20:25:07 +02:00
Lauri Ojansivu e4638d5fbc Fixed sidebar migrations to be per-board, not global. Clarified translations.
Thanks to xet7 !
2025-11-05 20:22:56 +02:00
Lauri Ojansivu bc5854dd29 Updated ChangeLog. 2025-11-05 19:04:47 +02:00
Lauri Ojansivu ba49d4d140 Remove old translations and code not in use anymore.
Thanks to xet7 !
2025-11-05 19:03:21 +02:00
Lauri Ojansivu 71b7dcffb5 Updated ChangeLog. 2025-11-05 18:46:56 +02:00
Lauri Ojansivu 7713e613b4 Fix 8.16 Lists with no items are deleted every time when board is opened. Moved migrations to right sidebar.
Thanks to xet7 !

Fixes #5994
2025-11-05 18:44:48 +02:00
Lauri Ojansivu 91a0aa7387 Updated ChangeLog. 2025-11-05 17:08:52 +02:00
Lauri Ojansivu fbd6b920ef Updated ChangeLog. 2025-11-05 17:08:10 +02:00
Lauri Ojansivu 1b25d1d572 Moved migrations from opening board to right sidebar / Migrations.
Thanks to xet7 !
2025-11-05 17:06:26 +02:00
Lauri Ojansivu e93e72234c Updated ChangeLog. 2025-11-05 16:38:10 +02:00
Lauri Ojansivu 15d9b0ae3a Updated ChangeLog. 2025-11-05 16:38:03 +02:00
Lauri Ojansivu 550d87ac6c Fix 8.16: Switching Board View fails with 403 error.
Thanks to xet7 !
2025-11-05 16:35:29 +02:00
Lauri Ojansivu f8e576e890 Try to fix Snap.
Thanks to xet7 !
2025-11-02 22:23:16 +02:00
Lauri Ojansivu fb8ef4d978 Try to fix Snap.
Thanks to xet7 !
2025-11-02 21:36:17 +02:00
Lauri Ojansivu 5127e87898 Try to fix Snap.
Thanks to xet7 !
2025-11-02 21:33:06 +02:00
Lauri Ojansivu 3f2d4444e4 Try to fix Snap. Part 2.
Thanks to xet7 !
2025-11-02 16:14:45 +02:00
Lauri Ojansivu 9c7badb0eb Merge branch 'main' of github.com:wekan/wekan 2025-11-02 16:04:16 +02:00
Lauri Ojansivu 9d9f77a731 Try to fix Snap.
Thanks to xet7 !
2025-11-02 16:02:53 +02:00
Lauri Ojansivu c400ce74b1 v8.16 2025-11-02 12:09:27 +02:00
Lauri Ojansivu c2e20ee4a3 Updated ChangeLog. 2025-11-02 11:43:33 +02:00
Lauri Ojansivu ccd9034339 Fix SECURITY ISSUE 5: Attachment API uses bearer value as userId and DoS (Low).
Thanks to Siam Thanat Hack (STH) and xet7 !
2025-11-02 11:42:07 +02:00
Lauri Ojansivu 0a1a075f31 Fix SECURITY ISSUE 4: Members can forge others’ votes (Low). Bonus: Similar fixes to planning poker too done by xet7.
Thanks to Siam Thanat Hack (STH) and xet7 !
2025-11-02 11:12:41 +02:00
Lauri Ojansivu 4aaeec9515 Updated ChangeLog. 2025-11-02 10:17:33 +02:00
Lauri Ojansivu ea310d7508 Fix SECURITY ISSUE 3: Unauthenticated (or any) user can update board sort.
Thanks to Siam Thanat Hack (STH) !
2025-11-02 10:13:45 +02:00
Lauri Ojansivu 0a2e6a0c38 Updated ChangeLog. 2025-11-02 09:20:28 +02:00
Lauri Ojansivu f26d582018 Fix SECURITY ISSUE 2: Access to boards of any Orgs/Teams, and avatar permissions.
Thanks to Siam Thanat Hack (STH) !
2025-11-02 09:11:50 +02:00
Lauri Ojansivu e9a727301d Fix SECURITY ISSUE 1: File Attachments enables stored XSS (High).
Thanks to Siam Thanat Hack (STH) !
2025-11-02 08:36:29 +02:00
Lauri Ojansivu d64d2f9c42 Updated translations. 2025-11-02 07:30:24 +02:00
Lauri Ojansivu 5c0d122e84 Updated funding 2025-11-02 06:15:08 +02:00
Lauri Ojansivu 5079c853a7 Updated translations. 2025-10-29 02:58:00 +02:00
Lauri Ojansivu b039ba12a2 Merge pull request #5984 from wekan/dependabot/github_actions/actions/download-artifact-6
Bump actions/download-artifact from 5 to 6
2025-10-28 06:00:19 +02:00
Lauri Ojansivu 3323ac6ac1 Merge pull request #5983 from wekan/dependabot/github_actions/actions/upload-artifact-5
Bump actions/upload-artifact from 4 to 5
2025-10-28 05:59:59 +02:00
dependabot[bot] 3204311ac1 Bump actions/download-artifact from 5 to 6
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 23:12:09 +00:00
dependabot[bot] 0fc2ad97cd Bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 20:32:10 +00:00
Lauri Ojansivu 30620d0ca4 Some migrations and mobile fixes.
Thanks to xet7 !
2025-10-25 21:09:07 +03:00
Lauri Ojansivu bccc22c5fe Updated ChangeLog. 2025-10-25 19:25:04 +03:00
Lauri Ojansivu ecf2418347 Fix changing swimlane color to not reload webpage.
Thanks to xet7 !
2025-10-25 19:23:35 +03:00
Lauri Ojansivu 0c99cb3103 Updated ChangeLog. 2025-10-25 19:19:35 +03:00
Lauri Ojansivu 034dc08269 Disabled migrations that happen when opening board. Defaulting to per-swimlane lists and drag drop list to same or different swimlane.
Thanks to xet7 !
2025-10-25 19:17:09 +03:00
Lauri Ojansivu d1a51b42f6 Updated translations. 2025-10-24 18:43:21 +03:00
Lauri Ojansivu 92bfbb2d0c Updated ChangeLog. 2025-10-23 05:54:25 +03:00
Lauri Ojansivu 91b846e2cd List menu / More / Delete duplicate lists that do not have any cards.
Thanks to xet7 !
2025-10-23 05:50:43 +03:00
Lauri Ojansivu 7fe7fb4c15 v8.15 2025-10-23 04:41:34 +03:00
Lauri Ojansivu 0cebd8aa4d Fix drag lists did not work. Part 2.
Thanks to xet7 !
2025-10-23 04:35:33 +03:00
Lauri Ojansivu 8662c96d1c Fix drag lists did not work.
Thanks to xet7 !
2025-10-23 04:33:34 +03:00
Lauri Ojansivu 0cbc9402f3 v8.14 2025-10-23 04:09:14 +03:00
Lauri Ojansivu 940df02456 Updated translations. 2025-10-23 04:08:49 +03:00
Lauri Ojansivu b4b598f542 Fix board reloading page every second.
Thanks to xet7 !
2025-10-23 04:03:52 +03:00
Lauri Ojansivu ef19c35b5a v8.12 2025-10-23 03:29:23 +03:00
Lauri Ojansivu fc98120269 Updated translations. 2025-10-23 03:24:28 +03:00
Lauri Ojansivu b8a3d6deaf Updated ChangeLog. 2025-10-23 03:17:13 +03:00
Lauri Ojansivu 45537ede87 Fix UI issues of Right Sidebar / Subtasks Settings and Card Settings.
Thanks to xet7 !

Fixes #5971
2025-10-23 03:15:26 +03:00
Lauri Ojansivu 29a9c5bc7b Updated ChangeLog. 2025-10-23 01:02:15 +03:00
Lauri Ojansivu 7ca81285b1 Fix opened card Date Format to be used at dates popups.
Thanks to xet7 !

Related #5971
2025-10-23 01:00:11 +03:00
Lauri Ojansivu 49a865cdbf Updated ChangeLog. 2025-10-23 00:48:31 +03:00
Lauri Ojansivu a0c30c35ed Removed not needed | at left side of minicard badges.
Thanks to xet7 !
2025-10-23 00:47:18 +03:00
Lauri Ojansivu de20424885 Updated translations. 2025-10-23 00:38:34 +03:00
Lauri Ojansivu f7e09ae89c Updated ChangeLog. 2025-10-23 00:36:17 +03:00
Lauri Ojansivu c6d4600683 Fix unable to add members to board.
Fixes #5972
2025-10-23 00:34:19 +03:00
Lauri Ojansivu bd1837ee36 Updated ChangeLog. 2025-10-23 00:16:27 +03:00
Lauri Ojansivu 544b24ceb1 Fix Regression - unable to rearrange tasks within a checklist - v8.11.
Thanks to xet7 !

Fixes #5973
2025-10-23 00:14:30 +03:00
Lauri Ojansivu 0825374183 Updated translations. 2025-10-22 23:56:23 +03:00
Lauri Ojansivu b053fb8e61 Updated ChangeLog. 2025-10-22 23:33:38 +03:00
Lauri Ojansivu ae11e80bde Fix Regression - unable to view cards by due date v8.11.
Thanks to xet7 !

Fixes #5964
2025-10-22 23:31:36 +03:00
Lauri Ojansivu 8e296231ba Updated translations. 2025-10-22 22:59:35 +03:00
Lauri Ojansivu 49891eff36 Updated ChangeLog. 2025-10-21 15:34:07 +03:00
Lauri Ojansivu 58df525b49 Fix duplicated lists and do not show debug messages when env DEBUG is not true. Part 3.
Thanks to xet7 !

Fixes #5952
2025-10-21 15:31:34 +03:00
Lauri Ojansivu 1761f43afa Merge newest changes. 2025-10-21 15:22:55 +03:00
Lauri Ojansivu 37d7d938c5 Updated ChangeLog. 2025-10-21 15:21:25 +03:00
Lauri Ojansivu b7ca2310b2 Fix duplicated lists.
Thanks to xet7 !

Fixes #5952
2025-10-21 15:19:19 +03:00
Lauri Ojansivu c562b3969a v8.11 2025-10-21 15:17:53 +03:00
Lauri Ojansivu d1d553e8d7 Updated ChangeLog. 2025-10-21 15:15:15 +03:00
Lauri Ojansivu b6e7b258e0 Fix duplicated lists.
Thanks to xet7 !

Fixes #5952
2025-10-21 15:14:01 +03:00
Lauri Ojansivu c7bbe47221 Updated ChangeLog. 2025-10-21 15:10:07 +03:00
Lauri Ojansivu 347fa9e5cd Fix Regression - due date taking a while to load all cards v8.06.
Thanks to xet7 !

Fixes #5955
2025-10-21 15:08:50 +03:00
Lauri Ojansivu 07ce151508 Updated ChangeLog. 2025-10-21 15:04:01 +03:00
Lauri Ojansivu 665c9b5e52 Verify that due background colors are correct also at My Due Cards.
Thanks to xet7 !
2025-10-21 15:02:39 +03:00
Lauri Ojansivu 9399a0c545 Updated ChangeLog. 2025-10-21 14:59:48 +03:00
Lauri Ojansivu a540b12895 Fix My Due Cards to be sorted by due date, oldest first.
Thanks to xet7 !

Fixes #5956
2025-10-21 14:57:57 +03:00
Lauri Ojansivu e29d9dcd17 Updated ChangeLog. 2025-10-21 14:49:59 +03:00
Lauri Ojansivu 1aa0d84977 Fix due dates to use colors: red = overdue, amber = due soon, no shade = not due yet.
Thanks to xet7 !

Fixes #5963
2025-10-21 14:47:57 +03:00
Lauri Ojansivu 7f31d7c812 v8.10 2025-10-21 14:15:16 +03:00
Lauri Ojansivu 4987a95d8e Prevent opened board re-migrating and reloading every 5 seconds.
Thanks to xet7 !
2025-10-21 14:12:12 +03:00
Lauri Ojansivu ef7771febb v8.09 2025-10-21 13:54:37 +03:00
Lauri Ojansivu 12cba0e148 Updated ChangeLog. 2025-10-21 13:36:43 +03:00
Lauri Ojansivu c3a4052227 Fix upgrade to 8.08 duplicates lists.
Thanks to xet7 !

Fixes #5962,
fixes #5952
2025-10-21 13:34:39 +03:00
Lauri Ojansivu 82f048ccef Updated ChangeLog. 2025-10-21 13:26:41 +03:00
Lauri Ojansivu 7a585a3dfb Fix Admin Panel / People editing and layout.
Thanks to xet7 !

Fixes #5961
2025-10-21 13:22:58 +03:00
Lauri Ojansivu 8d3b53f51d v8.08 2025-10-21 11:01:40 +03:00
Lauri Ojansivu d73e006935 Updated ChangeLog. 2025-10-21 10:48:45 +03:00
Lauri Ojansivu 9536e60bd1 Fix opening board migration of Shared Lists to Per-Swimlane lists to use ReactiveCache correctly without errors.
Thanks to xet7 !

Fixes #5960
2025-10-21 10:46:37 +03:00
Lauri Ojansivu 678ca978a3 Merge branch 'main' of github.com:wekan/wekan 2025-10-20 19:13:10 +03:00
Lauri Ojansivu 39420877fd Updated ChangeLog. 2025-10-20 19:12:07 +03:00
Lauri Ojansivu 6ea03cfba3 Revert moving mongodb raw database files.
Thanks to xet7 !
2025-10-20 18:08:52 +03:00
Lauri Ojansivu 9214b56aea v8.07 2025-10-20 17:43:18 +03:00
Lauri Ojansivu 699b4c464f Updated translations. 2025-10-20 17:30:42 +03:00
Lauri Ojansivu 9fa54a3148 Updated ChangeLog. 2025-10-20 17:29:29 +03:00
Lauri Ojansivu f2019b1059 If Snap Candidate MongoDB raw database files were at SNAP_COMMON/wekan, migrate them back to SNAP_COMMON.
Thanks to xet7 !
2025-10-20 17:26:53 +03:00
Lauri Ojansivu 714bbd0fb0 Updated ChangeLog. 2025-10-20 17:10:30 +03:00
Lauri Ojansivu 80777b4663 When opening board, add missing lists.
Thanks to xet7 !

Fixes #5926
2025-10-20 17:06:42 +03:00
Lauri Ojansivu 9473c1fe41 Updated ChangeLog. 2025-10-20 16:50:35 +03:00
Lauri Ojansivu 98f141d62f Fix Snap Candidate WeKan 8.00-8.06 commit ae01ea5 database directory from /var/snap/wekan/common/wekan back to 8.07 /var/snap/wekan/common.
Thanks to xet7 !
2025-10-20 16:42:28 +03:00
Lauri Ojansivu 85dd213b14 Updated translations. 2025-10-20 06:21:02 +03:00
Lauri Ojansivu 3cf00911f7 v8.06 2025-10-20 03:29:24 +03:00
Lauri Ojansivu bddaad8346 Updated ChangeLog. 2025-10-20 03:13:32 +03:00
Lauri Ojansivu 5df4efd7ba Have all iPhone use mobile view by default, while still having possibility to use mobile/desktop switch button for desktop mode.
Thanks to xet7 !
2025-10-20 03:11:02 +03:00
Lauri Ojansivu 59df6aad05 Updated ChangeLog. 2025-10-20 03:00:21 +03:00
Lauri Ojansivu c4af4d03ac Some mobile view fixes.
Thanks to xet7 !
2025-10-20 02:58:30 +03:00
Lauri Ojansivu 62679819d9 Updated ChangeLog. 2025-10-20 02:32:08 +03:00
Lauri Ojansivu 46d46e313c Fix Bug Member settings drops to the second line and overlaps when many boards are starred as favourites.
Thanks to xet7 !

Fixes #5943
2025-10-20 02:30:03 +03:00
Lauri Ojansivu 27e9d3ce47 Updated ChangeLog. 2025-10-20 01:59:21 +03:00
Lauri Ojansivu b6b0c5fe6d Fix Bug: Scale of Minicard icons is linked to horizontal screensize.
Thanks to xet7 !

Fixes #5947
2025-10-20 01:56:54 +03:00
Lauri Ojansivu 87b934a955 Updated translations. 2025-10-20 01:52:37 +03:00
Lauri Ojansivu 8cc6e9b812 Updated translations. 2025-10-20 01:45:00 +03:00
Lauri Ojansivu b7da17ff31 Updated ChangeLog. 2025-10-20 01:39:29 +03:00
Lauri Ojansivu 2dd3916f7e Added Date Format setting to Opened Card.
Thanks to xet7 !

Fixes #2011,
fixes #1176
2025-10-20 01:36:44 +03:00
Lauri Ojansivu 516552cce6 Updated ChangeLog. 2025-10-20 01:23:43 +03:00
Lauri Ojansivu 2d44881619 Fix card popup to use HTML date, not anymore JQuery date.
Thanks to xet7 !
2025-10-20 01:21:54 +03:00
Lauri Ojansivu 0acbf30b03 Fix migrations.
Thanks to xet7 !
2025-10-20 01:20:28 +03:00
Lauri Ojansivu e61f6b1c89 Updated ChangeLog. 2025-10-20 01:03:34 +03:00
Lauri Ojansivu 973a49526f Fix Broken Hyperlinks in Markdown to HTML conversion.
Thanks to xet7 !

Fixes #5932
2025-10-20 01:01:55 +03:00
Lauri Ojansivu e1902d58c1 Updated ChangeLog. 2025-10-20 00:35:33 +03:00
Lauri Ojansivu 1e53125499 Fix opened card attachments button text to be at tooltip, not at opened card.
Thanks to xet7 !
2025-10-20 00:33:02 +03:00
Lauri Ojansivu 91fb7d9e70 Updated ChangeLog. 2025-10-20 00:29:56 +03:00
Lauri Ojansivu eb6b42c4c9 Fix syntax error at migrations.
Thanks to xet7 !
2025-10-20 00:28:19 +03:00
Lauri Ojansivu 679d210667 Updated ChangeLog. 2025-10-20 00:24:46 +03:00
Lauri Ojansivu 1e6252de7f When opening board, migrate from Shared Lists to Per-Swimlane Lists.
Thanks to xet7 !

Fixes #5952
2025-10-20 00:22:26 +03:00
Lauri Ojansivu 48b645ee1e Updated ChangeLog. 2025-10-19 23:48:15 +03:00
Lauri Ojansivu 951d2e4937 Legacy Lists button at one board view to restore missing lists/cards.
Thanks to xet7 !

Fixes #5952
2025-10-19 23:40:02 +03:00
Lauri Ojansivu 1658883b78 Updated ChangeLog. 2025-10-19 23:19:54 +03:00
Lauri Ojansivu 3514335247 At Public Board, drag resize list width and swimlane height. For logged in users, fix adding labels.
Thanks to xet7 !

Fixes #5922
2025-10-19 23:15:55 +03:00
Lauri Ojansivu 55bec31a3f Fix drag drop lists. Part 2.
Thanks to xet7 !

Fixes #5951
2025-10-19 22:22:21 +03:00
Lauri Ojansivu 0d36abee4e Updated ChangeLog. 2025-10-19 21:47:51 +03:00
Lauri Ojansivu caa6e615ff Removed extra pipe characters.
Thanks to xet7 !
2025-10-19 21:46:14 +03:00
Lauri Ojansivu cd3576b995 Updated ChangeLog. 2025-10-19 21:41:44 +03:00
Lauri Ojansivu 324f3f7794 Fix drag drop lists. Part 1.
Thanks to xet7 !

Related #5951
2025-10-19 21:38:55 +03:00
Lauri Ojansivu 3257110673 Updated ChangeLog. 2025-10-19 20:07:39 +03:00
Lauri Ojansivu 66b444e2b0 Fix unable to see My Due Cards.
Thanks to xet7 !

Fixes #5948
2025-10-19 20:05:36 +03:00
Lauri Ojansivu 23860b1ee8 Updated ChangeLog. 2025-10-19 18:58:36 +03:00
Lauri Ojansivu 101048339b Fix Due dates to be color coded and have icons. Part 2.
Thanks to xet7 !

Fixes #5950
2025-10-19 18:55:44 +03:00
Lauri Ojansivu dc78e3b7a0 Updated ChangeLog. 2025-10-19 18:45:32 +03:00
Lauri Ojansivu d965faa317 Fix Due dates to be color coded and have icons.
Thanks to xet7 !

Fixes #5950
2025-10-19 18:42:37 +03:00
Lauri Ojansivu 5d2bfab0f5 Updated ChangeLog. 2025-10-19 18:12:25 +03:00
Lauri Ojansivu 841a6eaf8c Merge branch 'helioguardabaxo-master' 2025-10-19 18:11:05 +03:00
Lauri Ojansivu db59bb4aa4 Merge branch 'master' of github.com:helioguardabaxo/wekan into helioguardabaxo-master 2025-10-19 18:01:30 +03:00
helioguardabaxo 61f7099106 Fix stared, archive and clone icons 2025-10-19 09:24:18 -03:00
Lauri Ojansivu ef828bdd38 Updated translations. 2025-10-19 14:19:51 +03:00
Lauri Ojansivu 1134b45b05 Updated ChangeLog. 2025-10-19 11:07:49 +03:00
Lauri Ojansivu b06daff4c7 Fix add and drag drop attachments to minicards and card.
Thanks to xet7 !

Fixes #5946,
fixes #5436,
fixes #2936,
fixes #1926,
fixes #300,
fixes #142
2025-10-19 10:57:36 +03:00
Lauri Ojansivu cea414b589 Updated translations. 2025-10-17 21:55:49 +03:00
Lauri Ojansivu b8942b728f v8.05 2025-10-17 17:53:00 +03:00
Lauri Ojansivu 8e6eabd9e8 Updated transations. 2025-10-17 17:38:54 +03:00
Lauri Ojansivu 290dd6c4d1 Updated ChangeLog. 2025-10-17 07:56:49 +03:00
Lauri Ojansivu 088bc16072 Font Awesome to Unicode icons. Part 4.
Thanks to xet7 !
2025-10-17 07:55:04 +03:00
Lauri Ojansivu daad2fbd71 Updated ChangeLog. 2025-10-17 07:10:07 +03:00
Lauri Ojansivu 3af94c2a90 Font Awesome to Unicode icons. Part 3.
Thanks to xet7 !
2025-10-17 07:08:01 +03:00
Lauri Ojansivu a3ca76d3c4 Updated ChangeLog. 2025-10-17 06:09:42 +03:00
Lauri Ojansivu 62ede48196 Removed not needed visible text from mobile desktop switch button.
Thanks to xet7 !
2025-10-17 06:07:24 +03:00
Lauri Ojansivu 390a86a7a7 Updated ChangeLog. 2025-10-17 06:02:46 +03:00
Lauri Ojansivu 09631d6b0c Resize height of swimlane by dragging. Font Awesome to Unicode icons.
Thanks to xet7 !
2025-10-17 05:58:53 +03:00
Lauri Ojansivu 2947238a02 Convert Font Awesome to Unicode Icons. Part 1. In Progress.
Thanks to xet7 !
2025-10-17 02:19:43 +03:00
Lauri Ojansivu a7af4b4809 Updated ChangeLog. 2025-10-17 00:27:30 +03:00
Lauri Ojansivu cb6afe67a7 Replaced moment.js with Javascript date.
Thanks to xet7 !
2025-10-17 00:26:11 +03:00
Lauri Ojansivu 8c5b43295d Updated ChangeLog. 2025-10-16 23:21:47 +03:00
Lauri Ojansivu 79b94824ef Changed wekan-boostrap-datepicker to HTML datepicker.
Thanks to xet7 !
2025-10-16 23:19:26 +03:00
Lauri Ojansivu 33e4b046e8 Updated ChangeLog. 2025-10-16 22:25:20 +03:00
Lauri Ojansivu 386aea7c78 Popup fixes. Part 2.
Thanks to xet7 !
2025-10-16 22:24:11 +03:00
Lauri Ojansivu 4a7bccd983 Updated ChangeLog. 2025-10-16 21:46:35 +03:00
Lauri Ojansivu 1f0cae9e76 Updated ChangeLog. 2025-10-16 21:42:41 +03:00
Lauri Ojansivu 87ae085e6d Fix Edit avatar UI issue.
Thanks to xet7 !

Fixes #5940
2025-10-16 21:40:49 +03:00
Lauri Ojansivu 640ac2330f Updated ChangeLog. 2025-10-16 20:24:46 +03:00
Lauri Ojansivu 2543df9425 Show original positions of swimlanes, lists and cards.
Thanks to xet7 !

Fixes #5939
2025-10-16 20:23:05 +03:00
Lauri Ojansivu 915ab47a72 v8.04 2025-10-16 17:59:24 +03:00
Lauri Ojansivu 09ff287da2 Updated translations. 2025-10-16 17:52:03 +03:00
Lauri Ojansivu 2896180f80 Updated ChangeLog. 2025-10-16 17:50:52 +03:00
Lauri Ojansivu 4283b5b0e3 Disable not working minio and s3 support temporarily.
Thanks to xet7 !
2025-10-16 17:49:39 +03:00
Lauri Ojansivu bbbd3abf06 Try to fix Broken Hyperlinks in Markdown to HTML conversion.
Thanks to xet7 !

Fixes #5932
2025-10-16 17:47:59 +03:00
Lauri Ojansivu dd88483ec7 Removed extra npm packages.
Thanks to xet7 !
2025-10-15 23:26:33 +03:00
Lauri Ojansivu 00ddec7575 Fix popups positioning. Part 2.
Thanks to xet7 !
2025-10-15 23:19:07 +03:00
Lauri Ojansivu ab0ebab240 Updated ChangeLog. 2025-10-15 07:57:18 +03:00
Lauri Ojansivu 79e83e33ec Use only MongoDB 7 at Snap.
Thanks to xet7 !
2025-10-15 07:56:11 +03:00
Lauri Ojansivu aa402d652d Updated ChangeLog. 2025-10-15 07:49:05 +03:00
Lauri Ojansivu 690481c138 Remove using fork with MongoDB at Snap.
Thanks to xet7 !
2025-10-15 07:47:57 +03:00
Lauri Ojansivu 881125aa98 Updated ChangeLog. 2025-10-15 07:46:54 +03:00
Lauri Ojansivu 77eea4d494 Fix popups positioning.
Thanks to xet7 !

Fixes #5924
2025-10-15 07:44:46 +03:00
Lauri Ojansivu b26e16abb8 Updated ChangeLog. 2025-10-15 07:39:18 +03:00
Lauri Ojansivu f08c7702ee Fix wide screen.
Thanks to xet7 !

Fixes #5915
2025-10-15 07:38:14 +03:00
Lauri Ojansivu a4399c7ef4 Updated translations. 2025-10-15 07:25:33 +03:00
Lauri Ojansivu d6e50ed9a0 Updated ChangeLog. 2025-10-15 07:21:15 +03:00
Lauri Ojansivu 6b848b318d Make sure that all cards are visible.
Thanks to xet7 !

Related #5915
2025-10-15 07:15:46 +03:00
Lauri Ojansivu 70ce70cf0e Try to fix Snap to not fork mongodb.
Thanks to xet7 !
2025-10-14 14:29:42 +03:00
Lauri Ojansivu 5a79bc5ee3 v8.03 2025-10-14 13:51:47 +03:00
Lauri Ojansivu 5792a86959 Fix Snap MongoDB to not fork at systemd, so it stays running.
Thanks to xet7 !
2025-10-14 13:45:51 +03:00
Lauri Ojansivu 37c5436087 v8.02 2025-10-14 11:58:14 +03:00
Lauri Ojansivu 6592102e8f v8.02 2025-10-14 11:56:11 +03:00
Lauri Ojansivu 06a5a8f70d Try to fix Docker secrets to be optional.
Thanks to xet7 !

Fixes #5920
2025-10-14 11:54:09 +03:00
Lauri Ojansivu ef54ebada6 Updated ChangeLog. 2025-10-14 11:25:36 +03:00
Lauri Ojansivu d4f13de1d9 Try to fix swimlane hamburger menu popup positioning. In progress.
Thanks to xet7 !
2025-10-14 11:24:22 +03:00
Lauri Ojansivu 4fcedde529 Updated ChangeLog. 2025-10-14 11:04:40 +03:00
Lauri Ojansivu a4518bbefc Fix drag drop reorder swimlanes.
Thanks to xet7 !
2025-10-14 11:03:36 +03:00
Lauri Ojansivu 95f771aa26 Updated ChangeLog. 2025-10-14 10:47:00 +03:00
Lauri Ojansivu da98942cce Updated mobile Bookmarks/Starred boards. Part 1. In Progress.
Thanks to xet7 !
2025-10-14 10:43:39 +03:00
Lauri Ojansivu f3efaf59e1 Updated translations. 2025-10-14 09:39:19 +03:00
Lauri Ojansivu d64032f2a3 Updated ChangeLog. 2025-10-14 09:37:49 +03:00
Lauri Ojansivu abad8cc4d5 Change list width by dragging between lists.
Thanks to xet7 !
2025-10-14 09:36:11 +03:00
Lauri Ojansivu 0d9536e2f9 Updated ChangeLog. 2025-10-14 08:26:46 +03:00
Lauri Ojansivu 67b078b805 Accessibility improvements.
Thanks to xet7 !
2025-10-14 08:25:39 +03:00
Lauri Ojansivu 6f02eeae53 Updated ChangeLog. 2025-10-14 07:24:46 +03:00
Lauri Ojansivu 5bc03b23ea Updated dependencies.
Thanks to developers of dependencies !
2025-10-14 07:23:13 +03:00
Lauri Ojansivu 3d4acd8c8f Updated translations. 2025-10-14 07:21:41 +03:00
Lauri Ojansivu 448bec8181 Updated ChangeLog. 2025-10-14 01:54:28 +03:00
Lauri Ojansivu 0a34ee1b64 Removed not needed console log message.
Thanks to xet7 !
2025-10-14 01:52:58 +03:00
Lauri Ojansivu 34e8e4d4c3 Updated translations. 2025-10-14 01:38:38 +03:00
Lauri Ojansivu 32627c03f4 Updated ChangeLog. 2025-10-14 01:32:43 +03:00
Lauri Ojansivu 63c314ca18 Fixed migrations.
Thanks to xet7 !
2025-10-14 01:30:59 +03:00
Lauri Ojansivu e8453783da Updated translations. 2025-10-13 23:48:30 +03:00
Lauri Ojansivu 96522ec3a3 Updated translations. 2025-10-13 23:38:17 +03:00
Lauri Ojansivu 17dedab391 Updated translations. 2025-10-13 23:37:02 +03:00
Lauri Ojansivu 283d2ee09c Updated translations. 2025-10-13 23:33:27 +03:00
Lauri Ojansivu 289ff0127e Updated translations. 2025-10-13 23:23:32 +03:00
Lauri Ojansivu 931d7217b1 Updated translations. 2025-10-13 23:04:24 +03:00
Lauri Ojansivu 3149a3927e Updated translations. 2025-10-13 22:25:41 +03:00
Lauri Ojansivu c57bced7b1 Updated translations. 2025-10-13 22:21:23 +03:00
Lauri Ojansivu 8d794a59dc Updated ChangeLog. 2025-10-13 22:19:56 +03:00
Lauri Ojansivu 7bb1e24bda Fixed Admin Panel Settings menus Attachments and Cron.
Thanks to xet7 !
2025-10-13 22:17:32 +03:00
Lauri Ojansivu e0013b9b63 Fix Admin Panel Settings menu to show options correctly. Part 1.
Thanks to xet7 !
2025-10-13 20:51:29 +03:00
Lauri Ojansivu 7d81aab900 Updated ChangeLog. 2025-10-13 20:35:49 +03:00
Lauri Ojansivu cc99da5357 Fixed Error in migrate-lists-to-per-swimlane migration.
Thanks to xet7 !

Fixes #5918
2025-10-13 20:34:23 +03:00
Lauri Ojansivu 9bd21e1d1b Updated ChangeLog. 2025-10-12 05:38:08 +03:00
Lauri Ojansivu 2148aeea42 Change Admin Panel "Attachment Settings" and "Cron Settings" options to be tabs, not submenu. Part 3.
Thanks to xet7 !
2025-10-12 05:36:51 +03:00
Lauri Ojansivu 6a7a5505f9 Updated ChangeLog. 2025-10-12 05:26:46 +03:00
Lauri Ojansivu 5a6faafa30 Change Admin Panel "Attachment Settings" and "Cron Settings" options to be tabs, not submenu. Part 2.
Thanks to xet7 !
2025-10-12 05:25:44 +03:00
Lauri Ojansivu e2f3dad779 Updated ChangeLog. 2025-10-12 04:52:45 +03:00
Lauri Ojansivu ae2aa1f5cd Change Admin Panel "Attachment Settings" and "Cron Settings" options to be tabs, not submenu.
Thanks to xet7 !
2025-10-12 04:50:17 +03:00
Lauri Ojansivu 0e3a17d922 Updated ChangeLog. 2025-10-12 04:40:27 +03:00
Lauri Ojansivu 033919a270 Fix Admin Panel menus "Attachment Settings" and "Cron Settings" and make them translateable.
Thanks to xet7 !
2025-10-12 04:39:04 +03:00
Lauri Ojansivu f5d40a0a12 Updated ChangeLog. 2025-10-12 04:22:35 +03:00
Lauri Ojansivu 0fd781e80a Fix opening sidebar.
Thanks to xet7 !
2025-10-12 04:21:38 +03:00
Lauri Ojansivu a8f6170fdf Updated ChangeLog. 2025-10-12 03:49:52 +03:00
Lauri Ojansivu bd8c565415 Fixes to make board showing correctly.
Thanks to xet7 !
2025-10-12 03:48:21 +03:00
Lauri Ojansivu ffb02fe0ec Updated translations. 2025-10-11 20:39:08 +03:00
Lauri Ojansivu 114520302c Updated ChangeLog. 2025-10-11 20:35:58 +03:00
Lauri Ojansivu 317138ab72 If there is no cron jobs running, run migrations for boards that have not been opened yet.
Thanks to xet7 !
2025-10-11 20:33:31 +03:00
Lauri Ojansivu a990109f43 Updated ChangeLog. 2025-10-11 19:43:20 +03:00
Lauri Ojansivu da68b01502 Added Cron Manager to Admin Panel for long running jobs, like running migrations when opening board, copying or moving boards swimlanes lists cards etc.
Thanks to xet7 !
2025-10-11 19:41:09 +03:00
Lauri Ojansivu e90bc744d9 Updated ChangeLog. 2025-10-11 19:26:07 +03:00
Lauri Ojansivu 2b5c56484a Run database migrations when opening board. Not when updating WeKan.
Thanks to xet7 !
2025-10-11 19:23:47 +03:00
Lauri Ojansivu ea30612013 v8.01 2025-10-11 12:32:38 +03:00
Lauri Ojansivu 4445612bb8 Updated translations. 2025-10-11 12:30:09 +03:00
Lauri Ojansivu da56393078 Updated ChangeLog. 2025-10-11 12:15:25 +03:00
Lauri Ojansivu a86ff1e8d0 Fixed attachments and minicard related bugs that prevented WeKan starting.
Thanks to xet7 !
2025-10-11 12:13:11 +03:00
Lauri Ojansivu 7fce5650b8 Updated ChangeLog. 2025-10-11 11:55:41 +03:00
Lauri Ojansivu b949357e66 Snap MongoDB Server 3-8 support. Part 1.
Thanks to xet7 !
2025-10-11 11:54:14 +03:00
Lauri Ojansivu 8e71b68dbf Updated ChangeLog. 2025-10-11 11:39:39 +03:00
Lauri Ojansivu b77eed221f Fix count of Orgs Teams People at Admin Panel.
Thanks to xet7 !
2025-10-11 11:38:28 +03:00
Lauri Ojansivu 1fa91474d0 Updated ChangeLog. 2025-10-11 11:34:45 +03:00
Lauri Ojansivu fc32a89292 Fixed per-card and per-board settings of showing checkist at minicard.
Thanks to xet7 !
2025-10-11 11:31:57 +03:00
Lauri Ojansivu ea24010298 Updated ChangeLog. 2025-10-11 11:08:27 +03:00
Lauri Ojansivu ae1f80a52c Added attachments API and admin panel attachment management for file storage backends settings. Fixed drag drop upload attachments from file manager to minicard or opened card.
Thanks to xet7 !
2025-10-11 11:05:46 +03:00
Lauri Ojansivu 2f95431c9b Updated ChangeLog. 2025-10-11 10:50:05 +03:00
Lauri Ojansivu d59683eff1 Fixed attachments migrations at Admin Panel to not use too much CPU while migrating attachments.
Thanks to xet7 !
2025-10-11 10:48:12 +03:00
Lauri Ojansivu de77776cd0 Updated ChangeLog. 2025-10-11 10:33:52 +03:00
Lauri Ojansivu 74ccfea570 Add support for MongoDB 3-8, detecting which one is in use.
Thanks to xet7 !
2025-10-11 10:32:20 +03:00
Lauri Ojansivu 1f5a549589 Updated ChangeLog. 2025-10-11 10:17:41 +03:00
Lauri Ojansivu 3ccdc2e307 Made possible to start WeKan immediately without running any database migrations.
Thanks to xet7 !
2025-10-11 10:15:08 +03:00
Lauri Ojansivu 688b725807 v8.00 2025-10-11 07:50:28 +03:00
Lauri Ojansivu ae01ea576c Snap: Migrate MongoDB from 3 to 7 only when "snap set wekan migrate-mongodb='true'". Not automatically.
Thanks to xet7 !
2025-10-11 07:42:51 +03:00
Lauri Ojansivu cd0cd64849 v7.99 2025-10-11 06:13:27 +03:00
Lauri Ojansivu aab671398c Improve automatic Snap upgrades.
Thanks to xet7 !
2025-10-11 05:52:41 +03:00
Lauri Ojansivu d64aeb25d5 Updated ChangeLog. 2025-10-11 04:57:24 +03:00
Lauri Ojansivu aa4fa83127 Updated ChangeLog. 2025-10-11 04:50:23 +03:00
Lauri Ojansivu 81c3dc1d95 Security Fix JVN#15385465: CWE-79 XSS, that affected WeKan 7.94.
Thanks to Sho Sugiyama and xet7 !
2025-10-11 04:47:17 +03:00
Lauri Ojansivu 746eecf3d8 Updated ChangeLog. 2025-10-11 04:25:26 +03:00
Lauri Ojansivu cd948fb576 Added missing metadata fields to snapcraft.yaml .
Thanks to xet7 !
2025-10-11 04:20:28 +03:00
Lauri Ojansivu 4ec4e19e63 Try to fix Snap automatic upgrade.
Thanks to xet7 !
2025-10-11 04:02:02 +03:00
Lauri Ojansivu d88d197de9 Updated release scripts of snapcraft pack command syntax.
Thanks to xet7 !
2025-10-11 03:11:32 +03:00
Lauri Ojansivu 2a24918a9c Snap: Removed double mongo3 that's already at migratemongo.
Thanks to xet7 !
2025-10-11 03:09:33 +03:00
Lauri Ojansivu d2a85b41e4 v7.98 2025-10-11 02:07:44 +03:00
Lauri Ojansivu 9bcd991a61 Updated ChangeLog. 2025-10-11 02:02:10 +03:00
Lauri Ojansivu 1a7bd65e59 Fixed showing translations always, regardsless of is ROOT_URL set correctly or not.
Thanks to xet7 !
2025-10-11 01:57:08 +03:00
Lauri Ojansivu f8ee929cf7 Updated ChangeLog. 2025-10-11 01:46:01 +03:00
Lauri Ojansivu 734165f3c7 Fix sizes of drag handles at desktop mode.
Thanks to xet7 !
2025-10-11 01:44:38 +03:00
Lauri Ojansivu 8f9ef1bde8 Updated ChangeLog. 2025-10-11 01:24:31 +03:00
Lauri Ojansivu 2119c6ab0c Fix DOMPurify paths. Part 4.
Thanks to xet7 !
2025-10-11 01:23:18 +03:00
Lauri Ojansivu a85479f73c Updated ChangeLog. 2025-10-11 01:09:58 +03:00
Lauri Ojansivu 21ba0a9606 Fix DOMPurify paths. Part 3.
Thanks to xet7 !
2025-10-11 01:08:39 +03:00
Lauri Ojansivu 82ba0f9593 Updated ChangeLog. 2025-10-11 01:03:22 +03:00
Lauri Ojansivu 7769124401 Fix DOMPurify paths. Part 2.
Thanks to xet7 !
2025-10-11 00:58:00 +03:00
Lauri Ojansivu d9c978e7fc Merge branch 'main' of github.com:wekan/wekan 2025-10-11 00:50:14 +03:00
Lauri Ojansivu 90899f0928 Fix DOMPurify paths.
Thanks to xet7 !
2025-10-11 00:49:43 +03:00
Lauri Ojansivu f0421da517 Updated translations. 2025-10-11 00:41:06 +03:00
Lauri Ojansivu 573d4bf2cb Updated ChangeLog. 2025-10-11 00:31:46 +03:00
Lauri Ojansivu f1e1fd3593 Add Snap automatic upgrades. Part 2.
Thanks to xet7 !
2025-10-11 00:29:46 +03:00
Lauri Ojansivu c387c5bc34 Updated ChangeLog. 2025-10-11 00:27:04 +03:00
Lauri Ojansivu 0549bc0b0c Add Snap automatic upgrades.
Thanks to xet7 !
2025-10-11 00:25:16 +03:00
Lauri Ojansivu c2a3e11324 Updated ChangeLog. 2025-10-10 23:50:49 +03:00
Lauri Ojansivu 107e2ac900 Add support for Docker/Compose Secrets for passwords to Docker/Snap/Bundle platforms.
Thanks to Roemer and xet7 !

Fixes #5724
2025-10-10 23:46:48 +03:00
Lauri Ojansivu 3b60bdea14 Updated ChangeLog. 2025-10-10 23:22:59 +03:00
Lauri Ojansivu f6591d7820 Security Fix usd-2022-0041: CWE-284 Improper Access Control.
Thanks to Christian Pöschl of usd AG and xet7 !
2025-10-10 23:19:58 +03:00
Lauri Ojansivu 6bbd622066 Updated ChangeLog. 2025-10-10 23:16:26 +03:00
Lauri Ojansivu ee79cab7b2 Security Fix JVN#86586539: Stored XSS.
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7.
2025-10-10 23:14:06 +03:00
Lauri Ojansivu a0b94065c5 Updated ChangeLog. 2025-10-10 23:09:28 +03:00
Lauri Ojansivu e1fa607f87 Security Fix JVN#74210258: Stored XSS.
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7 !
2025-10-10 23:06:06 +03:00
Lauri Ojansivu 2e91a359f5 Updated ChangeLog. 2025-10-10 23:02:37 +03:00
Lauri Ojansivu 9720e703fd Security Fix JVN#14269684: Broken access control.
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7 !
2025-10-10 22:59:20 +03:00
Lauri Ojansivu f88898d5b8 Updated ChangeLog. 2025-10-10 22:22:43 +03:00
Lauri Ojansivu 30c1597b65 Security Fix FG-VD-22-078: Prevent SVG Billion Laughs Attack.
Thanks to Nguyen Thanh Nguyen of Fortinet's FortiGuard Labs and xet7 !
2025-10-10 22:16:47 +03:00
Lauri Ojansivu 5bc5171220 Updated ChangeLog. 2025-10-10 22:12:25 +03:00
Lauri Ojansivu d0f118e7af Security Fix: Computational Resource Abuse in Export endpoints.
Thanks to Anynymous Security Researcher and xet7 !
2025-10-10 22:09:27 +03:00
Lauri Ojansivu c481443667 Updated ChangeLog. 2025-10-10 22:04:30 +03:00
Lauri Ojansivu b87cff1289 Security Fix: IDOR CWE-639 that affected WeKan 7.80-7.93.
Thanks to apitech.fr and xet7 !
2025-10-10 21:59:04 +03:00
Lauri Ojansivu 0c080830bc Updated ChangeLog. 2025-10-10 21:48:27 +03:00
Lauri Ojansivu cdd7d69c66 Drag any files from file manager to minicard or opened card. Part 2.
Thanks to xet7 !

Fixes #2936
2025-10-10 21:46:07 +03:00
Lauri Ojansivu c1cbcdcc72 Updated ChangeLog. 2025-10-10 21:21:12 +03:00
Lauri Ojansivu 1c84b19f24 Show console.log 'Legacy attachments route loaded' only when environment variable DEBUG=true.
Thanks to xet7 !
2025-10-10 21:19:00 +03:00
Lauri Ojansivu 2c73dae019 Merge branch 'main' of github.com:wekan/wekan 2025-10-10 21:16:29 +03:00
Lauri Ojansivu d285850a04 Updated ChangeLog. 2025-10-10 21:15:55 +03:00
Lauri Ojansivu 719ef87efc Make possible for lists to have different names at different swimlanes. Make possible to drag list from one swimlane to another swimlane.
Thanks to xet7 !
2025-10-10 21:14:44 +03:00
Lauri Ojansivu 039b9abf5e Updated translations 2025-10-10 20:37:22 +03:00
Lauri Ojansivu 39daf56811 Updated ChangeLog. 2025-10-10 19:12:09 +03:00
Lauri Ojansivu a8de2f224f Use attachments from old CollectionFS database structure, when not yet migrated to Meteor-Files/ostrio-files, without needing to migrate database structure.
Thanks to xet7 !
2025-10-10 19:07:04 +03:00
Lauri Ojansivu dda013844c Updated ChangeLog. 2025-10-10 18:55:13 +03:00
Lauri Ojansivu 3e9481c5bd Drag any files from file manager to minicard or opened card.
Thanks to xet7 !

Fixes #2936
2025-10-10 18:52:30 +03:00
Lauri Ojansivu 85ac03a892 Updated ChangeLog. 2025-10-09 05:54:04 +03:00
Lauri Ojansivu 752699d1c2 Mobile one board per row. Board zoom size percent. Board toggle mobile/desktop mode. In Progress.
Thanks to xet7 !

Related #5902
2025-10-09 05:48:41 +03:00
Lauri Ojansivu 339ca581ab Merge branch 'main' of github.com:wekan/wekan 2025-10-09 02:07:00 +03:00
Lauri Ojansivu 20e9cf1144 Text and icons from fixed sizes to scaleable sizes. Thanks to xet7. 2025-10-09 02:06:26 +03:00
Lauri Ojansivu 9737884c4b Text and icon from fixed sized to scaleable sizes. Thanks to xet7. 2025-10-09 02:06:16 +03:00
Lauri Ojansivu 2f5670e830 v7.97 2025-10-08 23:57:08 +03:00
Lauri Ojansivu 108b18cebf Updated ChangeLog. 2025-10-08 23:48:26 +03:00
Lauri Ojansivu 814ac22a0d Updated ChangeLog. 2025-10-08 23:43:55 +03:00
Lauri Ojansivu 3814a218c2 Removed white box that appeared when clicking something.
Thanks to xet7 !

Fixes #5899
2025-10-08 23:38:44 +03:00
Lauri Ojansivu 3fda90612d Some mobile fixes.
Thanks to xet7 !

Fixes #5899
2025-10-08 23:32:13 +03:00
Lauri Ojansivu 05762aa50c Updated ChangeLog. 2025-10-08 09:37:51 +03:00
Lauri Ojansivu 9a31371de0 Fixed translation of "Change Language" at login page.
Thanks to xet7 !
2025-10-08 09:36:39 +03:00
Lauri Ojansivu b9b7143185 Updated ChangeLog. 2025-10-08 09:21:26 +03:00
Lauri Ojansivu 972721bdb5 Merge branch 'seve12-main' 2025-10-08 09:17:53 +03:00
Lauri Ojansivu 3a48982916 v7.96 2025-10-08 08:44:09 +03:00
Lauri Ojansivu 6b3a6f9f7d Updated ChangeLog. 2025-10-08 08:44:09 +03:00
Lauri Ojansivu 48fddecb62 Updated to MongoDB 7.0.25 at Snap Candidate.
Thanks to MongoDB developers !
2025-10-08 08:44:09 +03:00
Lauri Ojansivu 7f0d1cc5b3 Updated ChangeLog. 2025-10-08 08:44:09 +03:00
Lauri Ojansivu 70e82be0b4 Hide extra keyboard shortcuts toggle. Thanks to xet7. 2025-10-08 08:44:09 +03:00
Lauri Ojansivu 5fc0809844 Updated ChangeLog. 2025-10-08 08:44:09 +03:00
Lauri Ojansivu c79990bcd9 Added missing screenshots from wekan.github.io history to wekan/docs/Features/ . Thanks to xet7 2025-10-08 08:44:09 +03:00
dependabot[bot] cd9e7412ea Bump docker/login-action from 3.5.0 to 3.6.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/184bdaa0721073962dff0199f1fb9940f07167d1...5e57cd118135c172c3672efd75eb46360885c0ef)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-08 08:44:09 +03:00
Lauri Ojansivu 3e472606b5 Fixed links at docs. Thanks to xet7 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 2966bc3204 Updated translations 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 5dc6093eec Updated email address 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 86fc60f5ba Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 8189a3f9ab Fixed find.sh script errors about unmatched single quotes and binary files that are now ignored.
Thanks to xet7 !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu 76a65e2533 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Jean-Sébastien Guay ad2914934e Fix links in docker-compose.yml to point to doc in repo 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 2769ba2874 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 294f1e178e Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu c994d34bb8 Updated to MongoDB 7.0.24 at Snap Candidate.
Thanks to MongoDB developers !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu 42b5dd0751 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu f884d6d471 Added missing mobile drag drop image to docs from wekan.github.io git history.
Thanks to xet7 !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu abe915a8d6 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu a2e8de2fd8 Updated release script for new command of uploading snap package to Snap Store.
Thanks to xet7 !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu e34ca6a8a5 v7.95 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 596c9de603 Updated translations 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 4170361a1c Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 978a36ea77 Updated dependencies.
Thanks to developers of dependencies !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu 8745ef7de8 Reorganized docs 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 2ce929b7b3 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 2dcdfa2862 Added PGP public key for sending encrypted email.
Thanks to xet7 !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu b18daac9c9 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
sowwos 606041a00d docs(windows): clarify WRITABLE_PATH/attachments + LAN bind instructions (nits) 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 4ed5952a81 Updates 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 37bfce2eb7 Added missing image to WeKan Multiverse page.
Thanks to xet7 !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu 59541699ce Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu af73c16e37 More info about ToroDB, FerretDB, Turso, TigerBeetle, PostgreSQL, SQLite etc.
Thanks to xet7 !
2025-10-08 08:44:07 +03:00
Lauri Ojansivu 673b09b84b Updated ChangeLog. 2025-10-08 08:44:07 +03:00
Lauri Ojansivu 09f8edfead Fixed image link at docs.
Thanks to xet7 !
2025-10-08 08:44:07 +03:00
Lauri Ojansivu e1ebdeca4f Updated ChangeLog. 2025-10-08 08:44:07 +03:00
Lauri Ojansivu 31769aa4af Updated upgrade link.
Thanks to xet7 !
2025-10-08 08:44:07 +03:00
seve12 b32ad86ce7 fixed issue 5887 2025-10-07 22:23:19 +03:00
Lauri Ojansivu 7350473a65 v7.96 2025-10-07 01:14:42 +03:00
Lauri Ojansivu 1c87e337d6 Updated ChangeLog. 2025-10-07 01:06:21 +03:00
Lauri Ojansivu dec038e7ed Updated to MongoDB 7.0.25 at Snap Candidate.
Thanks to MongoDB developers !
2025-10-07 01:05:01 +03:00
Lauri Ojansivu ebe6f7813e Updated ChangeLog. 2025-10-07 00:45:05 +03:00
Lauri Ojansivu 706dbfacac Merge branch 'seve12-main' 2025-10-07 00:36:50 +03:00
Lauri Ojansivu 62ad588aa9 Hide extra keyboard shortcuts toggle. Thanks to xet7. 2025-10-07 00:35:17 +03:00
Lauri Ojansivu 3c776e2ab6 Merge branch 'main' of github.com:seve12/wekan into seve12-main 2025-10-07 00:19:46 +03:00
seve12 ab4e2d1ed6 fixed issue #5885 2025-10-06 16:34:49 +03:00
Lauri Ojansivu 5e90c4a142 Updated ChangeLog. 2025-10-02 20:15:35 +03:00
Lauri Ojansivu 9a7fa25ca3 Added missing screenshots from wekan.github.io history to wekan/docs/Features/ . Thanks to xet7 2025-10-02 20:05:38 +03:00
Lauri Ojansivu 65cb0641f3 Merge branch 'main' of github.com:wekan/wekan 2025-10-02 19:57:56 +03:00
Lauri Ojansivu 6f2b891214 Fixed links at docs. Thanks to xet7 2025-10-02 19:57:28 +03:00
Lauri Ojansivu 44d7ab83ec Merge pull request #5890 from wekan/dependabot/github_actions/docker/login-action-3.6.0
Bump docker/login-action from 3.5.0 to 3.6.0
2025-10-02 00:06:19 +03:00
dependabot[bot] b328cc3f6a Bump docker/login-action from 3.5.0 to 3.6.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/184bdaa0721073962dff0199f1fb9940f07167d1...5e57cd118135c172c3672efd75eb46360885c0ef)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-29 23:33:41 +00:00
seve12 836226a8d3 RICHER_CARD_COMMENT_EDITOR=true has no effect (no rich text toolbar shown) fixed! 2025-09-29 15:56:23 +03:00
Lauri Ojansivu 2083f6630a Updated translations 2025-09-28 00:42:45 +03:00
Lauri Ojansivu 25e1e9028f Updated email address 2025-09-28 00:38:04 +03:00
seve12 a5651c686f fix 22.9 Unable to download large PDF files attached to card issue fixed 2025-09-23 13:40:14 +03:00
Lauri Ojansivu 93f0e0b125 Updated ChangeLog. 2025-09-21 15:01:17 +03:00
Lauri Ojansivu 730bb6d166 Fixed find.sh script errors about unmatched single quotes and binary files that are now ignored.
Thanks to xet7 !
2025-09-21 14:59:00 +03:00
Lauri Ojansivu 855bac59bf Updated ChangeLog. 2025-09-19 23:46:32 +03:00
Lauri Ojansivu 870900b92a Merge pull request #5882 from Skylark13/main
Fix links in docker-compose.yml to point to doc in repo
2025-09-19 23:45:09 +03:00
Jean-Sébastien Guay a1d5802d36 Fix links in docker-compose.yml to point to doc in repo 2025-09-19 15:26:53 -04:00
Lauri Ojansivu 6e16fa3992 Updated ChangeLog. 2025-09-19 16:35:59 +03:00
Lauri Ojansivu ee3b49ce59 Updated ChangeLog. 2025-09-19 03:08:40 +03:00
Lauri Ojansivu 3253dd5010 Updated to MongoDB 7.0.24 at Snap Candidate.
Thanks to MongoDB developers !
2025-09-19 03:06:06 +03:00
Lauri Ojansivu a10d8e0438 Updated ChangeLog. 2025-09-19 01:56:18 +03:00
Lauri Ojansivu 5151814e98 Added missing mobile drag drop image to docs from wekan.github.io git history.
Thanks to xet7 !
2025-09-19 01:54:01 +03:00
Lauri Ojansivu 2e2a0f01f4 Updated ChangeLog. 2025-09-18 23:11:33 +03:00
Lauri Ojansivu dec9b82da0 Updated release script for new command of uploading snap package to Snap Store.
Thanks to xet7 !
2025-09-18 23:09:03 +03:00
Lauri Ojansivu 33f4db5871 v7.95 2025-09-18 21:59:50 +03:00
Lauri Ojansivu 9a086c0397 Updated translations 2025-09-18 21:43:38 +03:00
Lauri Ojansivu 013ddb8978 Updated ChangeLog. 2025-09-18 21:34:15 +03:00
Lauri Ojansivu c4161c5ce6 Updated dependencies.
Thanks to developers of dependencies !
2025-09-18 21:29:36 +03:00
seve12 392b8dd5b2 fix 17.9.2025 2025-09-17 22:34:46 +03:00
seve12 d19eb801f3 fixes 16.9.2025 2025-09-16 23:05:35 +03:00
seve12 ed416ca555 fixes 25.9 2025-09-15 19:31:18 +03:00
seve12 106009316f more fixes 2025-09-10 17:17:51 +03:00
seve12 cb10ad3a20 Fixed 9.2.4.6, 9.1.3.5 and 11.7 2025-09-10 13:04:37 +03:00
Lauri Ojansivu 2fad0099e4 Reorganized docs 2025-08-27 16:11:15 +03:00
Lauri Ojansivu 454416b0bd Updated ChangeLog. 2025-08-26 15:15:44 +03:00
Lauri Ojansivu dd80b7308b Added PGP public key for sending encrypted email.
Thanks to xet7 !
2025-08-26 15:14:19 +03:00
Lauri Ojansivu fe5c5f1bdc Updated ChangeLog. 2025-08-21 13:11:51 +03:00
Lauri Ojansivu 79074deb34 Merge pull request #5872 from sowwos/docs/windows-offline-clarify
This adds two actionable Windows notes to docs/Platforms/Propietary/Windows/Offline.md:  - Explain that WRITABLE_PATH and ATTACHMENTS_STORE_PATH must be set before start to avoid the attachments error   (“The 'path' argument must be of type string. Received undefined” from models/attachments.js). - Show how to expose the dev server on LAN on Windows (BIND_IP=0.0.0.0 + ROOT_URL=http://<LAN-IP>:4000).  Tested on Windows 11 with Meteor dev server. Follow-up to #5871 (closed as wrong file).
2025-08-21 13:07:59 +03:00
sowwos db0294c95e docs(windows): clarify WRITABLE_PATH/attachments + LAN bind instructions (nits) 2025-08-21 07:19:13 +03:00
Lauri Ojansivu 8f0fa88eac Updates 2025-08-20 03:20:49 +03:00
Lauri Ojansivu 946f7045e9 Added missing image to WeKan Multiverse page.
Thanks to xet7 !
2025-08-20 03:19:26 +03:00
Lauri Ojansivu dda8c90d44 Updated ChangeLog. 2025-08-20 02:26:20 +03:00
Lauri Ojansivu 701485d76a More info about ToroDB, FerretDB, Turso, TigerBeetle, PostgreSQL, SQLite etc.
Thanks to xet7 !
2025-08-20 02:24:38 +03:00
Lauri Ojansivu b25198b87e Updated ChangeLog. 2025-08-20 00:58:58 +03:00
Lauri Ojansivu ad7e3774c2 Fixed image link at docs.
Thanks to xet7 !
2025-08-20 00:57:40 +03:00
Lauri Ojansivu ee67dea96c Updated ChangeLog. 2025-08-20 00:43:26 +03:00
Lauri Ojansivu b3d3bf1593 Updated upgrade link.
Thanks to xet7 !
2025-08-20 00:41:22 +03:00
Lauri Ojansivu 53726fed24 Updated WeKan version to Dockerfile.
Thanks to xet7 !
2025-08-18 19:01:19 +03:00
Lauri Ojansivu 7d2ca2c811 v7.94 2025-08-18 18:54:35 +03:00
Lauri Ojansivu c0d10a0ec3 Updated ChangeLog. 2025-08-18 18:35:09 +03:00
Lauri Ojansivu 8e01e3c762 Upgraded to MongoDB 7.0.23 at Snap Candidate.
Thanks to MongoDB developers !
2025-08-18 18:30:21 +03:00
Lauri Ojansivu 04be599893 Updates 2025-08-18 18:15:51 +03:00
Lauri Ojansivu f6cb7fddf1 Updated ChangeLog. 2025-08-13 05:34:28 +03:00
Lauri Ojansivu a662283b7d Updates to design docs. 2025-08-13 05:32:26 +03:00
Lauri Ojansivu f34490fe28 Reorganized Design Docs 2025-08-13 05:30:35 +03:00
Lauri Ojansivu 1a98c86a37 Updated ChangeLog. 2025-08-12 16:55:06 +03:00
Lauri Ojansivu 97b5931a4f Updated dependencies.
Thanks to developers of dependencies !
2025-08-12 16:53:34 +03:00
Lauri Ojansivu 2a4dd9b693 Updated ChangeLog. 2025-08-12 16:04:41 +03:00
Lauri Ojansivu ecf31c3675 Updated MongoDB to 7.0.22.
Thanks to MongoDB developers !
2025-08-12 16:03:28 +03:00
Lauri Ojansivu 9b0d0a2b7c Updated ChangeLog. 2025-08-12 15:59:18 +03:00
Lauri Ojansivu e2ffca2e39 Merge pull request #5865 from wekan/dependabot/github_actions/actions/download-artifact-5
Bump actions/download-artifact from 4 to 5
2025-08-12 15:58:29 +03:00
Lauri Ojansivu a8435879cf Updated translations 2025-08-12 15:56:52 +03:00
Lauri Ojansivu e16695585a Updated ChangeLog. 2025-08-12 15:03:27 +03:00
Lauri Ojansivu a7bcfc6db7 Added docs for Windows SSL/TLS. Part 6.
Thanks to xet7 !

Related #5866
2025-08-12 15:01:56 +03:00
Lauri Ojansivu 21bed98d69 Updated ChangeLog. 2025-08-12 15:00:23 +03:00
Lauri Ojansivu 044793cc44 Added docs for Windows SSL/TLS. Part 5.
Thanks to xet7 !

Related #5866
2025-08-12 14:59:20 +03:00
Lauri Ojansivu 083a7050b9 Updated ChangeLog. 2025-08-12 14:55:13 +03:00
Lauri Ojansivu cc78e19740 Added docs for Windows SSL/TLS. Part 4.
Thanks to xet7 !

Related #5866
2025-08-12 14:53:09 +03:00
Lauri Ojansivu ee01a07b0a Added docs for Windows SSL/TLS. Part 3.
Thanks to xet7 !

Related #5866
2025-08-12 14:44:34 +03:00
Lauri Ojansivu ce528b1826 Added docs for Windows SSL/TLS. Part 2.
Thanks to xet7 !

Related #5866
2025-08-12 14:40:33 +03:00
Lauri Ojansivu 92c0543614 Added docs for Windows SSL/TLS.
Thanks to xet7 !

Related #5866
2025-08-12 14:33:55 +03:00
dependabot[bot] b6638f4a29 Bump actions/download-artifact from 4 to 5
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 07:34:46 +00:00
Lauri Ojansivu 96be56a620 Merge pull request #5864 from wekan/dependabot/github_actions/actions/checkout-5
Bump actions/checkout from 4 to 5
2025-08-12 10:33:51 +03:00
dependabot[bot] 2e555e420a Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 03:02:57 +00:00
Lauri Ojansivu a849951c53 Update LXD docs 2025-08-09 23:03:09 +03:00
Lauri Ojansivu 435cb04717 Update PWA docs 2025-08-09 21:14:30 +03:00
Lauri Ojansivu 25a375261e Move docs PWA to Browsers directory 2025-08-09 21:09:27 +03:00
Lauri Ojansivu 1a1a44616f Revert accessibility changes temporarily.
Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/5857
2025-08-09 14:23:40 +03:00
Lauri Ojansivu e6347a305c Updated ChangeLog. 2025-08-09 12:00:39 +03:00
Lauri Ojansivu b137108ae1 Fixed uppercase K of WeKan.
Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/5857
2025-08-09 11:55:50 +03:00
Lauri Ojansivu 4ce7ff7cef Merge pull request #5857 from seve12/main
Accessibility:
- Added product name to page titles, settings and global search.
- More accessible header and layout templates, modal dialogs, DOM structure, color contrast.
2025-08-09 11:33:50 +03:00
seve12 184415a026 Enhance color contrast and accessibility for various UI elements 2025-08-09 04:29:30 +03:00
Lauri Ojansivu 3977adcb8f Updated translations 2025-08-08 12:38:15 +03:00
Lauri Ojansivu 1c47f98f59 Feature: Added brute force login protection settings to Admin Panel/People/Locked Users. Part 2.
Thanks to xet7 !
2025-08-08 12:36:17 +03:00
seve12 9f0c37352e Enhance accessibility for modal dialogs and improve DOM structure 2025-08-07 23:59:34 +03:00
seve12 7a20fa4805 Merge branch 'main' of https://github.com/seve12/wekan 2025-08-06 19:29:25 +03:00
seve12 6a713d9e8d Refactor header and layout templates for improved accessibility and consistency 2025-08-06 19:18:01 +03:00
Lauri Ojansivu 51b0544752 Updated translations. 2025-08-06 08:17:02 +03:00
seve12 1022a7aa3a Update settingBody.js 2025-08-05 20:23:52 +03:00
seve12 c048678844 Update router.js 2025-08-05 20:22:09 +03:00
seve12 f9fb02457c Merge branch 'main' of https://github.com/seve12/wekan 2025-08-05 20:07:50 +03:00
seve12 ce419ce64e Merge pull request #1 from seve12/severi
Improves accessibility by disabling custom Tab handling
2025-08-05 20:05:39 +03:00
severi12345 ecb6ff57fc Update page titles to include product name in settings and global search 2025-08-05 19:59:33 +03:00
Lauri Ojansivu 663866562f Updated ChangeLog. 2025-08-05 12:57:00 +03:00
Lauri Ojansivu dfdd0b6cbb Added info about Sandstorm Radicale Calendar and Contacts.
Thanks to xet7 !
2025-08-05 12:55:29 +03:00
Lauri Ojansivu c81ca82822 Updated translations. 2025-08-05 12:02:36 +03:00
Lauri Ojansivu 66b067eb49 Updated translations. 2025-08-05 11:26:23 +03:00
Lauri Ojansivu 4e9f2dc46a Updated ChangeLog. 2025-08-05 11:24:34 +03:00
Lauri Ojansivu f02d8b61b5 Merge pull request #5856 from wekan/dependabot/github_actions/docker/login-action-3.5.0
Bump docker/login-action from 3.4.0 to 3.5.0
2025-08-05 11:18:16 +03:00
Lauri Ojansivu 088de1877c Merge pull request #5855 from wekan/dependabot/github_actions/docker/metadata-action-5.8.0
Bump docker/metadata-action from 5.7.0 to 5.8.0
2025-08-05 11:17:59 +03:00
dependabot[bot] 4611abffed Bump docker/login-action from 3.4.0 to 3.5.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/74a5d142397b4f367a81961eba4e8cd7edddf772...184bdaa0721073962dff0199f1fb9940f07167d1)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 3.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 03:24:07 +00:00
dependabot[bot] f206f2f45c Bump docker/metadata-action from 5.7.0 to 5.8.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.7.0 to 5.8.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/902fa8ec7d6ecbf8d84d538b9b233a880e428804...c1e51972afc2121e065aed6d45c65596fe445f3f)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 5.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 03:17:28 +00:00
Lauri Ojansivu 9c5f5757be Updated translations. 2025-08-05 00:50:29 +03:00
Lauri Ojansivu ec2e0f6fed Updated ChangeLog. 2025-08-05 00:33:46 +03:00
Lauri Ojansivu ae0d059b6f Feature: Added brute force login protection settings to Admin Panel/People/Locked Users.
Added filtering of Admin Panel/People/People: All Users/Locked Users Only/Active/Not Active.
Added visual indicators: red lock icon for locked users, green check for active users, and red X for inactive users.
Added "Unlock All" button to quickly unlock all brute force locked users.
Added ability to toggle user active status directly from the People page.
Moved lockout settings from environment variables to database so admins can configure the lockout thresholds directly in the UI.

Thanks to xet7.
2025-08-05 00:31:43 +03:00
Lauri Ojansivu 0132b801b2 Updated translations. 2025-08-04 21:34:33 +03:00
Lauri Ojansivu 06ca564ec2 Updated ChangeLog. 2025-08-04 21:26:51 +03:00
Lauri Ojansivu d83ce5e633 Feature: Accessibility page at /accessibility. Settings at Admin Panel. When enabled, link at right sidebar.
Thanks to xet7 !
2025-08-04 21:22:14 +03:00
Lauri Ojansivu 5287319fde Updated translations. 2025-08-04 19:53:31 +03:00
Lauri Ojansivu c75a23e693 Updated ChangeLog. 2025-08-04 19:49:59 +03:00
Lauri Ojansivu 180bf930c1 Updated translations. 2025-08-04 19:46:24 +03:00
Lauri Ojansivu c16e99ba1e Added FerretDB/PostgreSQL to changelog. 2025-08-04 19:21:16 +03:00
Lauri Ojansivu b9887fc917 Fixed link at OpenShift docs.
Thanks to xet7 !

Related #5854
2025-08-04 19:17:17 +03:00
Lauri Ojansivu 96b36bd8ef Updated ChangeLog. 2025-08-04 18:24:27 +03:00
Lauri Ojansivu 0e32f666eb Comment out not used Tab code at accessibility related changes.
Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/5853
2025-08-04 18:17:24 +03:00
Lauri Ojansivu 1341fc6a98 Merge pull request #5853 from seve12/severi
Improves accessibility by disabling custom Tab handling
2025-08-04 18:12:46 +03:00
seve12 81c9e96bf3 Improves accessibility by disabling custom Tab handling
Comments out custom Tab key behavior to allow default browser focus movement, enhancing accessibility for keyboard users and assistive technologies.
2025-08-04 17:45:53 +03:00
Lauri Ojansivu 20f91ef893 Updated ChangeLog. 2025-08-01 02:29:49 +03:00
Lauri Ojansivu 1187254573 Updated security email address.
Thanks to xet7 !
2025-08-01 02:28:15 +03:00
Lauri Ojansivu f22fb4f4a9 Updated translations 2025-07-28 23:28:36 +03:00
Lauri Ojansivu a14762e005 Updated ChangeLog. 2025-07-19 20:16:31 +03:00
Lauri Ojansivu 9a91214043 Update CHANGELOG.md 2025-07-19 05:14:56 +03:00
Lauri Ojansivu 30795a46cf Update CHANGELOG.md 2025-07-19 05:10:55 +03:00
Lauri Ojansivu b0865c8d06 Update CHANGELOG.md 2025-07-19 05:03:37 +03:00
Lauri Ojansivu c2aabbc6db Update CHANGELOG.md 2025-07-19 05:02:01 +03:00
Lauri Ojansivu 4aad3dafd4 Update CHANGELOG.md 2025-07-19 04:58:25 +03:00
Lauri Ojansivu 62269a9902 Update CHANGELOG.md 2025-07-19 04:54:59 +03:00
Lauri Ojansivu 4bc2fd4a7f Update CHANGELOG.md 2025-07-19 04:52:48 +03:00
Lauri Ojansivu 0e43a08689 Update CHANGELOG.md platforms info at top. Thanks to xet7! 2025-07-19 04:51:15 +03:00
Lauri Ojansivu 77b1416413 Updated ChangeLog. 2025-07-19 01:29:59 +03:00
Lauri Ojansivu 200545822c Fixes for building at Mac M1 Air.
Thanks to xet7 !
2025-07-18 22:31:17 +03:00
Lauri Ojansivu ac33f2164f Removed not needed files. 2025-07-18 19:04:25 +03:00
Lauri Ojansivu e82ca8a1f4 Updated ChangeLog. 2025-07-18 15:19:57 +03:00
Lauri Ojansivu f894f9ef6d Fixed building Docker image. Pushed new Docker image to Docker Hub, Quay and GitHub.
Thanks to xet7 !

Fixes #5835
2025-07-18 15:17:36 +03:00
Lauri Ojansivu ccfd8ef566 Updated ChangeLog. 2025-07-18 08:55:51 +03:00
Lauri Ojansivu 6c6b66c802 Updated release website script.
Thanks to xet7 !
2025-07-18 08:53:41 +03:00
Lauri Ojansivu 2cb2e7cb10 v7.93 2025-07-18 08:30:28 +03:00
Lauri Ojansivu 8744f47a0e Updated ChangeLog. 2025-07-17 01:25:27 +03:00
Lauri Ojansivu b742b25f96 Merge pull request #5832 from Atry/edit_list
Add REST API endpoint to edit a list with various properties
2025-07-17 01:21:06 +03:00
Yang, Bo 6d7c20f397 Add API endpoint to edit a list with various properties 2025-07-16 22:09:58 +00:00
Lauri Ojansivu f3d384c1dd Updated ChangeLog. 2025-07-17 00:52:34 +03:00
Lauri Ojansivu 69ce79a7b9 Fixed Snap local build script.
Thanks to xet7 !
2025-07-17 00:50:18 +03:00
Lauri Ojansivu 1cd191f76b Updated ChangeLog. 2025-07-16 01:10:59 +03:00
Lauri Ojansivu afc3c29341 Merge pull request #5829 from Atry/get_card_by_id
Avoid calling `ReactiveCache.getCard` twice
2025-07-16 01:08:27 +03:00
Lauri Ojansivu fedb3040d1 Updated ChangeLog. 2025-07-16 00:59:16 +03:00
Yang, Bo 0a969c59d3 Avoid calling ReactiveCache.getCard twice 2025-07-15 14:58:21 -07:00
Lauri Ojansivu d9fb9f49fd Merge pull request #5828 from Atry/get-card-by-id
Add a REST API endpoint to retrieve a card by ID
2025-07-16 00:53:42 +03:00
Yang, Bo fc77d0d201 Add REST API endpoint to retrieve a card by ID 2025-07-15 21:40:43 +00:00
Lauri Ojansivu 56700d1d06 Updated ChangeLog. 2025-07-10 05:22:38 +03:00
Lauri Ojansivu 84259c5116 Merge pull request #5826 from Atry/rest-api-custom-field-return-type
fix: correct return type in API documentation for custom fields
2025-07-09 19:14:13 +03:00
Yang, Bo 6cc746df8b fix: correct return type in API documentation for custom fields 2025-07-09 15:43:20 +00:00
Lauri Ojansivu b3ad06692f Updated ChangeLog. 2025-07-08 14:18:54 +03:00
Lauri Ojansivu bb0814bb11 Update Python.md 2025-07-08 14:16:49 +03:00
Lauri Ojansivu 722faf8aaa Updated ChangeLog. 2025-07-07 23:06:17 +03:00
Lauri Ojansivu 159324858b Fixed release script of building Snap locally at Ubuntu.
Thanks to xet7 !
2025-07-07 23:03:36 +03:00
Lauri Ojansivu f73a370719 Updated ChangeLog. 2025-07-07 22:42:12 +03:00
Lauri Ojansivu dfc658b910 Added release script to switch between using kvm, snapcraft.io/multipass, waydroid and virtualbox.
Thanks to xet7 !
2025-07-07 22:41:15 +03:00
Lauri Ojansivu 0a52f470b7 Updated ChangeLog. 2025-07-07 22:19:44 +03:00
Lauri Ojansivu e4822d8bc4 Updated issue template about pull requests for fixes to docs.
Thanks to xet7 !
2025-07-07 22:17:57 +03:00
Lauri Ojansivu 9d1cab3ac2 Updated ChangeLog. 2025-07-07 22:15:18 +03:00
Lauri Ojansivu 6d16ec238a Updated image links at Azure docs 2025-07-07 20:29:48 +03:00
Lauri Ojansivu e0284f225b Updated Keycloak link 2025-07-07 20:25:59 +03:00
Lauri Ojansivu a5acd0801a Updated Azure link 2025-07-07 20:24:34 +03:00
Lauri Ojansivu d59337ae47 Updated docs 2025-07-07 19:44:24 +03:00
Lauri Ojansivu 2f27a3f839 Updated docs about migrating manually. Part 2. 2025-07-07 19:27:54 +03:00
Lauri Ojansivu 450b33f98a Updated docs about migrating manually 2025-07-07 19:26:43 +03:00
Lauri Ojansivu 9adf5027fa Updated docs about importing from Asana 2025-07-07 19:21:27 +03:00
Lauri Ojansivu 1610b84845 Updated docs about importing from Trello. Part 3. 2025-07-07 19:18:29 +03:00
Lauri Ojansivu 40b2cf88fc Updated docs about importing from Trello. Part 2. 2025-07-07 19:17:41 +03:00
Lauri Ojansivu 55ef6c0c56 Updated docs about importing from Trello 2025-07-07 19:15:51 +03:00
Lauri Ojansivu a9c67ac200 Fix docs link about CSV. Part 2. 2025-07-07 19:09:57 +03:00
Lauri Ojansivu 3892be47ac Fix docs link about CSV 2025-07-07 19:07:48 +03:00
Lauri Ojansivu a2654b2e29 Removed not working link from docs 2025-07-07 19:05:49 +03:00
Lauri Ojansivu a052cc8fa5 Updated docs about Kubernetes 2025-07-07 19:04:05 +03:00
Lauri Ojansivu 5d09100cb6 Update info about hashing 2025-07-07 19:00:10 +03:00
Lauri Ojansivu 76769d1b85 Fixed not working link 2025-07-07 18:56:34 +03:00
Lauri Ojansivu 2cf57250e8 Fix link to image at docs 2025-07-07 18:54:56 +03:00
Lauri Ojansivu 5d0a0c931f Removed old link Test Edge from docs index. 2025-07-07 18:50:56 +03:00
Lauri Ojansivu fa1adfec76 Formatting 2025-07-07 18:43:26 +03:00
Lauri Ojansivu 9271b07383 Fix link to image about PWA app icon install.
Thanks to stevenroose and xet7 !

Fixes #5824
2025-07-07 18:40:52 +03:00
Lauri Ojansivu 4fe955650a Added most often used links 2025-07-07 18:36:39 +03:00
Lauri Ojansivu 6b401000b9 Updated Snap platforms setting. 2025-07-05 20:11:13 +03:00
Lauri Ojansivu aa681cde88 Updated building Snap 2025-07-05 16:59:33 +03:00
Lauri Ojansivu 0921c6ea53 Updated ChangeLog. 2025-07-05 16:09:33 +03:00
Lauri Ojansivu 2df73bedee Updated rebuild-wekan.sh install deps for macOS. Part 2. 2025-07-05 15:30:12 +03:00
Lauri Ojansivu 938fe49b2c Update rebuild-wekan.sh install deps for macOS 2025-07-05 15:27:11 +03:00
Lauri Ojansivu 7e2e649a8e Updated ChangeLog. 2025-07-05 14:16:02 +03:00
Lauri Ojansivu 6e11aa27f8 Reorganized docs to fix building WeKan 2025-07-04 04:08:41 +03:00
Lauri Ojansivu 57ee624398 Updated issue template. 2025-07-04 03:18:44 +03:00
Lauri Ojansivu 3cba95b60a Updated issue template. 2025-07-01 19:08:43 +03:00
Lauri Ojansivu bd796ce642 Updated links at readme 2025-06-28 14:22:01 +03:00
Lauri Ojansivu 3a8473e632 Fix image link 2025-06-28 14:10:41 +03:00
Lauri Ojansivu 89480b61ce wekan.github.io to wekan.fi, and blog.wekan.team to wekan.fi/blog 2025-06-28 14:08:57 +03:00
Lauri Ojansivu c5e5bb613e Moved images from wekan.github.io to docs 2025-06-28 11:50:55 +03:00
Lauri Ojansivu b52d1ca6c4 wekan.team to wekan.fi 2025-06-28 10:59:38 +03:00
Lauri Ojansivu 790bafbb09 wekan.team to wekan.fi 2025-06-27 21:37:17 +03:00
Lauri Ojansivu c256ce6968 Update Browser-compatibility-matrix.md about Servo 2025-06-26 20:29:48 +03:00
Lauri Ojansivu 85465e0dfb Updated ChangeLog. 2025-06-26 05:45:11 +03:00
Lauri Ojansivu b7409c1d0b Removed old broken snap files.
Thanks to xet7 !
2025-06-26 05:43:30 +03:00
Lauri Ojansivu 4060d33bbc Updated ChangeLog. 2025-06-26 05:42:34 +03:00
Lauri Ojansivu 6526d99123 Upgraded Snap Candidate to have base core24, MongoDB 7 and Caddy 2.
Thanks to xet7 !
2025-06-26 05:39:37 +03:00
Lauri Ojansivu 1b44c848ad Updated ChangeLog. 2025-06-26 03:47:57 +03:00
Lauri Ojansivu e6980be061 Updated dependencies.
Thanks to developers of dependencies !
2025-06-26 03:46:39 +03:00
Lauri Ojansivu 81c77650b4 Updated translations. 2025-06-26 03:08:38 +03:00
Lauri Ojansivu 791e37dd9c Updated ChangeLog. 2025-06-26 03:01:59 +03:00
Lauri Ojansivu f926448bbb Added docs about using MongoDB at unsupported CPUs with Qemu.
Thanks to xet7 !

Related #4321,
related #5814
2025-06-26 03:00:04 +03:00
Lauri Ojansivu 7128f067d0 Updated ChangeLog. 2025-06-26 02:48:12 +03:00
Lauri Ojansivu 59ab6c1cd8 Snap Candidate: If CPU does not support AVX, use Qemu that supports AVX, so that MongoDB 6 works. Part 3.
Thanks to xet7 !

Fixes #4321
2025-06-26 02:41:11 +03:00
Lauri Ojansivu 89105b6e72 Updated ChangeLog. 2025-06-26 01:20:41 +03:00
Lauri Ojansivu 51e43f1c25 Specify meteor version, otherwise the latest meteor version is not compatible with node14. Part 2.
Thanks to xet7 !
2025-06-26 01:19:06 +03:00
Lauri Ojansivu 9b24d644a4 Merge pull request #5815 from Atry/board-rest-api-doc
feat: enhance API documentation and add board-related endpoints
2025-06-26 01:09:42 +03:00
Lauri Ojansivu 2549e0e4c8 Merge pull request #5816 from dassio/main
specify meteor version, otherwise the lastes meteor version is not compatible with node14
2025-06-26 01:08:43 +03:00
xiangbin.li d974fa638c specify meteor version, otherwise the lastes version is not compatiable with node_14 2025-06-24 03:36:20 +00:00
Yang, Bo f399b5119f feat: enhance API documentation and add board-related endpoints
Previously, boards.js contains a `?.` operator, which is not supported by esprima, therefore boards.js is skipped.

This PR fixes the API generation for borads.js by removing `?.`.

See https://github.com/jquery/esprima/issues/2112
2025-06-23 20:01:38 +00:00
Lauri Ojansivu 12d3fabdb7 Updates 2025-06-18 17:12:53 +03:00
Lauri Ojansivu d5727f5b15 Updated github issue template 2025-06-18 17:08:49 +03:00
Lauri Ojansivu 1908d04fd4 Updates 2025-06-18 17:04:59 +03:00
Lauri Ojansivu c7f8c828cb Updates 2025-06-18 17:01:38 +03:00
Lauri Ojansivu 054d0913fd Updates 2025-06-18 16:56:37 +03:00
Lauri Ojansivu ca7dc69c85 Fix links and add more info 2025-06-18 16:53:29 +03:00
Lauri Ojansivu b2ff51d99c Updates 2025-06-18 16:48:33 +03:00
Lauri Ojansivu abd4b6bd87 Updates 2025-06-18 16:45:04 +03:00
Lauri Ojansivu b92d07c9a6 Updated translations 2025-06-18 11:30:37 +03:00
Lauri Ojansivu c6204417a3 Updated translations 2025-06-18 11:27:23 +03:00
Lauri Ojansivu 3a23401443 Updated ChangeLog. 2025-06-18 11:07:15 +03:00
Lauri Ojansivu 12e6e46924 Update Browser-compatibility-matrix.md 2025-06-17 00:19:33 +03:00
Lauri Ojansivu be1b959519 Update Browser-compatibility-matrix.md 2025-06-17 00:18:04 +03:00
Lauri Ojansivu 7841c9e801 Update Browser-compatibility-matrix.md 2025-06-17 00:15:23 +03:00
Lauri Ojansivu bc486e2a7d Updated ChangeLog. 2025-06-16 14:58:15 +03:00
Lauri Ojansivu d01885e2ad Updated ChangeLog. 2025-06-16 14:47:50 +03:00
Lauri Ojansivu 358ffe0601 Merge pull request #5805 from walster001/main
CleanDark Theme Fixes
2025-06-16 14:45:19 +03:00
walster001 8d0bf1b758 Fix invisible scrollbar on CleanDark cards
Found that scrollbars were blending in with the card background largely due to transparency on the main board.
2025-06-16 00:39:10 +09:30
walster001 c7961cf2f4 Fix spacing 2025-06-16 00:22:20 +09:30
walster001 2ac374e578 Fix font colour contrast CleanDark
Fixes the visibility of card titles when card is opened for CleanDark theme as was inheriting black title from CleanLight theme. 
Title now is white to match and heavily contrast theme.
2025-06-16 00:18:50 +09:30
Lauri Ojansivu ad3306e19e Update Browser-compatibility-matrix.md 2025-06-14 22:37:10 +03:00
Lauri Ojansivu f54cbac370 Updated docs 2025-06-13 23:05:01 +03:00
Lauri Ojansivu 4bfc0140be Updated docs links 2025-06-13 22:36:59 +03:00
Lauri Ojansivu cc7459b983 Updated docs: Fixed links 2025-06-13 22:15:36 +03:00
Lauri Ojansivu 11415cd517 Updated Docs: Updated deep dive link 2025-06-13 21:45:38 +03:00
Lauri Ojansivu 9aa028f32d Updates 2025-06-13 21:39:46 +03:00
Lauri Ojansivu 2a415cbd26 Updated docs: Moved content from Home.md to README.md 2025-06-13 21:38:12 +03:00
Lauri Ojansivu 40a52da2d3 Updated docs: Removed footer 2025-06-13 21:34:45 +03:00
Lauri Ojansivu 31e043c1d7 Updated docs 2025-06-13 21:32:36 +03:00
Lauri Ojansivu 985afafed0 Snap Candidate back to MongoDB 6.0.24 2025-06-12 21:22:16 +03:00
Lauri Ojansivu 3a4d20ecb2 Updates 2025-06-12 20:28:52 +03:00
Lauri Ojansivu 35b524f179 Updated ChangeLog. 2025-06-12 20:15:19 +03:00
Lauri Ojansivu d2f17ef140 Upgrade to MongoDB 7.0.21 2025-06-12 20:13:49 +03:00
Lauri Ojansivu d99864ca95 v7.92 2025-06-12 19:30:59 +03:00
Lauri Ojansivu e6e1191f8a Updated ChangeLog. 2025-06-12 15:50:06 +03:00
Lauri Ojansivu 1f10c20874 Updated dependencies.
Thanks to developers of dependencies !
2025-06-12 15:48:55 +03:00
Lauri Ojansivu c699f7a940 Updated ChangeLog. 2025-06-12 15:47:50 +03:00
Lauri Ojansivu 7115c292c7 Updated dependencies.
Thanks to developers of dependencies !
2025-06-12 15:46:44 +03:00
Lauri Ojansivu 7744b14b48 Updated ChangeLog. 2025-06-12 15:44:50 +03:00
Lauri Ojansivu 6fed9e73d8 Merge pull request #5801 from Atry/fix-login-openapi
fix: properly document `/users/login`
2025-06-12 15:43:09 +03:00
Yang, Bo e14a3f9c2d fix: properly document /users/login 2025-06-12 02:18:19 +00:00
Lauri Ojansivu 7bf75b1ff7 Updated ChangeLog. 2025-06-11 19:54:05 +03:00
Lauri Ojansivu 6905e24199 Updated to MongoDB 6.0.24 at Snap Candidate.
Thanks to MongoDB developers!
2025-06-11 19:52:13 +03:00
Lauri Ojansivu 9eb25c09da Updated ChangeLog. 2025-06-06 03:58:51 +03:00
Lauri Ojansivu c97f5ffca3 Updated ChangeLog. 2025-06-03 01:11:26 +03:00
Lauri Ojansivu eb19168b5f Merge pull request #5795 from wekan/dependabot/github_actions/docker/build-push-action-6.18.0
Bump docker/build-push-action from 6.17.0 to 6.18.0
2025-06-03 01:09:31 +03:00
dependabot[bot] e421b68766 Bump docker/build-push-action from 6.17.0 to 6.18.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.17.0 to 6.18.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/1dc73863535b631f98b2378be8619f83b136f4a0...263435318d21b8e681c14492fe198d362a7d2c83)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-02 20:16:16 +00:00
Lauri Ojansivu 6b86625c56 Updated ChangeLog. 2025-06-02 19:15:46 +03:00
Lauri Ojansivu 254b6dd5c7 Merge pull request #5793 from walster001/main
Allow selection of card text via webkit/user-select attributes
2025-06-02 19:13:18 +03:00
walster001 7b545d12c7 Allow selection of card text via webkit/user-select attributes
Fixes open issue around webkit/user-select attributes. Modifies values to allow "text" values to be selected in cards and on the board.
2025-06-02 22:03:16 +09:30
Lauri Ojansivu 01ed20b400 v7.91 2025-05-25 01:05:10 +03:00
Lauri Ojansivu fad930833a Updated translations. 2025-05-25 00:31:15 +03:00
Lauri Ojansivu 9192fbee44 Updated ChangeLog. 2025-05-25 00:30:11 +03:00
Lauri Ojansivu aaa5f9885d Reverted https://github.com/wekan/wekan/pull/5774 about due date changes.
Thanks to xet7 !

Fixes #5782
2025-05-25 00:22:47 +03:00
Lauri Ojansivu 1979b1692d Reverted date format changes.
Thanks to xet7 !
2025-05-25 00:11:09 +03:00
valhalla-creator fc31eeca88 Update cardDate.js 2025-05-22 21:20:20 +01:00
valhalla-creator 6d4de76a9a Update datepicker.js 2025-05-22 21:19:39 +01:00
valhalla-creator 9245ba4a5b Update utils.js 2025-05-22 21:18:52 +01:00
valhalla-creator 973a788c21 Update datepicker.js 2025-05-22 21:13:22 +01:00
valhalla-creator 0d5df8d3cf Update cardDate.js 2025-05-22 21:12:44 +01:00
valhalla-creator b67a236657 Update utils.js 2025-05-22 21:11:28 +01:00
Lauri Ojansivu 170617d457 Merge pull request #5780 from wekan/dependabot/github_actions/docker/build-push-action-6.17.0
Bump docker/build-push-action from 6.16.0 to 6.17.0
2025-05-19 23:12:48 +03:00
dependabot[bot] cc2f359b6c Bump docker/build-push-action from 6.16.0 to 6.17.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.16.0 to 6.17.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/14487ce63c7a62a4a324b0bfb37086795e31c6c1...1dc73863535b631f98b2378be8619f83b136f4a0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 20:08:52 +00:00
Lauri Ojansivu c0d44a8686 v7.90 2025-05-14 03:05:46 +03:00
Lauri Ojansivu a1700f38b1 Updated ChangeLog. 2025-05-14 01:14:08 +03:00
Lauri Ojansivu b82ba63532 Fix Lines in multiline markdown code block to not anymore have darker background.
Thanks to mueller-ma and xet7 !

Fixes #5689
2025-05-14 01:11:54 +03:00
Lauri Ojansivu dbd1324a90 Updated ChangeLog. 2025-05-14 00:15:37 +03:00
Lauri Ojansivu e52158b729 Changed start.bat default ROOT_URL=http://localhost , although it only works for local user.
Thanks to xet7 !
2025-05-14 00:13:52 +03:00
Lauri Ojansivu 68a717cf47 Updated ChangeLog. 2025-05-13 23:48:45 +03:00
Lauri Ojansivu c0a9780f80 Added missing quotes to Fix Due Date Problem in Non-English Numbers.
Thanks to xet7 !

Fixes https://github.com/wekan/wekan/pull/5774,
fixes #5752
2025-05-13 23:43:08 +03:00
Lauri Ojansivu 0520129a40 Updated ChangeLog. 2025-05-13 23:36:32 +03:00
Lauri Ojansivu 6b36e126ab Merge pull request #5774 from valhalla-creator/bugfix/fix-due-date
Bugfix/fix due date
2025-05-13 23:31:33 +03:00
valhalla-creator 3cb4662363 Update datepicker.js 2025-05-13 21:26:34 +01:00
valhalla-creator cef14f301f Update utils.js 2025-05-13 21:21:48 +01:00
valhalla-creator eca4a0c440 Update cardDate.js 2025-05-13 21:19:59 +01:00
Lauri Ojansivu cea04b2ada Updated ChangeLog. 2025-05-13 23:18:13 +03:00
Lauri Ojansivu b7d9af9ae7 v7.89 2025-05-13 22:45:44 +03:00
Lauri Ojansivu 0046b3c802 Merge pull request #5772 from oussama-madimagh/fix/css-compatibility
Fix: Add vendor prefixes for user-select and text-size-adjust for better browser compatibility
2025-05-13 22:37:32 +03:00
oussama-madimagh 25384c8ac3 Fix: Add vendor prefixes for user-select and text-size-adjust for better browser compatibility 2025-05-13 20:33:29 +01:00
Lauri Ojansivu 2eee72da8a Updated ChangeLog. 2025-05-13 22:00:50 +03:00
Lauri Ojansivu d65c422e3f Merge pull request #5769 from Adamsss001/feature/email-i18n
Add email notifications language localization feature
2025-05-13 21:50:53 +03:00
Omar Abid 2ab9bd3172 Add email notifications language localization feature 2025-05-13 19:45:08 +01:00
Lauri Ojansivu a0b5c2e88c Updated ChangeLog. 2025-05-13 19:42:41 +03:00
Lauri Ojansivu 0bd4108661 Upgraded to MongoDB 6.0.23 at Snap Candidate.
Thanks to MongoDB developers !
2025-05-13 19:37:42 +03:00
Lauri Ojansivu 7d1a1475ba Add missing code of fix insertion order of list.
Thanks to xet7 !

Fixes https://github.com/wekan/wekan/pull/5767,
fixes #5732
2025-05-13 18:54:14 +03:00
Lauri Ojansivu 6418263165 Merge branch 'correct-list-position' of github.com:valhalla-creator/wekan 2025-05-13 18:30:59 +03:00
Lauri Ojansivu b32c835cf9 Updated license 2025-05-13 17:00:54 +03:00
valhalla-creator a927685bc6 Update swimlanes.js 2025-05-12 22:33:42 +01:00
Lauri Ojansivu 6827d40e84 Updated ChangeLog. 2025-05-12 22:26:33 +03:00
Lauri Ojansivu 9aa12b0eb6 Updated Caddy docs.
Thanks to xet7 !
2025-05-12 22:25:18 +03:00
Lauri Ojansivu 8ca1a36d78 Updated ChangeLog. 2025-05-12 21:57:43 +03:00
Lauri Ojansivu 394f2eae69 Updated Browser Compatibility Matrix.
Thanks to xet7 !
2025-05-12 21:56:11 +03:00
Lauri Ojansivu 7588459c3e Updated translations. 2025-05-12 21:43:02 +03:00
Lauri Ojansivu 2c33f45a6a Updated translations. 2025-04-29 05:47:20 +03:00
Lauri Ojansivu 43cf0b66ac Merge pull request #5754 from wekan/dependabot/github_actions/docker/build-push-action-6.16.0
Bump docker/build-push-action from 6.15.0 to 6.16.0
2025-04-29 04:59:27 +03:00
dependabot[bot] c05f6fcff2 Bump docker/build-push-action from 6.15.0 to 6.16.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.15.0 to 6.16.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/471d1dc4e07e5cdedd4c2171150001c434f0b7a4...14487ce63c7a62a4a324b0bfb37086795e31c6c1)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 21:07:25 +00:00
Lauri Ojansivu a4eb32158b Updated ChangeLog. 2025-04-25 23:33:40 +03:00
Lauri Ojansivu 072ced9d0e Added script to build snap locally and push to snapcraft.io candidate and edge.
Thanks to xet7 !
2025-04-25 23:30:57 +03:00
Lauri Ojansivu c5fefc1414 v7.88 2025-04-25 22:12:37 +03:00
Lauri Ojansivu c825895ceb Reverted translation fix that sometimes did not work.
Thanks to xet7 !

Fixes #5751,
related https://github.com/wekan/wekan/pull/5748
2025-04-25 22:06:06 +03:00
Lauri Ojansivu 9488972ed8 Merge newest changes. 2025-04-25 21:07:22 +03:00
Lauri Ojansivu 1f4bed38f7 Merge pull request #5750 from walster001/main
Fix more contrasting issues
2025-04-25 21:02:50 +03:00
Lauri Ojansivu 747112957a v7.87 2025-04-25 20:59:20 +03:00
Lauri Ojansivu 18228096f9 Updated ChangeLog. 2025-04-25 20:56:07 +03:00
Lauri Ojansivu d0ea5bf500 Fix typos.
Thanks to xet7 !
2025-04-25 20:54:02 +03:00
walster001 74fe91fa3a Fix more contrasting issues
- Fix contrast issue with CleanDark & CleanLight buttons on theme selection menu.
2025-04-26 01:40:15 +09:30
Lauri Ojansivu d4e3075fcc v7.86 2025-04-25 19:00:08 +03:00
Lauri Ojansivu 413ae5f20e Updated translations. 2025-04-25 18:38:13 +03:00
Lauri Ojansivu e23f86f542 Updated ChangeLog. 2025-04-25 18:35:12 +03:00
Lauri Ojansivu b3c47dbe84 Merge pull request #5749 from walster001/main
Fix contrast issue checkbox
2025-04-25 18:32:28 +03:00
Lauri Ojansivu b10c2b9a15 Updated ChangeLog. 2025-04-25 18:31:35 +03:00
Lauri Ojansivu bb6910acd1 Merge branch 'nourguidara-fix-i18n-init-timing' 2025-04-25 18:29:43 +03:00
Lauri Ojansivu 76b000820e Updated ChangeLog. 2025-04-25 18:28:23 +03:00
Lauri Ojansivu 50b874629c Merge branch 'Rayene123-add-toggle-watch-icon-on-card' 2025-04-25 18:25:44 +03:00
Lauri Ojansivu 4d145ab4ad Added translations to questions about are you sure.
Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/5745
2025-04-25 18:24:40 +03:00
Lauri Ojansivu 4d67a4641f Merge branch 'fix-i18n-init-timing' of github.com:nourguidara/wekan into nourguidara-fix-i18n-init-timing 2025-04-25 17:54:41 +03:00
Lauri Ojansivu bc2eab6f9d Merge branch 'add-toggle-watch-icon-on-card' of github.com:Rayene123/wekan into Rayene123-add-toggle-watch-icon-on-card 2025-04-25 17:49:14 +03:00
walster001 3ccce75863 Fix contrast issue checkbox
- Fixed contrasting issue with tick check on custom fields, also fixed the ugly green tick coming up on the checklists in cards by utilisation of the !important tag to override it with the checkbox colour for custom fields also.
2025-04-25 20:15:34 +09:30
nour guidara b390b266e2 bug fix in imports\i18n\index.js 2025-04-25 11:10:46 +01:00
Lauri Ojansivu 561af8926c Merge branch 'main' of github.com:wekan/wekan 2025-04-24 22:20:06 +03:00
Lauri Ojansivu 5717dc2cf4 Updated ChangeLog. 2025-04-24 22:19:45 +03:00
Lauri Ojansivu d0e64ad6d2 Merge pull request #5746 from nourguidara/nourguidara-patch-1
Improve impersonate user documentation in docs/Admin/Impersonate-user.md
2025-04-24 22:18:07 +03:00
Lauri Ojansivu 8e1a735ec7 Updates 2025-04-24 22:17:47 +03:00
nour guidara 1301d67295 Update Impersonate-user.md
Restored direct link to the original pull request (#3280) as requested
2025-04-24 20:14:41 +01:00
nour guidara 7c239f5218 Update Impersonate-user.md 2025-04-24 19:45:29 +01:00
Rayene123 61235c953c added a watch icon button when clicked toggle if a card is watched or not 2025-04-24 11:53:08 +01:00
Lauri Ojansivu ea65a0308d Merge pull request #5741 from Firas-Git/documentation/login-and-signup
Documentation/login and signup
2025-04-21 22:57:08 +03:00
Firas Saidi f840b07c02 documentation/login-and-signup 2025-04-21 20:50:23 +01:00
Lauri Ojansivu 8af719d39e v7.85 2025-04-21 16:30:58 +03:00
Lauri Ojansivu c1a4250bd2 Updated to MongoDB 6.0.22.
Thanks to MongoDB developers !
2025-04-21 16:28:41 +03:00
Lauri Ojansivu b4b442f8a8 Updated translations. 2025-04-21 16:13:56 +03:00
Lauri Ojansivu b7e76fcfa1 Updated ChangeLog. 2025-04-21 16:10:24 +03:00
Lauri Ojansivu 01950cc796 Fix board sidebar menu doesn't open in mobile.
Thanks to mimZD and xet7 !

Fixes #5736
2025-04-21 16:07:43 +03:00
Firas Saidi 14f2022e21 fix-5434 2025-04-10 11:16:38 +01:00
Lauri Ojansivu 23bac73559 Updated translations. 2025-04-05 17:39:29 +03:00
Lauri Ojansivu 2de9b94b01 Updated ChangeLog. 2025-03-31 21:50:47 +03:00
Lauri Ojansivu 05d1736f5f Update Browser-compatibility-matrix.md 2025-03-31 21:45:22 +03:00
Lauri Ojansivu db5346fc5c Update Browser-compatibility-matrix.md 2025-03-31 21:38:06 +03:00
Lauri Ojansivu f09f5bd737 Updated translations. 2025-03-29 21:35:45 +02:00
Lauri Ojansivu d96a1a5c9e v7.84 2025-03-23 17:33:57 +02:00
Lauri Ojansivu ad3cc9c087 Updated translations. 2025-03-22 21:39:15 +02:00
Lauri Ojansivu d0c7bf65a4 Updated ChangeLog. 2025-03-22 21:30:53 +02:00
Lauri Ojansivu bb6ac70f63 Updated dependencies.
Thanks to developers of dependencies !
2025-03-22 21:26:41 +02:00
Lauri Ojansivu c38b9da7d6 Merge pull request #5718 from wekan/dependabot/github_actions/docker/login-action-3.4.0
Bump docker/login-action from 3.3.0 to 3.4.0
2025-03-18 01:37:59 +02:00
dependabot[bot] 19153ca489 Bump docker/login-action from 3.3.0 to 3.4.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/9780b0c442fbb1117ed29e0efdff1e18412f7567...74a5d142397b4f367a81961eba4e8cd7edddf772)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-17 21:00:44 +00:00
Lauri Ojansivu 8e7a5e8cb5 Updated translations. 2025-03-15 22:31:43 +02:00
Lauri Ojansivu 1407059937 Updated ChangeLog. 2025-03-15 19:33:49 +02:00
Lauri Ojansivu a2911bc9c3 Fixed building OpenAPI docs.
Thanks to xet7 !

Fixes #5512
2025-03-15 19:32:16 +02:00
Lauri Ojansivu f99b735746 Updated ChangeLog. 2025-03-11 04:23:55 +02:00
Lauri Ojansivu 4510ddda15 Fix typo at Shortcuts.
Thanks to xet7 !
2025-03-11 04:19:45 +02:00
Lauri Ojansivu 028ec46f46 Updated ChangeLog. 2025-03-09 20:05:08 +02:00
Lauri Ojansivu c0e4e01deb Added developer docs about Login code.
Thanks to xet7 !

Fixes #5714
2025-03-09 20:03:42 +02:00
Lauri Ojansivu cfcf682134 Updated ChangeLog. 2025-03-09 19:08:20 +02:00
Lauri Ojansivu 27bd9817d7 Merge pull request #5712 from Rayene123/Time-on-Minicard-for-Start/End/Due-Date
Time on minicard for start/end/due date
2025-03-09 19:03:54 +02:00
Firas Saidi dc389a68ab bug_fixing 2025-03-09 16:23:37 +01:00
Rayene123 6d982cdfd9 formatted the date when storing it 2025-03-09 14:15:17 +00:00
Rayene123 827ee615c1 added the start , due , end hour 2025-03-09 14:12:20 +00:00
Lauri Ojansivu f5f0ba721e v7.83 2025-03-08 21:32:37 +02:00
Lauri Ojansivu 1344f85986 Updated ChangeLog. 2025-03-08 21:14:12 +02:00
Lauri Ojansivu e7462ada12 Reverted Docker changes of WeKan v7.68 to get WeKan Docker version working.
Thanks to xet7 !

Fixes #5697
2025-03-08 21:09:09 +02:00
Lauri Ojansivu 11199b6225 Updated ChangeLog. 2025-03-08 19:58:05 +02:00
Lauri Ojansivu 345aece0f2 Updated ChangeLog. 2025-03-08 19:55:49 +02:00
Lauri Ojansivu 912c84422b Merge branch 'Firas-Git-CopyCard_FixError' 2025-03-08 19:52:42 +02:00
Lauri Ojansivu b402676079 Removed siteurl from manifest to fix browser console error about not matching URL.
Thanks to xet7 !
2025-03-08 19:51:23 +02:00
Lauri Ojansivu 908a5fc60d Comment out error message of non-existing Custom Field.
Thanks to xet7 !

Related #5684
2025-03-08 19:50:00 +02:00
Lauri Ojansivu 38e57d3635 Merge branch 'CopyCard_FixError' of github.com:Firas-Git/wekan into Firas-Git-CopyCard_FixError 2025-03-08 19:46:19 +02:00
Firas Saidi 14167b19b9 cards file 2025-03-08 18:02:03 +01:00
Lauri Ojansivu fc548b426d Updated translations. 2025-03-08 17:45:02 +02:00
Zegden Rayen 094f13934c added the confirm pop up before cloning or archiving a board 2025-03-08 15:38:22 +00:00
Lauri Ojansivu 71acd9603e Updated ChangeLog. 2025-03-06 01:52:46 +02:00
Lauri Ojansivu 341f655ab7 Merge pull request #5704 from wekan/dependabot/github_actions/docker/build-push-action-6.15.0
Bump docker/build-push-action from 6.14.0 to 6.15.0
2025-03-05 19:33:04 +02:00
Lauri Ojansivu 0c5323c106 Merge pull request #5703 from wekan/dependabot/github_actions/docker/metadata-action-5.7.0
Bump docker/metadata-action from 5.6.1 to 5.7.0
2025-03-05 19:30:27 +02:00
dependabot[bot] 7f871fdf30 Bump docker/build-push-action from 6.14.0 to 6.15.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.14.0 to 6.15.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/0adf9959216b96bec444f325f1e493d4aa344497...471d1dc4e07e5cdedd4c2171150001c434f0b7a4)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 20:41:23 +00:00
dependabot[bot] 6347b40a02 Bump docker/metadata-action from 5.6.1 to 5.7.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.6.1 to 5.7.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/369eb591f429131d6889c46b94e711f089e6ca96...902fa8ec7d6ecbf8d84d538b9b233a880e428804)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 20:41:20 +00:00
Lauri Ojansivu bce84a432a Updated ChangeLog. 2025-03-02 12:03:22 +02:00
Lauri Ojansivu b6fc4deb63 Merge pull request #5702 from adam-fu/main
Adding Development information to readme
2025-03-02 12:00:54 +02:00
adam-fu 6b48f9e259 Adding Development information to readme 2025-03-02 06:43:29 +01:00
Lauri Ojansivu 44b7666426 Merge branch 'main' of github.com:wekan/wekan 2025-02-25 14:33:34 +02:00
Lauri Ojansivu ef70ed76a2 Updated changelog 2025-02-25 14:33:06 +02:00
Lauri Ojansivu a1a1b3d1ee Merge pull request #5696 from wekan/dependabot/github_actions/docker/build-push-action-6.14.0
Bump docker/build-push-action from 6.13.0 to 6.14.0
2025-02-24 23:21:55 +02:00
dependabot[bot] 0326757399 Bump docker/build-push-action from 6.13.0 to 6.14.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.13.0 to 6.14.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/ca877d9245402d1537745e0e356eab47c3520991...0adf9959216b96bec444f325f1e493d4aa344497)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-24 21:18:37 +00:00
Lauri Ojansivu edbc8ed92b v7.82 2025-02-24 20:21:33 +02:00
Lauri Ojansivu 07e9ec0617 Updated ChangeLog. 2025-02-24 15:12:07 +02:00
Lauri Ojansivu 18d0fa4327 Fixed building WeKan. Updated dompurify. Forked Meteor 2.14 version of meteor-node-stubs to update elliptic.
Thanks to delopers of depedencies and xet7 !

Fixes #5694
2025-02-24 14:56:54 +02:00
Lauri Ojansivu 666ee84033 Updated dependencies.
Thanks to developes of dependencies "
2025-02-23 15:55:20 +02:00
Lauri Ojansivu 120642f47d Updated ChangeLog. 2025-02-21 21:22:14 +02:00
Lauri Ojansivu 148b81262d Updated requirements at docs.
Thanks to mueller-ma !

Fixes #5692
2025-02-21 21:12:28 +02:00
Lauri Ojansivu c41467f76e Merge pull request #5691 from wekan/dependabot/npm_and_yarn/dompurify-3.2.4
Bump dompurify from 2.5.6 to 3.2.4
2025-02-15 15:47:49 +02:00
dependabot[bot] c83e83b8b1 Bump dompurify from 2.5.6 to 3.2.4
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 2.5.6 to 3.2.4.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/2.5.6...3.2.4)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-15 08:58:49 +00:00
Lauri Ojansivu 563a508e26 Added missing ) character.
Thanks to xet7 !
2025-02-11 22:12:57 +02:00
Lauri Ojansivu 1d8347cc23 Merge pull request #5682 from salleman33/devel
Update metrics.js
2025-02-11 17:28:33 +02:00
salleman 874abf2c41 Update metrics.js
Add possibility to use a token in place of ipaddress to access metrics route
2025-02-11 12:06:23 +01:00
Lauri Ojansivu 3e18f820ea v7.81 2025-02-07 16:13:52 +02:00
Lauri Ojansivu b571f1c953 Upgraded to MongoDB 6.0.20 at Snap Candidate.
Thanks to MongoDB developers!
2025-02-07 16:11:48 +02:00
Lauri Ojansivu fd69c7ceb8 Updated ChangeLog. 2025-02-05 04:41:42 +02:00
Lauri Ojansivu d15faa1890 Updated ChangeLog. 2025-01-29 14:15:31 +02:00
Lauri Ojansivu 0c7e12c5e7 Added Meteor 3.1 learning course to docs.
Thanks to producer of learning course !
2025-01-29 14:13:21 +02:00
Lauri Ojansivu 36a3077853 Fix misspelling of hours at env variable setting LDAP_BACKGROUND_SYNC_INTERVAL.
Thanks to hubermam !

Fixes #5665
2025-01-29 14:09:31 +02:00
Lauri Ojansivu 51bc23dbd9 Updated ChangeLog. 2025-01-29 13:40:34 +02:00
Lauri Ojansivu 0b1e0bd395 Fixed env variable METRICS_ACCEPTED_IP_ADDRESS to be same as at docs.
Thanks to salleman33 !

Fixes #5671
2025-01-29 13:38:40 +02:00
Lauri Ojansivu 151aafd114 Updated ChangeLog. 2025-01-29 10:23:12 +02:00
Lauri Ojansivu 16c8a65a1c Updated ChangeLog. 2025-01-29 10:22:08 +02:00
Lauri Ojansivu f3133e9cd8 Merge pull request #5670 from wekan/dependabot/github_actions/docker/build-push-action-6.13.0
Bump docker/build-push-action from 6.12.0 to 6.13.0
2025-01-29 10:14:55 +02:00
dependabot[bot] de84aa7674 Bump docker/build-push-action from 6.12.0 to 6.13.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.12.0 to 6.13.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/67a2d409c0a876cbe6b11854e3e25193efe4e62d...ca877d9245402d1537745e0e356eab47c3520991)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-27 20:17:17 +00:00
Lauri Ojansivu 1bdbfe86bb Merge pull request #5663 from wekan/dependabot/github_actions/helm/chart-releaser-action-1.7.0
Bump helm/chart-releaser-action from 1.6.0 to 1.7.0
2025-01-21 22:44:23 +02:00
Lauri Ojansivu 397b9f439e Merge pull request #5662 from wekan/dependabot/github_actions/docker/build-push-action-6.12.0
Bump docker/build-push-action from 6.11.0 to 6.12.0
2025-01-21 22:44:12 +02:00
dependabot[bot] 261e0aee0f Bump helm/chart-releaser-action from 1.6.0 to 1.7.0
Bumps [helm/chart-releaser-action](https://github.com/helm/chart-releaser-action) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/helm/chart-releaser-action/releases)
- [Commits](https://github.com/helm/chart-releaser-action/compare/v1.6.0...v1.7.0)

---
updated-dependencies:
- dependency-name: helm/chart-releaser-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 20:02:15 +00:00
dependabot[bot] a6d9bde658 Bump docker/build-push-action from 6.11.0 to 6.12.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.11.0 to 6.12.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/b32b51a8eda65d6793cd0494a773d4f6bcef32dc...67a2d409c0a876cbe6b11854e3e25193efe4e62d)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 20:02:13 +00:00
Lauri Ojansivu 8d0a07e1a8 Updated translations. 2025-01-19 23:06:23 +02:00
Lauri Ojansivu 659615e6f2 Merge pull request #5658 from wekan/dependabot/github_actions/docker/build-push-action-6.11.0
Bump docker/build-push-action from 6.10.0 to 6.11.0
2025-01-15 12:18:49 +02:00
dependabot[bot] 9f0b82c0d5 Bump docker/build-push-action from 6.10.0 to 6.11.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.10.0 to 6.11.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/48aba3b46d1b1fec4febb7c5d0c644b249a11355...b32b51a8eda65d6793cd0494a773d4f6bcef32dc)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-13 20:55:32 +00:00
Lauri Ojansivu 9a23dcc991 v7.80 2025-01-12 23:48:05 +02:00
Lauri Ojansivu 980d345305 Updated ChangeLog. 2025-01-12 23:19:51 +02:00
Lauri Ojansivu 41f76ee974 Updated translations. 2025-01-11 20:53:31 +02:00
Lauri Ojansivu 83a60e6303 Merge pull request #5655 from NadavTasher/bugfix/fix-assignment-of-removed-members
Fix assignee toggling keyboard shortcut to only toggle current board members
2025-01-03 17:32:58 +02:00
Nadav Tasher 7b23c85117 Fix assignee toggling keyboard shortcut to only toggle current board members 2025-01-03 17:15:40 +02:00
Lauri Ojansivu ff3900d100 Merge pull request #5654 from NadavTasher/bugfix/mouse-over-card-reactive-cache 2025-01-03 16:12:17 +02:00
Nadav Tasher e5e4b8ebfb Fix card issues with ReactiveCache when using keyboard shortcuts
When using ReactiveCache.getCard, a buggy instance of Card is returned.
The bug experienced is that .assignees and .members are not always up-to-date.

This can be reproduced by trying to hover over cards and triggering a keyboard
shortcut that interacts with a card.
2025-01-03 12:08:08 +02:00
Lauri Ojansivu 9516b75d65 Updated translations. 2025-01-02 19:39:08 +02:00
Lauri Ojansivu 6b1a92001a v7.79 2025-01-02 13:08:53 +02:00
Lauri Ojansivu e4e1fdb187 Updated ChangeLog. 2025-01-02 12:59:37 +02:00
Lauri Ojansivu 58ad80218a Updated translations. 2025-01-02 12:40:14 +02:00
Lauri Ojansivu 3322d3b33d Merge pull request #5652 from NadavTasher/feature/toggle-week-of-year-display
Feature - Add toggle for week-of-year in date displays (ISO 8601)
2025-01-02 12:07:23 +02:00
Lauri Ojansivu bd9d0c2d1b Updated translations. 2025-01-02 06:11:10 +02:00
Lauri Ojansivu 02b99e0555 Merge pull request #5653 from NadavTasher/feature/assign-members-by-numbers
Feature - Assign members using keyboard shortcut `Ctrl+Alt+[1-9]`
2025-01-02 06:01:32 +02:00
Nadav Tasher f803190dd2 Change shortcut help message 2025-01-01 22:54:51 +02:00
Nadav Tasher deb3a8389a Fix member index bug in keyboard shortcut 2025-01-01 22:26:59 +02:00
Nadav Tasher e7d02c12eb Added translation for new assigning keyboard shortcut 2025-01-01 22:23:21 +02:00
Nadav Tasher 169eaa180b Added support for assigning members to cards using Ctrl+Alt+Num 2025-01-01 22:22:57 +02:00
Nadav Tasher 08cde06ce5 Support show week of year toggle in cardCustomFields 2025-01-01 21:13:55 +02:00
Nadav Tasher 4607bfe454 Support week of year toggle in cardDate 2025-01-01 21:13:30 +02:00
Nadav Tasher de0eece27c Add show week of year translation 2025-01-01 21:13:03 +02:00
Nadav Tasher 25ad901fb3 Add show week of year toggle to sidebar 2025-01-01 21:12:38 +02:00
Nadav Tasher 99e579f47d Add week of year toggle state in user model 2025-01-01 21:12:04 +02:00
Lauri Ojansivu 7df278e805 v7.78 2024-12-31 23:13:54 +02:00
Lauri Ojansivu 34325dde8c Updated translations. 2024-12-31 23:09:25 +02:00
Lauri Ojansivu c7e3cc7e0a Updated ChangeLog. 2024-12-31 22:57:49 +02:00
Lauri Ojansivu 826876ff11 Merge pull request #5649 from NadavTasher/bugfix/fix-list-header-width-in-cleandark-theme
Fix list header too wide in cleanlight and cleandark themes
2024-12-31 22:56:34 +02:00
Lauri Ojansivu b031da6c6d Updated ChangeLog. 2024-12-31 22:55:53 +02:00
Lauri Ojansivu 43e15a1ef4 Merge pull request #5648 from NadavTasher/bugfix/keyboard-shortcuts-behaving-differently-with-caps
Fix upper-case keyboard shortcuts & different language shortcuts getting triggered when shortcuts are disabled
2024-12-31 22:54:35 +02:00
Lauri Ojansivu 7c32188968 Updated ChangeLog. 2024-12-31 22:53:58 +02:00
Lauri Ojansivu 78d38bc4e2 Merge pull request #5647 from NadavTasher/bugfix/change-assign-self-shortcut
Fix assign-self shortcut in shortcut help popup (different from actual shortcut)
2024-12-31 22:52:42 +02:00
Lauri Ojansivu f942631fd4 Updated ChangeLog. 2024-12-31 22:52:01 +02:00
Lauri Ojansivu 5d64c28e89 Merge pull request #5646 from NadavTasher/feature/additional-card-archive-shortcut
Add additional archiving keyboard shortcut (added `-`)
2024-12-31 22:51:06 +02:00
Lauri Ojansivu 485c2f0a7d Updated ChangeLog. 2024-12-31 22:50:31 +02:00
Lauri Ojansivu 3d894d0e56 Merge pull request #5645 from NadavTasher/bugfix/vertical-scrollbar-toggle-style
Fix styling for vertical scrollbars toggle
2024-12-31 22:48:32 +02:00
Lauri Ojansivu b265701844 Updated ChangeLog. 2024-12-31 22:47:56 +02:00
Lauri Ojansivu 468760bd31 Merge pull request #5644 from NadavTasher/bugfix/hide-scrollbars-on-old-browser-versions
Disable scrollbars on older versions of Chrome and Safari in "no vertical scrollbars" mode
2024-12-31 22:46:01 +02:00
Nadav Tasher f03744d99b Fix list header too wide in cleanlight and cleandark themes 2024-12-31 21:42:42 +02:00
Nadav Tasher 26e78a1381 Fix upper-case keyboard shortcuts & different language shortcuts getting triggered when shortcuts are disabled 2024-12-31 21:18:17 +02:00
Nadav Tasher 44aeb323d9 Change assign-self shortcut in shortcut help popup 2024-12-31 19:47:21 +02:00
Nadav Tasher 503298a33f Add additional archiving keyboard shortcut 2024-12-31 19:38:46 +02:00
Nadav Tasher 58b456d5d5 Fix styling for vertical scrollbars toggle 2024-12-31 19:30:22 +02:00
Nadav Tasher d370cac14c Disable scrollbars on older versions of Chrome and Safari 2024-12-31 19:17:06 +02:00
Lauri Ojansivu b29c19f5e0 Merge newest changes. 2024-12-31 01:26:43 +02:00
Lauri Ojansivu a3ba0cf6d5 Updated translations. 2024-12-31 01:26:01 +02:00
Lauri Ojansivu 8bb089fe07 Updated translations. 2024-12-31 00:37:44 +02:00
Lauri Ojansivu 7ba66f6386 Updated translations. 2024-12-31 00:22:15 +02:00
Lauri Ojansivu b537f9b20a Merge pull request #5643 from NadavTasher/feature/optional-vertical-scrollbars
Allow vertical scrollbars to be disabled (new preference)
2024-12-30 23:44:33 +02:00
Lauri Ojansivu 7abe8d71a8 v7.77 2024-12-30 23:32:34 +02:00
Nadav Tasher 3e01231874 Allow vertical scrollbars to be disabled (user preferences, visible by default) 2024-12-30 23:22:54 +02:00
Lauri Ojansivu fb8e23dc4b Updated translations. 2024-12-30 23:20:32 +02:00
Lauri Ojansivu bf0d6cad2c Updated ChangeLog. 2024-12-30 23:18:04 +02:00
Lauri Ojansivu 5a9d36341c Merge pull request #5642 from NadavTasher/bugfix/generic-fix-for-keyboard-shortcuts-stop-callback
Fix "SPACE" shortcut not working after recent fixes
2024-12-30 23:17:14 +02:00
Lauri Ojansivu c7bf0b24a7 Updated ChangeLog. 2024-12-30 23:16:35 +02:00
Lauri Ojansivu d69a505928 Merge pull request #5641 from NadavTasher/bugfix/fix-weird-add-checklist-buttons-in-card-details
Fix weird add checklist buttons in card details
2024-12-30 23:15:24 +02:00
Lauri Ojansivu 7980899f37 Updated ChangeLog. 2024-12-30 23:14:39 +02:00
Lauri Ojansivu 91d245a414 Merge pull request #5640 from NadavTasher/bugfix/fix-bad-comments-background-in-dark-theme
Fix comment backgrounds in cleandark theme
2024-12-30 23:13:53 +02:00
Lauri Ojansivu 5db8d45f4d Updated ChangeLog. 2024-12-30 23:13:07 +02:00
Lauri Ojansivu ee4f09845c Merge pull request #5639 from NadavTasher/feature/enable-keyboard-shortcuts-by-default
Enable keyboard shortcuts by default
2024-12-30 23:11:26 +02:00
Nadav Tasher 01a717f143 Generic fix for keyboard shortcuts which fixes "SPACE" shortcut and more bugs 2024-12-30 21:03:18 +02:00
Nadav Tasher efd22df657 Add some padding to checklist title to make it seperate from card details body 2024-12-30 20:31:28 +02:00
Nadav Tasher 2948e0aa4f Fix confusing and broken "Add checklist" and "Add subtask" buttons in card details view 2024-12-30 20:31:00 +02:00
Nadav Tasher b253683b3c Fix comment backgrounds in cleandark theme 2024-12-30 20:23:54 +02:00
Nadav Tasher 189ebd4201 Enable keyboard shortcuts by default 2024-12-30 20:15:52 +02:00
Lauri Ojansivu f1810e47e0 v7.76 2024-12-30 01:57:04 +02:00
Lauri Ojansivu 37f7924524 Updated ChangeLog. 2024-12-30 01:37:27 +02:00
Lauri Ojansivu 6427a5e5f1 Merge pull request #5635 from NadavTasher/bugfix/move-swimlane-creation-button-to-board-header
Move swimlane creation button to board header when using swimlane view mode
2024-12-30 01:33:48 +02:00
Nadav Tasher 96e11cb727 Display new swimlane creation button when no swimlanes exist 2024-12-30 01:25:25 +02:00
Lauri Ojansivu a5f9157217 Updated ChangeLog. 2024-12-30 00:42:33 +02:00
Lauri Ojansivu 133066c900 Merge pull request #5636 from NadavTasher/bugfix/esc-keyboard-shortcut-not-working
Always handle the escape key when shortcuts are enabled
2024-12-30 00:39:53 +02:00
Nadav Tasher cf75623184 Always handle the escape key when shortcuts are enabled 2024-12-30 00:34:40 +02:00
Nadav Tasher fecae8d0a3 Revert "Move swimlane creation button to board header when using swimlane view mode"
This reverts commit d51e8d1d1d.
2024-12-30 00:17:56 +02:00
Lauri Ojansivu f1d8220ab7 v7.75 2024-12-29 23:50:26 +02:00
Nadav Tasher d51e8d1d1d Move swimlane creation button to board header when using swimlane view mode 2024-12-29 22:54:32 +02:00
Lauri Ojansivu 9a761d2a77 Updated ChangeLog. 2024-12-29 22:40:22 +02:00
Lauri Ojansivu 407d018067 Fix Cannot save Layout settings.
Thanks to tensor5g and xet7 !

Fixes #5630
2024-12-29 22:38:19 +02:00
Lauri Ojansivu 028b8b606a Updated ChangeLog. 2024-12-29 22:19:47 +02:00
Nadav Tasher ad0e86d725 Remove keyboard shortcut toggle from board header 2024-12-29 22:14:55 +02:00
Nadav Tasher 8aeed8b033 Impove margins around shortcuts toggle 2024-12-29 22:12:45 +02:00
Lauri Ojansivu 989c73f1f1 Updated translations. 2024-12-29 16:56:17 +02:00
Lauri Ojansivu f6a3a04dba Updated translations. 2024-12-25 20:40:37 +02:00
Lauri Ojansivu 8ff11ccc88 v7.74 2024-12-25 07:25:21 +02:00
Lauri Ojansivu 5d145d0dd1 Updated ChangeLog. 2024-12-25 07:17:29 +02:00
Lauri Ojansivu 275ac445d0 Keyboard Shortcuts Enable/Disable is now at Right Sidebar, where already was list of Keyboard Shortcuts.
Thanks to xet7 !

Fixes https://github.com/wekan/wekan/pull/5628
2024-12-25 07:14:22 +02:00
Lauri Ojansivu 7fc364cb63 Updated translations. 2024-12-25 06:51:18 +02:00
Lauri Ojansivu 93868fd905 Updated ChangeLog. 2024-12-25 06:47:51 +02:00
Lauri Ojansivu a862486ec3 "Auto List Width" is now at "List ☰ Set Width" popup.
Thanks to xet7 !

Fixes https://github.com/wekan/wekan/pull/5628
2024-12-25 06:43:02 +02:00
Lauri Ojansivu 14c9b70149 Updated translations. 2024-12-25 05:42:21 +02:00
Lauri Ojansivu b60c655b98 Updated ChangeLog. 2024-12-25 05:20:10 +02:00
Lauri Ojansivu fe5475d5ec Updated ChangeLog. 2024-12-25 05:01:55 +02:00
Lauri Ojansivu 955a46ca60 Fixes keyboard shortcuts defaults, icons and texts to be more understandable.
Thanks to xet7 !

Fixes https://github.com/wekan/wekan/pull/5628
2024-12-25 04:59:15 +02:00
Nadav Tasher 0d0c88ceaa Add translations for keyboard shortcut actions 2024-12-25 00:32:46 +02:00
Nadav Tasher fb008569ab Make sure keyboard shortcuts are enabled and no text is selected on shortcut triggers 2024-12-25 00:24:41 +02:00
Nadav Tasher 295c9c8617 Allow toggling profile.keyboardShortcuts from boardHeader 2024-12-25 00:23:18 +02:00
Nadav Tasher 658e43ab54 Add profile.keyboardShortcuts to User model 2024-12-25 00:22:37 +02:00
Nadav Tasher 41b1227b17 Add keyboard shortcut toggle 2024-12-25 00:22:04 +02:00
Nadav Tasher 68c7a41906 Revert "Hide and disable Keyboard Shortcuts, because they make using Ctrl-C to copy etc impossible."
This reverts commit 5606414f89.
2024-12-24 21:41:25 +02:00
Nadav Tasher 18f6d4cb16 Revert "Part 2. Hide and disable Keyboard Shortcuts, because they make using Ctrl-C to copy etc impossible."
This reverts commit 94391d4cde.
2024-12-24 21:41:13 +02:00
Nadav Tasher 7c60d7932a Revert "Part 3. Hide and disable Keyboard Shortcuts, because they make using Ctrl-C to copy etc impossible."
This reverts commit 8b73c702c3.
2024-12-24 21:41:03 +02:00
Lauri Ojansivu b9182a1fc7 v7.73 2024-12-24 20:16:31 +02:00
Lauri Ojansivu e45d35ba60 Updated ChangeLog. 2024-12-24 20:05:38 +02:00
Lauri Ojansivu 8b73c702c3 Part 3. Hide and disable Keyboard Shortcuts, because they make using Ctrl-C to copy etc impossible.
Thanks to xet7 !

Fixes #5603,
fixes #2423,
fixes #1878,
fixes #931
2024-12-24 20:04:35 +02:00
Lauri Ojansivu 8e744e860d Updated ChangeLog. 2024-12-24 19:55:25 +02:00
Lauri Ojansivu 94391d4cde Part 2. Hide and disable Keyboard Shortcuts, because they make using Ctrl-C to copy etc impossible.
Thanks to xet7 !

Fixes #5603,
fixes #2423,
fixes #1878,
fixes #931
2024-12-24 19:54:17 +02:00
Lauri Ojansivu 4e73c56afe Updated ChangeLog. 2024-12-24 19:48:38 +02:00
Lauri Ojansivu 5606414f89 Hide and disable Keyboard Shortcuts, because they make using Ctrl-C to copy etc impossible.
Thanks to xet7 !

Fixes #5603,
fixes #2423,
fixes #1878,
fixes #931
2024-12-24 19:41:56 +02:00
Lauri Ojansivu 8ebb1a7d7f Updated translations. 2024-12-24 19:34:00 +02:00
Lauri Ojansivu 586043e00b Updated ChangeLog. 2024-12-24 19:32:49 +02:00
Lauri Ojansivu e70c51a1f0 Hide Accessibility Settings at Admin Panel. It will be continued and added back later.
Thanks to xet7 !
2024-12-24 19:31:15 +02:00
Lauri Ojansivu ea8f8de391 Updated ChangeLog. 2024-12-24 19:29:49 +02:00
Lauri Ojansivu 0332ef3298 Hide support popup. It will be made editable later.
Thanks to xet7 !
2024-12-24 19:28:20 +02:00
Lauri Ojansivu 751b0aa073 Merge branch 'main' of github.com:wekan/wekan 2024-12-21 12:49:02 +02:00
Lauri Ojansivu 965db42170 Updated translations. 2024-12-21 12:48:47 +02:00
Lauri Ojansivu 73f16692da Updated 2024-12-21 12:48:36 +02:00
Lauri Ojansivu aab80e67bd Updated ChangeLog. 2024-12-17 19:59:29 +02:00
Lauri Ojansivu 3e3b629aa2 Updated Developer Docs about docker compose.
Thanks to sridharin2020 and xet7 !

Related https://github.com/wekan/wekan/discussions/5622
2024-12-17 19:57:29 +02:00
Lauri Ojansivu adeec24252 Updated ChangeLog. 2024-12-15 18:01:32 +02:00
Lauri Ojansivu ba0fdaef72 Revert back to have shortcut "c to archive" back for non-Persian keyboards.
Thanks to hatl and xet7 !

Related #1878
2024-12-15 17:58:48 +02:00
Lauri Ojansivu c357c77e7e Updated translations. 2024-12-13 02:12:40 +02:00
Lauri Ojansivu 702375856d Updated ChangeLog. 2024-12-13 02:08:35 +02:00
Lauri Ojansivu c936d83b38 Reverted all previous Oauth2 filepath code, thinking is there some better way.
Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/5619,
related https://github.com/wekan/wekan/pull/5616
2024-12-13 01:51:42 +02:00
Lauri Ojansivu 83d22c9ebf Updated translations. 2024-12-12 04:47:22 +02:00
Lauri Ojansivu 02f45f4e65 Merge pull request #5614 from NadavTasher/feature/change-default-maximum-width-for-lists
Changed the default maximum list width
2024-12-12 03:13:05 +02:00
Lauri Ojansivu da2ba45456 Merge pull request #5618 from NadavTasher/bugfix/weird-dragscroll-behaviour-in-lists-view
Fix buggy behaviours in board dragscrolling
2024-12-12 03:12:49 +02:00
Lauri Ojansivu 0566f7c89b Merge pull request #5616 from walster001/main
Add functionality to cross-check emails against a known local server-side file on OIDC login.
2024-12-12 03:11:24 +02:00
Nadav Tasher 30a2e8b990 Fix dragscroll getting stuck on view changes 2024-12-11 23:04:10 +02:00
Nadav Tasher 81b2bce385 Allow dragscrolling the board in Lists view mode 2024-12-11 22:19:52 +02:00
walster001 a5347cfcac Update wekan-help with local file email changes. 2024-12-12 00:52:28 +10:30
walster001 3422db31ee Local email checking modifications 2024-12-12 00:47:14 +10:30
walster001 755880ec90 Add OAUTH2 Email check keys 2024-12-12 00:41:19 +10:30
walster001 30273709ae Add support for external email verification
Add support for external email verification against OIDC login script. This will check local file for presence of email and log the user in if it is or deny them if it isn't.
2024-12-12 00:34:22 +10:30
Nadav Tasher 17f4bbde20 Changed the default maximum list width 2024-12-10 21:23:12 +02:00
Lauri Ojansivu 575e3750f1 Updated translations. 2024-12-09 23:05:57 +02:00
Lauri Ojansivu d7c8eced81 Revert changing URLs and email addresses. 2024-12-09 18:00:14 +02:00
Lauri Ojansivu 86fda62a48 Merge branch 'main' of github.com:wekan/wekan 2024-12-08 17:07:46 +02:00
Lauri Ojansivu a4ec20a7c8 Merge remote-tracking branch 'origin/feature-accessibility' 2024-12-08 17:07:39 +02:00
Lauri Ojansivu 90653c1472 Updated translations. 2024-12-08 17:06:29 +02:00
Lauri Ojansivu 30ec59140c Updated ChangeLog. 2024-12-08 15:04:17 +02:00
Lauri Ojansivu f689d1688a Updated URLs and email addresses.
Thanks to xet7 !
2024-12-08 15:02:43 +02:00
Lauri Ojansivu 57e545e7c4 Updated translations. 2024-12-08 15:01:48 +02:00
Lauri Ojansivu d0ea8e3a81 v7.72 2024-12-08 03:08:28 +02:00
Lauri Ojansivu c188d2bf65 Updated translations. 2024-12-08 03:01:51 +02:00
Lauri Ojansivu 75b3421222 Updated ChangeLog. 2024-12-08 02:59:15 +02:00
Lauri Ojansivu c062bd63bb Fix in API user role is not considered.
Thanks to mohammadZahedian and xet7 !

Fixes #5422
2024-12-08 02:56:37 +02:00
Lauri Ojansivu 0c753e85a8 Updated ChangeLog. 2024-12-08 02:02:26 +02:00
Lauri Ojansivu 32770c02ad Updated translations. 2024-12-08 01:02:19 +02:00
Lauri Ojansivu 133dd55f4c Merge branch 'feature/optional-auto-width' of https://github.com/NadavTasher/wekan 2024-12-08 00:33:58 +02:00
Nadav Tasher d1e2db9cb8 Replace Session.get with utility call 2024-12-07 21:26:25 +02:00
Nadav Tasher 52a02409f0 Use utility function instead of Session.get 2024-12-07 20:37:11 +02:00
Nadav Tasher eb3377deb8 Revert "Use utility function is autoWidth function"
This reverts commit c06bcac9f3.
2024-12-07 20:35:15 +02:00
Nadav Tasher c06bcac9f3 Use utility function is autoWidth function 2024-12-07 19:47:19 +02:00
Nadav Tasher f9f0523112 Updated translations with new texts for auto-width support 2024-12-07 19:00:51 +02:00
Nadav Tasher f7aa5d0871 Add auto-width and constraint support in list 2024-12-07 19:00:08 +02:00
Nadav Tasher 9576f6807b Add missing functions to users model for auto-width 2024-12-07 18:59:30 +02:00
Nadav Tasher efe50a65ee Add list constraint support in set-width popup 2024-12-07 18:59:01 +02:00
Nadav Tasher fb34dd6114 Add auto-width board-header toggle 2024-12-07 18:57:34 +02:00
Nadav Tasher 2ebff3a864 Revert adding migration 2024-12-07 18:56:40 +02:00
Lauri Ojansivu a3f70735ac Fix WeKan Snap Candidate v7.71 build. There was old version number.
Thanks to xet7 !
2024-12-06 11:22:07 +02:00
Lauri Ojansivu e1fd915ecd Updated ChangeLog. 2024-12-06 08:31:39 +02:00
Nadav Tasher 0097674fc0 Added initial support for auto-width lists option 2024-12-05 21:46:35 +02:00
Lauri Ojansivu f6341de610 Updated ChangeLog. 2024-12-05 15:55:49 +02:00
Lauri Ojansivu 17d5fae7bb Updated release scripts: Disabled Docker registry sync. Only pushing WeKan to GitHub, Quay and Docker Hub.
Thanks to xet7 !
2024-12-05 15:52:14 +02:00
Lauri Ojansivu 05eca83b15 v7.71 2024-12-05 13:35:32 +02:00
Lauri Ojansivu 6d004b2095 Updated ChangeLog. 2024-12-05 10:33:31 +02:00
Lauri Ojansivu 46327f19a1 To menu right top username, added Support, to have info about from where to get support.
Thanks to xet7 !
2024-12-05 10:29:15 +02:00
Lauri Ojansivu d4c8ea9361 v7.70 2024-12-04 18:41:05 +02:00
Lauri Ojansivu 7af0ddc226 Updated ChangeLog. 2024-12-04 14:18:43 +02:00
Lauri Ojansivu 80ea1782f9 Move card to archive, add shortcut key ÷ for Persian keyboard.
Thanks to mohammadZahedian and xet7 !

Fixes https://github.com/wekan/wekan/pull/5589,
fixes https://github.com/wekan/wekan/pull/5576.
2024-12-04 14:11:10 +02:00
Lauri Ojansivu aa46b42356 Updated ChangeLog. 2024-12-04 13:08:25 +02:00
Lauri Ojansivu 3cd069ffb9 Merge pull request #5598 from wekan/dependabot/github_actions/docker/build-push-action-6.10.0
Bump docker/build-push-action from 6.9.0 to 6.10.0
2024-12-03 13:39:14 +02:00
dependabot[bot] e621ad6d7c Bump docker/build-push-action from 6.9.0 to 6.10.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.9.0 to 6.10.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/4f58ea79222b3b9dc2c8bbdd6debcef730109a75...48aba3b46d1b1fec4febb7c5d0c644b249a11355)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-02 20:59:24 +00:00
Lauri Ojansivu 729d8fb435 Accessibility statement. Part 1. In Progress.
Thanks to xet7 !
2024-12-02 14:17:58 +02:00
Lauri Ojansivu de2ddbe8b5 Fix typo. 2024-12-02 10:51:48 +02:00
Lauri Ojansivu 57ddd82ef1 v7.69 2024-12-02 08:22:51 +02:00
Lauri Ojansivu 79f7ec2715 Updated release scripts.
Thanks to xet7 !
2024-12-02 08:14:54 +02:00
Lauri Ojansivu ab4c3bd2fc Updated Keycloak etc login settings at start-wekan.bat and start-wekan.sh.
Thanks to xet7 !
2024-12-02 08:10:32 +02:00
Lauri Ojansivu bd3a7e1068 Updated ChangeLog. 2024-12-02 06:19:38 +02:00
Lauri Ojansivu aa33ead7b2 Updated Windows docs. 2024-12-02 06:17:40 +02:00
Lauri Ojansivu 94cf2a80a5 Updated ChangeLog. 2024-11-28 16:37:52 +02:00
Lauri Ojansivu 2ee959a08e Merge pull request #5597 from malteprang/main
Update docker-compose.yml keycloak part
2024-11-28 16:36:33 +02:00
malteprang 54b7591ca0 Update docker-compose.yml keycloak part 2024-11-28 15:00:00 +01:00
Lauri Ojansivu b3f0392e7d Updated translations. 2024-11-27 16:28:48 +02:00
Lauri Ojansivu 77e7350e96 Updated ChangeLog. 2024-11-27 16:25:51 +02:00
Lauri Ojansivu 9c87572f90 Updated dependencies.
Thanks to developers of dependencies !
2024-11-27 16:24:11 +02:00
Lauri Ojansivu 65765f6c2f Updated ChangeLog. 2024-11-27 16:16:31 +02:00
Lauri Ojansivu 785b312009 Merge pull request #5595 from walster001/main
Fix issue with comments not showing
2024-11-27 14:48:55 +02:00
walster001 1d9a710e3b Fix issue with comments not showing 2024-11-27 22:05:43 +10:30
Lauri Ojansivu 909bf811d1 Merge pull request #5590 from wekan/dependabot/github_actions/docker/metadata-action-5.6.1
Bump docker/metadata-action from 5.5.1 to 5.6.1
2024-11-25 23:19:01 +02:00
dependabot[bot] 90abe01286 Bump docker/metadata-action from 5.5.1 to 5.6.1
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.5.1 to 5.6.1.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/8e5442c4ef9f78752691e2d8f8d19755c6f78e81...369eb591f429131d6889c46b94e711f089e6ca96)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-25 21:17:31 +00:00
Lauri Ojansivu 2c13d74c5f Merge pull request #5589 from NadavTasher/feature/change-card-archive-shortcut
Opinion - Change archive-card shortcut to backtick for better ergonomics
2024-11-24 22:13:21 +02:00
Lauri Ojansivu 5d975c5da4 Updated ChangeLog. 2024-11-24 21:17:10 +02:00
Nadav Tasher 35c1057527 Change archive-card shortcut to backtick for better ergonomics 2024-11-24 20:55:36 +02:00
Lauri Ojansivu 3912181857 v7.68 2024-11-24 20:44:30 +02:00
Lauri Ojansivu b9a01eb5d6 Updated ChangeLog. 2024-11-24 20:35:28 +02:00
Lauri Ojansivu 3027f0acb0 Updated translations. 2024-11-24 20:34:34 +02:00
Lauri Ojansivu 609c2a5ddb Updated ChangeLog. 2024-11-24 20:33:32 +02:00
Lauri Ojansivu f76d648012 Merge branch 'feature/new-dockerfile' of https://github.com/NadavTasher/wekan 2024-11-24 20:13:14 +02:00
Nadav Tasher 203bf92a0a Fix data directory regression 2024-11-24 19:49:32 +02:00
Lauri Ojansivu 3e8cc9e905 Merge branch 'feature/new-dockerfile' of https://github.com/NadavTasher/wekan 2024-11-24 04:22:27 +02:00
Nadav Tasher b9f32c1739 Remove ulimit from Dockerfile 2024-11-24 02:01:10 +02:00
Nadav Tasher 7e1c65f616 Removed stack-size changing, replaced with FD limit 2024-11-24 01:29:56 +02:00
Nadav Tasher 447ae93476 Updated NodeJS version to v14.21.4 (Meteor ESM) 2024-11-24 00:46:29 +02:00
Nadav Tasher 6df40f41ac Change source of GitHub wekan packages to HTTPs (eliminates git ls-remote) 2024-11-23 23:21:12 +02:00
Nadav Tasher 3e0ef3d070 Created efficient multi-stage Dockerfile 2024-11-23 23:20:57 +02:00
Lauri Ojansivu 33a17a9a1b v7.67 2024-11-21 01:42:38 +02:00
Lauri Ojansivu aed4bfb7f4 Updated translations. 2024-11-21 01:33:11 +02:00
Nadav Tasher 78f7c3e5bd Updated theming documentation on sidebar coloring 2024-11-21 00:43:20 +02:00
Nadav Tasher d764047c1f Remove non-effective height property (does nothing here) 2024-11-21 00:42:23 +02:00
Nadav Tasher 65015ea7c7 Remove non-required sidebar-shadow div in favor of direct sidebar background 2024-11-21 00:41:57 +02:00
Nadav Tasher 6ef2d9cb9d Remove bottom margin from sidebar (causes an out-of-theme white gap) 2024-11-21 00:24:40 +02:00
Nadav Tasher c39fdab11d Disable scrollbar hiding in swimlanes 2024-11-21 00:14:04 +02:00
Nadav Tasher 547261abb6 Disable scrollbar hiding in sidebar 2024-11-21 00:13:50 +02:00
Nadav Tasher 7696b7b769 Disable scrollbar hiding in list 2024-11-21 00:13:34 +02:00
Nadav Tasher 585635494a Disable scrollbar hiding in cardDetails 2024-11-21 00:13:22 +02:00
Nadav Tasher a36e80099a Revert "Revert some scrollbar, sidebar and list width changes."
This reverts commit 096fe130f6.
2024-11-21 00:10:49 +02:00
Nadav Tasher f5f8a4f6fb Revert "Updated translations."
This reverts commit 83a12a9a26.
2024-11-21 00:10:30 +02:00
Lauri Ojansivu e207bff91f v7.65 2024-11-20 21:22:23 +02:00
Lauri Ojansivu a2c7c230ef Updated ChangeLog. 2024-11-20 21:16:21 +02:00
Lauri Ojansivu 83a12a9a26 Updated translations. 2024-11-20 21:14:01 +02:00
Lauri Ojansivu 096fe130f6 Revert some scrollbar, sidebar and list width changes.
Thanks to xet7 !

Fixes #5585,
fixes https://github.com/wekan/wekan/pull/5583
2024-11-20 21:08:06 +02:00
Lauri Ojansivu 12d22f92b2 v7.64 2024-11-20 09:08:49 +02:00
Lauri Ojansivu 017628e2a6 Updated ChangeLog. 2024-11-20 08:57:40 +02:00
Lauri Ojansivu 332b9f5816 Updated translations. 2024-11-20 08:49:46 +02:00
Lauri Ojansivu 09a96c1118 Updated translations. 2024-11-20 08:15:19 +02:00
Lauri Ojansivu 82750ee8a2 Updated translations. 2024-11-20 03:04:51 +02:00
Lauri Ojansivu 4e89f27768 Updated translations. 2024-11-20 02:53:30 +02:00
Lauri Ojansivu 6f60235a3f Merge pull request #5584 from NadavTasher/feature/fix-minimum-width-on-list-auto-width
Improve list auto-width, fix regressions
2024-11-20 02:47:45 +02:00
Lauri Ojansivu 42be851d64 Merge pull request #5583 from NadavTasher/feature/better-scrollbar-disabling
Change way of disabling scrollbars, disable swimlane scrollbars
2024-11-20 02:44:45 +02:00
Nadav Tasher 6c32c210f8 Disable scrollbars in swimlanes 2024-11-20 01:20:40 +02:00
Nadav Tasher aca665ae4e Changed method of scrollbar hiding 2024-11-20 01:20:10 +02:00
Nadav Tasher 09bee30610 Change list width translation 2024-11-20 00:49:24 +02:00
Nadav Tasher 87d53f6f93 Fix dragscroll inside swimlanes 2024-11-20 00:48:13 +02:00
Nadav Tasher 98cf7ec715 Change max-width to min-width so that lists will only shrink when there is no space left 2024-11-20 00:47:45 +02:00
Lauri Ojansivu 12e50d93df Merge pull request #5581 from NadavTasher/feature/default-lists-to-space-evenly
Make lists fill up space evenly, change listWidth to max-width
2024-11-18 03:24:56 +02:00
Lauri Ojansivu dfcdb1994b Merge pull request #5580 from NadavTasher/bugfix/add-missing-semicolon
Add missing semicolon in keyboard.js
2024-11-18 03:24:28 +02:00
Nadav Tasher 30a5b87370 Change list width to max width, default to even spacing 2024-11-17 23:05:21 +02:00
Nadav Tasher 465e2b1b6a Remove swimlane size limit 2024-11-17 23:03:56 +02:00
Lauri Ojansivu 1ae52bbdb1 Updated translations. 2024-11-17 12:41:56 +02:00
Nadav Tasher d0024d397a Add missing semicolon 2024-11-16 23:35:39 +02:00
Lauri Ojansivu 0b2cdc4d56 v7.63 2024-11-16 21:37:58 +02:00
Lauri Ojansivu 92af6f71d9 Updated scaling docs.
Thanks to xet7 !
2024-11-16 21:36:35 +02:00
Lauri Ojansivu 8879b8498f Updated translations. 2024-11-16 21:19:04 +02:00
Lauri Ojansivu ad7e0e0bf9 Updated ChangeLog. 2024-11-16 21:17:37 +02:00
Lauri Ojansivu edb7398295 Revert adding more stack size.
Thanks to xet7 !
2024-11-16 21:16:30 +02:00
Lauri Ojansivu cfca28e25a Updated translations. 2024-11-16 21:00:46 +02:00
Lauri Ojansivu a811e22f95 Updated ChangeLog. 2024-11-16 20:53:41 +02:00
Lauri Ojansivu fbb2e6e261 Merge pull request #5578 from NadavTasher/feature/various-style-improvements
Sidebar style overhaul - absolute positioning, weird style fixes, disable sidebar scrollbar
2024-11-16 20:19:18 +02:00
Lauri Ojansivu c44b99d515 Merge pull request #5577 from NadavTasher/feature/new-keyboard-shortcut-for-assigning-user
Potential bug(fix?) - Add assign-self keyboard shortcut (old shortcut actually adds)
2024-11-16 20:18:42 +02:00
Lauri Ojansivu 0f283e6cdf Merge pull request #5576 from NadavTasher/bugfix/change-archive-shortcut-to-minus
Change move-to-archive keyboard shortcut to '-', because of Ctrl + C shortcut
2024-11-16 20:17:30 +02:00
Nadav Tasher b7e8f796a3 Sidebar overhaul - change position to absolute, fix weird style bugs, disable scrollbar 2024-11-16 18:56:38 +02:00
Nadav Tasher d63507dd97 Add margin to member and assignee avatars 2024-11-16 17:53:36 +02:00
Nadav Tasher e1168b5107 Added keyboard shortcut to "assign self" and rename old shortcut to "add self" 2024-11-16 17:40:35 +02:00
Nadav Tasher cecb4b8336 Change move-to-archive keyboard shortcut to '-' 2024-11-16 17:34:16 +02:00
Lauri Ojansivu 5bbbf9d0e6 Merge pull request #5575 from NadavTasher/feature/disable-filter-menu-popup-when-using-keyboard-filters
Disable sidebar showing when filtering using keyboard shortcut
2024-11-16 17:33:15 +02:00
Lauri Ojansivu 29775eef9a Updated ChangeLog. 2024-11-16 17:32:45 +02:00
Lauri Ojansivu 3f3e645c96 Merge pull request #5574 from NadavTasher/feature/support-shortcuts-when-not-using-english-keyboard-layout
Patch to allow shortcuts to work when another keyboard layout is used
2024-11-16 17:27:59 +02:00
Nadav Tasher ebece3f961 Disable sidebar showing when filtering using keyboard shortcut 2024-11-16 17:25:42 +02:00
Lauri Ojansivu 4951d409db Updated translations. 2024-11-16 17:22:37 +02:00
Nadav Tasher cf90511f3c Added multi-language support for keyboard shortcuts 2024-11-16 17:21:47 +02:00
Lauri Ojansivu 4ec0e63d99 Merge pull request #5573 from NadavTasher/feature/hide-scrollbars-in-card-details-and-lists
Hide scrollbars where they interrupt
2024-11-16 17:21:29 +02:00
Nadav Tasher 08843a9dd6 Hide scrollbars from lists (middle of the screen) 2024-11-16 17:18:46 +02:00
Nadav Tasher b3f229dc86 Hide scrollbars from card details popup 2024-11-16 17:17:05 +02:00
Lauri Ojansivu 18b74e7a61 Merge pull request #5572 from NadavTasher/feature/right-to-left
Fix some text alignment issues when using RTL languages
2024-11-16 17:16:20 +02:00
Lauri Ojansivu c60961cbb1 Merge pull request #5571 from NadavTasher/feature/always-close-sidebar-on-escape
Always close sidebar when user clicks ESC
2024-11-16 17:15:48 +02:00
Lauri Ojansivu 3338fc366d Merge pull request #5570 from NadavTasher/feature/new-card-keyboard-shortcut
Added 'n' shortcut for adding new minicards to current list
2024-11-16 17:15:22 +02:00
Nadav Tasher 79cbf25b73 Fix some text alignment issues when using RTL languages 2024-11-16 17:14:03 +02:00
Nadav Tasher 7963118032 Always close sidebar on escape button 2024-11-16 17:07:25 +02:00
Nadav Tasher 35e6c938dc Added 'n' shortcut for adding new minicards 2024-11-16 17:03:59 +02:00
Lauri Ojansivu c632bc4555 Merge newest changes. 2024-11-15 23:35:13 +02:00
Lauri Ojansivu 7a34bc3eb0 Updated Docker base image to Ubuntu 24.10.
Thanks to Ubuntu developers !
2024-11-15 23:33:18 +02:00
Lauri Ojansivu 6e0d41834c v7.62 2024-11-15 23:30:15 +02:00
Lauri Ojansivu 4bcbaf9113 Updated ChangeLog. 2024-11-15 23:24:19 +02:00
Lauri Ojansivu 5448a15691 Updated docs sidebar.
Thanks to xet7 !
2024-11-15 23:22:46 +02:00
Lauri Ojansivu c63feb3ff3 Updated ChangeLog. 2024-11-15 23:21:32 +02:00
Lauri Ojansivu fb4d95672e Update Snap Candidate to MongoDB 6.0.19. Updated WeKan Windows version numbers. Added Cron docs.
Thanks to xet7 !
2024-11-15 23:19:36 +02:00
Lauri Ojansivu bfb1658abe Updated translations. 2024-11-15 23:04:29 +02:00
Lauri Ojansivu 79e2c9175f Updated ChangeLog. 2024-11-15 22:56:59 +02:00
Lauri Ojansivu b9c2d49a1c Updated translations. 2024-11-15 22:44:46 +02:00
Lauri Ojansivu a25eb4ded6 Updated translations. 2024-11-15 22:39:14 +02:00
Lauri Ojansivu 3851de2774 Merge pull request #5569 from mfilser/checklist_items_hide_per_checklist
each checklist can now be configured to hide checked checklist items
2024-11-15 22:04:03 +02:00
Martin Filser 0783b733b0 Checklist, hide all checklist items possible, regardless if the checklist item is finished or not 2024-11-15 21:00:06 +01:00
Martin Filser bb17feaa17 Checklist, hide checked checklist items (configureable at each checklist) 2024-11-15 21:00:06 +01:00
Lauri Ojansivu 7623c8dcb7 Merge pull request #5568 from mfilser/checklist_multiline_insert
Checklist multiline insert (many checklist items at once)
2024-11-15 21:59:36 +02:00
Martin Filser 1d7eb8a03b Checklist, adding many items set's now the sorting correctly 2024-11-15 20:56:36 +01:00
Martin Filser c5712f5ae0 Checklist multiline option, adding description to both checkbox options 2024-11-15 20:54:30 +01:00
Martin Filser 00e5808a4c Checklist multiline option, adding option to keep the origin order if many items are added at the checklist top 2024-11-15 20:54:29 +01:00
Lauri Ojansivu 0a591564fd Merge pull request #5567 from mfilser/checklist_items_hide_per_card
Checklist items hide per card
2024-11-15 21:52:25 +02:00
Martin Filser 8448068d22 hide empty checklist if checklist items are hidden
conditions are:
- the checklist must have at least 1 checklist item
- all checklist items have to be finished
- the option "hide checked checklist items" is set at card details
2024-11-15 20:35:18 +01:00
Martin Filser 9fa36c3991 hide checklist-items per card now
- performance relevant
- more granular setting
2024-11-15 20:35:18 +01:00
Martin Filser d949753d54 preparation hide checklist-items per card 2024-11-15 20:35:17 +01:00
Lauri Ojansivu f6d2b08025 Merge pull request #5566 from mfilser/card_comment_section
added comment section on card details to avoid loading the card comment activities from the server
2024-11-15 21:21:12 +02:00
Martin Filser 8a446de3e9 added comment section on card details to avoid loading the card comment activities from the server
- and added to show only the activities a card

- to display the card comments a connection to the server was needed to get the activities of the card comments, now, it's not necessary
- also performance relevant. until now there were a lot of activities loaded, now only of the current card
2024-11-15 19:55:07 +01:00
Lauri Ojansivu 0196f46094 Merge branch 'main' of github.com:wekan/wekan 2024-11-11 17:46:43 +02:00
Lauri Ojansivu bd83b3bc8e Add info about if Snap slow 2024-11-11 17:46:09 +02:00
Lauri Ojansivu 89347abf53 Updated ChangeLog. 2024-11-02 18:56:52 +02:00
Lauri Ojansivu a27f8ecfa9 Fix Warning: missing space before text for line 210 of jade file client/components/activities/activities.jade
Thanks to xet7 !
2024-11-02 18:55:33 +02:00
Lauri Ojansivu 75ca4920c5 Updated ChangeLog. 2024-11-02 18:36:10 +02:00
Lauri Ojansivu 324be07b85 Add more stack size.
Thanks to xet7 !
2024-11-02 18:34:51 +02:00
Lauri Ojansivu 282a5b30f9 Updated ChangeLog. 2024-11-02 18:19:50 +02:00
Lauri Ojansivu b24acefa6f Updated dependencies.
Thanks to developers of dependencies!
2024-11-02 18:18:14 +02:00
Lauri Ojansivu 751b519167 Updated ChangeLog. 2024-11-02 18:17:34 +02:00
Lauri Ojansivu 330aec2bdd Merge pull request #5555 from emmanuel-ferdman/main
Update `ldap-sync.py` reference
2024-11-02 16:42:08 +02:00
Emmanuel Ferdman d5635c3a89 Update ldap-sync.py reference
Signed-off-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
2024-11-01 23:09:16 -07:00
Lauri Ojansivu 1e86d67bfe Updated ChangeLog. 2024-10-31 00:25:30 +02:00
Lauri Ojansivu 8ac9353c53 Copied from Sandstorm developer discussions to docs fix for running Sandstorm at Ubuntu 24.04.
Thanks to xet7 !
2024-10-31 00:23:45 +02:00
Lauri Ojansivu 1557970170 Updated ChangeLog. 2024-10-31 00:13:33 +02:00
Lauri Ojansivu 508bbb37ce Add docs about how at LXC/LXD Fix: System does not fully support snapd.
Thanks to xet7 !
2024-10-31 00:11:15 +02:00
Lauri Ojansivu a90fc396a9 Updated ChangeLog. 2024-10-30 22:36:26 +02:00
Lauri Ojansivu 96627540da Updated docs about Linked Cards.
Thanks to xet7 !
2024-10-30 22:34:53 +02:00
Lauri Ojansivu db6ebe0470 Updated ChangeLog. 2024-10-23 02:06:35 +03:00
Lauri Ojansivu 559251eb0d Copied updated Docs from wiki to WeKan repo.
Thanks to xet7 !
2024-10-23 02:04:30 +03:00
Lauri Ojansivu 23396d1bd6 v7.61 2024-10-23 01:05:15 +03:00
Lauri Ojansivu 9d92a79a28 Updated to MongoDB 6.0.18 at Snap Candidate.
Thanks to MongoDB developers !
2024-10-23 01:02:48 +03:00
Lauri Ojansivu 90a64a7403 Updated ChangeLog. 2024-10-23 00:51:43 +03:00
Lauri Ojansivu f709cc332c Merge pull request #5552 from mfilser/master
Fixing opening cards and slow performance of closing cards
2024-10-23 00:35:49 +03:00
Martin Filser c925a27870 Fixing opening cards and slow performance of closing cards
Fixes: #5533
Fixes: #5548

Revert "Switch from kadira:flow-router to ostrio:flow-router-extra"

This reverts commit 718c1a393d.
2024-10-22 21:45:36 +02:00
Lauri Ojansivu d31403a918 Updated ChangeLog. 2024-10-20 00:08:24 +03:00
Lauri Ojansivu f9051d768c Updated translations. 2024-10-20 00:06:08 +03:00
Lauri Ojansivu 06eb2adeaa Merge pull request #5549 from AdenKoziol/main
renaming list shows in activities
2024-10-20 00:00:01 +03:00
Aden Koziol 12af3a5d10 renaming list shows in activities 2024-10-16 16:40:20 -05:00
Lauri Ojansivu 8bf94d6ac6 Merge pull request #5538 from namar0x0309/patch-1
Update Candidate-WeKan-Snap-Manual-Upgrade.md in order to create a proper sh file snap-settings.sh
2024-10-03 05:44:19 +03:00
Nas A. 15af5d2c2e Update Candidate-WeKan-Snap-Manual-Upgrade.md
"sudo snap get wekan" outputs key value pairs but not sh code to set those values in snap wekan environment. 

Fixing this here
2024-10-02 16:40:16 -07:00
Lauri Ojansivu 60c5c5c723 Merge pull request #5535 from wekan/dependabot/github_actions/docker/build-push-action-6.9.0
Bump docker/build-push-action from 6.7.0 to 6.9.0
2024-10-01 15:00:48 +03:00
Lauri Ojansivu f972da7442 Merge pull request #5534 from majus/master
Update VSCode debugging configuration
2024-10-01 15:00:33 +03:00
dependabot[bot] 948537cb75 Bump docker/build-push-action from 6.7.0 to 6.9.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.7.0 to 6.9.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/5cd11c3a4ced054e52742c5fd54dca954e0edd85...4f58ea79222b3b9dc2c8bbdd6debcef730109a75)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-30 20:09:47 +00:00
Denis Perov ec5d0d00f5 Update VSCode debugging configuration 2024-09-30 16:23:27 +03:00
Lauri Ojansivu 0e7c454013 Updated ChangeLog. 2024-09-24 07:33:25 +03:00
Lauri Ojansivu 6e8e581ceb Testing packages without versions from 2024-09-24 07:22:22 +03:00
Lauri Ojansivu 2ec435af41 Updated ChangeLog. 2024-09-24 00:54:11 +03:00
Lauri Ojansivu 5aa38c2e40 Try 6 to fix apparmor denied in syslog at Snap Candidate.
Thanks to webenefits and xet7 !

Fixes #4855
2024-09-24 00:52:42 +03:00
Lauri Ojansivu 0ff3952a8b Updated ChangeLog. 2024-09-24 00:27:50 +03:00
Lauri Ojansivu e32d2daa45 Try 5 to fix apparmor denied in syslog at Snap Candidate.
Thanks to webenefits and xet7 !

Fixes #4855
2024-09-24 00:26:15 +03:00
Lauri Ojansivu 57780801aa Updated ChangeLog. 2024-09-24 00:03:42 +03:00
Lauri Ojansivu ecdfc68170 Try 4 to fix apparmor denied in syslog at Snap Candidate.
Thanks to webenefits and xet7 !

Fixes #4855
2024-09-24 00:02:00 +03:00
Lauri Ojansivu 3b29678ef1 Updated ChangeLog. 2024-09-23 23:11:53 +03:00
Lauri Ojansivu 6c54b38cdf Try 3 to fix apparmor denied in syslog at Snap Candidate. Changed MongoDB --host back to --bind_ip.
Thanks to webenefits and xet7 !

Fixes #4855
2024-09-23 23:08:47 +03:00
Lauri Ojansivu dfcabc5a36 v7.60 2024-09-23 22:00:47 +03:00
Lauri Ojansivu 5c8cf2ebbd Updated ChangeLog. 2024-09-23 21:18:54 +03:00
Lauri Ojansivu a9d41217bd Removed outdated dependency page. To be seen, does anything break.
Thanks to xet7 !
2024-09-23 21:15:19 +03:00
Lauri Ojansivu 75f44a821c Merge branch 'feature/ostrio-flow-router-extra' of https://github.com/majus/wekan 2024-09-23 20:52:11 +03:00
Lauri Ojansivu 0ab16764d1 Updated ChangeLog. 2024-09-23 20:28:13 +03:00
Lauri Ojansivu b6e7e03c95 Added to Docs CNAME DNS info about CloudFlare and Sandstorm.
Thanks to xet7 !
2024-09-23 20:26:20 +03:00
Denis Perov 718c1a393d Switch from kadira:flow-router to ostrio:flow-router-extra 2024-09-23 19:25:55 +03:00
Lauri Ojansivu 50f3316088 Removed old models files that caused problems with login.
Thanks to xet7 !
2024-09-15 19:40:49 +03:00
Lauri Ojansivu 2727651897 Comment out not in use old attachments models code. 2024-09-08 17:42:04 +03:00
Lauri Ojansivu e72646a4d4 Add back old attachments models for attachment migrations.
Thanks to xet7 !
2024-09-08 16:46:17 +03:00
Lauri Ojansivu 8ef8d546c5 v7.59 2024-09-04 21:06:53 +03:00
Lauri Ojansivu a8b2d7a6bd Updated ChangeLog. 2024-09-04 21:00:19 +03:00
Lauri Ojansivu 0a1074ca6e Try 2 to fix apparmor denied in syslog at Snap Candidate. Newest MongoDB uses --host, not anymore --bind_ip.
Thanks to webenefits and xet7 !

Fixes #4855
2024-09-04 20:56:32 +03:00
Lauri Ojansivu 019d7c92c3 v7.58 2024-09-04 19:08:01 +03:00
Lauri Ojansivu cb653e03f2 Updated ChangeLog. 2024-09-04 19:04:18 +03:00
Lauri Ojansivu a6c8833f65 Try to fix apparrmor denied in syslog at Snap Candidate.
Thanks to webenefits and xet7 !

Fixes #4855
2024-09-04 19:01:41 +03:00
Lauri Ojansivu f00b39d154 v7.57 2024-09-04 11:57:53 +03:00
Lauri Ojansivu 39597e04ac Updated ChangeLog. 2024-09-04 10:57:49 +03:00
Lauri Ojansivu 1610eff0e9 Updated dependencies.
Thanks to developers of dependencies.
2024-09-04 10:55:48 +03:00
Lauri Ojansivu c944f9fdff Updated ChangeLog. 2024-09-04 10:37:38 +03:00
Lauri Ojansivu 9b4d4c5953 Merge pull request #5523 from walster001/main
Large updates to UI
2024-09-04 10:32:13 +03:00
walster001 a8f09011e9 Exodark Margin Fix
Added 10px margin to ExoDark lists also (following on from Clearblue fix) as with those rounded backgrounded lists I feel it looks nicer to give it some padding. 

Open to other contributors perspective however.
2024-09-04 14:17:11 +09:30
walster001 2e1675969a Clearblue Margin - comment
Add comment to explain changes to margin in case someone wants to revert in future
2024-09-04 14:10:31 +09:30
walster001 a71973cc80 Clearblue Margin Fix
Fix ClearBlue lists being butted up against the left hand side of the screen when viewed from a non-editor account (IE comment only).
2024-09-04 14:09:28 +09:30
walster001 608ec63899 Large updates to UI
- Added a wide range of updates/tweaks to various board themes
- Better defined theme start/endpoints in code
- Added modern scrollbars matching each theme
- Added styling to scrollbars in pop-over and horizontally across screen
- Tweaks to opacity/themes to work better with board backgrounds.
2024-09-04 13:56:06 +09:30
Lauri Ojansivu 52bdba8e85 Updated ChangeLog. 2024-09-01 19:15:00 +03:00
Lauri Ojansivu f5b11b15ce Merge pull request #5519 from LanetNetwork/templ_upd
Update templates
2024-08-28 14:45:24 +03:00
Dmytro Novash 3359559ad2 Merge branch 'wekan:main' into templ_upd 2024-08-28 14:24:28 +03:00
Dmytro Novash b4aa464473 use label instead of span 2024-08-28 14:23:35 +03:00
Lauri Ojansivu dbe31a86b7 Update LICENSE 2024-08-28 05:27:49 +03:00
Lauri Ojansivu bd283ff4e2 Merge pull request #5517 from walster001/main
Rework fix for mobile devices to incorporate all themes/list headers
2024-08-27 20:58:27 +03:00
walster001 c020ce8895 Remove vertical-align - doesn't fix for all board themes 2024-08-27 19:53:19 +09:30
walster001 f3562525db Create boardColors.css 2024-08-27 19:50:01 +09:30
walster001 cc89c35c8d Merge branch 'main' of https://github.com/walster001/wekan-atlanz 2024-08-27 19:38:38 +09:30
walster001 2457084db2 Update padding values/display for Mobile Devices
Have modified this in my test dev server, it appears this is the property that defines the spacing/containment of text for lists. When tested on iOS device this appears to work correctly. 

Last commit removing vertical align, and iinitial commit unsetting line height for ModernDark fixes an issue where text was super spaced out on ModernDark theme only.
2024-08-27 19:31:13 +09:30
walster001 508a2d7103 Revert vertical-align. Left line-height unset.
Didn't fix issue as its more than just modern-dark theme. Have played around on dev server and found its in the list css itself.
2024-08-27 19:28:06 +09:30
Lauri Ojansivu 3d7fef67d8 v7.56 2024-08-26 17:39:24 +03:00
Lauri Ojansivu d63d445b7d Upgraded Snap Candidate MongoDB to 6.0.17.
Thanks to MongoDB developers !
2024-08-26 17:30:05 +03:00
Lauri Ojansivu 8d3fe29c68 Update Browser-compatibility-matrix.md 2024-08-23 15:29:46 +03:00
Lauri Ojansivu ad3ecbfd96 Update Browser-compatibility-matrix.md 2024-08-23 15:28:21 +03:00
Lauri Ojansivu 51ec43e7bc Update Browser-compatibility-matrix.md 2024-08-23 15:27:24 +03:00
Lauri Ojansivu 88dfc57e7e Update Browser-compatibility-matrix.md 2024-08-23 15:25:13 +03:00
Lauri Ojansivu 7409c366f6 Update Browser-compatibility-matrix.md 2024-08-23 15:24:01 +03:00
Lauri Ojansivu b99b2a6d66 Update Browser-compatibility-matrix.md 2024-08-23 15:21:21 +03:00
walster001 fa21b00bb6 Merge branch 'wekan:main' into main 2024-08-23 00:27:31 +09:30
walster001 f061b5e12a Clean up theme descriptions, add scrollbars
- Cleaned up theme descriptions as many themes weren't labelled/or had mismatched descriptions.
- Began adding scrollbars to default themes/board canvases.
- Test removal of lines/editing margins on nephritis theme
2024-08-23 00:25:29 +09:30
Lauri Ojansivu 8ca642edc8 Updated ChangeLog. 2024-08-21 00:55:31 +03:00
Lauri Ojansivu c3909edc5e Fix apparmor denied in syslog at Snap Candidate.
Thanks to webenefits and xet7 !

Fixes #4855
2024-08-21 00:52:15 +03:00
Lauri Ojansivu f4cf09d394 Merge pull request #5511 from wekan/dependabot/github_actions/docker/build-push-action-6.7.0
Bump docker/build-push-action from 6.6.1 to 6.7.0
2024-08-19 23:37:54 +03:00
dependabot[bot] 6aa4f9fb86 Bump docker/build-push-action from 6.6.1 to 6.7.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.6.1 to 6.7.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/16ebe778df0e7752d2cfcbd924afdbbd89c1a755...5cd11c3a4ced054e52742c5fd54dca954e0edd85)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-19 20:10:48 +00:00
Lauri Ojansivu a31545824e Updated ChangeLog. 2024-08-19 22:23:18 +03:00
Lauri Ojansivu a94cfd5b91 Update Docker.md for docker compose commands and building custom docker image
Update Docker.md for docker compose commands and building custom docker image
2024-08-19 11:03:58 +03:00
Lauri Ojansivu 6d6d51310e Update docker-compose.yml docker compose command
Update docker-compose.yml docker compose command
2024-08-19 11:00:47 +03:00
Lauri Ojansivu c9cf2971de Merge pull request #5505 from wekan/dependabot/github_actions/docker/build-push-action-6.6.1
Bump docker/build-push-action from 6.5.0 to 6.6.1
2024-08-12 23:47:53 +03:00
dependabot[bot] 54c481e3d8 Bump docker/build-push-action from 6.5.0 to 6.6.1
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.5.0 to 6.6.1.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/5176d81f87c23d6fc96624dfdbcd9f3830bbe445...16ebe778df0e7752d2cfcbd924afdbbd89c1a755)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-12 20:46:26 +00:00
Lauri Ojansivu 8b4fbd266d Merge pull request #5503 from walster001/main
Fix ModernDark Mobile View List Titles
2024-08-12 22:56:01 +03:00
Lauri Ojansivu 3c5241b007 Updated ChangeLog. 2024-08-12 22:09:48 +03:00
Lauri Ojansivu 42a1f94931 Updated ChangeLog. 2024-08-12 22:04:43 +03:00
Lauri Ojansivu cae6f38b80 Updated code of conduct. 2024-08-12 21:59:01 +03:00
walster001 25722e5e9d Tweaks to exodark for board backgrounds
Removed drop shadow on exodark cards, as when background applied to board it looks a bit rough design wise. 

Added background-color that will disappear when background is applied, and when background is not applied gives exodark a bit of a smoother cleaner look IMO
2024-08-12 23:49:12 +09:30
walster001 1d339ec17e Update boardColors.css 2024-08-12 21:28:14 +09:30
Lauri Ojansivu ec534c8cca Update Browser-compatibility-matrix.md 2024-08-11 19:15:15 +03:00
Lauri Ojansivu cab285c34d Update Browser-compatibility-matrix.md 2024-08-11 19:12:36 +03:00
Lauri Ojansivu 975993dd6d v7.55 2024-08-08 17:32:35 +03:00
Lauri Ojansivu 43084eb664 Updated ChangeLog. 2024-08-08 17:25:16 +03:00
Lauri Ojansivu 0e770ac3b3 Merge pull request #5501 from walster001/main
Fix board backgrounds not showing correctly after V7.54
2024-08-08 17:20:08 +03:00
walster001 206abc8c68 Fix board backgrounds not showing correctly.
Fixed board backgrounds not showing correctly on the following themes. Various code modified as different themes have used different code to implement the background.

Have tried to stick with board-wrapper as a standard to apply the background colour to.
Board background image will override board-wrapper colour every time.

Dark
Relax
Natural
Modern
ModernDark
Exodark
CleanDark
CleanLight

- Updated pull due to original file I had stored on my pc 139 commits behind! So synced that and then redid code changes to bring it all up to date.
2024-08-08 23:34:09 +09:30
walster001 62b13cc343 Merge branch 'main' of https://github.com/walster001/wekan-atlanz 2024-08-08 23:23:00 +09:30
walster001 7822dd3b75 Fix board backgrounds not showing correctly
Fixed board backgrounds not showing correctly on the following themes.
Various code modified as different themes have used different code to implement the background.

Have tried to stick with board-wrapper as a standard to apply the background colour to.

Board background image will override this every time.

- Dark
- Relax
- Natural
- Modern
- ModernDark
- Exodark
- CleanDark
- CleanLight
2024-08-08 22:51:07 +09:30
Lauri Ojansivu a214cd64b6 v7.54 2024-08-07 17:51:01 +03:00
Lauri Ojansivu 8839a8ea39 Updated ChangeLog. 2024-08-07 17:26:47 +03:00
Lauri Ojansivu a4169f3da7 Fix LDAP login fails after upgrade.
Thanks to juppees !

Fixes #5499
2024-08-07 17:24:14 +03:00
Lauri Ojansivu 19d59b3ab4 Updated ChangeLog. 2024-08-07 00:25:57 +03:00
Lauri Ojansivu 27b2e2384c Merge pull request #5498 from mfilser/master
Bugfix, edit description didn't work if it was clicked
2024-08-07 00:24:58 +03:00
Lauri Ojansivu 49d2cbc2c1 Updated ChangeLog. 2024-08-07 00:23:49 +03:00
Martin Filser bf2b3b40cd Bugfix, edit description didn't work if it was clicked
- introduced by commit: 0cc63b810c
2024-08-06 23:22:58 +02:00
Lauri Ojansivu 1541c6ca23 Merge pull request #5497 from mfilser/master
listHeader, simpler code logic at collapsed if conditions
2024-08-07 00:22:23 +03:00
Lauri Ojansivu 42c1ff94e2 Updated ChangeLog. 2024-08-07 00:13:13 +03:00
Martin Filser 53aa5ebc17 listHeader, simpler code logic at collapsed if conditions 2024-08-06 23:12:31 +02:00
Lauri Ojansivu 0f43818757 Merge pull request #5496 from mfilser/master
Bugfix, Cards Count on mobile view was missing
2024-08-07 00:12:11 +03:00
Lauri Ojansivu f3c5b1eb07 Updated ChangeLog. 2024-08-07 00:11:36 +03:00
Martin Filser 517d1bb7fa Bugfix, Cards Count on mobile view was missing
introduced by:
a601ba542a
2024-08-06 23:10:30 +02:00
Lauri Ojansivu 6ee0919ead Merge pull request #5495 from mfilser/master
Editor, Bugfix, copy text is now at each editor (textarea) again
2024-08-07 00:10:03 +03:00
Martin Filser 13eb1a58e0 Editor, migrate to markdown at same line than copy text icon 2024-08-06 23:06:51 +02:00
Martin Filser 08f9c09484 Editor, Bugfix, copy text is now at each editor (textarea) again 2024-08-06 23:05:54 +02:00
Lauri Ojansivu 3f3abe26ee Updated ChangeLog. 2024-08-07 00:05:09 +03:00
Lauri Ojansivu e31c5b6d42 Merge pull request #5494 from mfilser/master
Minicard, show creator, defaultValue of schema and other code is now the same
2024-08-07 00:03:47 +03:00
Martin Filser 7bf77fa7cb Minicard, show creator, defaultValue of schema and other code is now the same 2024-08-06 23:00:42 +02:00
Lauri Ojansivu a2662f1366 Updated ChangeLog. 2024-08-06 23:57:40 +03:00
Lauri Ojansivu 116cf6aa21 Merge pull request #5493 from mfilser/master
board view, first column a bit smaller to save screen space
2024-08-06 23:56:20 +03:00
Lauri Ojansivu 79bb6d0c55 Updated ChangeLog. 2024-08-06 23:55:12 +03:00
Martin Filser c157ecec38 board view, first column to add a new list was too large 2024-08-06 22:53:53 +02:00
Martin Filser 28893cf637 Bugfix, in View "Lists" the first column only showed the first 10 minicards, now all minicards again 2024-08-06 22:53:53 +02:00
Lauri Ojansivu 73ffc99f37 Merge pull request #5492 from mfilser/master
sidebar xmark icon, add padding and background color
2024-08-06 23:53:24 +03:00
Martin Filser 35802c7c62 sidebar xmark-icon, background color on hover the icon 2024-08-06 22:45:51 +02:00
Martin Filser bc44fdf89c sidebar xmark icon, add padding to easier click 2024-08-06 22:45:51 +02:00
Lauri Ojansivu 030c3dd587 Updated ChangeLog. 2024-08-06 23:38:33 +03:00
Lauri Ojansivu 498be2759e Merge pull request #5491 from mfilser/master
fix empty parentId in cards
2024-08-06 23:37:38 +03:00
Lauri Ojansivu 649d00733a Updated ChangeLog. 2024-08-06 23:36:07 +03:00
Martin Filser 8a7a4f3033 fix empty parentId in cards
- if the parentId is undefined or empty, the code run in a infinite loop and
  the browser "hangs"
2024-08-06 22:35:16 +02:00
Lauri Ojansivu b6ce81dc79 Merge pull request #5490 from mfilser/master
change Meteor.user() to ReactiveCache.getCurrentUser()
2024-08-06 23:35:07 +03:00
Lauri Ojansivu 490c417cee Updated ChangeLog. 2024-08-06 23:33:59 +03:00
Martin Filser 2dfeb3924b reactiveCache, removing commented out code 2024-08-06 22:33:03 +02:00
Martin Filser bff96f6ae2 change Meteor.user() to ReactiveCache.getCurrentUser()
- see also: https://github.com/wekan/wekan/issues/5000
2024-08-06 22:33:03 +02:00
Lauri Ojansivu 4801e26b2f Merge pull request #5489 from mfilser/master
attachment popup back was broken since new attachment viewer, now fixed
2024-08-06 23:32:53 +03:00
Lauri Ojansivu 027997f7b3 Updated ChangeLog. 2024-08-06 23:32:29 +03:00
Martin Filser 76aaefbde1 attachment popup back was broken since new attachment viewer, now fixed 2024-08-06 22:30:51 +02:00
Lauri Ojansivu a01bc0f325 Merge pull request #5488 from mfilser/master
remove attachment storage name from attachment list
2024-08-06 23:30:23 +03:00
Martin Filser f6f4f5660e remove attachment storage name from attachment list
- this was for debugging, now not necessary anymore
2024-08-06 22:26:00 +02:00
Lauri Ojansivu 956925889a Updated ChangeLog. 2024-08-06 23:23:42 +03:00
Lauri Ojansivu 0bd49326d8 Merge pull request #5487 from mfilser/master
little opacity to minicards to see the background image a little bit
2024-08-06 23:22:32 +03:00
Lauri Ojansivu 64c4e8eca8 Updated ChangeLog. 2024-08-06 23:22:04 +03:00
Lauri Ojansivu 55fc342f6d Added info how with Caddy webserver config, PWA and Android app override icons, showing toolbars, etc.
Thanks to xet7 !
2024-08-06 23:19:43 +03:00
Martin Filser 3ae0d96760 little opacity to minicards to see the background image a little bit 2024-08-06 22:03:16 +02:00
Lauri Ojansivu fc1e55cc19 Updated ChangeLog. 2024-08-06 22:58:13 +03:00
Lauri Ojansivu 58fc810a43 Merge pull request #5486 from mfilser/master
Bugfix, variable "color" didn't exist
2024-08-06 22:55:58 +03:00
Martin Filser 3c477e9783 Bugfix, variable "color" didn't exist
- background-color is maybe wrong too, but better than throwing an exception
2024-08-06 21:50:57 +02:00
Lauri Ojansivu f2247ed86d Updated ChangeLog. 2024-08-06 22:48:32 +03:00
Lauri Ojansivu 0d9a9d1ed8 Merge branch 'main' of github.com:wekan/wekan 2024-08-06 22:46:00 +03:00
Lauri Ojansivu ca5a579e22 PWA, move to standalone (standard) to display the status bar.
Thanks to mfilser !

Related https://github.com/wekan/wekan/pull/5484
2024-08-06 22:44:51 +03:00
Lauri Ojansivu 53d97a593f Merge pull request #5485 from mfilser/master
don't set background image in .board-canvas too
2024-08-06 22:38:27 +03:00
Martin Filser 3641a8f389 don't set background image in .board-canvas too 2024-08-06 21:30:27 +02:00
Lauri Ojansivu 1dea1bd09d Merge pull request #5483 from mfilser/master
fix error on console when user logout
2024-08-06 19:09:22 +03:00
Martin Filser 3db265d57f fix error on console when user logout (Part 2) 2024-08-06 17:24:43 +02:00
Martin Filser 38a32824ea fix error on console when user logout (Part 1) 2024-08-06 17:24:43 +02:00
Lauri Ojansivu b0c94f7ff2 Updated ChangeLog. 2024-08-05 13:06:51 +03:00
Lauri Ojansivu 2415aa3d2b v7.53 2024-08-03 22:16:18 +03:00
Lauri Ojansivu 1af1844f37 Updated Snap Candidate to MongoDB 6.0.16.
Thanks to MongoDB developers !
2024-08-03 22:13:08 +03:00
Lauri Ojansivu 75bb247c2b Updated ChangeLog. 2024-08-03 21:52:34 +03:00
Lauri Ojansivu 5a1b517733 Merge pull request #5481 from mfilser/master
reducing card size in database if no planning poker was started
2024-08-03 21:50:27 +03:00
Lauri Ojansivu 0fbc8754f7 Updated ChangeLog. 2024-08-03 21:49:12 +03:00
Lauri Ojansivu aaca60b676 Copied changes from wiki to docs.
Thanks to xet7 !
2024-08-03 21:47:10 +03:00
Martin Filser a929d1e3a4 reducing card size in database if no planning poker was started
reducing:
- cards collection size
- database size
- size to transfer from server to client (publish / subscribe)
2024-08-03 20:40:29 +02:00
Lauri Ojansivu 4a7fa7c396 Updated ChangeLog. 2024-08-03 21:36:22 +03:00
Lauri Ojansivu 45674806d7 Fix dragscroll package name.
Thanks to xet7 !
2024-08-03 21:35:04 +03:00
Lauri Ojansivu 8905bc7dfe Updated ChangeLog. 2024-08-03 21:21:19 +03:00
Lauri Ojansivu dd6aec1ba9 Merge pull request #5480 from mfilser/master
changing card color now closes the popup and doesn't refresh the whole boards page
2024-08-03 21:12:05 +03:00
Lauri Ojansivu aca5fa4d0a Merge branch 'main' of github.com:wekan/wekan 2024-08-03 21:11:23 +03:00
Lauri Ojansivu 0d1f45b8a2 Updated ChangeLog. 2024-08-03 21:11:01 +03:00
Lauri Ojansivu 3f9ae57144 Updated dependencies.
Thanks to developers of dependencies.
2024-08-03 21:09:30 +03:00
Martin Filser 45c2f1007b changing card color now closes the popup and doesn't refresh the whole boards page 2024-08-03 20:06:51 +02:00
Lauri Ojansivu 83adaa3074 Merge pull request #5479 from mfilser/master
fixing of "mode is undefined" on first activity component creation
2024-08-03 21:06:33 +03:00
Martin Filser 1951b279c0 fixing of "mode is undefined" on first activity component creation 2024-08-03 20:03:46 +02:00
Lauri Ojansivu 50406ad683 Merge pull request #5478 from mfilser/master
Board Menu Popup's were opened twice because of 2 same event creation
2024-08-03 21:03:15 +03:00
Martin Filser 95740eaa01 Board Menu Popup's were opened twice because of 2 same event creation 2024-08-03 19:58:25 +02:00
Lauri Ojansivu 08f2c1c735 Merge pull request #5477 from mfilser/dragscroll
adding Dragscroll to scroll the board
2024-08-03 20:54:03 +03:00
Martin Filser 32459ec405 No dragscroll on card details 2024-08-03 19:45:55 +02:00
Martin Filser c7ac0cbce1 No dragscroll while sorting swimlanes 2024-08-03 19:45:55 +02:00
Martin Filser 711fb5754e No dragscroll while sorting checklists 2024-08-03 19:45:55 +02:00
Martin Filser 24fffd8bfa Dragscroll, change cursor while scrolling + support summernote compatibily 2024-08-03 19:45:55 +02:00
Martin Filser 52556aff68 Dragscroll, disable scroll on input, textarea and select 2024-08-03 19:45:55 +02:00
Martin Filser c76959ff25 Dragscroll possible, scroll the screen with the mouse at desktop view
- click on a empty list area and drag the view left/right to scroll
2024-08-03 19:45:45 +02:00
Lauri Ojansivu a141871e60 Updated ChangeLog. 2024-08-03 20:42:30 +03:00
Lauri Ojansivu 5e639a7c2d Updated release script: New install webpage location.
Thanks to xet7 !
2024-08-03 20:39:49 +03:00
Lauri Ojansivu f9654d17d5 Updated ChangeLog. 2024-08-03 20:21:42 +03:00
Lauri Ojansivu c89f3ba3da Revert forking ldapjs.
Thanks to xet7 !
2024-08-03 20:18:53 +03:00
Lauri Ojansivu 1dc5ae444e Merge branch 'update' 2024-08-03 19:55:22 +03:00
Lauri Ojansivu 5db67e47a8 v7.52 2024-08-03 19:43:07 +03:00
Lauri Ojansivu 3877e5feb9 Updated ChangeLog. 2024-08-03 16:56:08 +03:00
Lauri Ojansivu 7456186265 Updated WeKan app webmanifest.
Thanks to xet7 !
2024-08-03 16:53:46 +03:00
Lauri Ojansivu 952f7feb49 Updates 2024-08-03 02:24:49 +03:00
Lauri Ojansivu 3983d750f3 Updated ChangeLog. 2024-08-03 01:38:17 +03:00
Lauri Ojansivu b4f2a8ab5b Updated ChangeLog. 2024-08-03 01:20:47 +03:00
Lauri Ojansivu e8a4554789 Updated ChangeLog. 2024-08-03 01:04:49 +03:00
Lauri Ojansivu de3bc9cb4d Fix typos at attachments code. 2024-08-03 00:52:51 +03:00
Lauri Ojansivu e09f028cd1 Merge pull request #5473 from wekan/dependabot/npm_and_yarn/fast-xml-parser-4.4.1
Bump fast-xml-parser from 4.3.2 to 4.4.1
2024-08-03 00:46:38 +03:00
Lauri Ojansivu ea9f597685 Merge pull request #5476 from mfilser/activities_add_back_created_at_field
Activities, adding back "created at" field
2024-08-03 00:46:01 +03:00
Martin Filser e538fb9514 Activities, adding back "created at" field
Fixes #5459
2024-08-02 23:27:03 +02:00
dependabot[bot] 32fed3d048 Bump fast-xml-parser from 4.3.2 to 4.4.1
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 4.3.2 to 4.4.1.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v4.3.2...v4.4.1)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-29 21:43:29 +00:00
Lauri Ojansivu c6b6d1aa40 Updated translations. 2024-07-28 22:26:54 +03:00
Lauri Ojansivu b9615ccbad Merge pull request #5471 from wekan/dependabot/github_actions/docker/build-push-action-6.5.0
Bump docker/build-push-action from 6.4.0 to 6.5.0
2024-07-23 12:11:31 +03:00
Lauri Ojansivu 0032a91f66 Merge pull request #5470 from wekan/dependabot/github_actions/docker/login-action-3.3.0
Bump docker/login-action from 3.2.0 to 3.3.0
2024-07-23 12:11:20 +03:00
dependabot[bot] 88f6076422 Bump docker/build-push-action from 6.4.0 to 6.5.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.4.0 to 6.5.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/a254f8ca60a858f3136a2f1f23a60969f2c402dd...5176d81f87c23d6fc96624dfdbcd9f3830bbe445)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-22 20:53:03 +00:00
dependabot[bot] 8e11ecf799 Bump docker/login-action from 3.2.0 to 3.3.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/0d4c9c5ea7693da7b068278f7b52bda2a190a446...9780b0c442fbb1117ed29e0efdff1e18412f7567)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-22 20:52:59 +00:00
Lauri Ojansivu d04c5c9846 Merge pull request #5469 from wekan/dependabot/github_actions/docker/build-push-action-6.4.0
Bump docker/build-push-action from 6.3.0 to 6.4.0
2024-07-16 21:31:52 +03:00
Lauri Ojansivu e46a66904f Removed old PGP key.
Thanks to xet7 !
2024-07-16 13:56:57 +03:00
dependabot[bot] d038cb4a2d Bump docker/build-push-action from 6.3.0 to 6.4.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.3.0 to 6.4.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/1a162644f9a7e87d8f4b053101d1d9a712edc18c...a254f8ca60a858f3136a2f1f23a60969f2c402dd)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-15 20:34:56 +00:00
Lauri Ojansivu 78e68c7fea Merge pull request #5464 from wekan/dependabot/github_actions/docker/build-push-action-6.3.0
Bump docker/build-push-action from 6.2.0 to 6.3.0
2024-07-11 16:04:28 +03:00
dependabot[bot] 700f345576 Bump docker/build-push-action from 6.2.0 to 6.3.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/15560696de535e4014efeff63c48f16952e52dd1...1a162644f9a7e87d8f4b053101d1d9a712edc18c)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-08 20:16:21 +00:00
Lauri Ojansivu 22067198ab Updated ChangeLog. 2024-07-05 11:59:56 +03:00
Lauri Ojansivu 21d6dfd790 Added RepoCloud.svg .
Related https://github.com/wekan/wekan/pull/5463
2024-07-05 10:43:07 +03:00
Lauri Ojansivu e663ce038a Added RepoCloud.
Related https://github.com/wekan/wekan/pull/5463
2024-07-05 10:38:58 +03:00
Lauri Ojansivu 367b7778fd Merge pull request #5460 from wekan/dependabot/github_actions/docker/build-push-action-6.2.0
Bump docker/build-push-action from 6.1.0 to 6.2.0
2024-07-02 22:55:51 +03:00
dependabot[bot] 989e0a5326 Bump docker/build-push-action from 6.1.0 to 6.2.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/31159d49c0d4756269a0940a750801a1ea5d7003...15560696de535e4014efeff63c48f16952e52dd1)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-01 20:21:29 +00:00
Lauri Ojansivu 13940f0663 Merge pull request #5458 from abramchikd/clean-theme
Clean theme fixes
2024-06-29 16:05:54 +03:00
Dmitrij Abramov 09e87f207c Some tweaks to clean light and clean dark themes 2024-06-28 00:38:45 +03:00
Lauri Ojansivu f9884b7782 v7.51 2024-06-27 15:16:25 +03:00
Lauri Ojansivu cca5f81c65 Updated ChangeLog. 2024-06-27 14:12:59 +03:00
Lauri Ojansivu c863428aa2 Reorganized docs. 2024-06-27 14:12:06 +03:00
Lauri Ojansivu 2104b853ef Updated ChangeLog. 2024-06-27 14:09:04 +03:00
Lauri Ojansivu 00a56f6aaa Reorganize files. 2024-06-27 14:08:24 +03:00
Lauri Ojansivu 67e7a75b9c Updated ChangeLog. 2024-06-27 14:06:57 +03:00
Lauri Ojansivu 52375df783 Reorganized docs. 2024-06-27 14:06:29 +03:00
Lauri Ojansivu 77fad0e7c6 Reorganized docs. 2024-06-27 14:04:44 +03:00
Lauri Ojansivu 802341384e Updated changelog. 2024-06-27 14:02:44 +03:00
Lauri Ojansivu 057ac4031e Reorganize docs. 2024-06-27 14:01:26 +03:00
Lauri Ojansivu ea5d0999c4 Copy Emoji page to Build from source. 2024-06-27 13:51:14 +03:00
Lauri Ojansivu 7b21650003 Updated ChangeLog. 2024-06-27 13:31:27 +03:00
Lauri Ojansivu 1cfaddff9c Reorganized docs. 2024-06-27 13:30:40 +03:00
Lauri Ojansivu 7690d91771 Updated ChangeLog. 2024-06-27 13:25:52 +03:00
Lauri Ojansivu 6b7b66801b Reorganized docs. 2024-06-27 13:25:06 +03:00
Lauri Ojansivu d671071758 Updated ChangeLog. 2024-06-27 13:21:45 +03:00
Lauri Ojansivu e9c1c620eb Reorganize docs. 2024-06-27 13:20:36 +03:00
Lauri Ojansivu b17a8757fb Updated ChangeLog. 2024-06-27 13:12:44 +03:00
Lauri Ojansivu 2b04cef50b Merge pull request #5455 from walster001/main
Fix ModernDark Cards not showing correctly.
2024-06-27 13:10:33 +03:00
Lauri Ojansivu 16060108b4 Updated ChangeLog. 2024-06-27 13:09:28 +03:00
Lauri Ojansivu 0fb2f7fdd6 Reorganize docs. 2024-06-27 13:07:52 +03:00
walster001 c002cf759e Fix ModernDark Card Alignment
Fix position from absolute to fixed, so it moves with the viewport when horizonally scrolling. 

Fix card top border due to changing position, adjust top border px to 82px
2024-06-27 18:49:01 +09:30
walster001 5fee0b05e0 Fix ModernDark Card Alignment 2024-06-27 18:39:48 +09:30
walster001 48bc176bdf Merge branch 'wekan:main' into main 2024-06-27 18:10:43 +09:30
walster001 ec56dc73c4 Merge branch 'main' of https://github.com/walster001/wekan-atlanz 2024-06-27 18:09:59 +09:30
walster001 83e9d681d7 Fix ModernDark Card Alignment
Fix cards not showing up properly in ModernDark theme, when more lists are created than will fit on a single screen, inciting a horizontal scrollbar, and then scrolling across trying to open cards.

Due to position being absolute, this then opened the card off-screen
2024-06-27 18:09:51 +09:30
Lauri Ojansivu e0b9e80698 Updated ChangeLog. 2024-06-27 11:16:53 +03:00
Lauri Ojansivu 449c02c42a Updated Snap docs from wiki. 2024-06-27 11:12:49 +03:00
Lauri Ojansivu ce89ff4833 Reorganized Docs. In Progress. 2024-06-27 11:08:43 +03:00
Lauri Ojansivu 1961e22cbd Added changes from wiki to wekan repo. 2024-06-27 10:31:35 +03:00
Lauri Ojansivu b95ee7cf4d Updated ChangeLog. 2024-06-26 18:57:10 +03:00
Lauri Ojansivu 14b2291590 Merge pull request #5452 from wekan/dependabot/github_actions/docker/build-push-action-6.1.0
Bump docker/build-push-action from 6.0.0 to 6.1.0
2024-06-25 09:13:44 +03:00
Dmitrij Abramov 954ec05d41 Clean themes tweaks 2024-06-25 01:57:31 +03:00
dependabot[bot] 4c25b40b2d Bump docker/build-push-action from 6.0.0 to 6.1.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/c382f710d39a5bb4e430307530a720f50c2d3318...31159d49c0d4756269a0940a750801a1ea5d7003)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-24 20:30:46 +00:00
Lauri Ojansivu 1792e3d884 v7.50 2024-06-22 09:12:23 +03:00
Lauri Ojansivu 3c35a6400b Updated docs for WeKan version for Windows. Part 2. 2024-06-22 08:58:18 +03:00
Lauri Ojansivu 2a4ba31a9e Updated ChangeLog. 2024-06-21 03:51:26 +03:00
Lauri Ojansivu 99a8afd6c3 Updated dependencies. 2024-06-21 03:48:52 +03:00
Lauri Ojansivu cc9ff4c8db Updated ChangeLog. 2024-06-21 03:31:52 +03:00
Lauri Ojansivu ed4189cc5e Merge pull request #5449 from abramchikd/theme-clean
Added "Clean dark" and "Clean light" themes
2024-06-21 03:08:30 +03:00
Dmitrij Abramov 6d66e60830 Fixes for clean light theme 2024-06-19 02:33:02 +03:00
Dmitrij Abramov 930f0a7f82 Added clean dark and clean light themes 2024-06-19 01:37:55 +03:00
Lauri Ojansivu 89347e2a56 Merge pull request #5446 from wekan/dependabot/github_actions/docker/build-push-action-6.0.0
Bump docker/build-push-action from 5.4.0 to 6.0.0
2024-06-18 19:55:37 +03:00
dependabot[bot] 09a08cd074 Bump docker/build-push-action from 5.4.0 to 6.0.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.4.0 to 6.0.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/ca052bb54ab0790a636c9b5f226502c73d547a25...c382f710d39a5bb4e430307530a720f50c2d3318)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-17 20:59:11 +00:00
Lauri Ojansivu c344474d9e Merge pull request #5443 from Hekatomb/bugfix/CardOverflow
Update cardDetails.css
2024-06-13 16:52:22 +03:00
Hekatomb d13d169768 Update cardDetails.css
Bugfix, task card may overflow below the screen when maximized, making the bottom part not viewable.

Reason: Top position is set to 97px, Height of the element is set to calc(100% - 20px).

Fix: Set the height to be lower than 100% - Top position
2024-06-13 09:45:31 +02:00
Lauri Ojansivu e3929973d1 Updated ChangeLog. 2024-06-11 02:05:57 +03:00
Lauri Ojansivu 9b428150a4 Updated docs for WeKan version for Windows.
Thanks to xet7.
2024-06-11 02:04:12 +03:00
Lauri Ojansivu 8ba565042f v7.49 2024-06-11 01:40:43 +03:00
Lauri Ojansivu 6df03294bd Updated ChangeLog. 2024-06-11 01:34:19 +03:00
Lauri Ojansivu 4a40ac3ced Merge pull request #5441 from wekan/dependabot/github_actions/docker/build-push-action-5.4.0
Bump docker/build-push-action from 5.3.0 to 5.4.0
2024-06-11 01:31:44 +03:00
dependabot[bot] 2f34d65164 Bump docker/build-push-action from 5.3.0 to 5.4.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.3.0 to 5.4.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/2cdde995de11925a030ce8070c3d77a52ffcf1c0...ca052bb54ab0790a636c9b5f226502c73d547a25)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-10 20:33:21 +00:00
Lauri Ojansivu 7c68d6a710 Updated ChangeLog. 2024-06-10 16:27:51 +03:00
Lauri Ojansivu 55fb7a8f27 Merge pull request #5440 from Hekatomb/bugfix/TeamsOrgAdminCard
Fill out Org and Team in adminReports
2024-06-10 16:19:48 +03:00
Lauri Ojansivu bb9fb1187e Updated ChangeLog. 2024-06-10 14:54:13 +03:00
Lauri Ojansivu f0170c576c Updated ChangeLog. 2024-06-10 14:52:35 +03:00
Lauri Ojansivu 02caaafc52 Merge branch 'main' of github.com:wekan/wekan 2024-06-10 14:49:51 +03:00
Lauri Ojansivu 168b17ac4e Updated ChangeLog. 2024-06-10 14:47:13 +03:00
Lauri Ojansivu e3214c874e Changed back to original icon of Edit Description.
Thanks to saschafoerster, C0rn3j and xet7 !

Fixes #5413,
related https://github.com/wekan/wekan/commit/1f2fb2ccce38e9cac348f1c459784d6e5a949ded
2024-06-10 14:40:49 +03:00
hekatomb 91444cce9b Fill out Org and Team in adminReports 2024-06-07 19:58:12 +02:00
Lauri Ojansivu c952aaadec Merge pull request #5435 from Hekatomb/bugfix/TeamsOrgStrikethrough 2024-06-07 01:11:37 +03:00
hekatomb 77ab5c1690 Bugfix: Strikethrough inactive Teams and orginizations rather than strikethrough active teams and orgs 2024-06-06 23:25:16 +02:00
Lauri Ojansivu 37857935f3 Updated ChangeLog. 2024-06-06 04:58:47 +03:00
Lauri Ojansivu e5c7650fc8 WeKan new release version number from wiki to WeKan repo docs.
Thanks to xet7 !
2024-06-06 04:55:45 +03:00
Lauri Ojansivu f42e0fe507 v7.48 2024-06-06 02:12:09 +03:00
Lauri Ojansivu 58dbd78997 Updated ChangeLog. 2024-06-06 02:07:32 +03:00
Lauri Ojansivu 04b995e77f Allow Normal user to add new swimlane, list and label.
Thanks to RyanHecht, norrig and xet7 !

Fixes #4276,
fixes #4785
2024-06-06 02:03:29 +03:00
Lauri Ojansivu 82aa3fb7ee Updated ChangeLog. 2024-06-06 01:44:56 +03:00
Lauri Ojansivu ec0e88ad2e Try to show more of title of collapsed list.
Thanks to C0rn3j and xet7 !

Related #5428
2024-06-06 01:39:57 +03:00
Lauri Ojansivu cac28fde4d Updated ChangeLog. 2024-06-04 23:45:46 +03:00
Lauri Ojansivu e65a8c9017 Add changes from wiki to docs. Part 2.
Thanks to xet7 !
2024-06-04 23:44:35 +03:00
Lauri Ojansivu 4a26f80fb1 Updated ChangeLog. 2024-06-04 23:30:57 +03:00
Lauri Ojansivu bca8a72a0f Merge branch 'main' of github.com:wekan/wekan 2024-06-04 23:28:59 +03:00
Lauri Ojansivu 13be8160d5 Add changes from wiki to docs.
Thanks to xet7 !
2024-06-04 23:27:55 +03:00
Lauri Ojansivu 8efea6c4e2 Updated ChangeLog. 2024-06-04 16:05:52 +03:00
Lauri Ojansivu 36bb5e099e Fix Admin Panel pages Organizations and Teams, where HTML Tables were broken.
Thanks to Hekatomb and xet7 !

Fixes #5429
2024-06-04 16:02:03 +03:00
Lauri Ojansivu b86a24d97a Merge pull request #5430 from wekan/dependabot/github_actions/docker/login-action-3.2.0
Bump docker/login-action from 3.1.0 to 3.2.0
2024-06-04 15:17:18 +03:00
dependabot[bot] 3febe80329 Bump docker/login-action from 3.1.0 to 3.2.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/e92390c5fb421da1463c202d546fed0ec5c39f20...0d4c9c5ea7693da7b068278f7b52bda2a190a446)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-03 20:32:31 +00:00
Lauri Ojansivu b11a2103a4 Updated ChangeLog. 2024-06-03 05:16:50 +03:00
Lauri Ojansivu 4a9d881e47 Updated release scripts.
Thanks to xet7 !
2024-06-03 05:14:58 +03:00
Lauri Ojansivu 8e5c6af612 v7.47 2024-06-03 05:07:30 +03:00
Lauri Ojansivu ca588a4b54 Updated translations. 2024-06-03 05:00:33 +03:00
Lauri Ojansivu 258032acb0 Updated ChangeLog. 2024-06-03 04:39:55 +03:00
Lauri Ojansivu 2c9c9c4356 Updated release scripts.
Thanks to xet7 !
2024-06-03 04:38:55 +03:00
Lauri Ojansivu 88d4e8a4d9 Updated ChangeLog. 2024-06-03 04:35:16 +03:00
Lauri Ojansivu 4e2a8735bc Updated to MongoDB 6.0.15 at Snap Candidate.
Thanks to MongoDB developers !
2024-06-03 04:33:40 +03:00
Lauri Ojansivu b72d24f6d0 Updated ChangeLog. 2024-06-03 04:30:24 +03:00
Lauri Ojansivu 1f2fb2ccce Fix Edit Description button is wildly out of place.
Thanks to C0rn3j and xet7 !

Fixes #5413
2024-06-03 04:23:09 +03:00
Lauri Ojansivu 5e2b423ef8 Only show Board name edit button to BoardAdmin.
Thanks to xet7 !
2024-06-03 04:03:31 +03:00
Lauri Ojansivu 79e2001708 Update Docker base images to Ubuntu 24.04.
Thanks to xet7 !
2024-06-03 03:06:58 +03:00
Lauri Ojansivu 2ea96518ad v7.46 2024-06-03 01:16:20 +03:00
Lauri Ojansivu 2666001226 Updated ChangeLog. 2024-05-30 23:22:48 +03:00
Lauri Ojansivu 1bd30bc121 For development, only recommend Debian 12 amd64, because Sandstorm works at Debian 12.
Sandstorm does not work at Ubuntu 24.04.

Thanks to xet7 !

Related https://github.com/sandstorm-io/sandstorm/issues/3712
2024-05-30 23:19:55 +03:00
Lauri Ojansivu d6d8144476 Updated dependencies. 2024-05-29 01:03:18 +03:00
Lauri Ojansivu 68e7818c1d Updated ChangeLog. 2024-05-29 00:58:05 +03:00
Lauri Ojansivu e0e5f4514b Merge pull request #5424 from Dexus/patch-1
Update exporter.js with fix for #5416
2024-05-28 18:04:57 +03:00
Josef Fröhle c2942fa269 Update exporter.js with fix for #5416
This should fix #5416
2024-05-28 16:42:44 +02:00
Lauri Ojansivu 6f31240c74 Updated ChangeLog. 2024-05-27 23:47:50 +03:00
Lauri Ojansivu 5124265142 Updated GitHub issue template for issue instructions to be more visible.
Related #5422
2024-05-27 14:00:49 +03:00
Lauri Ojansivu f0bd5eaca9 Updated ChangeLog. 2024-05-27 00:15:42 +03:00
Lauri Ojansivu 8589f85907 Merge pull request #5420 from mfilser/remove_second_created_at_on_activities
Remove second created at on activities
2024-05-26 23:17:34 +03:00
Martin Filser 66d739b3b1 Removed second "created at" text at activites / card comment
- the same text is already at line start, it makes no sense to print it
  again at line end
2024-05-26 22:05:51 +02:00
Lauri Ojansivu 2206e34ab6 Merge pull request #5419 from mfilser/dockerfile_production_and_dev_same_build
Dockerfile production and dev same build
2024-05-26 22:06:09 +03:00
Martin Filser cc1ca4a1bb Dockerfile for production and development same build (part 2) 2024-05-26 19:55:19 +02:00
Martin Filser c8b1ef8ea6 Dockerfile for production and development same build (part 1) 2024-05-26 19:49:31 +02:00
Lauri Ojansivu f836faad48 Merge pull request #5418 from mfilser/devcontainer_reduce_image_size_and_other_dev_updates
Devcontainer, reduce image size and other necessary changes for development
2024-05-26 00:26:45 +03:00
Lauri Ojansivu 7e27b916aa Updated ChangeLog. 2024-05-25 23:59:41 +03:00
Lauri Ojansivu ae9963c1f7 Merge pull request #5412 from e-gaulue/e-gaulue-patch-1
Remove notification while copying board
2024-05-25 22:40:58 +03:00
Martin Filser 2b4f4c8d4d .devcontainer/Dockerfile, updated RUN statements to heredoc style 2024-05-25 19:53:33 +02:00
Martin Filser 68104fe578 .devcontainer/Dockerfile, use Debian 11 because Ubuntu 21.10 can not build 2024-05-25 19:53:33 +02:00
Martin Filser 6f2c46a747 .devcontainer/Dockerfile, make is needed by "meteor npm update" 2024-05-25 19:53:30 +02:00
Martin Filser e7e1f1b667 .devcontainer/Dockerfile, don't remove ca-certificates because it's needed for "meteor npm install" 2024-05-25 19:53:25 +02:00
Martin Filser 7dc20616a7 .devcontainer/Dockerfile, don't remove curl/python3 because it's needed for "meteor npm" 2024-05-25 19:53:20 +02:00
Martin Filser b5b323000a .devcontainer/Dockerfile, reduce build a bit + image size to 3.42 GB
- on a test system it reduced from 11m36s to 9m34s
2024-05-25 19:53:07 +02:00
Martin Filser 19d204c7a8 .devcontainer/Dockerfile, 3.49 GB image size 2024-05-25 19:50:16 +02:00
Martin Filser 672c279b0a .devcontainer/Dockerfile, 4.12 GB image size 2024-05-25 19:50:16 +02:00
Martin Filser 669e31ea64 .devcontainer/Dockerfile, 4.16 GB image size 2024-05-25 19:50:16 +02:00
Martin Filser 4ab72170e3 .devcontainer/Dockerfile, 4.16 GB image size 2024-05-25 19:50:16 +02:00
Martin Filser 9ca39696b3 .devcontainer/Dockerfile, 5.64 GB image size
- first copy all files, then install to make it possible to install everything
  in one RUN section
2024-05-25 19:50:16 +02:00
Martin Filser 7c36279308 .devcontainer/Dockerfile, 5.64 GB image size 2024-05-25 19:50:16 +02:00
Martin Filser 89e5b3a979 .devcontainer/Dockerfile, 6.02 GB image size 2024-05-25 19:50:14 +02:00
Martin Filser 58782c9a89 .devcontainer/Dockerfile contained duplicated logic 2024-05-25 19:49:30 +02:00
Martin Filser c3824dcbd2 .devcontainer, added missing environments 2024-05-25 19:49:30 +02:00
Lauri Ojansivu cead2bc00f Merge pull request #5417 from LanetNetwork/fix-cards-load
fixed loading of cards if there are more than 20 of them on one swimlane
2024-05-24 17:50:24 +03:00
Dmytro Novash 0d5380466a fix cards load if cards > 20 on swimlane 2024-05-24 17:15:52 +03:00
e-gaulue 58f6acbc48 Remove notification while copying board
1. It takes too long while server stops after 2 minutes (#5371).
2. It is useless, because when you copy a board, most of the time your users don't want to be notified of every copied cards.
2024-05-15 22:17:54 +02:00
Lauri Ojansivu db73fb4e37 Updated translations. 2024-05-08 18:00:31 +03:00
Lauri Ojansivu a3d4c3d948 Merge pull request #5405 from LanetNetwork/uk_upd
Update ukrainian translation
2024-05-08 17:45:41 +03:00
Dmytro Novash f9dc5c6f80 upd 2024-05-07 18:57:48 +03:00
Dmitriy Novash 96b763fb89 Merge branch 'wekan:main' into uk_upd 2024-05-07 16:51:49 +03:00
Lauri Ojansivu 98a75305e7 Merge pull request #5404 from C0rn3j/fix-deprecated-grep
Swap deprecated `egrep` for `grep -E`
2024-05-06 17:09:58 +03:00
Lauri Ojansivu 0d8739327e Merge pull request #5403 from C0rn3j/image-optim
Optimize SVGs and PNGs to save 550KB~
2024-05-06 16:54:30 +03:00
Martin Rys 7dc4d9bb71 Swap deprecated egrep for grep -E
also remove some extra whitespace in MD doc
2024-05-06 11:19:59 +02:00
Martin Rys c814221185 Run SVG logos through svgo to reduce their filesize 2024-05-06 11:16:17 +02:00
Martin Rys f2f6b57944 Losslessly optimize PNGs (-522KB)
oxipng --zopfli --opt max
2024-05-06 11:12:54 +02:00
Lauri Ojansivu f50c2af914 v7.45 2024-05-06 01:38:35 +03:00
Lauri Ojansivu 5b7442436d Updated ChangeLog. 2024-05-06 01:33:54 +03:00
Lauri Ojansivu 9cebee7347 Fix Can't set a Due Date that has a leading zero in time, errors with invalid time.
Thanks to C0rn3j and xet7 !

Fixes #5395
2024-05-06 01:30:49 +03:00
Lauri Ojansivu f311359373 Updated ChangeLog. 2024-05-04 23:17:22 +03:00
Lauri Ojansivu 31b9970c04 Merge pull request #5401 from C0rn3j/set-silver
Allow `silver` color to be set in List and Swimlane
2024-05-04 23:14:06 +03:00
Martin Rys baf0edc51e Allow silver color to be set in List and Swimlane 2024-05-04 22:09:04 +02:00
Lauri Ojansivu 69a2a76b2e Merge pull request #5400 from C0rn3j/fix-white-list-color
Fix white List color and define Silver in CSS instead of leaving it unset
2024-05-04 23:01:05 +03:00
Martin Rys 7fd894f33d Do not leave silver color unset in Swimlane and List CSS 2024-05-04 21:59:05 +02:00
Martin Rys 3f366844e2 Fix white List color 2024-05-04 21:58:08 +02:00
Lauri Ojansivu 4156b6f932 Temporarily revert collapse per user that did not work yet.
Thanks to xet7 !

Related #5388
2024-05-04 22:57:13 +03:00
Lauri Ojansivu ed801f7082 Collapse Swimlane. In Progress.
Thanks to xet7 !

Related #5388
2024-05-04 22:50:13 +03:00
Lauri Ojansivu cedd10e067 Updated translations. 2024-05-02 00:06:30 +03:00
Lauri Ojansivu 86b756b6bc Updated ChangeLog. 2024-05-02 00:04:42 +03:00
Lauri Ojansivu 259a12acf9 Merge branch 'main' of github.com:wekan/wekan 2024-05-02 00:00:43 +03:00
Lauri Ojansivu 902f86d363 Collapse Lists to be per user, not per board. In Progress.
Related #5388

Thanks to xet7 !
2024-05-01 23:58:57 +03:00
Lauri Ojansivu d5fc75e345 Merge pull request #5392 from wekan/dependabot/github_actions/meteorengineer/setup-meteor-2
Bump meteorengineer/setup-meteor from 1 to 2
2024-04-30 17:56:10 +03:00
Lauri Ojansivu 5650bd829a Merge pull request #5393 from LanetNetwork/fix_tables
fix display of tables with a large number of rows
2024-04-30 17:55:46 +03:00
Dmitriy Novash f9ad46180e upd 2024-04-30 17:43:06 +03:00
Dmitriy Novash 6e534d7543 fix display of tables with a large number of rows 2024-04-30 15:54:28 +03:00
Dmitriy Novash 9aa56a8e42 update ukr translation 2024-04-30 15:49:48 +03:00
Dmitriy Novash 4ed67832d2 remove deprecated & invalid translation 2024-04-30 15:48:32 +03:00
dependabot[bot] 3409de9ed1 Bump meteorengineer/setup-meteor from 1 to 2
Bumps [meteorengineer/setup-meteor](https://github.com/meteorengineer/setup-meteor) from 1 to 2.
- [Release notes](https://github.com/meteorengineer/setup-meteor/releases)
- [Commits](https://github.com/meteorengineer/setup-meteor/compare/v1...v2)

---
updated-dependencies:
- dependency-name: meteorengineer/setup-meteor
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-29 20:50:33 +00:00
Lauri Ojansivu e73a44d15b Updated translations. 2024-04-28 16:22:55 +03:00
Lauri Ojansivu 5cf30f05fd Updated ChangeLog. 2024-04-28 16:21:49 +03:00
Lauri Ojansivu 63117e87e7 Update Docker base container to Ubuntu 24.04, and update software versions.
Thanks to developers of dependencies !
2024-04-28 16:19:14 +03:00
Lauri Ojansivu a8e520e7f0 v7.44 2024-04-26 14:35:54 +03:00
Lauri Ojansivu e14bb16d60 Updated ChangeLog. 2024-04-26 14:29:31 +03:00
Lauri Ojansivu b704d58f0f Collapse Swimlane. In Progress, does not work yet, not visible yet.
Thanks to xet7 !
2024-04-26 14:27:09 +03:00
Lauri Ojansivu 246e9a7764 Updated translations. 2024-04-26 14:23:46 +03:00
Lauri Ojansivu 1c7b63f583 Updated ChangeLog. 2024-04-26 08:00:15 +03:00
Lauri Ojansivu e6476319bc Fix board not visible.
Thanks to xet7 !
2024-04-26 07:57:16 +03:00
Lauri Ojansivu c954934b33 Updated translations. 2024-04-26 07:41:38 +03:00
Lauri Ojansivu a72a6886f6 Updated ChangeLog. 2024-04-26 07:35:15 +03:00
Lauri Ojansivu a601ba542a Collapse Lists.
Thanks to xet7 !
2024-04-26 07:33:06 +03:00
Lauri Ojansivu f22f470ba4 Updated translations. 2024-04-19 15:04:23 +03:00
Lauri Ojansivu 3faeeac126 v7.43 2024-04-18 04:53:26 +03:00
Lauri Ojansivu 40be1d416b Updated translations. 2024-04-18 04:44:10 +03:00
Lauri Ojansivu 9ef82458b7 Updated ChangeLog. 2024-04-18 04:21:38 +03:00
Lauri Ojansivu da99e363cd Updated dependencies.
Thanks to developers of dependencies !
2024-04-18 04:20:04 +03:00
Lauri Ojansivu 3110bb48fd Updated ChangeLog. 2024-04-18 03:47:22 +03:00
Lauri Ojansivu 08e2f2f273 Updated dependencies.
Thanks to developers of dependencies !
2024-04-18 03:45:48 +03:00
Lauri Ojansivu 6636d12215 Updated ChangeLog. 2024-04-18 03:30:39 +03:00
Lauri Ojansivu 5f243d173a Updated translations. 2024-04-18 03:23:07 +03:00
Lauri Ojansivu 5ea8d3a4c6 Merge pull request #5381 from tvogel/localized-timestamps
By default, use localized long date-time format
2024-04-17 22:25:00 +03:00
Tilman Vogel dad3fd22ec By default, use localized long date-time format
because ISO 8601 is not easy to the eye (at least for non-tech people).
2024-04-17 16:52:10 +02:00
Lauri Ojansivu f381402e8f Merge pull request #5380 from verdel/fix-debug-env-check
Fix DEBUG environment variable check
2024-04-17 15:40:31 +03:00
Vadim Aleksandrov f010235ff2 Fix DEBUG environment variable check 2024-04-17 14:06:15 +03:00
Lauri Ojansivu 09f6dcbde1 Updated translations. 2024-04-14 22:50:16 +03:00
Lauri Ojansivu 224b8e3492 Updated ChangeLog. 2024-04-14 22:47:25 +03:00
Martin Rys 28612bbc8a Dockerfile: Switch RUN commands to heredoc to avoid an insane amount of ANDs and escapes 2024-04-14 17:31:19 +02:00
Martin Rys dfe4f7bb56 docker-compose.yml: Remove obsolete version parameter 2024-04-14 17:24:56 +02:00
Lauri Ojansivu 3f28c0dd22 Merge pull request #5372 from wekan/dependabot/npm_and_yarn/tar-6.2.1
Bump tar from 6.2.0 to 6.2.1
2024-04-11 20:56:35 +03:00
dependabot[bot] 959dd1a95a Bump tar from 6.2.0 to 6.2.1
Bumps [tar](https://github.com/isaacs/node-tar) from 6.2.0 to 6.2.1.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v6.2.0...v6.2.1)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-11 12:34:10 +00:00
Lauri Ojansivu d5297cd1df Updated translations. 2024-04-11 06:41:33 +03:00
Lauri Ojansivu 95404f43b7 Updated ChangeLog. 2024-04-07 18:46:08 +03:00
Lauri Ojansivu 9838af5e56 Updated Transifex URL. 2024-04-07 18:44:43 +03:00
Lauri Ojansivu dab656f8ca Updated ChangeLog. 2024-04-07 18:35:52 +03:00
Lauri Ojansivu 802eeb1e6b Updated release script for Windows On-Premise, that is without container like Docker and Snap.
Thanks to xet7 !
2024-04-07 18:33:23 +03:00
Lauri Ojansivu 98dd28818a Updated wiki. 2024-04-07 16:49:05 +03:00
Lauri Ojansivu f705373cc4 v7.42 2024-04-03 01:20:29 +03:00
Lauri Ojansivu 5bc60a8dab Updated ChangeLog. 2024-04-03 01:17:13 +03:00
Lauri Ojansivu 1c8f783767 Updated dependencies.
Thanks to developers of dependencies !
2024-04-03 01:15:08 +03:00
Lauri Ojansivu 24d3075c85 Updated ChangeLog. 2024-04-03 01:13:20 +03:00
Lauri Ojansivu c461adff11 Fixed CRITICAL SECURITY ISSUE by updating meteor-node-stubs.
Thanks to Meteor developers !
2024-04-03 00:53:47 +03:00
Lauri Ojansivu b172f7207d Merge pull request #5363 from jghaanstra/main
Small tweaks to moderndark theme
2024-04-01 17:27:31 +03:00
Jelger Haanstra ef31fffa40 Small tweaks to moderndark theme 2024-03-28 19:27:35 +01:00
Lauri Ojansivu 426632a307 Updated translations. 2024-03-27 20:59:32 +02:00
Lauri Ojansivu 2c708b6df6 Updated translations. 2024-03-25 14:10:34 +02:00
Lauri Ojansivu b555d0ccc8 Merge pull request #5360 from dyercode/patch-1
Update README.md
2024-03-21 22:05:55 +02:00
Jon Dyer e1724c8a12 Update README.md
change link to the thing you're talking about (presumably) instead of cyclically linking to the page the link is on
2024-03-21 08:30:32 -04:00
Lauri Ojansivu cd35574c0b Merge pull request #5356 from wekan/dependabot/github_actions/docker/login-action-3.1.0
Bump docker/login-action from 3.0.0 to 3.1.0
2024-03-19 07:50:28 +02:00
Lauri Ojansivu d016cbcffc Merge pull request #5355 from wekan/dependabot/github_actions/docker/build-push-action-5.3.0
Bump docker/build-push-action from 5.2.0 to 5.3.0
2024-03-19 07:50:13 +02:00
dependabot[bot] 7e4b672888 Bump docker/login-action from 3.0.0 to 3.1.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/343f7c4344506bcbf9b4de18042ae17996df046d...e92390c5fb421da1463c202d546fed0ec5c39f20)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 20:06:55 +00:00
dependabot[bot] 06d9abf6f6 Bump docker/build-push-action from 5.2.0 to 5.3.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/af5a7ed5ba88268d5278f7203fb52cd833f66d6e...2cdde995de11925a030ce8070c3d77a52ffcf1c0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 20:06:52 +00:00
Lauri Ojansivu a1a6dae5c6 v7.41 2024-03-18 02:32:43 +02:00
Lauri Ojansivu c5f40f1be9 Updated ChangeLog. 2024-03-18 02:26:26 +02:00
Lauri Ojansivu 4358cb5e57 Merge pull request #5350 from lorodoes/main
Update mongodb-control
2024-03-18 01:46:46 +02:00
lorodoes a591bf05e0 Update mongodb-control
Missed a few mongosh lines.
2024-03-17 19:28:50 -04:00
Lauri Ojansivu 568b7538ad Merge pull request #5349 from lorodoes/main
Update mongodb-control
2024-03-18 01:06:54 +02:00
lorodoes bbd7765432 Update mongodb-control
Fixes for mongosh to allow snap packages to update to the edge/candidate version
2024-03-17 19:04:07 -04:00
Lauri Ojansivu 558024785f v7.40 2024-03-17 04:03:51 +02:00
Lauri Ojansivu 76043cc5b6 Updated ChangeLog. 2024-03-17 03:53:50 +02:00
Lauri Ojansivu 583fca1814 Fixed In RTL, hamburger margin is too much in mobile.
Thanks to mohammadZahedian and xet7 !

Fixes #5337
2024-03-17 03:49:46 +02:00
Lauri Ojansivu 806201b8cb Updated ChangeLog. 2024-03-17 03:38:26 +02:00
Lauri Ojansivu 24c89aeb64 Fixed centering of text below custom login logo.
Thanks to xet7 !
2024-03-17 03:36:05 +02:00
Lauri Ojansivu 8f0d88d9e0 v7.39 2024-03-16 15:08:24 +02:00
Lauri Ojansivu e92d8dc127 Updated ChangeLog. 2024-03-16 14:59:15 +02:00
Lauri Ojansivu 8a99e8f796 Merge pull request #5346 from kuba-orlik/patch-1
Make the contents of the cards grow to the list width
2024-03-14 20:38:18 +02:00
Kuba Orlik c0246c6834 Make the contents of the cards grow to the list width 2024-03-14 11:42:56 +01:00
Lauri Ojansivu 42ed92f346 Merge pull request #5344 from wekan/dependabot/github_actions/VeryGoodOpenSource/very_good_coverage-3.0.0
Bump VeryGoodOpenSource/very_good_coverage from 2.2.0 to 3.0.0
2024-03-13 16:06:19 +02:00
Lauri Ojansivu df0bd90fae Merge pull request #5343 from wekan/dependabot/github_actions/docker/build-push-action-5.2.0
Bump docker/build-push-action from 5.1.0 to 5.2.0
2024-03-13 16:05:57 +02:00
dependabot[bot] 3453f94b43 Bump VeryGoodOpenSource/very_good_coverage from 2.2.0 to 3.0.0
Bumps [VeryGoodOpenSource/very_good_coverage](https://github.com/verygoodopensource/very_good_coverage) from 2.2.0 to 3.0.0.
- [Release notes](https://github.com/verygoodopensource/very_good_coverage/releases)
- [Changelog](https://github.com/VeryGoodOpenSource/very_good_coverage/blob/main/CHANGELOG.md)
- [Commits](https://github.com/verygoodopensource/very_good_coverage/compare/v2.2.0...v3.0.0)

---
updated-dependencies:
- dependency-name: VeryGoodOpenSource/very_good_coverage
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 20:01:56 +00:00
dependabot[bot] ca537e266d Bump docker/build-push-action from 5.1.0 to 5.2.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/4a13e500e55cf31b7a5d59a38ab2040ab0f42f56...af5a7ed5ba88268d5278f7203fb52cd833f66d6e)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 20:01:53 +00:00
Lauri Ojansivu 8f3c948614 Updated docs. 2024-03-11 15:53:23 +02:00
Lauri Ojansivu 059743ad34 Merge pull request #5341 from e-gaulue/e-gaulue-wiki-1
Clarify usage of api.py
2024-03-11 15:29:04 +02:00
e-gaulue 33ccf68e17 Update New-card-with-Python3-and-REST-API.md 2024-03-11 14:17:20 +01:00
e-gaulue b6f22712f9 Update New-card-with-Python3-and-REST-API.md
Clarify usage, at least for me.
2024-03-11 14:14:42 +01:00
Lauri Ojansivu 9e413b3961 Merge pull request #5340 from e-gaulue/ED1 2024-03-11 11:49:55 +02:00
Lauri Ojansivu 5dd318a481 v7.38 2024-03-10 23:47:29 +01:00
Lauri Ojansivu 1783257c0e v7.38 2024-03-10 08:42:04 +02:00
Lauri Ojansivu 966852c212 Updated ChangeLog. 2024-03-10 08:37:21 +02:00
Lauri Ojansivu 07d6c1e514 Upgraded to MongoDB 6.0.14 at Snap Candidate.
Thanks to MongoDB developers !
2024-03-10 08:35:55 +02:00
Lauri Ojansivu 09be915ea5 Updated ChangeLog. 2024-03-10 08:34:27 +02:00
Lauri Ojansivu abd3c95dfa Fixed In RTL, hamburger needs margin.
Thanks to mohammadZahedian and xet7 !

Fixes #5337
2024-03-10 08:31:33 +02:00
Lauri Ojansivu 3fa61ac23c Updated ChangeLog. 2024-03-10 08:21:10 +02:00
Lauri Ojansivu 00bbc26698 Fixed text below custom login logo not visible.
Thanks to xet7 !
2024-03-10 08:18:50 +02:00
Lauri Ojansivu 3004f54b5d Updated ChangeLog. 2024-03-08 23:14:20 +02:00
Lauri Ojansivu ef5b888779 Add info about GitHub top committers at Finland.
Thanks to xet7 !
2024-03-08 23:02:41 +02:00
Lauri Ojansivu 835e33bf09 Added script to count lines of code changed per committer email address, because GitHub removed that feature from web UI.
Thanks to bgwines and xet7 !
2024-03-08 22:57:38 +02:00
Lauri Ojansivu 8ba3a05648 Updated contributing to wiki. 2024-03-08 21:36:29 +02:00
Lauri Ojansivu 73ae73d4c3 Added docs from wekan.wiki and wekan-snap.wiki 2024-03-08 21:24:14 +02:00
Lauri Ojansivu 76175a711a Merge pull request #5336 from xator91/patch-12
Update api.py
2024-03-08 14:18:55 +02:00
Mirko Genovese 574acd6744 Update api.py
#5322 Fix error during delete.
2024-03-08 11:45:34 +01:00
Lauri Ojansivu 9e0e052bba Updated ChangeLog. 2024-03-07 20:18:51 +02:00
Lauri Ojansivu ffafb30b9b Fixed API get_all_cards doesn't return SwimlaneId. Please test.
Thanks to mohammadZahedian, xator91 and xet7.

Fixes #5319
2024-03-07 13:36:42 +02:00
Lauri Ojansivu 9c4e402e6c v7.37 2024-03-07 13:27:49 +02:00
Lauri Ojansivu f6f9dbb5e3 Updated ChangeLog. 2024-03-07 13:14:23 +02:00
Lauri Ojansivu 7beced1e68 Fixed API get swimlane cards wrong order. Please test.
Thanks to mohammadZahedian, xator91 and xet7.

Fixes #5319
2024-03-07 13:10:41 +02:00
Lauri Ojansivu c8921b77f0 v7.36 2024-03-06 12:14:54 +02:00
Lauri Ojansivu 482ce0a265 Updated ChangeLog. 2024-03-06 12:10:03 +02:00
Lauri Ojansivu c570405d02 Try to fix API get cards wrong order. Please test.
Thanks to mohammadZahedian, xator91 and xet7.

Fixes #5319
2024-03-06 12:07:18 +02:00
Lauri Ojansivu 35ed465e10 Updated ChangeLog. 2024-03-06 11:57:26 +02:00
Lauri Ojansivu 747bc4c088 Fixed Card image cover should be margin-top:6px since hamburger menu and due date at the top.
Thanks to e-gaulue and xet7 !

Fixes #5331
2024-03-06 11:54:10 +02:00
Lauri Ojansivu 7c156927e4 Updated ChangeLog. 2024-02-28 23:08:10 +02:00
Lauri Ojansivu 13f0c77fb6 Merge pull request #5326 from xator91/patch-11
Update api.py
2024-02-28 23:03:03 +02:00
Mirko Genovese 82d9f77eb3 Update api.py
Added new 4 command. 

checklistid, checklistinfo, get_list_cards_count and get_board_cards_count
2024-02-28 07:58:19 +01:00
2049 changed files with 428677 additions and 164694 deletions

No files matched your search

+101 -94
View File
@@ -1,20 +1,24 @@
FROM ubuntu:21.10
LABEL maintainer="sgr"
FROM ubuntu:24.04
LABEL maintainer="wekan"
LABEL org.opencontainers.image.ref.name="ubuntu"
LABEL org.opencontainers.image.version="24.04"
LABEL org.opencontainers.image.source="https://github.com/wekan/wekan"
# 2022-04-25:
# - gyp does not yet work with Ubuntu 22.04 ubuntu:rolling,
# so changing to 21.10. https://github.com/wekan/wekan/issues/4488
ENV BUILD_DEPS="gnupg gosu libarchive-tools wget curl bzip2 g++ build-essential python3 git ca-certificates iproute2"
ENV DEBIAN_FRONTEND=noninteractive
ENV BUILD_DEPS="apt-utils gnupg gosu wget bzip2 g++ iproute2 apt-transport-https libarchive-tools"
ENV DEV_DEPS="curl python3 ca-certificates build-essential git"
ARG DEBIAN_FRONTEND=noninteractive
ENV \
DEBUG=false \
NODE_VERSION=v14.21.4 \
METEOR_RELEASE=METEOR@2.13 \
METEOR_RELEASE=METEOR@2.14 \
USE_EDGE=false \
METEOR_EDGE=1.5-beta.17 \
NPM_VERSION=latest \
NPM_VERSION=6.14.17 \
FIBERS_VERSION=4.0.1 \
ARCHITECTURE=linux-x64 \
SRC_PATH=./ \
@@ -28,15 +32,14 @@ ENV \
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 \
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 \
ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90 \
RICHER_CARD_COMMENT_EDITOR=false \
CARD_OPENED_WEBHOOK_ENABLED=false \
ATTACHMENTS_STORE_PATH="" \
ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM="" \
ATTACHMENTS_UPLOAD_MIME_TYPES="" \
ATTACHMENTS_UPLOAD_MAX_SIZE=0 \
AVATARS_UPLOAD_EXTERNAL_PROGRAM="" \
AVATARS_UPLOAD_MIME_TYPES="" \
AVATARS_UPLOAD_MAX_SIZE=0 \
RICHER_CARD_COMMENT_EDITOR=false \
CARD_OPENED_WEBHOOK_ENABLED=false \
MAX_IMAGE_PIXEL="" \
IMAGE_COMPRESS_RATIO="" \
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE="" \
@@ -48,10 +51,12 @@ ENV \
MATOMO_SITE_ID="" \
MATOMO_DO_NOT_TRACK=true \
MATOMO_WITH_USERNAME=false \
METRICS_ALLOWED_IP_ADDRESSES="" \
BROWSER_POLICY_ENABLED=true \
TRUSTED_URL="" \
WEBHOOKS_ATTRIBUTES="" \
OAUTH2_ENABLED=false \
OIDC_REDIRECTION_ENABLED=false \
OAUTH2_CA_CERT="" \
OAUTH2_ADFS_ENABLED=false \
OAUTH2_B2C_ENABLED=false \
@@ -71,6 +76,9 @@ ENV \
LDAP_ENABLE=false \
LDAP_PORT=389 \
LDAP_HOST="" \
LDAP_AD_SIMPLE_AUTH="" \
LDAP_USER_AUTHENTICATION=false \
LDAP_USER_AUTHENTICATION_FIELD=uid \
LDAP_BASEDN="" \
LDAP_LOGIN_FALLBACK=false \
LDAP_RECONNECT=true \
@@ -88,8 +96,6 @@ ENV \
LDAP_ENCRYPTION=false \
LDAP_CA_CERT="" \
LDAP_REJECT_UNAUTHORIZED=false \
LDAP_USER_AUTHENTICATION=false \
LDAP_USER_AUTHENTICATION_FIELD=uid \
LDAP_USER_SEARCH_FILTER="" \
LDAP_USER_SEARCH_SCOPE="" \
LDAP_USER_SEARCH_FIELD="" \
@@ -144,69 +150,32 @@ ENV \
SAML_IDENTIFIER_FORMAT="" \
SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE="" \
SAML_ATTRIBUTES="" \
DEFAULT_WAIT_SPINNER="" \
ORACLE_OIM_ENABLED=false \
WAIT_SPINNER="" \
WRITABLE_PATH=/data \
S3=""
# \
# NODE_OPTIONS="--max_old_space_size=4096"
#---------------------------------------------------------------------
# https://github.com/wekan/wekan/issues/3585#issuecomment-1021522132
# Add more Node heap:
# NODE_OPTIONS="--max_old_space_size=4096"
# Add more stack:
# bash -c "ulimit -s 65500; exec node --stack-size=65500 main.js"
#---------------------------------------------
# == at docker-compose.yml: AUTOLOGIN WITH OIDC/OAUTH2 ====
# https://github.com/wekan/wekan/wiki/autologin
#- OIDC_REDIRECTION_ENABLED=true
#---------------------------------------------------------------------
# Install OS
RUN set -o xtrace \
&& useradd --user-group -m --system --home-dir /home/wekan wekan \
&& apt-get update \
&& apt-get install --assume-yes --no-install-recommends apt-utils apt-transport-https ca-certificates 2>&1 \
&& apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS}
# OLD:
# && curl -fsSLO --compressed "https://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-$ARCHITECTURE.tar.xz" \
# && curl -fsSLO --compressed "https://nodejs.org/dist/$NODE_VERSION/SHASUMS256.txt.asc" \
# Install NodeJS
RUN set -o xtrace \
&& cd /tmp \
&& curl -fsSLO --compressed "https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/node-${NODE_VERSION}-${ARCHITECTURE}.tar.xz" \
&& curl -fsSLO --compressed "https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/SHASUMS256.txt" \
&& grep " node-$NODE_VERSION-$ARCHITECTURE.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
&& tar -xJf "node-$NODE_VERSION-$ARCHITECTURE.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
&& rm "node-$NODE_VERSION-$ARCHITECTURE.tar.xz" SHASUMS256.txt \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs \
&& mkdir -p /usr/local/lib/node_modules/fibers/.node-gyp /root/.node-gyp/${NODE_VERSION} /home/wekan/.config \
&& npm install -g npm@${NPM_VERSION} \
&& chown wekan:wekan --recursive /home/wekan/.config
ENV DEBIAN_FRONTEND=dialog
USER wekan
# Install Meteor
RUN set -o xtrace \
&& cd /home/wekan \
&& curl https://install.meteor.com/?release=$METEOR_VERSION --output /home/wekan/install-meteor.sh \
# Replace tar with bsdtar in the install script; https://github.com/jshimko/meteor-launchpad/issues/39
&& sed --in-place "s/tar -xzf.*/bsdtar -xf \"\$TARBALL_FILE\" -C \"\$INSTALL_TMPDIR\"/g" /home/wekan/install-meteor.sh \
&& sed --in-place 's/VERBOSITY="--silent"/VERBOSITY="--progress-bar"/' /home/wekan/install-meteor.sh \
&& printf "\n[-] Installing Meteor $METEOR_VERSION...\n\n" \
&& sh /home/wekan/install-meteor.sh
ENV PATH=$PATH:/home/wekan/.meteor/
USER root
RUN echo "export PATH=$PATH" >> /etc/environment
USER wekan
RUN <<EOR
echo "export PATH=$PATH" >> /etc/environment
EOR
# Copy source dir
RUN set -o xtrace \
&& mkdir -p /home/wekan/app/.meteor \
&& mkdir -p /home/wekan/app/packages
RUN <<EOR
set -o xtrace
mkdir -p /home/wekan/app/.meteor
mkdir -p /home/wekan/app/packages
EOR
COPY \
.meteor/.finished-upgraders \
@@ -231,44 +200,83 @@ COPY \
packages \
/home/wekan/app/packages/
USER root
# Install OS
RUN <<EOR
set -o xtrace
RUN set -o xtrace \
&& chown -R wekan:wekan /home/wekan/app /home/wekan/.meteor
# Add non-root user wekan
useradd --user-group --system --home-dir /home/wekan wekan
# OS dependencies
apt-get update --assume-yes
apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS} ${DEV_DEPS}
USER wekan
# Meteor installer doesn't work with the default tar binary, so using bsdtar while installing.
# https://github.com/coreos/bugs/issues/1095#issuecomment-350574389
cp $(which tar) $(which tar)~
ln -sf $(which bsdtar) $(which tar)
RUN \
set -o xtrace && \
# Build app
cd /home/wekan/app && \
/home/wekan/.meteor/meteor add standard-minifier-js && \
/home/wekan/.meteor/meteor npm install && \
/home/wekan/.meteor/meteor build --directory /home/wekan/app_build
# Install NodeJS
cd /tmp
RUN \
set -o xtrace && \
cd /home/wekan/app_build/bundle/programs/server/ && \
chmod u+w package.json npm-shrinkwrap.json && \
npm install && \
cd node_modules/fibers && \
node build.js
# Download nodejs
wget "https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz"
wget "https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/SHASUMS256.txt"
# Verify nodejs authenticity
grep "node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz" "SHASUMS256.txt" | shasum -a 256 -c -
rm -f "SHASUMS256.txt"
# Install Node
tar xzf "node-$NODE_VERSION-$ARCHITECTURE.tar.gz" -C /usr/local --strip-components=1 --no-same-owner
rm "node-$NODE_VERSION-$ARCHITECTURE.tar.gz" "SHASUMS256.txt"
ln -s "/usr/local/bin/node" "/usr/local/bin/nodejs"
mkdir -p "/opt/nodejs/lib/node_modules/fibers/.node-gyp" "/root/.node-gyp/${NODE_VERSION} /home/wekan/.config"
# Install node dependencies
npm install -g npm@${NPM_VERSION}
chown --recursive wekan:wekan /home/wekan/.config
# Install Meteor
cd /home/wekan
chown --recursive wekan:wekan /home/wekan
echo "Starting meteor ${METEOR_RELEASE} installation... \n"
gosu wekan:wekan curl https://install.meteor.com/ | /bin/sh
mv /root/.meteor /home/wekan/
chown --recursive wekan:wekan /home/wekan/.meteor
# sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' /home/wekan/app/packages/meteor-useraccounts-core/package.js
cd /home/wekan/.meteor
gosu wekan:wekan /home/wekan/.meteor/meteor -- help
# Build app (Development)
cd /home/wekan/app
gosu wekan:wekan /home/wekan/.meteor/meteor add standard-minifier-js
gosu wekan:wekan /home/wekan/.meteor/meteor npm install --no-audit
# Put back the original tar
mv $(which tar)~ $(which tar)
USER root
# Cleanup
RUN \
set -o xtrace && \
apt-get clean -y && \
apt-get autoremove -y && \
rm -Rf /tmp/* && \
rm -Rf /home/wekan/app_build && \
rm -Rf /var/cache/apt /var/lib/apt/lists && \
rm -Rf /var/lib/apt/lists/*
apt-get remove --purge --assume-yes ${BUILD_DEPS}
apt-get install --assume-yes --no-install-recommends build-essential
apt-get autoremove --assume-yes
apt-get clean --assume-yes
rm -Rf /tmp/*
rm -Rf /var/lib/apt/lists/*
rm -Rf /var/cache/apt
rm -Rf /var/lib/apt/lists
rm -Rf /home/wekan/app_build
mkdir /data
chown wekan --recursive /data
EOR
USER wekan
ENV PORT=3000
EXPOSE $PORT
STOPSIGNAL SIGKILL
WORKDIR /home/wekan/app
#---------------------------------------------------------------------
@@ -278,7 +286,6 @@ WORKDIR /home/wekan/app
# Add more stack:
# bash -c "ulimit -s 65500; exec node --stack-size=65500 main.js"
#---------------------------------------------------------------------
#TODO:
#CMD ["bash", "-c", "ulimit -s 65500; exec node --stack-size=65500 /build/main.js"]
#
CMD ["/home/wekan/.meteor/meteor", "run", "--verbose", "--settings", "settings.json"]
+38 -18
View File
@@ -20,7 +20,10 @@
"strict": 0,
"no-undef": 0,
"accessor-pairs": 2,
"comma-dangle": [2, "always-multiline"],
"comma-dangle": [
2,
"always-multiline"
],
"consistent-return": 2,
"dot-notation": 2,
"eqeqeq": 2,
@@ -28,15 +31,28 @@
"no-cond-assign": 2,
"no-constant-condition": 2,
"no-eval": 2,
"no-inner-declarations": [0],
"no-inner-declarations": [
0
],
"no-unneeded-ternary": 2,
"radix": 2,
"semi": [2, "always"],
"camelcase": [2, { "properties": "never" }],
"semi": [
2,
"always"
],
"camelcase": [
2,
{
"properties": "never"
}
],
"comma-spacing": 2,
"comma-style": 2,
"eol-last": 2,
"linebreak-style": [2, "unix"],
"linebreak-style": [
2,
"unix"
],
"meteor/audit-argument-checks": 0,
"new-parens": 2,
"no-lonely-if": 2,
@@ -45,7 +61,13 @@
"no-spaced-func": 2,
"no-trailing-spaces": 2,
"operator-linebreak": 2,
"quotes": [2, "single", { "avoidEscape": true }],
"quotes": [
2,
"single",
{
"avoidEscape": true
}
],
"semi-spacing": 2,
"space-unary-ops": 2,
"arrow-spacing": 2,
@@ -57,6 +79,7 @@
"prefer-spread": 2,
"prefer-template": 2,
"no-unused-vars": "warn",
"@typescript-eslint/no-floating-promises": "error",
"prettier/prettier": [
"error",
{
@@ -72,11 +95,18 @@
"settings": {
"import/resolver": {
"meteor": {
"extensions": [".js", ".jsx"]
"extensions": [
".js",
".jsx"
]
}
}
},
"plugins": ["prettier", "meteor"],
"plugins": [
"prettier",
"meteor",
"@typescript-eslint"
],
"globals": {
"Meteor": false,
"Session": false,
@@ -93,29 +123,22 @@
"Template": false,
"$": false,
"_": false,
"autosize": false,
"Avatar": true,
"Avatars": true,
"BlazeComponent": false,
"BlazeLayout": false,
"CollectionHooks": false,
"DocHead": false,
"ESSearchResults": false,
"FastRender": false,
"FlowRouter": false,
"FS": false,
"getSlug": false,
"Migrations": false,
"moment": false,
"Mousetrap": false,
"Picker": false,
"Presence": true,
"presences": true,
"Ps": true,
"ReactiveTabs": false,
"Restivus": false,
"SimpleSchema": false,
"SubsManager": false,
"T9n": false,
"TAPi18n": false,
"AccountsTemplates": true,
@@ -133,13 +156,11 @@
"CSSEvents": true,
"EscapeActions": true,
"Filter": true,
"Mixins": true,
"Modal": true,
"MultiSelection": true,
"Popup": true,
"Sidebar": true,
"Utils": true,
"InlinedForm": true,
"UnsavedEdits": true,
"Notifications": true,
"allowIsBoardAdmin": true,
@@ -152,7 +173,6 @@
"Checklists": true,
"Settings": true,
"InvitationCodes": true,
"JsonRoutes": true,
"Authentication": true,
"Integrations": true,
"HTTP": true,
-257
View File
@@ -1,257 +0,0 @@
name: wekan
version: 0
version-script: git describe --tags | cut -c 2-
summary: The open-source kanban
description: |
Wekan is an open-source and collaborative kanban board application.
Whether you’re maintaining a personal todo list, planning your holidays with some friends, or working in a team on your next revolutionary idea, Kanban boards are an unbeatable tool to keep your things organized. They give you a visual overview of the current state of your project, and make you productive by allowing you to focus on the few items that matter the most.
Depending on target environment, some configuration settings might need to be adjusted.
For full list of configuration options call:
$ wekan.help
confinement: strict
grade: stable
architectures:
- amd64
plugs:
mongodb-plug:
interface: content
target: $SNAP_DATA/shared
hooks:
configure:
plugs:
- network
- network-bind
slots:
mongodb-slot:
interface: content
write:
- $SNAP_DATA/share
apps:
wekan:
command: wekan-control
daemon: simple
plugs: [network, network-bind]
mongodb:
command: mongodb-control
daemon: simple
plugs: [network, network-bind]
caddy:
command: caddy-control
daemon: simple
plugs: [network, network-bind]
help:
command: wekan-help
database-backup:
command: mongodb-backup
plugs: [network, network-bind]
database-list-backups:
command: ls -al $SNAP_COMMON/db-backups/
database-restore:
command: mongodb-restore
plugs: [network, network-bind]
parts:
mongodb:
source: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-4.2.6.tgz
plugin: dump
stage-packages: [libssl1.0.0, libcurl3]
filesets:
mongo:
- usr
- bin
- lib
stage:
- $mongo
prime:
- $mongo
wekan:
source: .
plugin: nodejs
node-engine: 14.21.3
node-packages:
- node-gyp
- node-pre-gyp
- fibers
build-packages:
- ca-certificates
- apt-utils
- python
- python3
- g++
- capnproto
- curl
- libcurl3
- execstack
- nodejs
- npm
stage-packages:
- libfontconfig1
override-build: |
echo "Cleaning environment first"
rm -rf ~/.meteor ~/.npm /usr/local/lib/node_modules
# Create the OpenAPI specification
rm -rf .build
## Use Meteor 1.8.x on Snap
#rm -rf .meteor
#mv .snap-meteor-1.8/.meteor .
#mv .snap-meteor-1.8/package.json .
#mv .snap-meteor-1.8/package-lock.json .
## Meteor 1.9.x has changes to Buffer() => Buffer.alloc(), so reverting those
#mv .snap-meteor-1.8/cfs_access-point.txt fix-download-unicode/
#mv .snap-meteor-1.8/export.js models/
#mv .snap-meteor-1.8/wekanCreator.js models/
#mv .snap-meteor-1.8/ldap.js packages/wekan-ldap/server/ldap.js
#mv .snap-meteor-1.8/oidc_server.js packages/wekan-oidc/oidc_server.js
rm -rf .snap-meteor-1.8
#mkdir -p .build/python
#cd .build/python
#git clone --depth 1 -b master https://github.com/Kronuz/esprima-python
#cd esprima-python
#python3 setup.py install
#cd ../../..
#mkdir -p ./public/api
#python3 ./openapi/generate_openapi.py --release $(git describe --tags --abbrev=0) > ./public/api/wekan.yml
# we temporary need api2html and mkdirp
#npm install -g api2html@0.3.0
#npm install -g mkdirp
#api2html -c ./public/logo-header.png -o ./public/api/wekan.html ./public/api/wekan.yml
#npm uninstall -g mkdirp
#npm uninstall -g api2html
# Node Fibers 100% CPU usage issue:
# https://github.com/wekan/wekan-mongodb/issues/2#issuecomment-381453161
# https://github.com/meteor/meteor/issues/9796#issuecomment-381676326
# https://github.com/sandstorm-io/sandstorm/blob/0f1fec013fe7208ed0fd97eb88b31b77e3c61f42/shell/server/00-startup.js#L99-L129
# Also see beginning of wekan/server/authentication.js
# import Fiber from "fibers";
# Fiber.poolSize = 1e9;
# OLD: Download node version 8.12.0 prerelease build => Official node 8.12.0 has been released
# Description at https://releases.wekan.team/node.txt
##echo "375bd8db50b9c692c0bbba6e96d4114cd29bee3770f901c1ff2249d1038f1348 node" >> node-SHASUMS256.txt.asc
##curl https://releases.wekan.team/node -o node
# Verify Fibers patched node authenticity
##echo "Fibers 100% CPU issue patched node authenticity:"
##grep node node-SHASUMS256.txt.asc | shasum -a 256 -c -
##rm -f node-SHASUMS256.txt.asc
##chmod +x node
##mv node `which node`
# DOES NOT WORK: paxctl fix.
# Removed from build-packages: - paxctl
#echo "Applying paxctl fix for alpine linux: https://github.com/wekan/wekan/issues/1303"
#paxctl -mC `which node`
#echo "Installing npm"
#curl -L https://www.npmjs.com/install.sh | sh
echo "Installing meteor"
curl https://install.meteor.com/ -o install_meteor.sh
#sed -i "s|RELEASE=.*|RELEASE=\"1.8.1-beta.0\"|g" install_meteor.sh
chmod +x install_meteor.sh
sh install_meteor.sh
rm install_meteor.sh
# REPOS BELOW ARE INCLUDED TO WEKAN REPO
#if [ ! -d "packages" ]; then
# mkdir packages
#fi
#if [ ! -d "packages/kadira-flow-router" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router
# cd ..
#fi
#if [ ! -d "packages/meteor-useraccounts-core" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core
# sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' meteor-useraccounts-core/package.js
# cd ..
#fi
#if [ ! -d "packages/meteor-accounts-cas" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-cas.git meteor-accounts-cas
# cd ..
#fi
#if [ ! -d "packages/wekan-ldap" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/wekan/wekan-ldap.git
# cd ..
#fi
#if [ ! -d "packages/wekan-scrollbar" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/wekan/wekan-scrollbar.git
# cd ..
#fi
#if [ ! -d "packages/wekan_accounts-oidc" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-oidc.git
# mv meteor-accounts-oidc/packages/switch_accounts-oidc wekan-accounts-oidc
# mv meteor-accounts-oidc/packages/switch_oidc wekan-oidc
# rm -rf meteor-accounts-oidc
# cd ..
#fi
#if [ ! -d "packages/markdown" ]; then
# cd packages
# git clone --depth 1 -b master --recurse-submodules https://github.com/wekan/markdown.git
# cd ..
#fi
rm -rf .build
meteor add standard-minifier-js --allow-superuser
meteor npm install --allow-superuser
meteor npm install --allow-superuser --save babel-runtime
meteor build .build --directory --allow-superuser
cp -f fix-download-unicode/cfs_access-point.txt .build/bundle/programs/server/packages/cfs_access-point.js
#Removed binary version of bcrypt because of security vulnerability that is not fixed yet.
#https://github.com/wekan/wekan/commit/4b2010213907c61b0e0482ab55abb06f6a668eac
#https://github.com/wekan/wekan/commit/7eeabf14be3c63fae2226e561ef8a0c1390c8d3c
#cd .build/bundle/programs/server/npm/node_modules/meteor/npm-bcrypt
#rm -rf node_modules/bcrypt
#meteor npm install --save bcrypt
# Change from npm-bcrypt directory back to .build/bundle/programs/server directory.
#cd ../../../../
# Change to directory .build/bundle/programs/server
cd .build/bundle/programs/server
npm install
npm install --allow-superuser --save babel-runtime
#meteor npm install --save bcrypt
# Change back to Wekan source directory
cd ../../../..
cp -r .build/bundle/* $SNAPCRAFT_PART_INSTALL/
cp .build/bundle/.node_version.txt $SNAPCRAFT_PART_INSTALL/
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/wekan
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/tar/lib/.mkdir.js.swp
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-gyp/node_modules/tar/lib/.mkdir.js.swp
# Meteor 1.8.x additional .swp remove
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
organize:
README: README.wekan
prime:
- -lib/node_modules/node-pre-gyp/node_modules/tar/lib/.unpack.js.swp
helpers:
source: snap-src
plugin: dump
caddy:
plugin: dump
source: https://caddyserver.com/download/linux/amd64?license=personal&telemetry=off
source-type: tar
organize:
caddy: bin/caddy
CHANGES.txt: CADDY_CHANGES.txt
EULA.txt: CADDY_EULA.txt
LICENSES.txt: CADDY_LICENSES.txt
README.txt: CADDY_README.txt
stage:
- -init
-198
View File
@@ -1,198 +0,0 @@
#!/bin/bash
echo "Note: If you use other locale than en_US.UTF-8 , you need to additionally install en_US.UTF-8"
echo " with 'sudo dpkg-reconfigure locales' , so that MongoDB works correctly."
echo " You can still use any other locale as your main locale."
#Below script installs newest node 8.x for Debian/Ubuntu/Mint.
#NODE_VERSION=12.21.0
#X64NODE="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz"
function pause(){
read -p "$*"
}
function cprec(){
if [[ -d "$1" ]]; then
if [[ ! -d "$2" ]]; then
sudo mkdir -p "$2"
fi
for i in $(ls -A "$1"); do
cprec "$1/$i" "$2/$i"
done
else
sudo cp "$1" "$2"
fi
}
# sudo npm doesn't work right, so this is a workaround
function npm_call(){
TMPDIR="/tmp/tmp_npm_prefix"
if [[ -d "$TMPDIR" ]]; then
rm -rf $TMPDIR
fi
mkdir $TMPDIR
NPM_PREFIX="$(npm config get prefix)"
npm config set prefix $TMPDIR
npm "$@"
npm config set prefix "$NPM_PREFIX"
echo "Moving files to $NPM_PREFIX"
for i in $(ls -A $TMPDIR); do
cprec "$TMPDIR/$i" "$NPM_PREFIX/$i"
done
rm -rf $TMPDIR
}
#function wekan_repo_check(){
## UNCOMMENTING, IT'S NOT REQUIRED THAT /HOME/USERNAME IS /HOME/WEKAN
# git_remotes="$(git remote show 2>/dev/null)"
# res=""
# for i in $git_remotes; do
# res="$(git remote get-url $i | sed 's/.*wekan\/wekan.*/wekan\/wekan/')"
# if [[ "$res" == "wekan/wekan" ]]; then
# break
# fi
# done
#
# if [[ "$res" != "wekan/wekan" ]]; then
# echo "$PWD is not a wekan repository"
# exit;
# fi
#}
echo
PS3='Please enter your choice: '
options=("Install Wekan dependencies" "Build Wekan" "Run Meteor for dev on http://localhost:4000" "Run Meteor for dev on http://CURRENT-IP-ADDRESS:4000" "Run Meteor for dev on http://CUSTOM-IP-ADDRESS:PORT" "Quit")
select opt in "${options[@]}"
do
case $opt in
"Install Wekan dependencies")
if [[ "$OSTYPE" == "linux-gnu" ]]; then
echo "Linux";
# Debian, Ubuntu, Mint
sudo apt-get install -y build-essential gcc g++ make git curl wget
# npm nodejs
#sudo npm -g install npm
curl -0 -L https://npmjs.org/install.sh | sudo sh
sudo chown -R $(id -u):$(id -g) $HOME/.npm
sudo npm -g install n
sudo n 12.21.0
#curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
#sudo apt-get install -y nodejs
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo "macOS";
pause '1) Install XCode 2) Install Node 8.x from https://nodejs.org/en/ 3) Press [Enter] key to continue.'
elif [[ "$OSTYPE" == "cygwin" ]]; then
# POSIX compatibility layer and Linux environment emulation for Windows
echo "TODO: Add Cygwin";
exit;
elif [[ "$OSTYPE" == "msys" ]]; then
# Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
echo "TODO: Add msys on Windows";
exit;
elif [[ "$OSTYPE" == "win32" ]]; then
# I'm not sure this can happen.
echo "TODO: Add Windows";
exit;
elif [[ "$OSTYPE" == "freebsd"* ]]; then
echo "TODO: Add FreeBSD";
exit;
else
echo "Unknown"
echo ${OSTYPE}
exit;
fi
## Latest npm with Meteor 1.8.x
npm_call -g install npm
npm_call -g install node-gyp
# Latest fibers for Meteor 1.8.x
sudo mkdir -p /usr/local/lib/node_modules/fibers/.node-gyp
npm_call -g install fibers
# Install Meteor, if it's not yet installed
curl https://install.meteor.com | bash
sudo chown -R $(id -u):$(id -g) $HOME/.npm $HOME/.meteor
break
;;
"Build Wekan")
echo "Building Wekan."
#wekan_repo_check
# REPOS BELOW ARE INCLUDED TO WEKAN REPO
#rm -rf packages/kadira-flow-router packages/meteor-useraccounts-core packages/meteor-accounts-cas packages/wekan-ldap packages/wekan-ldap packages/wekan-scrfollbar packages/meteor-accounts-oidc packages/markdown
#mkdir packages
#cd packages
#git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router
#git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core
#git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-cas.git
#git clone --depth 1 -b master https://github.com/wekan/wekan-ldap.git
#git clone --depth 1 -b master https://github.com/wekan/wekan-scrollbar.git
#git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-oidc.git
#git clone --depth 1 -b master --recurse-submodules https://github.com/wekan/markdown.git
#mv meteor-accounts-oidc/packages/switch_accounts-oidc wekan_accounts-oidc
#mv meteor-accounts-oidc/packages/switch_oidc wekan_oidc
#rm -rf meteor-accounts-oidc
#if [[ "$OSTYPE" == "darwin"* ]]; then
# echo "sed at macOS";
# sed -i '' 's/api\.versionsFrom/\/\/api.versionsFrom/' ~/repos/wekan/packages/meteor-useraccounts-core/package.js
#else
# echo "sed at ${OSTYPE}"
# sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' ~/repos/wekan/packages/meteor-useraccounts-core/package.js
#fi
#cd ..
sudo chown -R $(id -u):$(id -g) $HOME/.npm $HOME/.meteor
rm -rf node_modules .meteor/local
npm install
rm -rf .build
meteor build .build --directory
cp -f fix-download-unicode/cfs_access-point.txt .build/bundle/programs/server/packages/cfs_access-point.js
# Remove legacy webbroser bundle, so that Wekan works also at Android Firefox, iOS Safari, etc.
rm -rf .build/bundle/programs/web.browser.legacy
#Removed binary version of bcrypt because of security vulnerability that is not fixed yet.
#https://github.com/wekan/wekan/commit/4b2010213907c61b0e0482ab55abb06f6a668eac
#https://github.com/wekan/wekan/commit/7eeabf14be3c63fae2226e561ef8a0c1390c8d3c
#cd ~/repos/wekan/.build/bundle/programs/server/npm/node_modules/meteor/npm-bcrypt
#rm -rf node_modules/bcrypt
#meteor npm install bcrypt
cd .build/bundle/programs/server
rm -rf node_modules
npm install
#meteor npm install bcrypt
cd ../../../..
echo Done.
break
;;
"Run Meteor for dev on http://localhost:4000")
WITH_API=true RICHER_CARD_COMMENT_EDITOR=false ROOT_URL=http://localhost:4000 meteor run --exclude-archs web.browser.legacy,web.cordova --port 4000
break
;;
"Run Meteor for dev on http://CURRENT-IP-ADDRESS:4000")
IPADDRESS=$(ip a | grep 'noprefixroute' | grep 'inet ' | cut -d: -f2 | awk '{ print $2}' | cut -d '/' -f 1)
echo "Your IP address is $IPADDRESS"
WITH_API=true RICHER_CARD_COMMENT_EDITOR=false ROOT_URL=http://$IPADDRESS:4000 meteor run --exclude-archs web.browser.legacy,web.cordova --port 4000
break
;;
"Run Meteor for dev on http://CUSTOM-IP-ADDRESS:PORT")
ip address
echo "From above list, what is your IP address?"
read IPADDRESS
echo "On what port you would like to run Wekan?"
read PORT
echo "ROOT_URL=http://$IPADDRESS:$PORT"
WITH_API=true RICHER_CARD_COMMENT_EDITOR=false ROOT_URL=http://$IPADDRESS:$PORT meteor run --exclude-archs web.browser.legacy,web.cordova --port $PORT
break
;;
"Quit")
break
;;
*) echo invalid option;;
esac
done
-155
View File
@@ -1,155 +0,0 @@
name: wekan
version: git
summary: The open-source kanban
description: |
Wekan is an open-source and collaborative kanban board application.
Whether you’re maintaining a personal todo list, planning your holidays with some friends, or working in a team on your next revolutionary idea, Kanban boards are an unbeatable tool to keep your things organized. They give you a visual overview of the current state of your project, and make you productive by allowing you to focus on the few items that matter the most.
Depending on target environment, some configuration settings might need to be adjusted.
For full list of configuration options call:
$ wekan.help
confinement: strict
grade: stable
base: core18
architectures:
- amd64
plugs:
mongodb-plug:
interface: content
target: $SNAP_DATA/shared
hooks:
configure:
plugs:
- network
- network-bind
slots:
mongodb-slot:
interface: content
write:
- $SNAP_DATA/share
apps:
wekan:
command: wekan-control
daemon: simple
plugs: [network, network-bind]
mongodb:
command: mongodb-control
daemon: simple
plugs: [network, network-bind]
caddy:
command: caddy-control
daemon: simple
plugs: [network, network-bind]
help:
command: wekan-help
database-backup:
command: mongodb-backup
plugs: [network, network-bind]
database-list-backups:
command: ls -al $SNAP_COMMON/db-backups/
database-restore:
command: mongodb-restore
plugs: [network, network-bind]
parts:
mongodb:
source: https://repo.mongodb.org/apt/ubuntu/dists/xenial/mongodb-org/4.2/multiverse/binary-amd64/mongodb-org-server_4.2.2_amd64.deb
#https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.14.tgz
#https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.2.22.tgz
plugin: dump
stage-packages: [libssl1.0.0, libcurl3]
filesets:
mongo:
- usr
- bin
- lib
stage:
- $mongo
prime:
- $mongo
wekan:
source: .
plugin: nodejs
node-engine: 14.19.0
node-packages:
- node-gyp
- node-pre-gyp
- fibers
build-packages:
- ca-certificates
- apt-utils
- build-essential
- python
- python3
- g++
- capnproto
- curl
- libcurl3
- execstack
- nodejs
- npm
stage-packages:
- libfontconfig1
override-build: |
echo "Cleaning environment first"
rm -rf ~/.meteor ~/.npm /usr/local/lib/node_modules
rm -rf .build
echo "Installing meteor"
curl https://install.meteor.com/ -o install_meteor.sh
chmod +x install_meteor.sh
sh install_meteor.sh
rm install_meteor.sh
rm -rf .build
meteor add standard-minifier-js --allow-superuser
meteor npm install --allow-superuser
meteor npm install --allow-superuser --save babel-runtime
meteor build .build --directory --allow-superuser
cp -f fix-download-unicode/cfs_access-point.txt .build/bundle/programs/server/packages/cfs_access-point.js
cd .build/bundle/programs/server
npm install
npm install --allow-superuser --save babel-runtime
# Change back to Wekan source directory
cd ../../../..
cp -r .build/bundle/* $SNAPCRAFT_PART_INSTALL/
cp .build/bundle/.node_version.txt $SNAPCRAFT_PART_INSTALL/
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/wekan
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/tar/lib/.mkdir.js.swp
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-gyp/node_modules/tar/lib/.mkdir.js.swp
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
organize:
README: README.wekan
prime:
- -lib/node_modules/node-pre-gyp/node_modules/tar/lib/.unpack.js.swp
helpers:
source: snap-src
plugin: dump
caddy:
plugin: dump
source: https://caddyserver.com/download/linux/amd64?license=personal&telemetry=off
source-type: tar
organize:
caddy: bin/caddy
CHANGES.txt: CADDY_CHANGES.txt
EULA.txt: CADDY_EULA.txt
LICENSES.txt: CADDY_LICENSES.txt
README.txt: CADDY_README.txt
stage:
- -init
-183
View File
@@ -1,183 +0,0 @@
name: wekan
version: '6.21'
base: core20
summary: Open Source kanban
description: |
WeKan ® is an Open Source and collaborative kanban board application.
Whether you’re maintaining a personal todo list, planning your holidays with some friends, or working in a team on your next revolutionary idea, Kanban boards are an unbeatable tool to keep your things organized. They give you a visual overview of the current state of your project, and make you productive by allowing you to focus on the few items that matter the most.
Depending on target environment, some configuration settings might need to be adjusted.
For full list of configuration options call:
$ wekan.help
confinement: strict
grade: stable
architectures:
- build-on: amd64
run-on: amd64
- build-on: arm64
run-on: arm64
- build-on: ppc64el
run-on: ppc64el
- build-on: s390x
run-on: s390x
plugs:
mongodb-plug:
interface: content
target: $SNAP_DATA/shared
hooks:
configure:
plugs:
- network
- network-bind
slots:
mongodb-slot:
interface: content
write:
- $SNAP_DATA/share
apps:
wekan:
command: wekan-control
daemon: simple
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
restart-condition: on-failure
mongodb:
command: mongodb-control
daemon: simple
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
restart-condition: on-failure
caddy:
command: caddy-control
daemon: simple
plugs: [network, network-bind]
help:
command: wekan-help
database-backup:
command: mongodb-backup
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
database-list-backups:
command: ls -al $SNAP_COMMON/db-backups/
database-restore:
command: mongodb-restore
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
parts:
mongodb:
plugin: dump
source:
- on amd64: https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/4.4/multiverse/binary-amd64/mongodb-org-server_4.4.13_amd64.deb
- on arm64: https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/4.4/multiverse/binary-arm64/mongodb-org-server_4.4.13_arm64.deb
- on ppc64el: https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/4.4/multiverse/binary-ppc64el/mongodb-org-server_4.4.13_ppc64el.deb
- on s390x: https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/4.4/multiverse/binary-s390x/mongodb-org-server_4.4.13_s390x.deb
stage-packages:
- libssl1.1
- libcurl3-dev
- libcurl4-openssl-dev
filesets:
mongo:
- usr
- bin
- lib
stage:
- $mongo
prime:
- $mongo
wekan:
#plugin: npm
plugin: dump
source:
# Fixed URLs to some allowed GitHub releases URL.
# Non-GitHub build server file urls are not allowed at 2022-03-02 and later.
- on amd64: https://github.com/wekan/wekan/releases/download/v6.20/wekan-6.20-amd64.zip
- on arm64: https://github.com/wekan/wekan/releases/download/v6.20/wekan-6.20-arm64.zip
- on ppc64el: https://github.com/wekan/wekan/releases/download/v6.20/wekan-6.20-ppc64el.zip
- on s390x: https://github.com/wekan/wekan/releases/download/v6.20/wekan-6.20-s390x.zip
# npm-node-version: 14.19.1
# node-packages:
# - node-gyp
# - node-pre-gyp
# - fibers
# build-packages:
# - npm
# - build-essential
# - ca-certificates
# - apt-utils
# - python
# - python3
# - g++
# - capnproto
# - curl
# - execstack
# - nodejs
# - npm
# - p7zip-full
# stage-packages:
# - libfontconfig1
override-build: |
cp -r bundle/* $SNAPCRAFT_PART_INSTALL/
cp bundle/.node_version.txt $SNAPCRAFT_PART_INSTALL/
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/wekan
snapcraftctl build
organize:
README: README.wekan
prime:
- -lib/node_modules/node-pre-gyp/node_modules/tar/lib/.unpack.js.swp
- -lib/node_modules/weka*
helpers:
source: snap-src
plugin: dump
caddy:
plugin: dump
## Caddy v1 is not developed anymore. TODO: Sometime migrate to Caddy v2.
## https://caddy.community/t/caddyfile-v1-adapter/9129
## https://github.com/caddyserver/caddy/tree/v1
#source: https://caddyserver.com/download/linux/amd64?license=personal&telemetry=off
#source-type: tar
# Using last working binary that was downloaded from above URL to Wekan Snap,
# and .txt files from https://github.com/caddyserver/caddy/tree/v1/dist
source: https://wekan.github.io/caddy-v1-linux-amd64.7z
source-type: 7z
organize:
caddy: bin/caddy
CHANGES.txt: CADDY_CHANGES.txt
EULA.txt: CADDY_EULA.txt
LICENSES.txt: CADDY_LICENSES.txt
README.txt: CADDY_README.txt
stage:
- -init
caddy2:
plugin: dump
source:
# Fixed URLs to some allowed GitHub releases URL.
# Non-GitHub build server file urls are not allowed at 2022-03-02 and later.
- on amd64: https://github.com/wekan/wekan/releases/download/v6.20/caddy-v2-amd64.zip
- on arm64: https://github.com/wekan/wekan/releases/download/v6.20/caddy-v2-arm64.zip
- on ppc64el: https://github.com/wekan/wekan/releases/download/v6.20/caddy-v2-ppc64el.zip
- on s390x: https://github.com/wekan/wekan/releases/download/v6.20/caddy-v2-s390x.zip
source-type: zip
organize:
caddy: bin/caddy
CHANGES.txt: CADDY_CHANGES.txt
EULA.txt: CADDY_EULA.txt
LICENSES.txt: CADDY_LICENSES.txt
README.txt: CADDY_README.txt
stage:
- -init
+2 -1
View File
@@ -1,3 +1,4 @@
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
.gitea/CODEOWNERS linguist-detectable=false
+3
View File
@@ -0,0 +1,3 @@
# Pull requests request review from the eligible staff team(s).
# One approval from either an Admin or Developer satisfies branch protection.
* @trueog/Admins @trueog/Developers
+2 -1
View File
@@ -1,3 +1,4 @@
# These are supported funding model platforms
custom: ['https://wekan.team/commercial-support/']
github: wekan
custom: ['https://wekan.fi/commercial-support/']
-35
View File
@@ -1,35 +0,0 @@
## Issue
<!--
Please report these elsewhere:
- SECURITY ISSUES, PGP EMAIL: https://github.com/wekan/wekan/blob/main/SECURITY.md
- UCS: https://github.com/wekan/univention/issues
**[PLEASE UPGRADE](https://github.com/wekan/wekan/wiki/Backup)** to the newest WeKan ® before reporting an issue.
Please search existing Open and Closed issues, most questions have already been answered.
If you can not login for any reason: https://github.com/wekan/wekan/wiki/Forgot-Password
Email settings, only SMTP MAIL_URL and MAIL_FROM are in use: https://github.com/wekan/wekan/wiki/Troubleshooting-Mail
-->
### Server Setup Information
<!-- Please anonymize info, and do not any of your Wekan board URLs, passwords, API tokens etc to this public issue. -->
* Did you test in newest Wekan?:
* Did you configure root-url correctly so Wekan cards open correctly (see https://github.com/wekan/wekan/wiki/Settings)?
* Operating System:
* Deployment Method (Snap/Docker/Sandstorm/bundle/source):
* Http frontend if any (Caddy, Nginx, Apache, see config examples from Wekan GitHub wiki first):
* Node.js Version:
* MongoDB Version:
* What webbrowser version are you using (Wekan should work on all modern browsers that support Javascript)?
### Problem description
<!-- Add a recorded animated gif (e.g. with https://github.com/phw/peek) about how it works currently, and screenshot mockups how it should work. -->
#### Reproduction Steps
#### Logs
<!-- Check Right Click>Inspect>Console in you browser - generally Chrome shows more detailed info than Firefox. -->
<!-- Please anonymize logs.
Snap: sudo snap logs wekan.wekan
Docker: sudo docker logs wekan-app
If logs are very long, attach them in .zip file -->
+42
View File
@@ -0,0 +1,42 @@
name: 🐛 Bug Report
description: Report a bug to help improve WeKan
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for reporting a bug! Please ensure you are using the [latest version of WeKan](https://wekan.fi/install) and [Upgrade](https://wekan.fi/upgrade) before submitting.
- type: textarea
id: description
attributes:
label: Bug Description
description: A clear and concise description of what the bug is. Mention versions of WeKan, Node.js, database name and version, frontend webserver version like Caddy etc.
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Steps to Reproduce
description: How can we recreate this issue?
placeholder: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant Logs
description: |
- Please paste any relevant anonymized server logs or browser console errors here.
- Snap: sudo snap logs wekan.wekan
- Docker: sudo docker logs wekan-app
- If logs are very long, attach them in .zip file
render: shell
- type: textarea
id: context
attributes:
label: Additional Context
description: Add any other context, anonymized screenshots or GIF video about the bug, and screenshot mockups about how it should work.
@@ -0,0 +1,31 @@
name: ✨ Feature Request
description: Suggest a new feature for WeKan
labels: ["Feature:Request"]
body:
- type: textarea
id: feature-description
attributes:
label: Problem Statement
description: Is your feature request related to a problem? Please describe.
placeholder: I'm always frustrated when [...]
validations:
required: true
- type: textarea
id: solution
attributes:
label: Proposed Solution
description: A clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives Considered
description: Any alternative solutions or features you've considered.
- type: textarea
id: context
attributes:
label: Additional Context
description: Add any other context, like anonymized screenshot mockups about how it should work.
@@ -0,0 +1,14 @@
name: 🛡️ Security Issue
description: Report a security vulnerability
labels: ["security", "critical"]
body:
- type: markdown
attributes:
value: |
## ⚠️ IMPORTANT: Please do not report security vulnerabilities via public issues.
To protect the WeKan community, we ask that you report security bugs privately. This allows us to fix the issue before it can be exploited by malicious actors.
### How to report:
Please read our **[Security Policy (SECURITY.md)](https://github.com/wekan/wekan/blob/main/SECURITY.md)** for the official reporting process and contact information.
+23
View File
@@ -0,0 +1,23 @@
name: 🗳️ Univention (UCS) Issue
description: Problems specifically related to the WeKan app on Univention Corporate Server
labels: ["UCS"]
body:
- type: markdown
attributes:
value: |
## 🛑 Is this a UCS-specific issue?
If your issue is related to the **Univention Corporate Server (UCS) integration**, packaging, or installation via the Univention App Center, it should be reported in the dedicated Univention repository.
### ➡️ [Report UCS Issues Here](https://github.com/wekan/univention/issues)
---
**Why?**
Reporting there ensures that the maintainers specifically focused on the UCS environment see your request.
If you are certain this is a **core WeKan bug** that affects all platforms (Docker, Snap, etc.), please go back and use the standard [Bug Report](https://github.com/wekan/wekan/issues/new?template=bug-report.yml) template.
- type: textarea
id: ucs-details
attributes:
label: Brief Description (Optional)
description: If you still wish to post here, please provide a brief summary of why this is a core Wekan issue and not a UCS-specific integration bug.
+2 -2
View File
@@ -9,6 +9,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
uses: actions/dependency-review-action@v5
+4 -4
View File
@@ -32,13 +32,13 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
@@ -48,14 +48,14 @@ jobs:
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
+1 -1
View File
@@ -15,6 +15,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Build the Docker image
run: docker build . --file Dockerfile --tag wekan:$(date +%s)
+251
View File
@@ -0,0 +1,251 @@
name: Playwright E2E Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: playwright-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
unit-tests:
name: Meteor unit tests
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- name: Setup Node 24
uses: actions/setup-node@v6
with:
node-version: '24'
cache: 'npm'
- name: Cache Meteor installation
uses: actions/cache@v5
with:
path: ~/.meteor
key: meteor-${{ hashFiles('.meteor/release') }}-${{ hashFiles('.meteor/packages') }}
restore-keys: meteor-
- name: Cache Meteor build (.meteor/local)
uses: actions/cache@v5
with:
path: .meteor/local
key: meteor-local-unit-${{ hashFiles('.meteor/versions') }}
restore-keys: meteor-local-unit-
- name: Install Meteor
run: |
if [ ! -x ~/.meteor/meteor ]; then
curl https://install.meteor.com/ | sh
fi
echo "$HOME/.meteor" >> "$GITHUB_PATH"
- name: Install npm dependencies
run: npm ci
- name: Run Meteor unit tests
# First Meteor build is slow; allow time before the test driver starts.
timeout-minutes: 45
run: meteor test --once --driver-package meteortesting:mocha
env:
TEST_WATCH: '0'
e2e-tests:
name: Playwright E2E (${{ matrix.project }})
runs-on: ubuntu-24.04
needs: unit-tests
strategy:
fail-fast: false
matrix:
project: [chromium, firefox]
# webkit excluded from CI (requires macOS runner) — run locally with npm run test:e2e:all
services:
mongodb:
image: mongo:7
ports: ['27017:27017']
options: >-
--health-cmd "mongosh --eval 'db.adminCommand(\"ping\")'"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v6
- name: Setup Node 24
uses: actions/setup-node@v6
with:
node-version: '24'
cache: 'npm'
- name: Cache Meteor installation
uses: actions/cache@v5
with:
path: ~/.meteor
key: meteor-${{ hashFiles('.meteor/release') }}-${{ hashFiles('.meteor/packages') }}
restore-keys: meteor-
- name: Cache Meteor build (.meteor/local)
uses: actions/cache@v5
with:
path: .meteor/local
key: meteor-local-e2e-${{ hashFiles('.meteor/versions') }}
restore-keys: meteor-local-e2e-
- name: Install Meteor
run: |
if [ ! -x ~/.meteor/meteor ]; then
curl https://install.meteor.com/ | sh
fi
echo "$HOME/.meteor" >> "$GITHUB_PATH"
- name: Install app npm dependencies
run: npm ci
- name: Install Playwright test dependencies
run: npm ci
working-directory: tests/playwright
- name: Install Playwright browsers
run: npx playwright install --with-deps ${{ matrix.project }}
working-directory: tests/playwright
- name: Start WeKan in background
run: |
MONGO_URL=mongodb://localhost:27017/wekan_test \
ROOT_URL=http://localhost:3000 \
PORT=3000 \
meteor run --settings settings.json > wekan-run.log 2>&1 &
# The first Meteor build is slow, so wait up to 20 minutes for the
# server to start responding before giving up.
for i in $(seq 1 120); do
if curl -sf http://localhost:3000 > /dev/null; then
echo "WeKan is up after $((i * 10))s"
break
fi
echo "Waiting for WeKan... attempt $i/120"
sleep 10
done
if ! curl -sf http://localhost:3000 > /dev/null; then
echo "WeKan failed to start. Last 200 log lines:"
tail -n 200 wekan-run.log
exit 1
fi
env:
DISABLE_CAPTCHA: 'true'
- name: Run Playwright tests (${{ matrix.project }})
run: |
npx playwright test \
--project=${{ matrix.project }} \
--reporter=github
working-directory: tests/playwright
env:
WEKAN_BASE_URL: http://localhost:3000
WEKAN_MONGO_URL: mongodb://localhost:27017/wekan_test
- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v7
with:
name: playwright-report-${{ matrix.project }}
path: tests/playwright/playwright-report/
retention-days: 14
- name: Upload test results (screenshots / videos)
if: failure()
uses: actions/upload-artifact@v7
with:
name: test-results-${{ matrix.project }}
path: tests/playwright/test-results/
retention-days: 7
e2e-regression:
name: Puppeteer regression suite
runs-on: ubuntu-24.04
needs: unit-tests
services:
mongodb:
image: mongo:7
ports: ['27017:27017']
options: >-
--health-cmd "mongosh --eval 'db.adminCommand(\"ping\")'"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v6
- name: Setup Node 24
uses: actions/setup-node@v6
with:
node-version: '24'
cache: 'npm'
- name: Cache Meteor installation
uses: actions/cache@v5
with:
path: ~/.meteor
key: meteor-${{ hashFiles('.meteor/release') }}-${{ hashFiles('.meteor/packages') }}
restore-keys: meteor-
- name: Cache Meteor build (.meteor/local)
uses: actions/cache@v5
with:
path: .meteor/local
key: meteor-local-regression-${{ hashFiles('.meteor/versions') }}
restore-keys: meteor-local-regression-
- name: Install Meteor
run: |
if [ ! -x ~/.meteor/meteor ]; then
curl https://install.meteor.com/ | sh
fi
echo "$HOME/.meteor" >> "$GITHUB_PATH"
- name: Install npm dependencies
run: npm ci
- name: Install Chromium
run: sudo apt-get install -y chromium-browser
- name: Start WeKan in background
run: |
MONGO_URL=mongodb://localhost:27017/wekan_regression \
ROOT_URL=http://localhost:3000 \
PORT=3000 \
meteor run > wekan-run.log 2>&1 &
# The first Meteor build is slow, so wait up to 20 minutes.
for i in $(seq 1 120); do
if curl -sf http://localhost:3000 > /dev/null; then
echo "WeKan is up after $((i * 10))s"
break
fi
echo "Waiting for WeKan... attempt $i/120"
sleep 10
done
if ! curl -sf http://localhost:3000 > /dev/null; then
echo "WeKan failed to start. Last 200 log lines:"
tail -n 200 wekan-run.log
exit 1
fi
env:
DISABLE_CAPTCHA: 'true'
- name: Run list-regressions e2e
run: node tests/e2e/list-regressions.js
env:
WEKAN_BASE_URL: http://localhost:3000
WEKAN_MONGO_URL: mongodb://localhost:27017/wekan_regression
CHROMIUM_PATH: /usr/bin/chromium-browser
HEADLESS: 'true'
+633
View File
@@ -0,0 +1,633 @@
name: Release All Platforms
# Triggered manually via GitHub CLI or the Actions UI.
# Usage:
# gh workflow run release-all.yml -f old_version=9.35 -f new_version=9.36
#
# Or use the convenience script (bumps versions, commits, pushes, then triggers):
# ./releases/release-all.sh 9.35 9.36
#
# Builds only the platforms MongoDB ships server binaries for (amd64, arm64,
# win64, mac); MongoDB 7.x is the default database. s390x/ppc64le are not built
# because MongoDB has no server binaries for them.
#
# This workflow does EVERYTHING for a release remotely (nothing is built or
# pushed on the maintainer's machine), running jobs in parallel where possible:
# - bump: runs releases/version.sh + releases/rebuild-docs.sh on the runner
# (bumps Node/MongoDB/WeKan versions, rebuilds API docs), then
# commits and pushes the bump to wekan/wekan main
# - prepare: tags the bumped main as v<new_version> and extracts release notes
# - website: updates the wekan/wekan.fi repo (install page + API docs) and pushes
# - charts: updates and publishes the wekan/charts Helm chart and pushes
# - build-*: builds the amd64 bundle (full Meteor 3 build), then rebuilds native
# modules for arm64, win64, mac-arm64 from that amd64 base
# - release: creates the GitHub Release with the newest CHANGELOG.md notes and
# uploads every wekan-<version>-<platform>.zip bundle
# - docker: builds and pushes the multi-arch image to Docker Hub, Quay.io, GHCR
# - snap: builds the snap on Launchpad (amd64 + arm64), pushes it to the Snap
# Store and attaches the .snap files to the GitHub Release
#
# Required GitHub Secrets:
# GHCR_AUTH - base64("username:token") for ghcr.io
# DOCKERHUB_AUTH - base64("username:token") for Docker Hub
# QUAY_AUTH - base64("username:token") for Quay.io
# SNAP_AUTH - Snap Store credentials (output of `snapcraft export-login`)
# LP_CREDENTIALS - base64 of the Launchpad credentials file used by
# `snapcraft remote-build` (see releases/snap-build.sh notes)
# WEKAN_REPO_TOKEN - Personal Access Token with write access to wekan/wekan.fi
# and wekan/charts, used by the website + charts jobs to push
# to those repos (the built-in GITHUB_TOKEN only covers
# wekan/wekan). See releases/create-github-secrets.sh.
on:
workflow_dispatch:
inputs:
old_version:
description: 'Previous version number (e.g. 9.35, without v prefix)'
required: true
type: string
new_version:
description: 'New version number (e.g. 9.36, without v prefix)'
required: true
type: string
permissions:
contents: write
packages: write
# Node.js major version that Meteor 3.5-beta bundles. Used for native module
# rebuilds on every platform — it must match the amd64 build's Node ABI.
env:
NODE_VERSION: '24'
jobs:
# ─── 0. Bump versions + rebuild API docs, commit to main ────────────────────
# Runs releases/version.sh (probes upstream for the newest Node.js/MongoDB,
# bumps every version reference) and releases/rebuild-docs.sh (regenerates
# public/api/wekan.yml + wekan.html), then commits and pushes to main so the
# tag, builds, website and charts jobs all see the bumped sources.
bump:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v6
with:
ref: main
fetch-depth: 0
- uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install version-bump and docs build dependencies
run: |
sudo apt-get update
sudo apt-get install -y python3 python3-pip curl wget
- name: Bump versions and rebuild API docs
env:
# Builds fetch dependencies from upstream themselves, so skip the slow
# pre-download of Node/MongoDB tarballs that the local flow does.
RELEASE_SKIP_DEP_DOWNLOAD: '1'
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
./releases/version.sh "${{ inputs.old_version }}" "${{ inputs.new_version }}"
./releases/rebuild-docs.sh "${{ inputs.new_version }}"
- name: Commit and push version bump
run: |
git add --all
if git diff --cached --quiet; then
echo "No version changes to commit."
else
git commit -m "Bump versions for v${{ inputs.new_version }}"
git push origin main
fi
# ─── 1. Tag the release and extract release notes ───────────────────────────
prepare:
needs: bump
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
changelog: ${{ steps.changelog.outputs.content }}
steps:
- uses: actions/checkout@v6
with:
ref: main
fetch-depth: 0
- name: Normalise version from input
id: version
run: |
VERSION="${{ inputs.new_version }}"
VERSION="${VERSION#v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Create and push tag v${{ steps.version.outputs.version }}
run: |
VERSION="${{ steps.version.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
echo "Tag v$VERSION already exists, leaving it as is."
else
git tag -a "v$VERSION" -m "v$VERSION"
git push origin "v$VERSION"
fi
- name: Extract release notes from CHANGELOG.md
id: changelog
run: |
VERSION="${{ steps.version.outputs.version }}"
# Prefer a version-specific "# v<version> ..." section, otherwise fall
# back to the topmost "# Upcoming/Upcomig WeKan ® release" section.
NOTES=$(python3 - <<PYEOF
import re, sys
version = "$VERSION"
with open("CHANGELOG.md", encoding="utf-8") as f:
content = f.read()
patterns = [
rf"(# v{re.escape(version)} .*?)(?=\n# v[0-9]|\Z)",
r"(# Upcom\w* WeKan.*?)(?=\n# v[0-9]|\Z)",
]
for pat in patterns:
m = re.search(pat, content, re.DOTALL)
if m:
print(m.group(1).strip())
sys.exit(0)
print(f"WeKan v{version}")
PYEOF
)
{
echo "content<<GHEOF"
echo "$NOTES"
echo "GHEOF"
} >> "$GITHUB_OUTPUT"
# ─── 1b. Update the wekan.fi website repo (parallel) ────────────────────────
# Bumps the version/Meteor/Node/MongoDB strings on the install page and copies
# the freshly rebuilt API docs into wekan.fi/api/v<new>, then commits + pushes
# to wekan/wekan.fi. Runs as soon as `bump` has pushed the bumped sources.
website:
needs: bump
runs-on: ubuntu-latest
steps:
- name: Checkout wekan repo (bumped main, with rebuilt API docs)
uses: actions/checkout@v6
with:
ref: main
path: wekan
- name: Checkout wekan.fi website repo
uses: actions/checkout@v6
with:
repository: wekan/wekan.fi
token: ${{ secrets.WEKAN_REPO_TOKEN }}
path: wekan.fi
- name: Update and push website
env:
WEBDIR: ${{ github.workspace }}/wekan.fi
WEKANREPODIR: ${{ github.workspace }}/wekan
RELEASE_PUSH_WEBSITE: '1'
run: |
cd wekan.fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
cd ..
./wekan/releases/release-website.sh "${{ inputs.old_version }}" "${{ inputs.new_version }}"
# ─── 1c. Update and publish the Helm chart repo (parallel) ──────────────────
# Bumps the WeKan version in wekan/charts, packages the chart and publishes it
# to the gh-pages Helm index, then pushes both branches. Runs in parallel with
# the platform builds; packaging the chart does not need the built artifacts.
charts:
needs: bump
runs-on: ubuntu-latest
steps:
- name: Checkout wekan repo (for releases/release-charts.sh + version refs)
uses: actions/checkout@v6
with:
ref: main
path: wekan
- name: Checkout wekan/charts repo (main + gh-pages)
uses: actions/checkout@v6
with:
repository: wekan/charts
token: ${{ secrets.WEKAN_REPO_TOKEN }}
fetch-depth: 0
path: charts
- name: Install Helm
uses: azure/setup-helm@v4
- name: Fetch gh-pages branch (release-charts.sh switches to it)
run: |
cd charts
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git fetch origin '+refs/heads/*:refs/remotes/origin/*'
git branch --track gh-pages origin/gh-pages 2>/dev/null || true
- name: Release and publish chart
env:
CHARTS_DIR: ${{ github.workspace }}/charts
run: |
./wekan/releases/release-charts.sh "${{ inputs.new_version }}"
# ─── 2. Build amd64 bundle (full Meteor 3 build) ────────────────────────────
# Meteor 3.5-beta installer supports only Linux x86_64/aarch64, macOS, Windows.
# The full Meteor build always runs here on x86_64; every other platform then
# only rebuilds the native npm modules from this bundle.
build-amd64:
needs: prepare
runs-on: ubuntu-24.04
timeout-minutes: 180
env:
VERSION: ${{ needs.prepare.outputs.version }}
steps:
- uses: actions/checkout@v6
with:
ref: refs/tags/v${{ needs.prepare.outputs.version }}
- name: Cache Meteor installation
uses: actions/cache@v5
with:
path: ~/.meteor
key: meteor-${{ hashFiles('.meteor/release') }}-${{ hashFiles('.meteor/packages') }}
restore-keys: meteor-
- name: Cache npm packages
uses: actions/cache@v5
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential g++ make python3 curl wget zip unzip
- uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install Meteor
run: |
if [ ! -f ~/.meteor/meteor ]; then
curl https://install.meteor.com/ | sh
fi
echo "$HOME/.meteor" >> $GITHUB_PATH
- name: Build WeKan bundle
run: |
rm -rf .build node_modules .meteor/local
(meteor update --npm 2>/dev/null || true) && meteor npm install
meteor build .build --directory
- name: Install server npm modules
run: |
cd .build/bundle/programs/server
npm install
- name: Create amd64 zip
run: |
cd .build
zip -r wekan-${VERSION}-amd64.zip bundle
- uses: actions/upload-artifact@v7
with:
name: bundle-amd64
path: .build/wekan-${{ needs.prepare.outputs.version }}-amd64.zip
retention-days: 1
# ─── 3. Build arm64 bundle (rebuild native modules natively) ─────────────────
build-arm64:
needs: [prepare, build-amd64]
runs-on: ubuntu-24.04-arm
timeout-minutes: 60
env:
VERSION: ${{ needs.prepare.outputs.version }}
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential g++ make python3 curl unzip zip
- name: Download amd64 bundle
uses: actions/download-artifact@v8
with:
name: bundle-amd64
- name: Rebuild native modules for arm64 in container
run: |
unzip wekan-${VERSION}-amd64.zip
# Fix: bcrypt 5.0.1 (Meteor accounts-password) ships node-addon-api@3
# which fails to compile on Node.js 24. Replace with bcrypt 6.0.0.
BCRYPT_DIR="$(pwd)/bundle/programs/server/npm/node_modules/meteor/accounts-password/node_modules/bcrypt"
if [ -d "$BCRYPT_DIR" ]; then
rm -rf "$BCRYPT_DIR"
TMP=$(mktemp -d)
pushd "$TMP" > /dev/null
npm pack bcrypt@6.0.0
mkdir bcrypt && tar xzf bcrypt-*.tgz --strip-components=1 -C bcrypt
cd bcrypt && npm install --ignore-scripts && cd ..
cp -a bcrypt "$BCRYPT_DIR"
popd > /dev/null
rm -rf "$TMP"
fi
docker run --rm --platform linux/arm64 \
-v "$(pwd)/bundle:/bundle" \
-w /bundle/programs/server \
node:${NODE_VERSION}-slim \
sh -c "apt-get update -qq && apt-get install -y -q build-essential python3 && npm install"
- name: Create arm64 zip
run: |
zip -r wekan-${VERSION}-arm64.zip bundle
- uses: actions/upload-artifact@v7
with:
name: bundle-arm64
path: wekan-${{ needs.prepare.outputs.version }}-arm64.zip
retention-days: 1
# ─── 5. Build win64 bundle (rebuild native modules on Windows) ───────────────
build-win64:
needs: [prepare, build-amd64]
runs-on: windows-latest
timeout-minutes: 60
env:
VERSION: ${{ needs.prepare.outputs.version }}
steps:
# Checked out into src/ so start-wekan.bat and snapcraft.yaml (which pins
# the MongoDB tools/mongosh versions) are available; the downloaded bundle
# is extracted alongside it in the workspace root.
- uses: actions/checkout@v6
with:
ref: refs/tags/v${{ needs.prepare.outputs.version }}
path: src
- uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install 7-zip
run: choco install -y 7zip
- name: Download amd64 bundle
uses: actions/download-artifact@v8
with:
name: bundle-amd64
- name: Fix bcrypt for Node.js 24
shell: bash
run: |
7z x wekan-${VERSION}-amd64.zip
# Fix: bcrypt 5.0.1 (Meteor accounts-password) ships node-addon-api@3
# which fails to compile on Node.js 24. Replace with bcrypt 6.0.0.
BCRYPT_DIR="$(pwd)/bundle/programs/server/npm/node_modules/meteor/accounts-password/node_modules/bcrypt"
if [ -d "$BCRYPT_DIR" ]; then
rm -rf "$BCRYPT_DIR"
TMP=$(mktemp -d)
pushd "$TMP" > /dev/null
npm pack bcrypt@6.0.0
mkdir bcrypt && tar xzf bcrypt-*.tgz --strip-components=1 -C bcrypt
cd bcrypt && npm install --ignore-scripts && cd ..
cp -r bcrypt "$BCRYPT_DIR"
popd > /dev/null
rm -rf "$TMP"
fi
- name: Rebuild native modules for Windows
shell: bash
run: |
cd bundle/programs/server
rm -rf node_modules
npm install
- name: Add MongoDB tools, mongosh and start-wekan.bat to the bundle
shell: bash
run: |
set -euo pipefail
# Use the same MongoDB tools/mongosh versions as the snap, which
# releases/version.sh keeps at the newest release for each bundle.
TOOLS_VER=$(grep -oE 'mongodb-database-tools-ubuntu2204-\$\{TOOLS_ARCH\}-[0-9]+\.[0-9]+\.[0-9]+' src/snapcraft.yaml \
| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
MONGOSH_VER=$(grep -oE 'mongosh-[0-9]+\.[0-9]+\.[0-9]+-linux' src/snapcraft.yaml \
| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
echo "MongoDB Database Tools: $TOOLS_VER mongosh: $MONGOSH_VER"
# MongoDB Database Tools (Windows): bsondump, mongodump, mongoexport,
# mongofiles, mongoimport, mongorestore, mongostat, mongotop.
TOOLS_DIR="mongodb-database-tools-windows-x86_64-${TOOLS_VER}"
curl -fL -o tools.zip \
"https://fastdl.mongodb.org/tools/db/${TOOLS_DIR}.zip"
7z x -y tools.zip > /dev/null
cp "${TOOLS_DIR}/bin/"*.exe bundle/
# mongosh (Windows): mongosh.exe + mongosh_crypt_v1.dll.
MONGOSH_DIR="mongosh-${MONGOSH_VER}-win32-x64"
curl -fL -o mongosh.zip \
"https://downloads.mongodb.com/compass/${MONGOSH_DIR}.zip"
7z x -y mongosh.zip > /dev/null
cp "${MONGOSH_DIR}/bin/mongosh.exe" bundle/
cp "${MONGOSH_DIR}/bin/mongosh_crypt_v1.dll" bundle/
# Windows launcher from the repo root.
cp src/start-wekan.bat bundle/
echo "=== bundle contents ==="
ls -1 bundle/
- name: Create win64 zip
shell: cmd
run: 7z a wekan-%VERSION%-win64.zip bundle
- uses: actions/upload-artifact@v7
with:
name: bundle-win64
path: wekan-${{ needs.prepare.outputs.version }}-win64.zip
retention-days: 1
# ─── 6. Build mac-arm64 bundle (rebuild native modules on Apple Silicon) ─────
build-mac-arm64:
needs: [prepare, build-amd64]
runs-on: macos-14 # macos-14 runners are Apple Silicon (arm64)
timeout-minutes: 60
env:
VERSION: ${{ needs.prepare.outputs.version }}
steps:
- uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: Download amd64 bundle
uses: actions/download-artifact@v8
with:
name: bundle-amd64
- name: Rebuild native modules for macOS arm64
run: |
unzip -q wekan-${VERSION}-amd64.zip
# Fix: bcrypt 5.0.1 (Meteor accounts-password) ships node-addon-api@3
# which fails to compile on Node.js 24. Replace with bcrypt 6.0.0.
BCRYPT_DIR="$(pwd)/bundle/programs/server/npm/node_modules/meteor/accounts-password/node_modules/bcrypt"
if [ -d "$BCRYPT_DIR" ]; then
rm -rf "$BCRYPT_DIR"
TMP=$(mktemp -d)
pushd "$TMP" > /dev/null
npm pack bcrypt@6.0.0
mkdir bcrypt && tar xzf bcrypt-*.tgz --strip-components=1 -C bcrypt
cd bcrypt && npm install --ignore-scripts && cd ..
cp -a bcrypt "$BCRYPT_DIR"
popd > /dev/null
rm -rf "$TMP"
fi
cd bundle/programs/server
rm -rf node_modules
npm install
cd ../../..
- name: Create mac-arm64 zip
run: zip -r wekan-${VERSION}-mac-arm64.zip bundle
- uses: actions/upload-artifact@v7
with:
name: bundle-mac-arm64
path: wekan-${{ needs.prepare.outputs.version }}-mac-arm64.zip
retention-days: 1
# ─── 7. Create GitHub Release and upload all bundles ────────────────────────
release:
needs:
- prepare
- build-amd64
- build-arm64
- build-win64
- build-mac-arm64
runs-on: ubuntu-latest
env:
VERSION: ${{ needs.prepare.outputs.version }}
steps:
- name: Download all bundles
uses: actions/download-artifact@v8
with:
pattern: bundle-*
merge-multiple: true
- name: Create GitHub Release with all bundles
uses: softprops/action-gh-release@v3
with:
tag_name: v${{ needs.prepare.outputs.version }}
name: v${{ needs.prepare.outputs.version }}
body: ${{ needs.prepare.outputs.changelog }}
files: |
wekan-${{ needs.prepare.outputs.version }}-amd64.zip
wekan-${{ needs.prepare.outputs.version }}-arm64.zip
wekan-${{ needs.prepare.outputs.version }}-win64.zip
wekan-${{ needs.prepare.outputs.version }}-mac-arm64.zip
# ─── 8. Build and push the multi-arch Docker image to all registries ────────
# Mirrors releases/docker-build.sh step 3 (multi-arch buildx --push).
# Needs `release` because the Dockerfile downloads wekan-<version>-<arch>.zip
# from the GitHub Release; building before those assets exist 404s and (without
# set -e in the Dockerfile) shipped a broken image missing /build/main.js.
docker:
needs: [prepare, release]
runs-on: ubuntu-latest
env:
VERSION: ${{ needs.prepare.outputs.version }}
steps:
- uses: actions/checkout@v6
with:
ref: refs/tags/v${{ needs.prepare.outputs.version }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub, Quay.io and GHCR
env:
DOCKERHUB_AUTH: ${{ secrets.DOCKERHUB_AUTH }}
QUAY_AUTH: ${{ secrets.QUAY_AUTH }}
GHCR_AUTH: ${{ secrets.GHCR_AUTH }}
run: |
login() {
# $1 = registry host, $2 = base64("user:token")
local host="$1" creds user token
creds="$(printf '%s' "$2" | base64 -d)"
user="${creds%%:*}"
token="${creds#*:}"
printf '%s' "$token" | docker login "$host" -u "$user" --password-stdin
}
login docker.io "$DOCKERHUB_AUTH"
login quay.io "$QUAY_AUTH"
login ghcr.io "$GHCR_AUTH"
- name: Build and push multi-arch image
run: |
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t wekanteam/wekan:v${VERSION} \
-t wekanteam/wekan:latest \
-t quay.io/wekan/wekan:v${VERSION} \
-t quay.io/wekan/wekan:latest \
-t ghcr.io/wekan/wekan:v${VERSION} \
-t ghcr.io/wekan/wekan:latest \
--push \
.
# ─── 9. Build the snap on Launchpad, push to the store, attach to release ────
# The snap's `wekan` part downloads wekan-<version>-<arch>.zip from the GitHub
# Release, so this job runs only after `release` has published those assets.
# `snapcraft remote-build` builds every platform listed in snapcraft.yaml
# (amd64 + arm64) on Launchpad.
snap:
needs: [prepare, release]
runs-on: ubuntu-latest
env:
VERSION: ${{ needs.prepare.outputs.version }}
steps:
- uses: actions/checkout@v6
with:
ref: refs/tags/v${{ needs.prepare.outputs.version }}
# remote-build (Launchpad) rejects shallow clones, so fetch full history
fetch-depth: 0
- name: Install snapcraft
run: sudo snap install snapcraft --classic
- name: Provide Launchpad credentials for remote-build
env:
LP_CREDENTIALS: ${{ secrets.LP_CREDENTIALS }}
run: |
mkdir -p ~/.local/share/snapcraft
printf '%s' "$LP_CREDENTIALS" | base64 -d > ~/.local/share/snapcraft/launchpad-credentials
chmod 600 ~/.local/share/snapcraft/launchpad-credentials
- name: Build snaps on Launchpad (amd64 + arm64)
run: |
snapcraft remote-build --launchpad-accept-public-upload
- name: Push snaps to the Snap Store (edge + beta channels)
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_AUTH }}
run: |
for f in wekan_${VERSION}_*.snap; do
echo "Uploading $f to the Snap Store (edge,beta)..."
snapcraft upload --release=edge,beta "$f"
done
- name: Attach snaps to the GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload "v${VERSION}" wekan_${VERSION}_*.snap --clobber
+2 -2
View File
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
@@ -25,6 +25,6 @@ jobs:
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.6.0
uses: helm/chart-releaser-action@v1.7.0
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
-163
View File
@@ -1,163 +0,0 @@
name: Test suite
on:
push:
branches:
- main
pull_request:
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
# the following are optional jobs and need to be configured according
# to this project's settings:
#
# lintcode:
# name: Javascript lint
# runs-on: ubuntu-latest
# steps:
# - name: checkout
# uses: actions/checkout@v4
#
# - name: setup node
# uses: actions/setup-node@v1
# with:
# node-version: '12.x'
#
# - name: cache dependencies
# uses: actions/cache@v1
# with:
# path: ~/.npm
# key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# restore-keys: |
# ${{ runner.os }}-node-
#
# - run: npm install
# - run: npm run lint:code
#
# lintstyle:
# name: SCSS lint
# runs-on: ubuntu-latest
# needs: [lintcode]
# steps:
# - name: checkout
# uses: actions/checkout@v4
#
# - name: setup node
# uses: actions/setup-node@v1
# with:
# node-version: '12.x'
#
# - name: cache dependencies
# uses: actions/cache@v1
# with:
# path: ~/.npm
# key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# restore-keys: |
# ${{ runner.os }}-node-
# - run: npm install
# - run: npm run lint:style
#
# lintdocs:
# name: documentation lint
# runs-on: ubuntu-latest
# needs: [lintcode,lintstyle]
# steps:
# - name: checkout
# uses: actions/checkout@v4
#
# - name: setup node
# uses: actions/setup-node@v1
# with:
# node-version: '12.x'
#
# - name: cache dependencies
# uses: actions/cache@v1
# with:
# path: ~/.npm
# key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# restore-keys: |
# ${{ runner.os }}-node-
#
# - run: npm install
# - run: npm run lint:markdown
tests:
name: Meteor ${{ matrix.meteor }} tests
runs-on: ubuntu-latest
steps:
# CHECKOUTS
- name: Checkout
uses: actions/checkout@v4
# CACHING
- name: Install Meteor
id: cache-meteor-install
uses: actions/cache@v4
with:
path: ~/.meteor
key: v1-meteor-${{ hashFiles('.meteor/versions') }}
restore-keys: |
v1-meteor-
- name: Cache NPM dependencies
id: cache-meteor-npm
uses: actions/cache@v4
with:
path: ~/.npm
key: v1-npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
v1-npm-
- name: Cache Meteor build
id: cache-meteor-build
uses: actions/cache@v4
with:
path: |
.meteor/local/resolver-result-cache.json
.meteor/local/plugin-cache
.meteor/local/isopacks
.meteor/local/bundler-cache/scanner
key: v1-meteor_build_cache-${{ github.ref }}-${{ github.sha }}
restore-keys: |
v1-meteor_build_cache-
- name: Setup meteor
uses: meteorengineer/setup-meteor@v1
with:
meteor-release: '2.2'
- name: Install NPM Dependencies
run: meteor npm ci
- name: Run Tests
run: sh ./test-wekan.sh -cv
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage-folder
path: .coverage/
coverage:
name: Coverage report
runs-on: ubuntu-latest
needs: [tests]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download coverage
uses: actions/download-artifact@v4
with:
name: coverage-folder
path: .coverage/
- name: Coverage Report
uses: VeryGoodOpenSource/very_good_coverage@v2.2.0
with:
path: ".coverage/lcov.info"
min_coverage: 1 # TODO add tests and increase to 95!
+25
View File
@@ -1,4 +1,5 @@
*~
/*.log
*.sw*
.meteor-spk
*.sublime-workspace
@@ -35,7 +36,31 @@ ehthumbs.db
.devcontainer/volumes*/
.coverage
# Rspack build artifacts
_build/
public/build-assets/
public/build-chunks/
private/build-assets/
private/build-chunks/
public/client-rspack.js.map
# Helm chart
# Chart dependencies
/helm/wekan/**/*.tgz
/helm/wekan/charts
# Meteor Modern-Tools build context directories
_build
*/build-assets
*/build-chunks
.rsdoctor
# Tests
playwright-report/
test-results/
# Claude AI
.claude/
# Tools like mongosh etc so that they work inside Flatpak sandbox
.tools/
+36 -67
View File
@@ -3,32 +3,29 @@
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
meteor-base@1.5.1
meteor-base@1.5.2
# Build system
ecmascript@0.16.8
standard-minifier-js@2.8.1
mquandalle:jade
coffeescript@2.4.1!
ecmascript@0.18.0
standard-minifier-js@3.2.0
rspack@1.1.0
# Polyfills
es5-shim@4.8.0
blaze@3.0.2
# Collections
aldeed:collection2
cottz:publish-relations
dburles:collection-helpers
idmontie:migrations
easy:search
mongo@1.16.8
mquandalle:collection-mutations
aldeed:schema-index@4.0.0-beta.5
reywood:publish-composite
mongo@2.4.0-rc350.1
# Account system
accounts-password@2.4.0
useraccounts:core
useraccounts:flow-routing
useraccounts:unstyled
simple:rest-accounts-password
accounts-password@3.3.0-rc350.1
accounts-express@1.0.0-rc350.1
communitypackages:core
communitypackages:unstyled
communitypackages:flow-routing
# Routing
ostrio:flow-router-extra
wekan-ldap
wekan-accounts-cas
wekan-accounts-sandstorm
@@ -37,60 +34,32 @@ wekan-oidc
wekan-accounts-oidc
# Utilities
check@1.3.2
jquery@3.0.0!
random@1.2.1
reactive-dict@1.3.1
session@1.2.1
tracker@1.3.3
underscore@1.0.13
arillo:flow-router-helpers
audit-argument-checks@1.0.7
kadira:dochead
mquandalle:autofocus
ongoworks:speakingurl
raix:handlebar-helpers
http@2.0.0! # force new http package
# Datepicker
wekan-bootstrap-datepicker
check@1.5.0
random@1.2.2
reactive-dict@1.3.2
session@1.2.3-rc350.1
tracker@1.3.4
audit-argument-checks@1.0.8
# UI components
ostrio:i18n
reactive-var@1.0.12
mousetrap:mousetrap
mquandalle:jquery-textcomplete
mquandalle:mousetrap-bindglobal
templates:tabs
meteor-autosize
shell-server@0.5.0
email@2.2.5
dynamic-import@0.7.3
msavin:usercache
# Keep stylus in 1.1.0, because building v2 takes extra 52 minutes.
meteorhacks:subs-manager
meteorhacks:aggregate@1.3.0
reactive-var@1.0.13
shell-server@0.7.0
email@3.2.0-rc350.1
dynamic-import@0.7.4
wekan-markdown
konecty:mongo-counter
percolate:synced-cron
quave:synced-cron
ostrio:cookies
ostrio:files@2.3.0
pascoual:pdfkit
lmieulet:meteor-coverage
meteortesting:mocha@2.0.3
aldeed:simple-schema
ostrio:files
# lmieulet:meteor-coverage
meteortesting:mocha@3.0.0
matb33:collection-hooks
simple:json-routes
kadira:flow-router
spacebars
service-configuration@1.3.2
communitypackages:picker
minifier-css@1.6.4
blaze
kadira:blaze-layout
peerlibrary:blaze-components
ejson@1.1.3
logging@1.3.3
service-configuration@1.3.5
minifier-css@2.0.2-rc350.1
ejson@1.2.0-rc350.1
logging@1.3.6
wekan-fullcalendar
momentjs:moment@2.29.3
wekan-fontawesome
jam:offline
jam:method
jam:pub-sub
+1 -1
View File
@@ -1 +1 @@
METEOR@2.14
METEOR@3.5-rc.1
+116 -161
View File
@@ -1,166 +1,121 @@
accounts-base@2.2.10
accounts-oauth@1.4.3
accounts-password@2.4.0
aldeed:collection2@2.10.0
aldeed:collection2-core@1.2.0
aldeed:schema-deny@1.1.0
aldeed:schema-index@1.1.1
aldeed:simple-schema@1.5.4
allow-deny@1.1.1
arillo:flow-router-helpers@0.5.2
audit-argument-checks@1.0.7
autoupdate@1.8.0
babel-compiler@7.10.5
babel-runtime@1.5.1
base64@1.0.12
binary-heap@1.0.11
blaze@2.7.1
blaze-tools@1.1.3
boilerplate-generator@1.7.2
caching-compiler@1.2.2
caching-html-compiler@1.2.1
callback-hook@1.5.1
check@1.3.2
coffeescript@2.7.0
coffeescript-compiler@2.4.1
communitypackages:picker@1.1.1
cottz:publish-relations@2.0.8
dburles:collection-helpers@1.1.0
ddp@1.4.1
ddp-client@2.6.1
ddp-common@1.4.0
ddp-rate-limiter@1.2.1
ddp-server@2.7.0
deps@1.0.12
diff-sequence@1.1.2
dynamic-import@0.7.3
easy:search@2.2.1
easysearch:components@2.2.2
easysearch:core@2.2.2
ecmascript@0.16.8
ecmascript-runtime@0.8.1
ecmascript-runtime-client@0.12.1
ecmascript-runtime-server@0.11.0
ejson@1.1.3
email@2.2.5
es5-shim@4.8.0
fetch@0.1.4
geojson-utils@1.0.11
hot-code-push@1.0.4
html-tools@1.1.3
htmljs@1.1.1
http@2.0.0
id-map@1.1.1
idmontie:migrations@1.0.3
inter-process-messaging@0.1.1
jquery@3.0.0
kadira:blaze-layout@2.3.0
kadira:dochead@1.5.0
kadira:flow-router@2.12.1
konecty:mongo-counter@0.0.5_3
lmieulet:meteor-coverage@1.1.4
localstorage@1.2.0
logging@1.3.3
matb33:collection-hooks@1.3.0
mdg:validation-error@0.5.1
meteor@1.11.5
meteor-autosize@5.0.1
meteor-base@1.5.1
meteorhacks:aggregate@1.3.0
meteorhacks:collection-utils@1.2.0
meteorhacks:picker@1.0.3
meteorhacks:subs-manager@1.6.4
meteortesting:browser-tests@1.4.2
meteortesting:mocha@2.1.0
meteortesting:mocha-core@8.0.1
minifier-css@1.6.4
minifier-js@2.7.5
minifiers@1.1.8-faster-rebuild.0
minimongo@1.9.3
modern-browsers@0.1.10
modules@0.20.0
modules-runtime@0.13.1
momentjs:moment@2.29.3
mongo@1.16.8
mongo-decimal@0.1.3
mongo-dev-server@1.1.0
mongo-id@1.0.8
mongo-livedata@1.0.12
mousetrap:mousetrap@1.4.6_1
mquandalle:autofocus@1.0.0
mquandalle:collection-mutations@0.1.0
mquandalle:jade@0.4.9
mquandalle:jade-compiler@0.4.5
mquandalle:jquery-textcomplete@0.8.0_1
mquandalle:mousetrap-bindglobal@0.0.1
msavin:usercache@1.8.0
npm-mongo@4.17.2
oauth@2.2.1
oauth2@1.3.2
observe-sequence@1.0.21
ongoworks:speakingurl@1.1.0
ordered-dict@1.1.0
ostrio:cookies@2.7.2
accounts-base@3.3.0-rc350.1
accounts-express@1.0.0-rc350.1
accounts-oauth@1.4.7-rc350.1
accounts-password@3.3.0-rc350.1
aldeed:collection2@4.2.0
aldeed:schema-index@4.0.0
aldeed:simple-schema@1.13.1
allow-deny@2.1.0
audit-argument-checks@1.0.8
autoupdate@2.0.1
babel-compiler@7.14.0
babel-runtime@1.5.2
base64@1.0.14-rc350.1
binary-heap@1.0.13-rc350.1
blaze@3.0.3
blaze-tools@2.0.1
boilerplate-generator@2.1.0
caching-compiler@2.0.1
caching-html-compiler@2.0.1
callback-hook@1.8.0-rc350.1
check@1.5.0
communitypackages:core@2.0.3
communitypackages:flow-routing@2.1.0
communitypackages:unstyled@2.0.1
core-runtime@1.0.0
ddp@1.4.2
ddp-client@3.3.0-rc350.1
ddp-common@1.4.5-rc350.1
ddp-rate-limiter@1.3.0-rc350.1
ddp-server@3.3.0-rc350.1
diff-sequence@1.1.3
dynamic-import@0.7.4
ecmascript@0.18.0
ecmascript-runtime@0.8.3
ecmascript-runtime-client@0.13.0
ecmascript-runtime-server@0.11.1
ejson@1.2.0-rc350.1
email@3.2.0-rc350.1
es5-shim@4.8.1
facts-base@1.0.2
fetch@0.2.0-rc350.1
geojson-utils@1.0.12
hot-code-push@1.0.5
html-tools@2.0.1
htmljs@2.0.2
id-map@1.2.0
inter-process-messaging@0.1.2
jam:method@1.9.1
jam:offline@0.4.1
jam:pub-sub@0.5.1
jquery@3.0.2
lai:collection-extensions@1.0.0
localstorage@1.2.1
logging@1.3.6
matb33:collection-hooks@2.1.0
meteor@2.3.1-rc350.1
meteor-base@1.5.2
meteortesting:browser-tests@1.8.0
meteortesting:mocha@3.3.0
meteortesting:mocha-core@8.2.0
minifier-css@2.0.2-rc350.1
minifier-js@3.2.0
minimongo@2.2.0-rc350.1
modern-browsers@0.2.3
modules@0.20.3
modules-runtime@0.13.2
mongo@2.4.0-rc350.1
mongo-decimal@0.2.0
mongo-dev-server@1.1.1
mongo-id@1.0.9
npm-mongo@6.16.1
oauth@3.0.4-rc350.1
oauth2@1.3.3
observe-sequence@2.0.1
ordered-dict@1.2.0
ostrio:cookies@2.9.2
ostrio:cstorage@4.0.1
ostrio:files@2.3.3
ostrio:files@3.0.1
ostrio:flow-router-extra@3.15.3
ostrio:i18n@3.2.1
pascoual:pdfkit@1.0.7
peerlibrary:assert@0.3.0
peerlibrary:base-component@0.17.1
peerlibrary:blaze-components@0.23.0
peerlibrary:computed-field@0.10.0
peerlibrary:data-lookup@0.3.0
peerlibrary:reactive-field@0.6.0
percolate:synced-cron@1.5.2
promise@0.12.2
raix:eventemitter@0.1.3
raix:handlebar-helpers@0.2.5
random@1.2.1
rate-limit@1.1.1
react-fast-refresh@0.2.8
reactive-dict@1.3.1
reactive-var@1.0.12
reload@1.3.1
retry@1.1.0
routepolicy@1.1.1
service-configuration@1.3.3
session@1.2.1
sha@1.0.9
shell-server@0.5.0
simple:authenticate-user-by-token@1.2.1
simple:json-routes@2.3.1
simple:rest-accounts-password@1.2.2
simple:rest-bearer-token-parser@1.1.1
simple:rest-json-error-handler@1.1.1
socket-stream-client@0.5.2
spacebars@1.4.1
spacebars-compiler@1.3.1
standard-minifier-js@2.8.1
templates:tabs@2.3.0
templating@1.4.1
templating-compiler@1.4.1
templating-runtime@1.5.0
templating-tools@1.2.2
tracker@1.3.3
typescript@4.9.5
ui@1.0.13
underscore@1.0.13
url@1.3.2
useraccounts:core@1.16.2
useraccounts:flow-routing@1.15.0
useraccounts:unstyled@1.14.2
webapp@1.13.6
webapp-hashing@1.1.1
wekan-accounts-cas@0.1.0
wekan-accounts-lockout@1.0.0
promise@1.0.0
quave:synced-cron@2.4.0
raix:eventemitter@1.0.0
random@1.2.2
rate-limit@1.2.0-rc350.1
react-fast-refresh@0.3.0
reactive-dict@1.3.2
reactive-var@1.0.13
reload@1.3.2
retry@1.1.1
reywood:publish-composite@1.9.0
routepolicy@1.1.2
rspack@1.1.0
service-configuration@1.3.5
session@1.2.3-rc350.1
sha@1.0.10
shell-server@0.7.0
socket-stream-client@0.7.0-rc350.1
spacebars@2.0.1
spacebars-compiler@2.0.1
standard-minifier-js@3.2.0
templating@1.4.5
templating-compiler@2.0.1
templating-runtime@2.0.2
templating-tools@2.0.1
tools-core@1.1.0
tracker@1.3.4
typescript@5.10.0
url@1.3.6-rc350.1
webapp@2.2.0-rc350.1
webapp-hashing@1.1.2
wekan-accounts-cas@0.2.0
wekan-accounts-lockout@1.1.0
wekan-accounts-oidc@1.0.10
wekan-accounts-sandstorm@0.8.0
wekan-bootstrap-datepicker@1.10.0
wekan-accounts-sandstorm@0.9.0
wekan-fontawesome@6.4.2
wekan-fullcalendar@3.10.5
wekan-ldap@0.0.2
wekan-fullcalendar@5.11.5
wekan-ldap@0.1.0
wekan-markdown@1.0.9
wekan-oidc@1.0.12
yasaricli:slugify@0.0.7
zimme:active-route@2.3.2
zodern:types@1.0.10
wekan-oidc@1.1.0
zodern:types@1.0.13
+2
View File
@@ -0,0 +1,2 @@
npm-packages/
tests/
+1 -1
View File
@@ -1,6 +1,6 @@
[main]
host = https://www.transifex.com
lang_map = es_AR: es-AR, es_419: es-LA, es_TX: es-TX, he_IL: he-IL, zh_CN: zh-CN, ar_EG: ar-EG, cs_CZ: cs-CZ, fa_IR: fa-IR, ms_MY: ms-MY, nl_NL: nl-NL, de_CH: de-CH, en_IT: en-IT, uz_UZ: uz-UZ, fr_CH: fr-CH, hi_IN: hi-IN, et_EE: et-EE, es_PE: es-PE, es_MX: es-MX, gl_ES: gl-ES, mn_MN: mn, sl_SI: sl, zh_TW: zh-TW, ast_ES: ast-ES, es_CL: es-CL, ja_JP: ja, lv_LV: lv, ro_RO: ro-RO, az_AZ: az-AZ, cy_GB: cy-GB, gu_IN: gu-IN, pl_PL: pl-PL, vep: ve-PP, en_BR: en-BR, en@ysv: en-YS, hu_HU: hu, ko_KR: ko-KR, pt_BR: pt-BR, zh_HK: zh-HK, zu_ZA: zu-ZA, en_MY: en-MY, ja-Hira: ja-HI, fi_FI: fi, vec: ve-CC, vi_VN: vi-VN, fr_FR: fr-FR, id_ID: id, zh_Hans: zh-Hans, en_DE: en-DE, en_GB: en-GB, el_GR: el-GR, uk_UA: uk-UA, az@latin: az-LA, de_AT: de-AT, uz@Latn: uz-LA, vls: vl-SS, ar_DZ: ar-DZ, bg_BG: bg, es_PY: es-PY, fy_NL: fy-NL, uz@Arab: uz-AR, ru_UA: ru-UA, war: wa-RR, zh_CN.GB2312: zh-GB
lang_map = te_IN: te-IN, es_AR: es-AR, es_419: es-LA, es_TX: es-TX, he_IL: he-IL, zh_CN: zh-CN, ar_EG: ar-EG, cs_CZ: cs-CZ, fa_IR: fa-IR, ms_MY: ms-MY, nl_NL: nl-NL, de_CH: de-CH, en_IT: en-IT, uz_UZ: uz-UZ, fr_CH: fr-CH, hi_IN: hi-IN, et_EE: et-EE, es_PE: es-PE, es_MX: es-MX, gl_ES: gl-ES, mn_MN: mn, zh_TW: zh-TW, ast_ES: ast-ES, es_CL: es-CL, ja_JP: ja, lv_LV: lv, ro_RO: ro-RO, az_AZ: az-AZ, cy_GB: cy-GB, gu_IN: gu-IN, pl_PL: pl-PL, vep: ve-PP, en_BR: en-BR, en@ysv: en-YS, hu_HU: hu, ko_KR: ko-KR, pt_BR: pt-BR, zh_HK: zh-HK, zu_ZA: zu-ZA, en_MY: en-MY, ja-Hira: ja-HI, fi_FI: fi, vec: ve-CC, vi_VN: vi-VN, fr_FR: fr-FR, id_ID: id, zh_Hans: zh-Hans, en_DE: en-DE, en_GB: en-GB, el_GR: el-GR, uk_UA: uk-UA, az@latin: az-LA, de_AT: de-AT, uz@Latn: uz-LA, vls: vl-SS, ar_DZ: ar-DZ, bg_BG: bg, es_PY: es-PY, fy_NL: fy-NL, uz@Arab: uz-AR, ru_UA: ru-UA, war: wa-RR, zh_CN.GB2312: zh-GB
[o:wekan:p:wekan:r:application]
file_filter = imports/i18n/data/<lang>.i18n.json
+48 -36
View File
@@ -1,45 +1,57 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Meteor: Chrome",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}"
{
"type": "node",
"request": "launch",
"name": "Meteor: Node",
"runtimeExecutable": "meteor",
"runtimeArgs": [
"--port=4000",
"--exclude-archs=web.browser.legacy,web.cordova",
"--raw-logs"
],
"env": {
"WRITABLE_PATH": "/tmp/uploads",
},
{
"type": "node",
"request": "launch",
"name": "Meteor: Node",
"runtimeExecutable": "/home/wekan/.meteor/meteor",
"runtimeArgs": ["run", "--inspect-brk=9229"],
"outputCapture": "std",
"port": 9229,
"timeout": 60000
"outputCapture": "std",
"restart": true,
"timeout": 60000
},
{
"type": "chrome",
"request": "launch",
"name": "Meteor: Chrome",
"url": "http://localhost:4000",
"sourceMapPathOverrides": {
"meteor://💻app/*": "${workspaceFolder}/*"
},
{
"type": "node",
"request": "launch",
"name": "Test: Node",
"runtimeExecutable": "meteor",
"runtimeArgs": [
"test",
"--inspect-brk=9229",
"--port=4040",
"--exclude-archs=web.browser.legacy,web.cordova",
"--driver-package=meteortesting:mocha",
"--settings=settings.json"
],
"outputCapture": "std",
"port": 9229,
"timeout": 60000
}
"userDataDir": "${env:HOME}/.vscode/chrome"
},
{
"type": "node",
"request": "launch",
"name": "Test: Node",
"runtimeExecutable": "meteor",
"runtimeArgs": [
"test",
"--port=4040",
"--exclude-archs=web.browser.legacy,web.cordova",
"--driver-package=meteortesting:mocha",
"--settings=settings.json",
"--raw-logs"
],
"env": {
"TEST_WATCH": "1"
},
"outputCapture": "std",
"timeout": 60000
}
],
"compounds": [
{
"name": "Meteor: All",
"configurations": ["Meteor: Node", "Meteor: Chrome"]
}
{
"name": "Meteor: All",
"configurations": ["Meteor: Node", "Meteor: Chrome"]
}
]
}
+15 -11
View File
@@ -1,12 +1,16 @@
{
"editor.tabSize": 2,
"editor.rulers": [80],
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"node_modules": true,
".meteor/local": true
}
}
"terminal.integrated.env.linux": {
"TERM": "xterm-256color"
},
"terminal.integrated.env.osx": {
"TERM": "xterm-256color"
},
"terminal.integrated.env.windows": {
"TERM": "xterm-256color"
},
"terminal.integrated.shell.linux": "/bin/bash",
"terminal.integrated.shellArgs.linux": [
"-l"
],
"files.simpleDialog.enable": true
}
+5222 -18
View File
File diff suppressed because it is too large. Load diff
+7 -2
View File
@@ -3,15 +3,20 @@
For all code at WeKan GitHub Organization https://github.com/wekan
- All code in pull requests need to have permission already to add it to WeKan with MIT license, and will become MIT license.
- All code xet7 add is MIT license.
- For any dependencies, permissive licenses like https://copyfree.org are preferred
- For anything currently that is non-permissive (like GPL, AGPL, SSPL), those will be replaced with permissive-licensed alternatives
- Any intelligence allowed: Human, AI or any other. No discrimination, please have world peace. Mentioning participants optional.
- All code is checked and validated by xet7 and many different security AI. If code is real working fix or feature, it usually will be merged.
- All known vulnerabilities have been fixed at newest WeKan, please upgrade https://wekan.fi/upgrade/
- There is no known backdoors. If WeKan is installed by someone else, first registered user is Admin and has Admin Panel access.
- Maintainer of WeKan has no access to someone elses installed WeKan.
- For someone elses installed WeKan, see [Forgot Password](https://github.com/wekan/wekan/blob/main/docs/Login/Forgot-Password.md)
# Reporting about violations or something else
## Private reports
- Email support (at) wekan.team using [this PGP public key](support-at-wekan.team_pgp-publickey.asc) if possible
- Email support@wekan.fi
- Security issues: [SECURITY.md](SECURITY.md)
- License violations
- Anything private, sensitive or negative
+29 -26
View File
@@ -6,38 +6,45 @@ Not paid:
- Security reports, see [SECURITY.md](SECURITY.md)
- Pull requests
- xet7 checking pull requests
- Public Community Support
- This is because full-featured WeKan FLOSS kanban with MIT license is free to use
also for Commercial Use without any payment, with full source code at
https://github.com/wekan/wekan for all platforms at https://wekan.fi/install/ .
There is nothing proprietary. WeKan is NOT Big Tech.
WeKan is maintained by https://github.com/xet7 at Finland https://wekan.fi .
- Public FLOSS Developer Community Support:
- https://github.com/wekan/wekan/issues
Paid by customers of WeKan Team:
Paid by customers of WeKan to WeKan:
- Commercial Support at https://wekan.team/commercial-support/
- Support
- Private Chat
- Features
- Fixes
- Hosting
- Optional Private Paid Commercial Support at https://wekan.fi/commercial-support/
- Optional Paid Support/Features/Fixes/PrivateChat . All Paid Features and Fixes are added directly to FLOSS WeKan https://github.com/wekan/wekan
- Optional Paid Official SaaS Hosting https://wekan.fi/saas/ , if you need full-featured hosting, that is more than free app https://wekan.fi/app/
## Contributing Security related
For responsible security disclosure, please follow this process:
https://github.com/wekan/wekan/blob/main/SECURITY.md
For responsible security disclosure, please follow this process: [SECURITY.md](SECURITY.md)
CVE Hall of Fame is at https://wekan.github.io/hall-of-fame/
CVE Hall of Fame is at https://wekan.fi/hall-of-fame/
## Contributing to Documentation Wiki
Please clone wiki:
```
git clone https://github.com/wekan/wekan.wiki
```
Edit .md files, and add changed files in .zip attachment
directly to comment of new issue at
https://github.com/wekan/wekan/issues
Fork WeKan repo https://github.com/wekan/wekan ,
edit `docs` directory content at GitHub web interface,
and click send PR.
## Contributing code
[Building WeKan and sending PR](https://github.com/wekan/wekan/wiki/Emoji).
Use rebuild-wekan.sh to run all tests to verify you don't break any features, before sending PR.
Only send one feature or fix at one PR. Do not add many unrelated changes.
Only send those changed code lines, that are related to your one feature or fix.
Do not format unrelated code. Do not use code formatting or linting like eslist or prettier.
Send your code ASAP, because there are daily releases of WeKan with major features and fixes added.
[Building WeKan and sending PR](https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Build-and-Create-Pull-Request.md).
WeKan code contributors Hall of Fame is at ChangeLog, where
GitHub usernames are mentioned with changes added:
@@ -48,13 +55,9 @@ Changes can be like typo fixes, bugfixes, features, or anything else
like for example at open GitHub issues https://github.com/wekan/wekan/issues .
Closed issues are already fixed or implemented.
Also see other docs at wiki, for example:
Also see other docs:
https://github.com/wekan/wekan/wiki/Developer-Documentation
Do not use code formatting or linting like eslist or prettier.
Only send minimal changed code lines, that are related to feature or fix.
https://github.com/wekan/wekan/tree/main/docs/DeveloperDocs
WeKan code has MIT license.
@@ -68,7 +71,7 @@ so that WeKan code will still work OK.
## Contributing translations
Non-English translations are contributed only at
https://transifex.com/wekan/wekan
https://app.transifex.com/wekan/wekan
When adding new features, in your PR to
https://github.com/wekan/wekan/pulls
+92 -138
View File
@@ -1,38 +1,26 @@
FROM --platform=linux/amd64 ubuntu:23.10 as wekan
LABEL maintainer="wekan" \
org.opencontainers.image.ref.name="ubuntu" \
org.opencontainers.image.version="23.10" \
org.opencontainers.image.source="https://github.com/wekan/wekan"
FROM ubuntu:26.04
LABEL maintainer="wekan"
LABEL org.opencontainers.image.ref.name="ubuntu"
LABEL org.opencontainers.image.version="26.04"
LABEL org.opencontainers.image.source="https://github.com/wekan/wekan"
# 2022-09-04:
# - above "--platform=linux/amd64 ubuntu:22.04 as wekan" is needed to build Dockerfile
# correctly on Mac M1 etc, to not get this error:
# https://stackoverflow.com/questions/71040681/qemu-x86-64-could-not-open-lib64-ld-linux-x86-64-so-2-no-such-file-or-direc
# 2022-04-25:
# - gyp does not yet work with Ubuntu 22.04 ubuntu:rolling,
# so changing to 21.10. https://github.com/wekan/wekan/issues/4488
# 2021-09-18:
# - Above Ubuntu base image copied from Docker Hub ubuntu:hirsute-20210825
# to Quay to avoid Docker Hub rate limits.
# Set the environment variables (defaults where required)
# DOES NOT WORK: paxctl fix for alpine linux: https://github.com/wekan/wekan/issues/1303
# ENV BUILD_DEPS="paxctl"
# TARGETARCH and TARGETVARIANT are automatically provided by Docker Buildx
ARG TARGETARCH
ARG TARGETVARIANT
ARG VERSION=9.42
ARG DEBIAN_FRONTEND=noninteractive
ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-essential git ca-certificates python3" \
ENV BUILD_DEPS="apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip"
ENV \
DEBUG=false \
NODE_VERSION=v14.21.4 \
METEOR_RELEASE=METEOR@2.13.3 \
NODE_VERSION=v24.16.0 \
METEOR_RELEASE=METEOR@3.5-beta.12 \
USE_EDGE=false \
METEOR_EDGE=1.5-beta.17 \
NPM_VERSION=9.8.1 \
FIBERS_VERSION=4.0.1 \
ARCHITECTURE=linux-x64 \
NPM_VERSION=11.11.0 \
SRC_PATH=./ \
WITH_API=true \
MONGO_OPLOG_URL="" \
RESULTS_PER_PAGE="" \
DEFAULT_BOARD_ID="" \
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 \
@@ -73,6 +61,7 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
OAUTH2_LOGIN_STYLE=redirect \
OAUTH2_CLIENT_ID="" \
OAUTH2_SECRET="" \
OAUTH2_SECRET_FILE="" \
OAUTH2_SERVER_URL="" \
OAUTH2_AUTH_ENDPOINT="" \
OAUTH2_USERINFO_ENDPOINT="" \
@@ -98,6 +87,7 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
LDAP_AUTHENTIFICATION=false \
LDAP_AUTHENTIFICATION_USERDN="" \
LDAP_AUTHENTIFICATION_PASSWORD="" \
LDAP_AUTHENTIFICATION_PASSWORD_FILE="" \
LDAP_LOG_ENABLED=false \
LDAP_BACKGROUND_SYNC=false \
LDAP_BACKGROUND_SYNC_INTERVAL="" \
@@ -163,122 +153,86 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
ORACLE_OIM_ENABLED=false \
WAIT_SPINNER="" \
WRITABLE_PATH=/data \
S3=""
S3="" \
MAIL_SERVICE_PASSWORD_FILE="" \
MONGO_PASSWORD_FILE="" \
S3_SECRET_FILE=""
# NODE_OPTIONS="--max_old_space_size=4096" \
RUN <<EOR
set -o xtrace
# Fail hard on any error so a missing release zip / failed download can never
# produce a "successful" image with an empty /build (Cannot find /build/main.js).
set -eo pipefail
#---------------------------------------------
# == at docker-compose.yml: AUTOLOGIN WITH OIDC/OAUTH2 ====
# https://github.com/wekan/wekan/wiki/autologin
#- OIDC_REDIRECTION_ENABLED=true
#---------------------------------------------------------------------
# Create Wekan user. --create-home is required because --system users do not
# get a home directory by default; without it /home/wekan never exists and the
# later `chown ... /home/wekan/` aborts the build (now that set -e is active).
useradd --user-group --system --create-home --home-dir /home/wekan wekan
# Copy the app to the image
COPY ${SRC_PATH} /home/wekan/app
# OS Updates
apt-get update --assume-yes
apt-get upgrade --assume-yes
apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS}
RUN \
set -o xtrace && \
# Add non-root user wekan
useradd --user-group --system --home-dir /home/wekan wekan && \
\
# OS dependencies
apt-get update -y && apt-get install -y --no-install-recommends ${BUILD_DEPS} && \
\
# Meteor installer doesn't work with the default tar binary, so using bsdtar while installing.
# https://github.com/coreos/bugs/issues/1095#issuecomment-350574389
cp $(which tar) $(which tar)~ && \
ln -sf $(which bsdtar) $(which tar) && \
\
# Download nodejs
wget https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz && \
wget https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/SHASUMS256.txt && \
#wget https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz && \
#wget https://nodejs.org/dist/${NODE_VERSION}/SHASUMS256.txt.asc && \
#---------------------------------------------------------------------------------------------
\
# Verify nodejs authenticity
grep node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz SHASUMS256.txt | shasum -a 256 -c - && \
rm -f SHASUMS256.txt && \
#grep ${NODE_VERSION}-${ARCHITECTURE}.tar.gz SHASUMS256.txt.asc | shasum -a 256 -c - && \
#rm -f SHASUMS256.txt.asc && \
\
# Install Node
tar xvzf node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz && \
rm node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz && \
mv node-${NODE_VERSION}-${ARCHITECTURE} /opt/nodejs && \
ln -s /opt/nodejs/bin/node /usr/bin/node && \
ln -s /opt/nodejs/bin/npm /usr/bin/npm && \
mkdir -p /opt/nodejs/lib/node_modules/fibers/.node-gyp /root/.node-gyp/${NODE_VERSION} /home/wekan/.config && \
chown wekan --recursive /home/wekan/.config && \
\
#DOES NOT WORK: paxctl fix for alpine linux: https://github.com/wekan/wekan/issues/1303
#paxctl -mC `which node` && \
\
# Install Node dependencies. Python path for node-gyp.
#npm install -g npm@${NPM_VERSION} && \
\
# Change user to wekan and install meteor
cd /home/wekan/ && \
chown wekan --recursive /home/wekan && \
echo "Starting meteor ${METEOR_RELEASE} installation... \n" && \
gosu wekan:wekan curl https://install.meteor.com/ | /bin/sh && \
mv /root/.meteor /home/wekan/ && \
chown wekan --recursive /home/wekan/.meteor && \
\
sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' /home/wekan/app/packages/meteor-useraccounts-core/package.js && \
cd /home/wekan/.meteor && \
gosu wekan:wekan /home/wekan/.meteor/meteor -- help; \
\
# Build app
cd /home/wekan/app && \
mkdir -p /home/wekan/.npm && \
chown wekan --recursive /home/wekan/.npm /home/wekan/.config /home/wekan/.meteor && \
chmod u+w *.json && \
gosu wekan:wekan meteor npm install && \
gosu wekan:wekan /home/wekan/.meteor/meteor build --directory /home/wekan/app_build && \
cd /home/wekan/app_build/bundle/programs/server/ && \
chmod u+w *.json && \
gosu wekan:wekan meteor npm install && \
cd node_modules/fibers && \
node build.js && \
cd ../.. && \
# Remove legacy webbroser bundle, so that Wekan works also at Android Firefox, iOS Safari, etc.
rm -rf /home/wekan/app_build/bundle/programs/web.browser.legacy && \
mv /home/wekan/app_build/bundle /build && \
\
# Put back the original tar
mv $(which tar)~ $(which tar) && \
\
# Cleanup
apt-get remove --purge -y ${BUILD_DEPS} && \
apt-get autoremove -y && \
npm uninstall -g api2html &&\
rm -R /tmp/* && \
rm -R /var/lib/apt/lists/* && \
rm -R /home/wekan/.meteor && \
rm -R /home/wekan/app && \
rm -R /home/wekan/app_build && \
mkdir /data && \
chown wekan --recursive /data
#cat /home/wekan/python/esprima-python/files.txt | xargs rm -R && \
#rm -R /home/wekan/python
#rm /home/wekan/install_meteor.sh
# Multi-arch mapping: Docker TARGETARCH -> Node.js arch name + WeKan bundle name
# arm/v7 uses TARGETARCH=arm; armhf has no MongoDB Community -> uses FerretDB
case "${TARGETARCH}" in
"amd64") NODE_ARCH="x64" WEKAN_ARCH="amd64" ;;
"arm64") NODE_ARCH="arm64" WEKAN_ARCH="arm64" ;;
"arm") NODE_ARCH="armv7l" WEKAN_ARCH="armhf" ;;
"ppc64le") NODE_ARCH="ppc64le" WEKAN_ARCH="ppc64le" ;;
"s390x") NODE_ARCH="s390x" WEKAN_ARCH="s390x" ;;
*) echo "Unsupported architecture: ${TARGETARCH}"; exit 1 ;;
esac
# Node.js Installation (official nodejs.org builds for Node 22)
cd /tmp
wget "https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-${NODE_ARCH}.tar.gz"
wget "https://nodejs.org/dist/${NODE_VERSION}/SHASUMS256.txt.asc"
grep "node-${NODE_VERSION}-linux-${NODE_ARCH}.tar.gz" SHASUMS256.txt.asc | shasum -a 256 -c -
tar xzf "node-${NODE_VERSION}-linux-${NODE_ARCH}.tar.gz" -C /usr/local --strip-components=1 --no-same-owner
rm -f "node-${NODE_VERSION}-linux-${NODE_ARCH}.tar.gz" SHASUMS256.txt.asc
ln -s "/usr/local/bin/node" "/usr/local/bin/nodejs"
# NPM configuration
npm install -g npm@${NPM_VERSION}
chown --recursive wekan:wekan /home/wekan/
# Temporary Tar swap for Meteor bundle
cp $(which tar) $(which tar)~
ln -sf $(which bsdtar) $(which tar)
# WeKan Bundle Installation
mkdir -p /home/wekan/app
cd /home/wekan/app
wget "https://github.com/wekan/wekan/releases/download/v${VERSION}/wekan-${VERSION}-${WEKAN_ARCH}.zip"
unzip "wekan-${VERSION}-${WEKAN_ARCH}.zip"
rm "wekan-${VERSION}-${WEKAN_ARCH}.zip"
npm install --prefix ./bundle/programs/server
mv /home/wekan/app/bundle /build
# Restore original tar
mv $(which tar)~ $(which tar)
# Cleanup
# Remove unused Go-based pebble binary shipped by base image to reduce CVE surface.
apt-get remove --purge --assume-yes pebble || true
rm -f /usr/bin/pebble
apt-get remove --purge --assume-yes ${BUILD_DEPS}
apt-get autoremove --assume-yes
apt-get clean --assume-yes
rm -Rf /tmp/*
rm -Rf /var/lib/apt/lists/*
rm -Rf /home/wekan/app
mkdir -p /data
chown wekan:wekan --recursive /data
EOR
USER wekan
ENV PORT=8080
EXPOSE $PORT
USER wekan
STOPSIGNAL SIGKILL
WORKDIR /build
#---------------------------------------------------------------------
# https://github.com/wekan/wekan/issues/3585#issuecomment-1021522132
# Add more Node heap:
# NODE_OPTIONS="--max_old_space_size=4096"
# Add more stack:
# bash -c "ulimit -s 65500; exec node --stack-size=65500 main.js"
#---------------------------------------------------------------------
#
# CMD ["node", "/build/main.js"]
#CMD ["bash", "-c", "ulimit -s 65500; exec node --stack-size=65500 /build/main.js"]
CMD ["bash", "-c", "ulimit -s 65500; exec node /build/main.js"]
CMD ["bash", "-c", "ulimit -s 65500; exec node main.js"]
-92
View File
@@ -1,92 +0,0 @@
FROM arm64v8/ubuntu:23.04 AS builder
#FROM amd64/alpine:latest AS builder
# Set the environment variables for builder
ENV QEMU_VERSION=v7.2.0-1 \
QEMU_ARCHITECTURE=aarch64 \
NODE_ARCHITECTURE=linux-arm64 \
NODE_VERSION=v14.21.4 \
WEKAN_VERSION=latest \
WEKAN_ARCHITECTURE=arm64
# Install dependencies
#RUN apk update && apk add ca-certificates outils-sha1 && \
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
RUN apt update && apt install ca-certificates wget unzip -y && \
\
# Download qemu static for our architecture
wget https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_VERSION}/qemu-${QEMU_ARCHITECTURE}-static.tar.gz -O - | tar -xz && \
\
# Download wekan and shasum
wget https://releases.wekan.team/raspi3/wekan-${WEKAN_VERSION}-${WEKAN_ARCHITECTURE}.zip && \
wget https://releases.wekan.team/raspi3/SHA256SUMS.txt && \
# Verify wekan
grep wekan-${WEKAN_VERSION}-${WEKAN_ARCHITECTURE}.zip SHA256SUMS.txt | sha256sum -c - && \
\
# Unzip wekan
unzip wekan-${WEKAN_VERSION}-${WEKAN_ARCHITECTURE}.zip && \
\
# Download node and shasums
wget https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/node-${NODE_VERSION}-${NODE_ARCHITECTURE}.tar.gz && \
wget https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/SHASUMS256.txt && \
#wget https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-${NODE_ARCHITECTURE}.tar.gz && \
#wget https://nodejs.org/dist/${NODE_VERSION}/SHASUMS256.txt.asc && \
#wget https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-${NODE_ARCHITECTURE}.tar.gz && \
#wget https://nodejs.org/dist/${NODE_VERSION}/SHASUMS256.txt.asc && \
\
# Verify nodejs authenticity
grep node-${NODE_VERSION}-${NODE_ARCHITECTURE}.tar.gz SHASUMS256.txt | sha256sum -c - && \
\
# Extract node and remove tar.gz
tar xvzf node-${NODE_VERSION}-${NODE_ARCHITECTURE}.tar.gz
# Build wekan dockerfile
FROM --platform=linux/arm64 arm64v8/ubuntu:23.04
LABEL maintainer="wekan"
# Set the environment variables (defaults where required)
ENV QEMU_ARCHITECTURE=aarch64 \
NODE_ARCHITECTURE=linux-arm64 \
NODE_VERSION=v14.21.4 \
NODE_ENV=production \
NPM_VERSION=latest \
WITH_API=true \
PORT=8080 \
ROOT_URL=http://localhost \
MONGO_URL=mongodb://127.0.0.1:27017/wekan
# Copy qemu-static to image
COPY --from=builder qemu-${QEMU_ARCHITECTURE}-static /usr/bin
# Copy the app to the image
COPY --from=builder bundle /home/wekan/bundle
# Copy
COPY --from=builder node-${NODE_VERSION}-${NODE_ARCHITECTURE} /opt/nodejs
RUN \
set -o xtrace && \
# Add non-root user wekan
useradd --user-group --system --home-dir /home/wekan wekan && \
\
# Install Node
ln -s /opt/nodejs/bin/node /usr/bin/node && \
ln -s /opt/nodejs/bin/npm /usr/bin/npm && \
mkdir -p /opt/nodejs/lib/node_modules/fibers/.node-gyp /root/.node-gyp/8.16.1 /home/wekan/.config && \
chown wekan --recursive /home/wekan/.config
# \
# # Install Node dependencies
# #npm install -g npm@${NPM_VERSION} && \
# \
# # Install Health Check dependencies
# #apk add curl
#
#HEALTHCHECK --start-period=30s --interval=30s --timeout=10s --retries=3 \
# CMD curl --fail "http://localhost:$PORT" || exit 1
EXPOSE $PORT
USER wekan
CMD ["bash", "-c", "ulimit -s 65500; exec node /home/wekan/bundle/main.js"]
-94
View File
@@ -1,94 +0,0 @@
FROM arm64v8/ubuntu:23.04 AS builder
#FROM --platform=linux/amd64 amd64/ubuntu:23.04 AS builder
#FROM --platform=linux/amd64 ghcr.io/wekan/wekan:main AS builder
#FROM arm64v8/ubuntu:23.04 AS builder
#FROM amd64/alpine:latest AS builder
# Set the environment variables for builder
ENV QEMU_VERSION=v7.2.0-1 \
QEMU_ARCHITECTURE=s390x \
NODE_ARCHITECTURE=linux-s390x \
NODE_VERSION=v14.21.4 \
WEKAN_VERSION=latest \
WEKAN_ARCHITECTURE=s390x
# Install dependencies
#RUN apk update && apk add ca-certificates outils-sha1 && \
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
RUN apt update && apt install ca-certificates wget unzip -y && \
\
# Download qemu static for our architecture
wget https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_VERSION}/qemu-${QEMU_ARCHITECTURE}-static.tar.gz -O - | tar -xz && \
\
# Download wekan and shasum
wget https://releases.wekan.team/${WEKAN_ARCHITECTURE}/wekan-${WEKAN_VERSION}-${WEKAN_ARCHITECTURE}.zip && \
wget https://releases.wekan.team/${WEKAN_ARCHITECTURE}/SHA256SUMS.txt && \
# Verify wekan
grep wekan-${WEKAN_VERSION}-${WEKAN_ARCHITECTURE}.zip SHA256SUMS.txt | sha256sum -c - && \
\
# Unzip wekan
unzip wekan-${WEKAN_VERSION}-${WEKAN_ARCHITECTURE}.zip && \
\
# Download node and shasums
wget https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/node-${NODE_VERSION}-${NODE_ARCHITECTURE}.tar.gz && \
wget https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/SHASUMS256.txt && \
#wget https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-${NODE_ARCHITECTURE}.tar.gz && \
#wget https://nodejs.org/dist/${NODE_VERSION}/SHASUMS256.txt.asc && \
#wget https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-${NODE_ARCHITECTURE}.tar.gz && \
#wget https://nodejs.org/dist/${NODE_VERSION}/SHASUMS256.txt.asc && \
\
# Verify nodejs authenticity
grep node-${NODE_VERSION}-${NODE_ARCHITECTURE}.tar.gz SHASUMS256.txt | sha256sum -c - && \
\
# Extract node and remove tar.gz
tar xvzf node-${NODE_VERSION}-${NODE_ARCHITECTURE}.tar.gz
# Build wekan dockerfile
FROM --platform=linux/s390x s390x/ubuntu:23.04
LABEL maintainer="wekan"
# Set the environment variables (defaults where required)
ENV QEMU_ARCHITECTURE=s390x \
NODE_ARCHITECTURE=linux-s390x \
NODE_VERSION=v14.21.4 \
NODE_ENV=production \
NPM_VERSION=latest \
WITH_API=true \
PORT=8080 \
ROOT_URL=http://localhost \
MONGO_URL=mongodb://127.0.0.1:27017/wekan
# Copy qemu-static to image
COPY --from=builder qemu-${QEMU_ARCHITECTURE}-static /usr/bin
# Copy the app to the image
COPY --from=builder bundle /home/wekan/bundle
# Copy
COPY --from=builder node-${NODE_VERSION}-${NODE_ARCHITECTURE} /opt/nodejs
RUN \
set -o xtrace && \
# Add non-root user wekan
useradd --user-group --system --home-dir /home/wekan wekan && \
\
# Install Node
ln -s /opt/nodejs/bin/node /usr/bin/node && \
ln -s /opt/nodejs/bin/npm /usr/bin/npm && \
mkdir -p /opt/nodejs/lib/node_modules/fibers/.node-gyp /root/.node-gyp/8.16.1 /home/wekan/.config && \
chown wekan --recursive /home/wekan/.config
# \
# # Install Node dependencies
# #npm install -g npm@${NPM_VERSION} && \
# \
# # Install Health Check dependencies
# #apk add curl
#
#HEALTHCHECK --start-period=30s --interval=30s --timeout=10s --retries=3 \
# CMD curl --fail "http://localhost:$PORT" || exit 1
EXPOSE $PORT
USER wekan
CMD ["bash", "-c", "ulimit -s 65500; exec node /home/wekan/bundle/main.js"]
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014-2023 The Wekan Team
Copyright (c) Lauri Ojansivu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+93 -32
View File
@@ -1,10 +1,8 @@
[Gitpod Ready-to-Code](https://gitpod.io/#https://github.com/wekan/wekan)
# WeKan ® - Open Source kanban
## Downloads
https://wekan.github.io / Install WeKan ® Server
https://wekan.fi/install/
## Docker Containers
@@ -12,11 +10,11 @@ https://wekan.github.io / Install WeKan ® Server
- [Quay](https://quay.io/repository/wekan/wekan)
- [Docker Hub](https://hub.docker.com/r/wekanteam/wekan)
docker-compose.yml at https://github.com/wekan/wekan
docker-compose.yml at https://github.com/wekan/wekan/blob/main/docker-compose.yml
## Standards
- [WeKan and Standard for Public Code](https://wekan.github.io/standard-for-public-code/) assessment was made at 2023-11.
- [WeKan and Standard for Public Code](https://wekan.fi/standard-for-public-code/) assessment was made at 2023-11.
Currently Wekan meets 8 out of 16 criteria out of the box.
Some others could be met with small changes.
@@ -27,21 +25,19 @@ docker-compose.yml at https://github.com/wekan/wekan
- [Open Hub](https://www.openhub.net/p/wekan)
- [OSS Insight](https://ossinsight.io/analyze/wekan/wekan)
## [Translate WeKan ® at Transifex](https://app.transifex.com/wekan/)
## Translate WeKan ® at Transifex
Translations to non-English languages are accepted only at [Transifex](https://app.transifex.com/wekan/) using webbrowser.
Translations to non-English languages are accepted only at [Transifex](https://app.transifex.com/wekan/wekan) using webbrowser.
New English strings of new features can be added as PRs to master branch file wekan/imports/i18n/data/en.i18n.json .
## [WeKan ® feature requests and bugs](https://github.com/wekan/wekan/issues)
## WeKan ® feature requests and bugs
Please add most of your questions as GitHub issue: [WeKan ® Feature Requests and Bugs](https://github.com/wekan/wekan/issues).
It's better than at chat where details get lost when chat scrolls up.
## Chat
## Discussions
[Discussions][discussions] - WeKan Community GitHub Discussions, that are not [Feature Requests and Bugs](https://github.com/wekan/wekan/issues).
[WeKan IRC FAQ](https://github.com/wekan/wekan/wiki/IRC-FAQ)
[IRC](https://github.com/wekan/wekan/blob/main/docs/FAQ/IRC-FAQ.md)
## Docker: Latest tag has newest release
@@ -51,12 +47,13 @@ See bottom of https://github.com/wekan/wekan/issues/3874
## FAQ
**NOTE**:
- Please read the [FAQ](https://github.com/wekan/wekan/wiki/FAQ) first
- Please don't feed the [trolls](https://github.com/wekan/wekan/wiki/FAQ#why-am-i-called-a-troll) and [spammers](https://github.com/wekan/wekan/wiki/FAQ#why-am-i-called-a-spammer) that are mentioned in the FAQ :)
- Please read the [FAQ](https://github.com/wekan/wekan/blob/main/docs/FAQ/FAQ.md) first
- Please don't feed the [trolls](https://github.com/wekan/wekan/blob/main/docs/FAQ/FAQ.md#why-am-i-called-a-troll) and [spammers](https://github.com/wekan/wekan/blob/main/docs/FAQ/FAQ.md#why-am-i-called-a-spammer) that are mentioned in the FAQ :)
## About WeKan ®
WeKan ® is an completely [Open Source][open_source] and [Free software][free_software]
WeKan ® is a completely [Open Source][open_source] and [Free software][free_software]
collaborative kanban board application with MIT license.
Whether you’re maintaining a personal todo list, planning your holidays with some friends,
@@ -72,26 +69,23 @@ that by providing one-click installation on various platforms.
- WeKan ® largest user has 30k users using WeKan ® in their company.
- WeKan ® has been [translated](https://app.transifex.com/wekan/) to about 105 languages.
- [Features][features]: WeKan ® has real-time user interface.
- [Platforms][platforms]: WeKan ® supports many platforms.
- [Platforms](https://wekan.fi/install/): WeKan ® supports many platforms.
WeKan ® is critical part of new platforms Wekan is currently being integrated to.
## Requirements
- 64bit: Linux [Snap](https://github.com/wekan/wekan-snap/wiki/Install) or [Sandstorm](https://sandstorm.io) /
[Mac](https://github.com/wekan/wekan/wiki/Mac) / [Windows](https://github.com/wekan/wekan/wiki/Install-Wekan-from-source-on-Windows).
[More Platforms](https://github.com/wekan/wekan/wiki/Platforms), bundle for RasPi3 ARM and other CPUs where Node.js and MongoDB exists.
- 1 GB RAM minimum free for WeKan ®. Production server should have minimum total 4 GB RAM.
For thousands of users, for example with [Docker](https://github.com/wekan/wekan/blob/main/docker-compose.yml): 3 frontend servers,
each having 2 CPU and 2 wekan-app containers. One backend wekan-db server with many CPUs.
- Enough disk space and alerts about low disk space. If you run out disk space, MongoDB database gets corrupted.
- Enough disk space and alerts about low disk space. If you run out of disk space, MongoDB database gets corrupted.
- SECURITY: Updating to newest WeKan ® version very often. Please check you do not have automatic updates of Sandstorm or Snap turned off.
Old versions have security issues because of old versions Node.js etc. Only newest WeKan ® is supported.
WeKan ® on Sandstorm is not usually affected by any Standalone WeKan ® (Snap/Docker/Source) security issues.
- [Reporting all new bugs immediately](https://github.com/wekan/wekan/issues).
New features and fixes are added to WeKan ® [many times a day](https://github.com/wekan/wekan/blob/main/CHANGELOG.md).
- [Backups](https://github.com/wekan/wekan/wiki/Backup) of WeKan ® database once a day miminum.
- [Backups](https://github.com/wekan/wekan/blob/main/docs/Backup/Backup.md) of WeKan ® database once a day minimum.
Bugs, updates, users deleting list or card, harddrive full, harddrive crash etc can eat your data. There is no undo yet.
Some bug can cause WeKan ® board to not load at all, requiring manual fixing of database content.
Some bugs can cause WeKan ® board to not load at all, requiring manual fixing of database content.
## Roadmap and Demo
@@ -99,17 +93,88 @@ that by providing one-click installation on various platforms.
[Developer Documentation][dev_docs]
- There is many companies and individuals contributing code to WeKan ®, to add features and bugfixes
- There are many companies and individuals contributing code to WeKan ®, to add features and bugfixes
[many times a day](https://github.com/wekan/wekan/blob/main/CHANGELOG.md).
- [Please add Add new Feature Requests and Bug Reports immediately](https://github.com/wekan/wekan/issues).
- [Commercial Support](https://wekan.team/commercial-support/).
- [Commercial Support](https://wekan.fi/commercial-support/).
We also welcome sponsors for features and bugfixes.
By working directly with WeKan ® you get the benefit of active maintenance and new features added by growing WeKan ® developer community.
## Getting Started with Development
The default branch uses Meteor 3.5-beta.7 with Node.js 24.x.
See [CHANGELOG.md](https://github.com/wekan/wekan/blob/main/CHANGELOG.md) for the latest runtime updates.
To contribute, [create a fork](https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Build-and-Create-Pull-Request.md#2-create-fork-of-httpsgithubcomwekanwekan-at-github-web-page) and run `./rebuild-wekan.sh` (or `./rebuild-wekan.bat` on Windows) as detailed [here](https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Build-and-Create-Pull-Request.md#3-select-option-1-to-install-dependencies-and-then-enter). Once you're ready, please test your code and [submit a pull request (PR)](https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Build-and-Create-Pull-Request.md#7-test).
Please refer to the [developer documentation](https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Developer-Documentation.md) for more information.
## First-Time Setup for Development
### Prerequisites
Before building WeKan from source, ensure you have:
- **Git** - for cloning the repository
- **Node.js 24.x** - WeKan requires Node.js 24.x
- **Meteor** - the JavaScript framework WeKan is built with
### Installing Node.js 24.x
```bash
# Using nvm (recommended)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.zshrc # or ~/.bashrc
nvm install 24
nvm use 24
```
### Installing Meteor
```bash
curl https://install.meteor.com/ | sh
```
### Building WeKan
The `rebuild-wekan.sh` script guides you through a three-stage process:
1. **Install dependencies (Option 1)** - Downloads all required Meteor packages and npm modules
2. **Build WeKan (Option 2)** - Compiles the application
3. **Run WeKan (Option 3)** - Starts the development server at http://localhost:4000
```bash
# Clone your fork
git clone git@github.com:YOUR_USERNAME/wekan.git
cd wekan
# Make the script executable
chmod +x rebuild-wekan.sh
# Step 1: Install dependencies
./rebuild-wekan.sh
# Press 1 and Enter
# Step 2: Build WeKan (after dependencies complete)
./rebuild-wekan.sh
# Press 2 and Enter
# Step 3: Run WeKan in development mode
./rebuild-wekan.sh
# Press 3 and Enter
```
### WSL Users
WSL users can use Snap Candidate. See [install docs](https://wekan.fi/install/).
The development server will start at http://localhost:4000. Any changes you make to the source code will automatically trigger a rebuild and refresh your browser.
## Screenshot
[More screenshots at Features page](https://github.com/wekan/wekan/wiki/Features)
[More screenshots at Features page](https://github.com/wekan/wekan/tree/main/docs/Features)
[![Screenshot of WeKan ®][screenshot_wekan]][roadmap_wekan]
@@ -118,16 +183,12 @@ By working directly with WeKan ® you get the benefit of active maintenance and
WeKan ® is released under the very permissive [MIT license](LICENSE), and made
with [Meteor](https://www.meteor.com).
[platforms]: https://github.com/wekan/wekan/wiki/Platforms
[dev_docs]: https://github.com/wekan/wekan/wiki/Developer-Documentation
[screenshot_wekan]: https://wekan.github.io/wekan-dark-mode.png
[dev_docs]: https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Developer-Documentation.md
[screenshot_wekan]: https://wekan.fi/wekan-dark-mode.png
[features]: https://github.com/wekan/wekan/wiki/Features
[roadmap_wekan]: https://boards.wekan.team/b/D2SzJKZDS4Z48yeQH/wekan-open-source-kanban-board-with-mit-license
[wekan_issues]: https://github.com/wekan/wekan/issues
[wekan_issues]: https://github.com/wekan/wekan/issues
[docker_image]: https://hub.docker.com/r/wekanteam/wekan/
[wekan_wiki]: https://github.com/wekan/wekan/wiki
[translate_wekan]: https://app.transifex.com/wekan/
[translate_wekan]: https://app.transifex.com/wekan/wekan/
[open_source]: https://en.wikipedia.org/wiki/Open-source_software
[free_software]: https://en.wikipedia.org/wiki/Free_software
[discussions]: https://github.com/wekan/wekan/discussions
+113
View File
@@ -0,0 +1,113 @@
# 🔐 WeKan — Login System Overview
This document provides a detailed overview of WeKan’s **login and authentication system**, covering client-side UI, server-side logic, external authentication methods, and potential upgrade paths.
---
## 🖥️ Login Web UI
WeKan's login interface is implemented using a combination of:
- `layouts.jade` – Login HTML structure
- `layouts.js` – Login logic and interactivity
- `layouts.css` – Styling and layout
📁 Source: [`client/components/main`](https://github.com/wekan/wekan/tree/main/client/components/main)
---
## ⚙️ Server-Side Authentication
Server-side login functionality is handled in:
- [`server/authentication.js`](https://github.com/wekan/wekan/blob/main/server/authentication.js)
Other related configurations:
- 🔧 Account config: [`config/accounts.js`](https://github.com/wekan/wekan/blob/main/config/accounts.js)
- 📨 Sign-up invitations: [`models/settings.js#L275`](https://github.com/wekan/wekan/blob/main/models/settings.js#L275)
- 👤 User creation logic: [`models/users.js#L1339`](https://github.com/wekan/wekan/blob/main/models/users.js#L1339)
---
## 👥 Meteor User Accounts
WeKan utilizes Meteor’s `accounts` system. Relevant resources:
- 📚 Meteor 2.x Accounts Docs: [v2-docs.meteor.com/api/accounts](https://v2-docs.meteor.com/api/accounts)
- 🔍 Meteor Packages:
- [`packages`](https://github.com/wekan/wekan/blob/main/.meteor/packages)
- [`versions`](https://github.com/wekan/wekan/blob/main/.meteor/versions)
- 📦 Meteor 2.14 core packages: [Meteor 2.14 packages](https://github.com/meteor/meteor/tree/release/METEOR%402.14/packages)
---
## 🔐 External Authentication (OIDC, LDAP, etc.)
WeKan supports external authentication methods via internal packages.
📁 See [`packages/`](https://github.com/wekan/wekan/tree/main/packages) for:
- OpenID Connect (OIDC)
- LDAP
- OAuth and other integrations
---
## 📦 NPM & AtmosphereJS Dependencies
- 🔗 `package.json`: [Dependencies list](https://github.com/wekan/wekan/blob/main/package.json)
- 🧩 WekanTeam scoped NPM packages: [@wekanteam on npm](https://www.npmjs.com/search?q=%40wekanteam)
- ☁️ AtmosphereJS Meteor packages: [atmospherejs.com](https://atmospherejs.com)
---
## 🚧 Meteor Version & Upgrade Notes
- 📌 Current Version: **Meteor 2.14**
- [`.meteor/release`](https://github.com/wekan/wekan/blob/main/.meteor/release)
- 🔧 Maintained with only **critical fixes** until ~Summer 2025
- 🚀 Migration to **Meteor 3** or a new framework is under consideration
📘 Meteor 3 API: [docs.meteor.com/api/accounts](https://docs.meteor.com/api/accounts)
---
## 🧪 Prototypes & Examples
### 🐘 PHP Prototype Sign-Up
Used in experimental versions:
- Step 1: [`sign-up1.php`](https://github.com/wekan/php/blob/main/page/sign-up1.php)
- Step 2: [`sign-up2.php`](https://github.com/wekan/php/blob/main/page/sign-up2.php)
- Main entry: [`index.php#L72-L83`](https://github.com/wekan/php/blob/main/public/index.php#L72-L83)
---
### 🎨 WeKan Studio Prototype
Sign-up logic in the **WeKan Studio** version:
- [`signUp.fmt`](https://github.com/wekan/wekanstudio/blob/main/srv/templates/login/signUp.fmt)
---
## 📎 Future Considerations
- Upgrading to **Meteor 3.x**
- Refactoring frontend logic to fix translation rendering order
- Exploring **simplified authentication systems** in future prototypes
---
## 🔗 Project Links
- 🔧 Main Repo: [github.com/wekan/wekan](https://github.com/wekan/wekan)
- 🌐 Website: [wekan.github.io](https://wekan.github.io)
- 📚 Documentation: [Wekan Wiki](https://github.com/wekan/wekan/wiki)
---
---
+150 -87
View File
@@ -1,14 +1,34 @@
About money, see [CONTRIBUTING.md](CONTRIBUTING.md)
## About Money: No bounty
Security is very important to us. If you discover any issue regarding security, please disclose
the information responsibly by sending an email to support (at) wekan.team using
[this PGP public key](support-at-wekan.team_pgp-publickey.asc) and not by
creating a GitHub issue. We will respond swiftly to fix verifiable security issues.
There is no bounty, like described at [CONTRIBUTING.md](CONTRIBUTING.md),
because WeKan is NOT Big Tech. WeKan is FLOSS.
We thank you with a place at our hall of fame page, that is
at https://wekan.github.io/hall-of-fame
## Steps for Coordinated Vulnerability Disclosure
## How should reports be formatted?
### 1. Security Researcher:
- **Report**: Click "New draft security advisory" at [WeKan Security Advisories](https://github.com/wekan/wekan/security/advisories).
More info at [GitHub Docs about reporting privately](https://docs.github.com/en/code-security/how-tos/report-and-fix-vulnerabilities/report-privately).
- **Proof of Concept (PoC)**: If possible, include a fix or a reproduction script/code.
- **If GitHub does not work**: Please send report to **security@wekan.fi**
- **Optional Email Encryption**: An optional PGP key is available at [security-at-wekan.fi.asc](security-at-wekan.fi.asc).
### 2. WeKan Security Team:
- **Remediation**: Please wait for a new WeKan release that addresses the issue.
Fixes are announced at the top of the [ChangeLog](https://github.com/wekan/wekan/blob/main/CHANGELOG.md).
- **Recognition**: We will acknowledge your contribution by adding you to our
[Hall of Fame](https://wekan.fi/hall-of-fame/).
- **CVE Policy**: WeKan Security requests CVE at GitHub when releasing Security Advisory.
### 3. Post-Release and Public Disclosure:
- Publicity: If you publish blog posts, give talks, or write articles about the
reported vulnerabilities, please send the links to us. We will link them
to your entry in the [Hall of Fame](https://wekan.fi/hall-of-fame/) for additional context.
- Advisories reported at GitHub are listed at [WeKan Security Advisories](https://github.com/wekan/wekan/security/advisories).
## How Should Reports Be Formatted?
```
Name: %name
@@ -26,35 +46,40 @@ CWSS (optional): %cwss
Anyone who reports a unique security issue in scope and does not disclose it to
a third party before we have patched and updated may be upon their approval
added to the Wekan Hall of Fame.
added to the WeKan Hall of Fame https://wekan.fi/hall-of-fame/
## Which domains are in scope?
No public domains, because all those are donated to Wekan Open Source project,
No public domains, because all those are donated to WeKan Open Source project,
and we don't have any permissions to do security scans on those donated servers.
Please don't perform research that could impact other users. Secondly, please keep
the reports short and succinct. If we fail to understand the logics of your bug, we will tell you.
Please don't perform research that could impact other users. Second, please keep
the reports short and succinct. If we fail to understand the logic of your bug, we will tell you.
You can [Install Wekan](https://github.com/wekan/wekan/releases) to your own computer
You can [Install WeKan](https://wekan.fi/install/) on your own computer
and scan it's vulnerabilities there.
## About Wekan versions
## About WeKan Versions
There are only 2 versions of Wekan: Standalone Wekan, and Sandstorm Wekan.
There are 2 versions of WeKan: Standalone WeKan, and Sandstorm WeKan.
### Standalone Wekan Security
## Meteor Security
Standalone Wekan includes all non-Sandstorm platforms. Some Standalone Wekan platforms
https://guide.meteor.com/security
### Standalone WeKan Security
Standalone WeKan includes all non-Sandstorm platforms. Some Standalone WeKan platforms
like Snap and Docker have their own specific sandboxing etc features.
Standalone Wekan by default does not load any files from Internet, like fonts, CSS, etc.
This also means all Standalone Wekan functionality works in offline local networks.
WeKan is used at most countries of the world https://snapcraft.io/wekan
and by by companies that have 30k users.
Standalone WeKan by default does not load any files from Internet, like fonts, CSS, etc.
This also means all Standalone WeKan functionality works in offline local networks.
WeKan is used in most countries of the world https://snapcraft.io/wekan
and by companies that have 30k users.
- Wekan private board attachments are not accessible without logging in.
- There is feature to set board public, so that board is visible without logging in in readonly mode, with realtime updates.
- WeKan private board attachments are not accessible without logging in.
- There is feature to set board public, so that board is visible without logging
in readonly mode, with realtime updates.
- Admin Panel has feature to disable all public boards, so all boards are private.
## SSL/TLS
@@ -63,32 +88,28 @@ and by by companies that have 30k users.
- If you are thinking about TLS MITM, look at https://github.com/caddyserver/caddy/issues/2530
- Let's Encrypt TLS requires publicly accessible webserver, that Let's Encrypt TLS validation servers check.
- If firewall limits to only allowed IP addresses, you may need non-Let's Encrypt TLS cert.
- For On Premise:
- https://caddyserver.com/docs/automatic-https#local-https
- https://github.com/wekan/wekan/wiki/Caddy-Webserver-Config
- https://github.com/wekan/wekan/wiki/Azure
- https://github.com/wekan/wekan/wiki/Traefik-and-self-signed-SSL-certs
## XSS
- Dompurify https://www.npmjs.com/package/dompurify
- WeKan uses dompurify npm package to filter for XSS at fields like cards, as you can see from
- DOMPurify https://www.npmjs.com/package/dompurify
- WeKan uses DOMPurify npm package to filter for XSS at fields like cards, as you can see from
[package.json](https://github.com/wekan/wekan/blob/main/package.json). Other used versions can be seen from
[Meteor versions file](https://github.com/wekan/wekan/blob/main/.meteor/versions).
- Forms can include markdown links, html, image tags etc like you see at https://wekan.github.io .
- Forms can include markdown links, html, image tags etc like you see at https://wekan.fi .
- It's possible to add attachments to cards, and markdown/html links to files.
- Dompurify cleans up viewed code, so Javascript in input fields does not execute
- https://wekan.github.io/hall-of-fame/fieldbleed/
- DOMPurify cleans up viewed code, so JavaScript in input fields does not execute
- https://wekan.fi/hall-of-fame/fieldbleed/
- Reaction in comment is now checked, that it does not have extra added code
- https://wekan.github.io/hall-of-fame/reactionbleed/
- https://wekan.fi/hall-of-fame/reactionbleed/
- https://github.com/wekan/wekan/blob/main/packages/markdown/src/template-integration.js#L76
## QA about PubSub
## QA About PubSub
Q:
Hello,
I have just seen the Meteor DevTools Evolved extension and was wondering if anyone had asked themselves the question of security.
I have just seen the Meteor DevTools Evolved extension and was wondering if anyone
had asked themselves the question of security.
Insofar as all data is shown in the minimongo tab in plain text.
How can data be hidden from this extension?
@@ -96,32 +117,36 @@ A:
## PubSub
- It is not security issue to show some text or image, that user has permission to see. It is a security issue, if browserside is some text or image that user should not see.
- Meteor has browserside minimongo database, made with Javascript, updated with Publish/Subscribe, PubSub.
- Publish/Subscribe means, that realtime web framework reads database changes stream, and then immediately updates webpage,
like like dashboards, chat, kanban. That is the point in any realtime web framework in any programming language.
- Yes, you should check with Meteor DevTools Evolved Chromium/Firefox extension that at minimongo is only text that user has permission to see.
- Do checking as logged in user, and logged out user.
- It is not a security issue to show text or images that the user has permission to see.
It is a security issue, if browserside is some text or image that user should not see.
- Meteor has browserside minimongo database, made with JavaScript, updated with Publish/Subscribe, PubSub.
- Publish/Subscribe means, that realtime web framework reads database changes stream,
and then immediately updates webpage, like dashboards, chat, kanban.
That is the point of any realtime web framework in any programming language.
- Yes, you should check with Meteor DevTools Evolved Chromium/Firefox extension that
at minimongo is only text that user has permission to see.
- Check as a logged-in user and as a logged-out user.
- Check permissions and sanitize before allowing some change, because someone could modify content of input field,
PubSub/websocket data (for example with Burp Suite Community Edition), etc.
- If you have REST API, also check that only those that have login token, and have permission, can view or edit text
- If you have a REST API, also check that only those who have a login token and permission can view or edit text.
- You should not include any data user is not allowed to see. Not to webpage text, not to websockets/PubSub, etc.
- Minimongo should not have password hashes PubSub https://wekan.github.io/hall-of-fame/userbleed/
- PubSub uses Websockets, so you need those to be enabled at webserver like Caddy/Nginx/Apache etc, examples of settings
- Minimongo should not have password hashes PubSub https://wekan.fi/hall-of-fame/userbleed/
- PubSub uses WebSockets, so you need those to be enabled on the webserver like Caddy/Nginx/Apache etc, examples of settings
at right menu of https://github.com/wekan/wekan/wiki
- Clientside https://github.com/wekan/wekan/tree/main/client/components subscribes to
PubSub https://github.com/wekan/wekan/tree/main/server/publications or calls meteor methods at https://github.com/wekan/wekan/tree/main/models
- Clientside https://github.com/wekan/wekan/tree/main/client/components subscribes to
PubSub https://github.com/wekan/wekan/tree/main/server/publications or calls meteor methods
at https://github.com/wekan/wekan/tree/main/models
- For Admin:
- You can have input field for password https://github.com/wekan/wekan/blob/main/client/components/cards/attachments.js#L303-L312
- You can save password to database https://github.com/wekan/wekan/blob/main/client/components/cards/attachments.js#L303-L312
- Check that only current user or Admin can change password https://github.com/wekan/wekan/blob/main/client/components/cards/attachments.js#L303-L312
- Note that currentUser uses code like Meteor.user() in .js file
- Do not have password hashes in PubSub https://github.com/wekan/wekan/blob/main/server/publications/users.js
- Do not include password hashes in PubSub https://github.com/wekan/wekan/blob/main/server/publications/users.js
- Only show Admin Panel to Admin https://github.com/wekan/wekan/blob/main/client/components/settings/settingBody.jade#L3
- If there is a lot of data, use pagination https://github.com/wekan/wekan/blob/main/client/components/settings/peopleBody.js
- Only have limited amount of data published in PubSub. Limit in MongoDB query in publications how much is published. Too much could make browser too slow.
- Use Environment variables for any email etc passwords.
- But what if you would like to remove minimongo? And only use Meteor methods for saving? In that case, you don't have realtime updates,
- If there is a large amount of data, use pagination https://github.com/wekan/wekan/blob/main/client/components/settings/peopleBody.js
- Only publish a limited amount of data in PubSub. Limit in MongoDB query in publications how much is published. Too much could make browser too slow.
- Environment variables for email and other passwords.
- But what if you would like to remove Minimongo and only use Meteor methods for saving? In that case, you don't have realtime updates,
and you need to write much more code to load and save data yourself, handle any multi user data saving conflicts yourself,
and many Meteor Atmospherejs.com PubSub using packages would not work anymore https://github.com/wekan/we
@@ -129,14 +154,14 @@ A:
- With PubSub, there is checking, that someone modifying Websockets content, like permission isAdmin, can not change to Admin.
- https://github.com/wekan/wekan/commit/cbad4cf5943d47b916f64b4582f8ca76a9dfd743
- https://wekan.github.io/hall-of-fame/adminbleed/
- https://wekan.fi/hall-of-fame/adminbleed/
## Permissions and Roles
- For any user permissions, it's best to use Meteor package package https://github.com/Meteor-Community-Packages/meteor-roles .
- Currently WeKan has custom hardcoded permissions, WeKan does not yet use that meteor-roles package.
- For any user permissions, it's best to use Meteor package https://github.com/Meteor-Community-Packages/meteor-roles .
- Currently, WeKan has custom hardcoded permissions and does not yet use the meteor-roles package.
- Using permissions at WeKan sidebar https://github.com/wekan/wekan/blob/main/client/components/sidebar/sidebar.js#L1854-L1875
- List of roles https://github.com/wekan/wekan/wiki/REST-API-Role . Change at board or Admin Panel. Also Organizations/Teams.
- List of roles: https://github.com/wekan/wekan/wiki/REST-API-Role . Change at board or Admin Panel. Also Organizations/Teams.
- Worker role: https://github.com/wekan/wekan/issues/2788
- Not implemented yet: Granular Roles https://github.com/wekan/wekan/issues/3022
- Check is user logged in, with `if (Meteor.user()) {`
@@ -145,8 +170,8 @@ A:
## Environment variables
- For any passwords, use environment variables, those are serverside
- Do not copy environment variable to public variable that is visible browserside https://github.com/wekan/wekan/blob/main/server/max-size.js
- For any passwords, use environment variables; those are serverside
- Do not copy environment variables to public variables that are visible on the browserside https://github.com/wekan/wekan/blob/main/server/max-size.js
```
Meteor.startup(() => {
@@ -157,42 +182,91 @@ Meteor.startup(() => {
```
- For serverside, you can set Meteor.settings.variablename, without text public
- For WeKan kanban, there is feature for setting board public, it can be viewed by anyone, there is realtime updates. But
- For WeKan kanban, there is a feature for setting a board to public; it can be viewed by anyone, with realtime updates. But
- Some of those permissions are checked at users.js models at https://github.com/wekan/wekan/tree/main/models
- Environment variables are used for email server passwords, etc, at all platforms https://github.com/wekan/wekan/commit/a781c0e7dcfdbe34c1483ee83cec12455b7026f7
## Escape HTML comment tags so that HTML comments are visible
- Someone reported, that it is problem that content of HTML comments in edit mode, are not visible at at view mode, so this makes HTML comments visible.
- Someone reported that it was a problem that the content of HTML comments in edit mode was not visible in view mode, so this change makes HTML comments visible.
- https://github.com/wekan/wekan/commit/167863d95711249e69bb3511175d73b34acbbdb3
- https://wekan.github.io/hall-of-fame/invisiblebleed/
- https://wekan.fi/hall-of-fame/invisiblebleed/
## Attachments: XSS in filename is sanitized
- https://github.com/wekan/wekan/blob/main/client/components/cards/attachments.js#L303-L312
- https://wekan.github.io/hall-of-fame/filebleed/
- https://wekan.fi/hall-of-fame/filebleed/
### Attachments: Forced download to prevent stored XSS
- To prevent browser-side execution of uploaded content under the app origin, all attachment downloads are served with safe headers:
- `Content-Type: application/octet-stream`
- `Content-Disposition: attachment`
- `X-Content-Type-Options: nosniff`
- A restrictive `Content-Security-Policy` with `sandbox`
- This means attachments are downloaded instead of rendered inline by default. This mitigates HTML/JS/SVG based stored XSS vectors.
- Avatars and inline images remain supported but SVG uploads are blocked and never rendered inline.
## Users: Client update restrictions
- Client-side updates to user documents are limited to safe fields only:
- `username`
- `profile.*`
- Sensitive fields are blocked from any client updates and can only be modified by server methods with authorization:
- `orgs`, `teams`, `roles`, `isAdmin`, `createdThroughApi`, `loginDisabled`, `authenticationMethod`, `services.*`, `emails.*`, `sessionData.*`
- Attempts to update forbidden fields from the client are denied.
- Admin operations like managing org/team membership or toggling flags must use server methods that check permissions.
## Voting: integrity and authorization
- Client updates to card `vote` fields are blocked to prevent forged votes and inconsistent policy enforcement.
- Voting is performed via a server method that enforces:
- Authentication and board membership, or an explicit per-card flag allowing non-members to vote.
- Only the caller's own userId is added/removed from `vote.positive`/`vote.negative`.
- This prevents members from fabricating other users' votes and ensures non-members cannot vote unless explicitly allowed.
## Planning Poker: integrity and authorization
- Client updates to card `poker` fields are blocked. All poker actions go through server methods that enforce:
- Authentication and board membership for configuration and results.
- For casting a poker vote, either board membership or an explicit per-card flag allowing non-members to participate.
- Only the caller's own userId is added/removed from the selected estimation bucket (e.g., one, two, five, etc.).
- Methods cover setting/unsetting poker question/end, casting votes, replaying, and setting final estimation.
## Attachment API: authentication and DoS prevention
- The attachment API (`/api/attachment/*`) requires proper authentication using `X-User-Id` and `X-Auth-Token` headers.
- Authentication validates tokens by hashing with `Accounts._hashLoginToken` and matching against stored login tokens, preventing identity spoofing.
- Request handlers implement:
- 30-second timeout to prevent hanging connections.
- Request body size limits (50MB for uploads, 10MB for metadata operations).
- Proper error handling and guaranteed response completion.
- Request error event handlers to clean up failed connections.
- This prevents:
- DoS attacks via concurrent unauthenticated or malformed requests.
- Identity spoofing by using arbitrary bearer tokens or user IDs.
- Resource exhaustion from hanging connections or excessive payloads.
- Access control: all attachment operations verify board membership before allowing access.
## Brute force login protection
- https://github.com/wekan/wekan/commit/23e5e1e3bd081699ce39ce5887db7e612616014d
- https://github.com/wekan/wekan/tree/main/packages/wekan-accounts-lockout
### Sandstorm Wekan Security
### Sandstorm WeKan Security
On Sandstorm platform using environment variable Standalone Wekan features like Admin Panel etc are
turned off, because Sandstorm platform provides SSO for all apps running on Sandstorm.
On the Sandstorm platform, Standalone WeKan features like the Admin Panel are turned off using environment variables, because Sandstorm platform provides SSO for all apps running on Sandstorm.
[Sandstorm](https://sandstorm.io) is separate Open Source platform that has been
[Sandstorm](https://sandstorm.io) is a separate Open Source platform that has been
[security audited](https://sandstorm.io/news/2017-03-02-security-review) and found bugs fixed.
Sandstorm also has passwordless login, LDAP, SAML, Google etc auth options already.
At Sandstorm code is read-only and signed by app maintainers, only grain content can be modified.
Wekan at Sandstorm runs in sandboxed grain, it does not have access elsewhere without user-visible
PowerBox request or opening randomly-generated API key URL.
Sandstorm also has passwordless login, LDAP, SAML, Google, and other auth options already.
On Sandstorm, code is read-only and signed by app maintainers; only grain content can be modified.
WeKan on Sandstorm runs in a sandboxed grain; it does not have access elsewhere without a user-visible PowerBox request or opening a randomly-generated API key URL.
Also read [Sandstorm Security Practices](https://docs.sandstorm.io/en/latest/using/security-practices/) and
[Sandstorm Security non-events](https://docs.sandstorm.io/en/latest/using/security-non-events/).
For Sandstorm specific security issues you can contact [kentonv](https://github.com/kentonv) by email.
For Sandstorm specific security issues you can contact [kentonv](https://github.com/kentonv) by email.
## What Wekan bugs are eligible?
## What WeKan bugs are eligible?
Any typical web security bugs. If any of the previously mentioned is somehow problematic and
a security issue, we'd like to know about it, and also how to fix it:
@@ -204,23 +278,12 @@ a security issue, we'd like to know about it, and also how to fix it:
- Authentication bypass
- Server-side code execution
## What Wekan bugs are NOT eligible?
## What WeKan bugs are NOT eligible?
Typical already known or "no impact" bugs such as:
Typical already-known or 'no impact' bugs such as:
- [Wekan API old tokens not replaced correctly](https://github.com/wekan/wekan/issues/1437)
- Missing Cookie flags on non-session cookies or 3rd party cookies
- Logout CSRF
- Social engineering
- Denial of service
- SSL BEAST/CRIME/etc. Wekan does not have SSL built-in, it uses Caddy/Nginx/Apache etc at front.
Integrated Caddy support is updated often.
- Email spoofing, SPF, DMARC & DKIM. Wekan does not include email server.
- SSL BEAST/CRIME/etc. WeKan does not have SSL built-in; it uses Caddy/Nginx/Apache on the front end.
Wekan is Open Source with MIT license, and free to use also for commercial use.
We welcome all fixes to improve security by email to security (at) wekan.team .
## Bonus Points
If your Responsible Security Disclosure includes code for fixing security issue,
you get bonus points, as seen on [Hall of Fame](https://wekan.github.io/hall-of-fame).
WeKan is Open Source with MIT license, and free to use also for commercial use.
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v7.35.0"
appVersion: "v9.42.0"
files:
userUploads:
- README.md
+859 -23
View File
@@ -25,33 +25,99 @@ syntax = """=== Wekan API Python CLI: Shows IDs for addcard ===
# AUTHORID is USERID that writes card or custom field.
If *nix: chmod +x api.py => ./api.py users
Syntax:
User API:
User API:
python3 api.py user # Current user and list of current user boards
python3 api.py users # All users
python3 api.py boards # All Public Boards
python3 api.py boards USERID # Boards of USERID
python3 api.py board BOARDID # Info of BOARDID
Board/List/Card API:
python3 api.py swimlanes BOARDID # Swimlanes of BOARDID
python3 api.py lists BOARDID # Lists of BOARDID
python3 api.py list BOARDID LISTID # Info of LISTID
python3 api.py createlist BOARDID LISTTITLE # Create list
python3 api.py addcard AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION
python3 api.py editcard BOARDID LISTID CARDID NEWCARDTITLE NEWCARDDESCRIPTION
python3 api.py getcard BOARDID LISTID CARDID # Get card info
python3 api.py cardsbyswimlane BOARDID SWIMLANEID # Retrieve cards list on a swimlane
python3 api.py deleteallcards BOARDID SWIMLANEID ( * Be careful will delete ALL CARDS INSIDE the swimlanes automatically in every list * ) # Delete all cards on a swimlane
python3 api.py get_list_cards_count BOARDID LISTID # Retrieve how many cards in a list
python3 api.py get_board_cards_count BOARDID # Retrieve how many cards in a board
python3 api.py editboardtitle BOARDID NEWBOARDTITLE # Edit board title
python3 api.py copyboard BOARDID NEWBOARDTITLE # Copy a board
Custom Fields / Labels API:
python3 api.py customfields BOARDID # Custom Fields of BOARDID
python3 api.py customfield BOARDID CUSTOMFIELDID # Info of CUSTOMFIELDID
python3 api.py addcustomfieldtoboard AUTHORID BOARDID NAME TYPE SETTINGS SHOWONCARD AUTOMATICALLYONCARD SHOWLABELONMINICARD SHOWSUMATTOPOFLIST # Add Custom Field to Board
python3 api.py editcustomfield BOARDID LISTID CARDID CUSTOMFIELDID NEWCUSTOMFIELDVALUE
python3 api.py editcustomfield BOARDID LISTID CARDID CUSTOMFIELDID NEWCUSTOMFIELDVALUE # Edit Custom Field
python3 api.py createlabel BOARDID LABELCOLOR LABELNAME (Color available: `white`, `green`, `yellow`, `orange`, `red`, `purple`, `blue`, `sky`, `lime`, `pink`, `black`, `silver`, `peachpuff`, `crimson`, `plum`, `darkgreen`, `slateblue`, `magenta`, `gold`, `navy`, `gray`, `saddlebrown`, `paleturquoise`, `mistyrose`, `indigo`) # Create a new label
python3 api.py addlabel BOARDID LISTID CARDID LABELID # Add label to a card
python3 api.py addcardwithlabel AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION LABELIDS # Add a card and a label
python3 api.py editcardcolor BOARDID LISTID CARDID COLOR (Color available: `white`, `green`, `yellow`, `orange`, `red`, `purple`, `blue`, `sky`, `lime`, `pink`, `black`, `silver`, `peachpuff`, `crimson`, `plum`, `darkgreen`, `slateblue`, `magenta`, `gold`, `navy`, `gray`, `saddlebrown`, `paleturquoise`, `mistyrose`, `indigo`) # Edit card color
Checklist API:
python3 api.py addchecklist BOARDID CARDID TITLE ITEM1 ITEM2 ITEM3 ITEM4 (You can add multiple items or just one, or also without any item, just TITLE works as well. * If items or Title contains spaces, you should add ' between them.) # Add checklist + item on a card
python3 api.py checklistid BOARDID CARDID # Retrieve Checklist ID attached to a card
python3 api.py checklistinfo BOARDID CARDID CHECKLISTID # Get checklist info
Attachment API:
python3 api.py listattachments BOARDID # List attachments
python3 api.py cardsbyswimlane SWIMLANEID LISTID
python3 api.py getcard BOARDID LISTID CARDID
python3 api.py addlabel BOARDID LISTID CARDID LABELID
python3 api.py addcardwithlabel AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION LABELIDS
python3 api.py editboardtitle BOARDID NEWBOARDTITLE
python3 api.py createlabel BOARDID LABELCOLOR LABELNAME (Color available: `white`, `green`, `yellow`, `orange`, `red`, `purple`, `blue`, `sky`, `lime`, `pink`, `black`, `silver`, `peachpuff`, `crimson`, `plum`, `darkgreen`, `slateblue`, `magenta`, `gold`, `navy`, `gray`, `saddlebrown`, `paleturquoise`, `mistyrose`, `indigo`)
python3 api.py editcardcolor BOARDID LISTID CARDID COLOR (Color available: `white`, `green`, `yellow`, `orange`, `red`, `purple`, `blue`, `sky`, `lime`, `pink`, `black`, `silver`, `peachpuff`, `crimson`, `plum`, `darkgreen`, `slateblue`, `magenta`, `gold`, `navy`, `gray`, `saddlebrown`, `paleturquoise`, `mistyrose`, `indigo`)
python3 api.py addchecklist BOARDID CARDID TITLE ITEM1 ITEM2 ITEM3 ITEM4 (You can add multiple items or just one, or also without any item, just TITLE works as well. * If items or Title contains spaces, you should add ' between them.)
python3 api.py deleteallcards BOARDID SWIMLANEID ( * Be careful will delete ALL CARDS INSIDE the swimlanes automatically in every list * )
python3 api.py uploadattachment BOARDID SWIMLANEID LISTID CARDID FILEPATH [STORAGE_BACKEND] # Upload attachment to card
python3 api.py downloadattachment ATTACHMENTID OUTPUTPATH # Download attachment to local file
python3 api.py attachmentinfo ATTACHMENTID # Get attachment information
python3 api.py listcardattachments BOARDID SWIMLANEID LISTID CARDID # List attachments for specific card
python3 api.py copymoveattachment ATTACHMENTID TARGETBOARDID TARGETSWIMLANEID TARGETLISTID TARGETCARDID [copy|move] # Copy or move attachment
python3 api.py deleteattachment ATTACHMENTID # Delete attachment
Board Member API (Issue #5998):
python3 api.py addboardmember BOARDID USERID ROLE # Add/activate board member. ROLE: admin, normal, comment, readonly, worker, normalassignedonly, commentassignedonly, readassignedonly, nocomments
python3 api.py removeboardmember BOARDID USERID # Remove (deactivate) board member
python3 api.py setboardmemberrole BOARDID USERID ROLE # Change permission/role of existing board member
Card Member / Assignee API (board member -> card member/assignee):
python3 api.py setcardmembers BOARDID LISTID CARDID MEMBERIDS # Set card members. MEMBERIDS = comma-separated userIds, or '' to clear
python3 api.py setcardassignees BOARDID LISTID CARDID ASSIGNEEIDS # Set card assignees. ASSIGNEEIDS = comma-separated userIds, or '' to clear
Card Dates API (Issue #5846):
python3 api.py setcarddate BOARDID LISTID CARDID DATETYPE [DATEVALUE] # DATETYPE: received, start, due, end. DATEVALUE: ISO 8601, e.g. 2026-06-07T12:00:00.000Z. Omit DATEVALUE (or pass '') to clear the date.
Card Labels API (Issue #5819):
python3 api.py setcardlabels BOARDID LISTID CARDID LABELIDS # Set (replace) card labels. LABELIDS = comma-separated labelIds, or '' to clear
Card Copy/Move API:
python3 api.py movecard BOARDID LISTID CARDID NEWBOARDID NEWSWIMLANEID NEWLISTID # Move card to another board/swimlane/list
Bulk Card API (Issue #4743, #5819):
python3 api.py bulkaddcards BOARDID LISTID AUTHORID SWIMLANEID CARDSJSONFILE # Create many cards in one request. CARDSJSONFILE = JSON file with a list of titles, or a list of card objects {title,description,members,assignees,...}
python3 api.py bulkdeletecards BOARDID CARDIDS # Delete many cards in one request. CARDIDS = comma-separated cardIds
python3 api.py bulkcardlabels BOARDID CARDIDS ADDLABELIDS REMOVELABELIDS # Merge-add/remove labels across many cards. CARDIDS/ADDLABELIDS/REMOVELABELIDS = comma-separated, or '' for none
Linked Card API (Issue #5897):
python3 api.py linkcard BOARDID LISTID SWIMLANEID AUTHORID LINKEDCARDID # Create a linked card in BOARDID/LISTID that references LINKEDCARDID (may be on another board)
Card Member/Assignee Merge API (Issue #5998):
python3 api.py addcardmember BOARDID LISTID CARDID MEMBERID # Add one board member to a card (validated)
python3 api.py removecardmember BOARDID LISTID CARDID MEMBERID # Remove one member from a card
python3 api.py addcardassignee BOARDID LISTID CARDID ASSIGNEEID # Add one assignee to a card (validated)
python3 api.py removecardassignee BOARDID LISTID CARDID ASSIGNEEID # Remove one assignee from a card
Copy/Move Swimlane/List/Card API (position = 0-based index from top-left):
python3 api.py copycard BOARDID LISTID CARDID TOSWIMLANEID [TOBOARDID] [TOLISTID] [POSITION] # Copy a card (deep copy)
python3 api.py copyswimlane BOARDID SWIMLANEID [TOBOARDID] [POSITION] # Copy a swimlane (deep copy)
python3 api.py moveswimlane BOARDID SWIMLANEID [TOBOARDID] [POSITION] # Move a swimlane
python3 api.py copylist BOARDID LISTID TOSWIMLANEID [TOBOARDID] [POSITION] # Copy a list (deep copy)
python3 api.py movelist BOARDID LISTID [TOSWIMLANEID] [TOBOARDID] [POSITION] # Move a list
My Cards / Due Cards API (Issue #4815):
python3 api.py mycards [due] [FROM] [TO] # Current user's cards. 'due' = only cards with a due date; FROM/TO = ISO 8601 due-date range
Card Settings API (Issue #3062):
python3 api.py getcardsettings BOARDID # Get board-level card settings (allows* toggles)
python3 api.py setcardsetting BOARDID KEY VALUE # Set one board card setting, e.g. allowsDueDate true
Admin API:
python3 api.py users # All users
python3 api.py boards # All Public Boards
python3 api.py newuser USERNAME EMAIL PASSWORD
"""
@@ -422,7 +488,7 @@ if arguments >= 4:
print(f"Checklist '{checklist_title}' created. ID: {checklist_id}")
# Aggiungi gli items alla checklist
items_to_add = sys.argv[5:] # Gli argomenti successivi sono considerati come titoli degli items
items_to_add = sys.argv[5:]
for item_title in items_to_add:
checklist_item_url = wekanurl + apiboards + board_id + s + cs + s + card_id + s + 'checklists' + s + checklist_id + '/items'
item_data = {'title': item_title}
@@ -435,6 +501,22 @@ if arguments >= 4:
print(f"Item '{item_title}' added. ID: {checklist_item_id}")
if sys.argv[1] == 'checklistinfo':
# ------- ADD CHECKLIST START -----------
board_id = sys.argv[2]
card_id = sys.argv[3]
checklist_id = sys.argv[4]
checklist_url = wekanurl + apiboards + board_id + s + cs + s + card_id + '/checklists' + s + checklist_id
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
response = requests.get(checklist_url, headers=headers)
response.raise_for_status()
checklist_info = response.json()
print("Checklist Info:")
print(checklist_info)
if arguments == 3:
if sys.argv[1] == 'editboardtitle':
@@ -460,7 +542,31 @@ if arguments == 3:
print(body.text)
# ------- EDIT BOARD TITLE END -----------
if sys.argv[1] == 'copyboard':
# ------- COPY BOARD START -----------
boardid = sys.argv[2]
boardtitle = sys.argv[3]
edboardcopy = wekanurl + apiboards + boardid + s + 'copy'
print(edboardcopy)
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
post_data = {'title': boardtitle}
body = requests.post(edboardcopy, json=post_data, headers=headers)
print("=== COPY BOARD ===\n")
#body = requests.get(edboardcopy, headers=headers)
data2 = body.text.replace('}',"}\n")
print(data2)
if body.status_code == 200:
print("Succesfull!")
else:
print(f"Error: {body.status_code}")
print(body.text)
# ------- COPY BOARD END -----------
if sys.argv[1] == 'createlist':
# ------- CREATE LIST START -----------
@@ -536,9 +642,12 @@ if arguments == 3:
delete_card_url = wekanurl + apiboards + boardid + s + "lists" + s + card['listId'] + s + "cards" + s + card['_id']
try:
response = requests.delete(delete_card_url, headers=headers)
response.raise_for_status()
deleted_card_data = response.json()
print(f"Card Deleted Successfully. Card ID: {deleted_card_data['_id']}")
if response.status_code == 404:
print(f"Card not found: {card['_id']}")
else:
response.raise_for_status()
deleted_card_data = response.json()
print(f"Card Deleted Successfully. Card ID: {deleted_card_data['_id']}")
except requests.exceptions.RequestException as e:
print(f"Error deleting card: {e}")
# ------- DELETE CARD END -----------
@@ -548,6 +657,39 @@ if arguments == 3:
sys.exit(1)
# ------- GET SWIMLANE CARDS END -----------
if sys.argv[1] == 'get_list_cards_count':
# ------- GET LIST CARDS COUNT START -----------
boardid = sys.argv[2]
listid = sys.argv[3]
get_list_cards_count_url = wekanurl + apiboards + boardid + s + l + s + listid + s + "cards_count"
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
try:
response = requests.get(get_list_cards_count_url, headers=headers)
response.raise_for_status()
data = response.json()
print(f"List Cards Count: {data['list_cards_count']}")
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
# ------- GET LIST CARDS COUNT END -----------
if sys.argv[1] == 'checklistid':
# ------- ADD CHECKLIST START -----------
board_id = sys.argv[2]
card_id = sys.argv[3]
checklist_url = wekanurl + apiboards + board_id + s + cs + s + card_id + '/checklists'
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
response = requests.get(checklist_url, headers=headers)
response.raise_for_status()
checklists = response.json()
print("Checklists:")
for checklist in checklists:
print(checklist)
if arguments == 2:
# ------- BOARDS LIST START -----------
@@ -619,9 +761,25 @@ if arguments == 2:
print(data2)
# ------- LISTS OF ATTACHMENTS END -----------
if arguments == 1:
if sys.argv[1] == 'get_board_cards_count':
# ------- GET BOARD CARDS COUNT START -----------
boardid = sys.argv[2]
if sys.argv[1] == 'users':
get_board_cards_count_url = wekanurl + apiboards + boardid + s + "cards_count"
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
try:
response = requests.get(get_board_cards_count_url, headers=headers)
response.raise_for_status()
data = response.json()
print(f"Board Cards Count: {data['board_cards_count']}")
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
# ------- GET BOARD CARDS COUNT END -----------
if arguments >= 1:
if arguments == 1 and sys.argv[1] == 'users':
# ------- LIST OF USERS START -----------
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
@@ -632,7 +790,7 @@ if arguments == 1:
print(data2)
# ------- LIST OF USERS END -----------
if sys.argv[1] == 'user':
if arguments == 1 and sys.argv[1] == 'user':
# ------- LIST OF ALL USERS START -----------
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
print(user)
@@ -642,7 +800,7 @@ if arguments == 1:
print(data2)
# ------- LIST OF ALL USERS END -----------
if sys.argv[1] == 'boards':
if arguments == 1 and sys.argv[1] == 'boards':
# ------- LIST OF PUBLIC BOARDS START -----------
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
@@ -652,3 +810,681 @@ if arguments == 1:
data2 = body.text.replace('}',"}\n")
print(data2)
# ------- LIST OF PUBLIC BOARDS END -----------
# ------- NEW ATTACHMENT API ENDPOINTS START -----------
if sys.argv[1] == 'uploadattachment':
# ------- UPLOAD ATTACHMENT START -----------
if arguments < 6:
print("Usage: python3 api.py uploadattachment BOARDID SWIMLANEID LISTID CARDID FILEPATH [STORAGE_BACKEND]")
print("Storage backends: fs, gridfs, s3")
exit(1)
boardid = sys.argv[2]
swimlaneid = sys.argv[3]
listid = sys.argv[4]
cardid = sys.argv[5]
filepath = sys.argv[6]
storage_backend = sys.argv[7] if arguments > 6 else None
# Read file and convert to base64
try:
with open(filepath, 'rb') as f:
file_data = f.read()
import base64
base64_data = base64.b64encode(file_data).decode('utf-8')
except FileNotFoundError:
print(f"Error: File '{filepath}' not found")
exit(1)
except Exception as e:
print(f"Error reading file: {e}")
exit(1)
# Get file info
import os
filename = os.path.basename(filepath)
import mimetypes
file_type = mimetypes.guess_type(filepath)[0] or 'application/octet-stream'
# Prepare request data
upload_data = {
'boardId': boardid,
'swimlaneId': swimlaneid,
'listId': listid,
'cardId': cardid,
'fileData': base64_data,
'fileName': filename,
'fileType': file_type
}
if storage_backend:
upload_data['storageBackend'] = storage_backend
# Make API call
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
upload_url = wekanurl + 'api/attachment/upload'
try:
response = requests.post(upload_url, headers=headers, json=upload_data)
response.raise_for_status()
result = response.json()
print(f"Upload successful!")
print(f"Attachment ID: {result.get('attachmentId')}")
print(f"File: {result.get('fileName')}")
print(f"Size: {result.get('fileSize')} bytes")
print(f"Storage: {result.get('storageBackend')}")
except requests.exceptions.RequestException as e:
print(f"Upload failed: {e}")
if hasattr(e, 'response') and e.response is not None:
print(f"Response: {e.response.text}")
# ------- UPLOAD ATTACHMENT END -----------
if sys.argv[1] == 'downloadattachment':
# ------- DOWNLOAD ATTACHMENT START -----------
if arguments < 3:
print("Usage: python3 api.py downloadattachment ATTACHMENTID OUTPUTPATH")
exit(1)
attachmentid = sys.argv[2]
outputpath = sys.argv[3]
# Make API call
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
download_url = wekanurl + f'api/attachment/download/{attachmentid}'
try:
response = requests.get(download_url, headers=headers)
response.raise_for_status()
result = response.json()
if result.get('success'):
# Decode base64 data and save to file
import base64
file_data = base64.b64decode(result.get('base64Data'))
with open(outputpath, 'wb') as f:
f.write(file_data)
print(f"Download successful!")
print(f"File saved to: {outputpath}")
print(f"Original filename: {result.get('fileName')}")
print(f"Size: {result.get('fileSize')} bytes")
print(f"Storage: {result.get('storageBackend')}")
else:
print(f"Download failed: {result.get('message', 'Unknown error')}")
except requests.exceptions.RequestException as e:
print(f"Download failed: {e}")
if hasattr(e, 'response') and e.response is not None:
print(f"Response: {e.response.text}")
# ------- DOWNLOAD ATTACHMENT END -----------
if sys.argv[1] == 'attachmentinfo':
# ------- ATTACHMENT INFO START -----------
if arguments < 2:
print("Usage: python3 api.py attachmentinfo ATTACHMENTID")
exit(1)
attachmentid = sys.argv[2]
# Make API call
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
info_url = wekanurl + f'api/attachment/info/{attachmentid}'
try:
response = requests.get(info_url, headers=headers)
response.raise_for_status()
result = response.json()
if result.get('success'):
print("=== ATTACHMENT INFO ===")
print(f"Attachment ID: {result.get('attachmentId')}")
print(f"File Name: {result.get('fileName')}")
print(f"File Size: {result.get('fileSize')} bytes")
print(f"File Type: {result.get('fileType')}")
print(f"Storage Backend: {result.get('storageBackend')}")
print(f"Board ID: {result.get('boardId')}")
print(f"Swimlane ID: {result.get('swimlaneId')}")
print(f"List ID: {result.get('listId')}")
print(f"Card ID: {result.get('cardId')}")
print(f"Created At: {result.get('createdAt')}")
print(f"Is Image: {result.get('isImage')}")
print(f"Versions: {len(result.get('versions', []))}")
else:
print(f"Failed to get attachment info: {result.get('message', 'Unknown error')}")
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
if hasattr(e, 'response') and e.response is not None:
print(f"Response: {e.response.text}")
# ------- ATTACHMENT INFO END -----------
if sys.argv[1] == 'listcardattachments':
# ------- LIST CARD ATTACHMENTS START -----------
if arguments < 5:
print("Usage: python3 api.py listcardattachments BOARDID SWIMLANEID LISTID CARDID")
exit(1)
boardid = sys.argv[2]
swimlaneid = sys.argv[3]
listid = sys.argv[4]
cardid = sys.argv[5]
# Make API call
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
list_url = wekanurl + f'api/attachment/list/{boardid}/{swimlaneid}/{listid}/{cardid}'
try:
response = requests.get(list_url, headers=headers)
response.raise_for_status()
result = response.json()
if result.get('success'):
attachments = result.get('attachments', [])
print(f"=== CARD ATTACHMENTS ({len(attachments)}) ===")
for attachment in attachments:
print(f"ID: {attachment.get('attachmentId')}")
print(f"Name: {attachment.get('fileName')}")
print(f"Size: {attachment.get('fileSize')} bytes")
print(f"Type: {attachment.get('fileType')}")
print(f"Storage: {attachment.get('storageBackend')}")
print(f"Created: {attachment.get('createdAt')}")
print("---")
else:
print(f"Failed to list attachments: {result.get('message', 'Unknown error')}")
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
if hasattr(e, 'response') and e.response is not None:
print(f"Response: {e.response.text}")
# ------- LIST CARD ATTACHMENTS END -----------
if sys.argv[1] == 'copymoveattachment':
# ------- COPY/MOVE ATTACHMENT START -----------
if arguments < 6:
print("Usage: python3 api.py copymoveattachment ATTACHMENTID TARGETBOARDID TARGETSWIMLANEID TARGETLISTID TARGETCARDID [copy|move]")
exit(1)
attachmentid = sys.argv[2]
targetboardid = sys.argv[3]
targetswimlaneid = sys.argv[4]
targetlistid = sys.argv[5]
targetcardid = sys.argv[6]
operation = sys.argv[7] if arguments > 6 else 'copy'
if operation not in ['copy', 'move']:
print("Operation must be 'copy' or 'move'")
exit(1)
# Prepare request data
request_data = {
'attachmentId': attachmentid,
'targetBoardId': targetboardid,
'targetSwimlaneId': targetswimlaneid,
'targetListId': targetlistid,
'targetCardId': targetcardid
}
# Make API call
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
api_url = wekanurl + f'api/attachment/{operation}'
try:
response = requests.post(api_url, headers=headers, json=request_data)
response.raise_for_status()
result = response.json()
if result.get('success'):
print(f"{operation.capitalize()} successful!")
if operation == 'copy':
print(f"Source Attachment ID: {result.get('sourceAttachmentId')}")
print(f"New Attachment ID: {result.get('newAttachmentId')}")
else:
print(f"Attachment ID: {result.get('attachmentId')}")
print(f"Source Board: {result.get('sourceBoardId')}")
print(f"Target Board: {result.get('targetBoardId')}")
print(f"File: {result.get('fileName')}")
print(f"Size: {result.get('fileSize')} bytes")
else:
print(f"{operation.capitalize()} failed: {result.get('message', 'Unknown error')}")
except requests.exceptions.RequestException as e:
print(f"{operation.capitalize()} failed: {e}")
if hasattr(e, 'response') and e.response is not None:
print(f"Response: {e.response.text}")
# ------- COPY/MOVE ATTACHMENT END -----------
if sys.argv[1] == 'deleteattachment':
# ------- DELETE ATTACHMENT START -----------
if arguments < 2:
print("Usage: python3 api.py deleteattachment ATTACHMENTID")
exit(1)
attachmentid = sys.argv[2]
# Make API call
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
delete_url = wekanurl + f'api/attachment/delete/{attachmentid}'
try:
response = requests.delete(delete_url, headers=headers)
response.raise_for_status()
result = response.json()
if result.get('success'):
print("Delete successful!")
print(f"Attachment ID: {result.get('attachmentId')}")
print(f"File: {result.get('fileName')}")
else:
print(f"Delete failed: {result.get('message', 'Unknown error')}")
except requests.exceptions.RequestException as e:
print(f"Delete failed: {e}")
if hasattr(e, 'response') and e.response is not None:
print(f"Response: {e.response.text}")
# ------- DELETE ATTACHMENT END -----------
# ------- NEW ATTACHMENT API ENDPOINTS END -----------
# ------- BOARD MEMBER / CARD FIELD API ENDPOINTS START -----------
# These commands wrap REST endpoints that already exist in Wekan.
# See CHANGELOG.md "Upcoming" section for related issues and design notes.
# Map a human readable ROLE to the board member permission boolean flags
# used by /api/boards/:boardId/members/:userId/add and .../members/:memberId
def board_role_flags(role):
flags = {
'isAdmin': 'false',
'isNoComments': 'false',
'isCommentOnly': 'false',
'isWorker': 'false',
'isNormalAssignedOnly': 'false',
'isCommentAssignedOnly': 'false',
'isReadOnly': 'false',
'isReadAssignedOnly': 'false',
}
role = (role or 'normal').lower()
rolemap = {
'admin': 'isAdmin',
'nocomments': 'isNoComments',
'comment': 'isCommentOnly',
'commentonly': 'isCommentOnly',
'worker': 'isWorker',
'normalassignedonly': 'isNormalAssignedOnly',
'commentassignedonly': 'isCommentAssignedOnly',
'readonly': 'isReadOnly',
'readassignedonly': 'isReadAssignedOnly',
}
if role in ('normal', 'member'):
return flags # all false == Normal board member
if role in rolemap:
flags[rolemap[role]] = 'true'
return flags
print("Invalid ROLE. Valid: admin, normal, comment, readonly, worker, "
"normalassignedonly, commentassignedonly, readassignedonly, nocomments")
sys.exit(1)
if sys.argv[1] == 'addboardmember':
# ------- ADD BOARD MEMBER START -----------
if arguments < 3:
print("Usage: python3 api.py addboardmember BOARDID USERID ROLE")
exit(1)
boardid = sys.argv[2]
userid = sys.argv[3]
role = sys.argv[4] if arguments > 3 else 'normal'
add_member_url = wekanurl + apiboards + boardid + s + 'members' + s + userid + s + 'add'
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
post_data = {'action': 'add'}
post_data.update(board_role_flags(role))
body = requests.post(add_member_url, data=post_data, headers=headers)
print("=== ADD BOARD MEMBER ===\n")
print(body.text)
# ------- ADD BOARD MEMBER END -----------
if sys.argv[1] == 'removeboardmember':
# ------- REMOVE BOARD MEMBER START -----------
if arguments < 3:
print("Usage: python3 api.py removeboardmember BOARDID USERID")
exit(1)
boardid = sys.argv[2]
userid = sys.argv[3]
remove_member_url = wekanurl + apiboards + boardid + s + 'members' + s + userid + s + 'remove'
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
post_data = {'action': 'remove'}
body = requests.post(remove_member_url, data=post_data, headers=headers)
print("=== REMOVE BOARD MEMBER ===\n")
print(body.text)
# ------- REMOVE BOARD MEMBER END -----------
if sys.argv[1] == 'setboardmemberrole':
# ------- SET BOARD MEMBER ROLE START -----------
if arguments < 4:
print("Usage: python3 api.py setboardmemberrole BOARDID USERID ROLE")
exit(1)
boardid = sys.argv[2]
userid = sys.argv[3]
role = sys.argv[4]
set_role_url = wekanurl + apiboards + boardid + s + 'members' + s + userid
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
post_data = board_role_flags(role)
body = requests.post(set_role_url, data=post_data, headers=headers)
print("=== SET BOARD MEMBER ROLE ===\n")
print(body.text)
# ------- SET BOARD MEMBER ROLE END -----------
if sys.argv[1] in ('setcardmembers', 'setcardassignees'):
# ------- SET CARD MEMBERS / ASSIGNEES START -----------
if arguments < 4:
print("Usage: python3 api.py {} BOARDID LISTID CARDID IDS".format(sys.argv[1]))
print("IDS = comma-separated userIds, or '' to clear")
exit(1)
boardid = sys.argv[2]
listid = sys.argv[3]
cardid = sys.argv[4]
ids_raw = sys.argv[5] if arguments > 4 else ''
ids = [x for x in ids_raw.split(',') if x] if ids_raw else []
field = 'members' if sys.argv[1] == 'setcardmembers' else 'assignees'
edcard = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
# Empty array clears the field; send as JSON so the array type is preserved.
put_data = {field: ids if ids else []}
body = requests.put(edcard, json=put_data, headers=headers)
print("=== SET CARD {} ===\n".format(field.upper()))
print(body.text)
# ------- SET CARD MEMBERS / ASSIGNEES END -----------
if sys.argv[1] == 'setcarddate':
# ------- SET CARD DATE START -----------
if arguments < 5:
print("Usage: python3 api.py setcarddate BOARDID LISTID CARDID DATETYPE DATEVALUE")
print("DATETYPE: received, start, due, end")
print("DATEVALUE: ISO 8601, e.g. 2026-06-07T12:00:00.000Z")
exit(1)
boardid = sys.argv[2]
listid = sys.argv[3]
cardid = sys.argv[4]
datetype = sys.argv[5].lower()
datevalue = sys.argv[6] if arguments > 5 else ''
datemap = {
'received': 'receivedAt',
'start': 'startAt',
'due': 'dueAt',
'end': 'endAt',
}
if datetype not in datemap:
print("Invalid DATETYPE. Valid: received, start, due, end")
sys.exit(1)
edcard = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
put_data = {datemap[datetype]: datevalue}
body = requests.put(edcard, data=put_data, headers=headers)
print("=== SET CARD DATE {} ===\n".format(datetype.upper()))
print(body.text)
# ------- SET CARD DATE END -----------
if sys.argv[1] == 'setcardlabels':
# ------- SET CARD LABELS START -----------
if arguments < 4:
print("Usage: python3 api.py setcardlabels BOARDID LISTID CARDID LABELIDS")
print("LABELIDS = comma-separated labelIds, or '' to clear")
exit(1)
boardid = sys.argv[2]
listid = sys.argv[3]
cardid = sys.argv[4]
labelids_raw = sys.argv[5] if arguments > 4 else ''
labelids = [x for x in labelids_raw.split(',') if x] if labelids_raw else []
edcard = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
# NOTE: this REPLACES the card's labels. Bulk add/remove (merge) is not yet
# implemented server-side, see Issue #5819 in CHANGELOG.md "Upcoming".
put_data = {'labelIds': labelids if labelids else []}
body = requests.put(edcard, json=put_data, headers=headers)
print("=== SET CARD LABELS ===\n")
print(body.text)
# ------- SET CARD LABELS END -----------
if sys.argv[1] == 'movecard':
# ------- MOVE CARD START -----------
if arguments < 7:
print("Usage: python3 api.py movecard BOARDID LISTID CARDID NEWBOARDID NEWSWIMLANEID NEWLISTID")
exit(1)
boardid = sys.argv[2]
listid = sys.argv[3]
cardid = sys.argv[4]
newboardid = sys.argv[5]
newswimlaneid = sys.argv[6]
newlistid = sys.argv[7]
edcard = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
put_data = {
'newBoardId': newboardid,
'newSwimlaneId': newswimlaneid,
'newListId': newlistid,
}
body = requests.put(edcard, data=put_data, headers=headers)
print("=== MOVE CARD ===\n")
print(body.text)
# ------- MOVE CARD END -----------
if sys.argv[1] == 'bulkaddcards':
# ------- BULK ADD CARDS START -----------
if arguments < 5:
print("Usage: python3 api.py bulkaddcards BOARDID LISTID AUTHORID SWIMLANEID CARDSJSONFILE")
print("CARDSJSONFILE = JSON file with a list of titles, e.g. [\"Card A\", \"Card B\"],")
print(" or a list of card objects [{\"title\": \"Card A\", \"description\": \"...\"}, ...]")
exit(1)
boardid = sys.argv[2]
listid = sys.argv[3]
authorid = sys.argv[4]
swimlaneid = sys.argv[5]
cardsjsonfile = sys.argv[6] if arguments > 5 else None
if not cardsjsonfile:
print("CARDSJSONFILE is required")
exit(1)
try:
with open(cardsjsonfile, 'r') as f:
raw_cards = json.load(f)
except Exception as e:
print("Error reading CARDSJSONFILE: {}".format(e))
exit(1)
if not isinstance(raw_cards, list) or len(raw_cards) == 0:
print("CARDSJSONFILE must contain a non-empty JSON list")
exit(1)
cards = []
for item in raw_cards:
if isinstance(item, str):
cards.append({'title': item})
elif isinstance(item, dict):
cards.append(item)
else:
print("Each card must be a string (title) or an object")
exit(1)
bulk_url = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + 'bulk'
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
post_data = {'authorId': authorid, 'swimlaneId': swimlaneid, 'cards': cards}
body = requests.post(bulk_url, json=post_data, headers=headers)
print("=== BULK ADD CARDS ===\n")
print(body.text)
# ------- BULK ADD CARDS END -----------
if sys.argv[1] == 'bulkdeletecards':
# ------- BULK DELETE CARDS START -----------
if arguments < 3:
print("Usage: python3 api.py bulkdeletecards BOARDID CARDIDS")
print("CARDIDS = comma-separated cardIds")
exit(1)
boardid = sys.argv[2]
cardids_raw = sys.argv[3]
cardids = [x for x in cardids_raw.split(',') if x]
bulk_url = wekanurl + apiboards + boardid + s + cs + s + 'bulk'
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
# requests sends a body with DELETE via the json= parameter.
body = requests.delete(bulk_url, json={'cardIds': cardids}, headers=headers)
print("=== BULK DELETE CARDS ===\n")
print(body.text)
# ------- BULK DELETE CARDS END -----------
if sys.argv[1] == 'bulkcardlabels':
# ------- BULK CARD LABELS START -----------
if arguments < 5:
print("Usage: python3 api.py bulkcardlabels BOARDID CARDIDS ADDLABELIDS REMOVELABELIDS")
print("CARDIDS / ADDLABELIDS / REMOVELABELIDS = comma-separated, or '' for none")
exit(1)
boardid = sys.argv[2]
cardids = [x for x in sys.argv[3].split(',') if x]
add_labelids = [x for x in sys.argv[4].split(',') if x]
remove_labelids = [x for x in sys.argv[5].split(',') if x]
bulk_url = wekanurl + apiboards + boardid + s + cs + s + 'labels'
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
post_data = {'cardIds': cardids, 'addLabelIds': add_labelids, 'removeLabelIds': remove_labelids}
body = requests.post(bulk_url, json=post_data, headers=headers)
print("=== BULK CARD LABELS ===\n")
print(body.text)
# ------- BULK CARD LABELS END -----------
if sys.argv[1] == 'linkcard':
# ------- CREATE LINKED CARD START -----------
if arguments < 6:
print("Usage: python3 api.py linkcard BOARDID LISTID SWIMLANEID AUTHORID LINKEDCARDID")
exit(1)
boardid = sys.argv[2]
listid = sys.argv[3]
swimlaneid = sys.argv[4]
authorid = sys.argv[5]
linkedcardid = sys.argv[6]
link_url = wekanurl + apiboards + boardid + s + l + s + listid + s + cs
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
post_data = {'authorId': authorid, 'swimlaneId': swimlaneid, 'linkedId': linkedcardid}
body = requests.post(link_url, data=post_data, headers=headers)
print("=== CREATE LINKED CARD ===\n")
print(body.text)
# ------- CREATE LINKED CARD END -----------
if sys.argv[1] in ('addcardmember', 'removecardmember', 'addcardassignee', 'removecardassignee'):
# ------- ADD/REMOVE CARD MEMBER / ASSIGNEE START -----------
if arguments < 5:
print("Usage: python3 api.py {} BOARDID LISTID CARDID USERID".format(sys.argv[1]))
exit(1)
boardid = sys.argv[2]
listid = sys.argv[3]
cardid = sys.argv[4]
userid = sys.argv[5]
field = 'members' if 'member' in sys.argv[1] else 'assignees'
url = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid + s + field + s + userid
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
if sys.argv[1].startswith('add'):
body = requests.post(url, headers=headers)
else:
body = requests.delete(url, headers=headers)
print("=== {} ===\n".format(sys.argv[1].upper()))
print(body.text)
# ------- ADD/REMOVE CARD MEMBER / ASSIGNEE END -----------
if sys.argv[1] == 'copycard':
# ------- COPY CARD START -----------
if arguments < 4:
print("Usage: python3 api.py copycard BOARDID LISTID CARDID TOSWIMLANEID [TOBOARDID] [TOLISTID] [POSITION]")
exit(1)
boardid = sys.argv[2]
listid = sys.argv[3]
cardid = sys.argv[4]
toswimlaneid = sys.argv[5] if arguments > 4 else None
if not toswimlaneid:
print("TOSWIMLANEID is required")
exit(1)
toboardid = sys.argv[6] if arguments > 5 else boardid
tolistid = sys.argv[7] if arguments > 6 else listid
url = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid + s + 'copy'
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
post_data = {'toBoardId': toboardid, 'toSwimlaneId': toswimlaneid, 'toListId': tolistid}
if arguments > 7:
post_data['position'] = int(sys.argv[8])
body = requests.post(url, json=post_data, headers=headers)
print("=== COPY CARD ===\n")
print(body.text)
# ------- COPY CARD END -----------
if sys.argv[1] in ('copyswimlane', 'moveswimlane'):
# ------- COPY/MOVE SWIMLANE START -----------
if arguments < 3:
print("Usage: python3 api.py {} BOARDID SWIMLANEID [TOBOARDID] [POSITION]".format(sys.argv[1]))
exit(1)
boardid = sys.argv[2]
swimlaneid = sys.argv[3]
toboardid = sys.argv[4] if arguments > 3 else boardid
action = 'copy' if sys.argv[1] == 'copyswimlane' else 'move'
url = wekanurl + apiboards + boardid + s + sws + s + swimlaneid + s + action
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
post_data = {'toBoardId': toboardid}
if arguments > 4:
post_data['position'] = int(sys.argv[5])
body = requests.post(url, json=post_data, headers=headers)
print("=== {} ===\n".format(sys.argv[1].upper()))
print(body.text)
# ------- COPY/MOVE SWIMLANE END -----------
if sys.argv[1] in ('copylist', 'movelist'):
# ------- COPY/MOVE LIST START -----------
if arguments < 3:
print("Usage: python3 api.py {} BOARDID LISTID [TOSWIMLANEID] [TOBOARDID] [POSITION]".format(sys.argv[1]))
exit(1)
boardid = sys.argv[2]
listid = sys.argv[3]
toswimlaneid = sys.argv[4] if arguments > 3 else None
toboardid = sys.argv[5] if arguments > 4 else boardid
action = 'copy' if sys.argv[1] == 'copylist' else 'move'
url = wekanurl + apiboards + boardid + s + l + s + listid + s + action
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
post_data = {'toBoardId': toboardid}
if toswimlaneid:
post_data['toSwimlaneId'] = toswimlaneid
if arguments > 5:
post_data['position'] = int(sys.argv[6])
body = requests.post(url, json=post_data, headers=headers)
print("=== {} ===\n".format(sys.argv[1].upper()))
print(body.text)
# ------- COPY/MOVE LIST END -----------
if sys.argv[1] == 'mycards':
# ------- MY CARDS / DUE CARDS START -----------
params = {}
if arguments >= 2 and sys.argv[2].lower() == 'due':
params['due'] = 'true'
if arguments >= 3:
params['from'] = sys.argv[3]
if arguments >= 4:
params['to'] = sys.argv[4]
url = wekanurl + 'api/user/cards'
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
body = requests.get(url, headers=headers, params=params)
print("=== MY CARDS ===\n")
data2 = body.text.replace('}', "}\n")
print(data2)
# ------- MY CARDS / DUE CARDS END -----------
if sys.argv[1] == 'getcardsettings':
# ------- GET CARD SETTINGS START -----------
if arguments < 2:
print("Usage: python3 api.py getcardsettings BOARDID")
exit(1)
boardid = sys.argv[2]
url = wekanurl + apiboards + boardid + s + 'cardSettings'
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
body = requests.get(url, headers=headers)
print("=== CARD SETTINGS ===\n")
data2 = body.text.replace(',', ",\n")
print(data2)
# ------- GET CARD SETTINGS END -----------
if sys.argv[1] == 'setcardsetting':
# ------- SET CARD SETTING START -----------
if arguments < 4:
print("Usage: python3 api.py setcardsetting BOARDID KEY VALUE")
print("e.g. python3 api.py setcardsetting BOARDID allowsDueDate true")
exit(1)
boardid = sys.argv[2]
key = sys.argv[3]
value = sys.argv[4]
url = wekanurl + apiboards + boardid + s + 'cardSettings'
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey), 'Content-Type': 'application/json'}
body = requests.put(url, json={key: value}, headers=headers)
print("=== SET CARD SETTING ===\n")
print(body.text)
# ------- SET CARD SETTING END -----------
# ------- BOARD MEMBER / CARD FIELD API ENDPOINTS END -----------
+165 -2
View File
@@ -1,6 +1,169 @@
// PWA
// Fix dynamic-import chunk loading when Wekan runs under a sub-path (ROOT_URL includes a pathname,
// e.g. https://example.com/wekan). Rspack uses __webpack_public_path__ to prefix chunk URLs; by
// default it is set to /build-chunks/ (no context path). We update it here, at module evaluation
// time, before any import() expression runs (those are deferred to Meteor.startup callbacks).
/* global __webpack_public_path__:writable */
try {
const _cfg = typeof window !== 'undefined' && window.__meteor_runtime_config__;
const _rootUrl = _cfg && _cfg.ROOT_URL;
if (_rootUrl) {
const _rootPath = new URL(_rootUrl).pathname.replace(/\/+$/, '');
if (_rootPath && _rootPath !== '/') {
__webpack_public_path__ = _rootPath + '/build-chunks/';
}
}
} catch (_) {}
// Fix bug in jam:offline 0.4.1: s?.message.includes() crashes when s.message is
// undefined (e.g. during WebSocket reconnect errors that don't carry a .message).
// Wrap _debug so the optional chain is complete: s?.message?.includes().
(function patchJamOfflineDebug() {
const patched = Meteor._debug;
Meteor._debug = function (m, s) {
try {
return patched.call(this, m, s);
} catch (e) {
// jam:offline's override threw — fall back to the bare console log.
if (typeof console !== 'undefined') {
console.log(m, s);
}
}
};
})();
// PWA — use Meteor.absoluteUrl so the path is correct under sub-URL deployments
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/pwa-service-worker.js');
const swPath = new URL('pwa-service-worker.js', Meteor.absoluteUrl()).pathname;
navigator.serviceWorker.register(swPath);
});
}
// Import Blaze helpers (replaces removed raix:handlebar-helpers package)
import '/client/config/blazeHelpers';
// Import board converter for on-demand conversion
import '/client/lib/boardConverter';
import '/client/features/boardConversion';
import { Utils } from '/client/lib/utils';
// Import migration manager and progress UI - COMMENTED OUT
// import '/client/lib/attachmentMigrationManager';
// import '/client/components/settings/migrationProgress';
// Import cron settings - COMMENTED OUT
// import '/client/components/settings/cronSettings';
// Custom head tags
// Mirror Meteor login token into a cookie for server-side file route auth
// This enables cookie-based auth for /cdn/storage/* without leaking ROOT_URL
// Token already lives in localStorage; cookie adds same-origin send-on-request semantics
Meteor.startup(() => {
const COOKIE_NAME = 'meteor_login_token';
const USER_ID_COOKIE = 'meteor_user_id';
const TOKEN_EXPIRES_COOKIE = 'meteor_login_token_expires';
const getCookie = (name) => {
try {
const parts = document.cookie ? document.cookie.split(';') : [];
for (const part of parts) {
const [k, ...rest] = part.trim().split('=');
if (decodeURIComponent(k) === name) {
return decodeURIComponent(rest.join('='));
}
}
} catch (_) {}
return '';
};
const cookieAttrs = () => {
const attrs = ['Path=/', 'SameSite=Lax'];
try {
if (window.location && window.location.protocol === 'https:') {
attrs.push('Secure');
}
} catch (_) {}
return attrs.join('; ');
};
const setCookie = (name, value) => {
if (!value) return;
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; ${cookieAttrs()}`;
};
const clearCookie = (name) => {
document.cookie = `${encodeURIComponent(name)}=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; ${cookieAttrs()}`;
};
const syncCookie = () => {
try {
const token = Accounts && typeof Accounts._storedLoginToken === 'function' ? Accounts._storedLoginToken() : null;
if (token) setCookie(COOKIE_NAME, token); else clearCookie(COOKIE_NAME);
} catch (e) {
// ignore
}
};
const bootstrapTokenFromCookie = () => {
try {
const currentToken = Accounts && typeof Accounts._storedLoginToken === 'function'
? Accounts._storedLoginToken()
: null;
if (currentToken) {
return;
}
const token = getCookie(COOKIE_NAME);
const userId = getCookie(USER_ID_COOKIE);
const tokenExpiresRaw = getCookie(TOKEN_EXPIRES_COOKIE);
const tokenExpires = tokenExpiresRaw ? new Date(tokenExpiresRaw) : null;
if (!token || !userId || !tokenExpires || Number.isNaN(tokenExpires.getTime())) {
return;
}
if (Accounts && typeof Accounts._storeLoginToken === 'function') {
Accounts._storeLoginToken(userId, token, tokenExpires);
if (Meteor.status && !Meteor.status().connected && typeof Meteor.reconnect === 'function') {
Meteor.reconnect();
}
}
} catch (_) {
// ignore
}
};
bootstrapTokenFromCookie();
// Initial sync on startup
syncCookie();
// Keep cookie in sync on login/logout
if (Accounts && typeof Accounts.onLogin === 'function') Accounts.onLogin(syncCookie);
if (Accounts && typeof Accounts.onLogout === 'function') Accounts.onLogout(syncCookie);
// Sync across tabs/windows when localStorage changes
window.addEventListener('storage', (ev) => {
if (ev && typeof ev.key === 'string' && ev.key.indexOf('Meteor.loginToken') !== -1) {
syncCookie();
}
});
});
// Subscribe to per-user small publications
Meteor.startup(() => {
Tracker.autorun(() => {
if (Meteor.userId()) {
Meteor.subscribe('userGreyIcons');
Meteor.subscribe('userDesktopDragHandles');
}
});
// Initialize mobile mode on startup for iOS devices
// This ensures mobile mode is applied correctly on page load
Tracker.afterFlush(() => {
if (typeof Utils !== 'undefined' && Utils.initializeUserSettings) {
Utils.initializeUserSettings();
}
});
});
+14 -51
View File
@@ -1,16 +1,16 @@
.activity-title {
margin: 0 0.5em 0.8em;
margin: 0 0.7vw 1vh;
display: flex;
justify-content: space-between;
}
.reactions-popup .add-comment-reaction {
display: inline-block;
cursor: pointer;
border-radius: 5px;
font-size: 22px;
border-radius: 0.7vw;
font-size: clamp(18px, 4vw, 22px);
text-align: center;
line-height: 30px;
width: 40px;
line-height: 1.3;
width: 5vw;
}
.reactions-popup .add-comment-reaction:hover {
background-color: #b0c4de;
@@ -19,13 +19,13 @@
clear: both;
}
.activities .activity {
margin: 0.5px 0;
padding: 6px 0;
margin: 0.1vh 0;
padding: 0.8vh 0;
display: flex;
}
.activities .activity .member {
width: 32px;
height: 32px;
width: 4vw;
height: 4vw;
}
.activities .activity .activity-member {
font-weight: 700;
@@ -36,55 +36,18 @@
flex: 1;
align-self: center;
margin: 0;
margin-left: 3px;
margin-left: 0.4vw;
overflow: hidden;
word-break: break-word;
}
.activities .activity .activity-desc .activity-comment {
display: block;
border-radius: 3px;
border-radius: 0.4vw;
background: #fff;
text-decoration: none;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
margin-top: 5px;
padding: 5px;
}
.activities .activity .activity-desc .reactions {
display: flex;
margin-top: 5px;
gap: 5px;
}
.activities .activity .activity-desc .reactions .open-comment-reaction-popup {
display: flex;
align-items: center;
text-decoration: none;
height: 24px;
}
.activities .activity .activity-desc .reactions .open-comment-reaction-popup i.fa.fa-smile-o {
font-size: 17px;
font-weight: 500;
margin-left: 2px;
}
.activities .activity .activity-desc .reactions .open-comment-reaction-popup i.fa.fa-plus {
font-size: 8px;
margin-top: -7px;
margin-left: 1px;
}
.activities .activity .activity-desc .reactions .reaction {
cursor: pointer;
border: 1px solid #808080;
border-radius: 15px;
display: flex;
padding: 2px 5px;
}
.activities .activity .activity-desc .reactions .reaction.selected {
background-color: #b0c4de;
}
.activities .activity .activity-desc .reactions .reaction:hover {
background-color: #b0c4de;
}
.activities .activity .activity-desc .reactions .reaction .reaction-count {
font-size: 12px;
box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.2);
margin-top: 0.7vh;
padding: 0.7vh 0.7vw;
}
.activities .activity .activity-desc .activity-checklist {
display: block;
+26 -69
View File
@@ -1,46 +1,21 @@
template(name="activities")
.activities.js-sidebar-activities
//- We should use Template.dynamic here but there is a bug with
//- blaze-components: https://github.com/peerlibrary/meteor-blaze-components/issues/30
if $eq mode "board"
+boardActivities
else
+cardActivities
if showActivities
.activities.js-sidebar-activities
//- We should use Template.dynamic here but there is a bug with
//- blaze-components: https://github.com/peerlibrary/meteor-blaze-components/issues/30
if $eq mode "board"
+boardActivities
else
+cardActivities
template(name="boardActivities")
each activityData in currentBoard.activities
each activityData in boardActivitiesList
+activity(activity=activityData card=card mode=mode)
template(name="cardActivities")
each activityData in activities
each activityData in cardActivitiesList
+activity(activity=activityData card=card mode=mode)
template(name="editOrDeleteComment")
= ' - '
a.js-open-inlined-form {{_ "edit"}}
= ' - '
a.js-delete-comment {{_ "delete"}}
template(name="deleteCommentPopup")
p {{_ "comment-delete"}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
template(name="commentReactions")
.reactions
each reaction in reactions
span.reaction(class="{{#if isSelected reaction.userIds}}selected{{/if}}" data-codepoint="#{reaction.reactionCodepoint}" title="{{userNames reaction.userIds}}")
span.reaction-codepoint !{reaction.reactionCodepoint}
span.reaction-count #{reaction.userIds.length}
if (currentUser.isBoardMember)
a.open-comment-reaction-popup(title="{{_ 'addReactionPopup-title'}}")
i.fa.fa-smile-o
i.fa.fa-plus
template(name="addReactionPopup")
.reactions-popup
each codepoint in codepoints
span.add-comment-reaction(data-codepoint="#{codepoint}") !{codepoint}
template(name="activity")
.activity(data-id=activity._id)
+userAvatar(userId=activity.user._id)
@@ -130,39 +105,17 @@ template(name="activity")
| {{{_ 'activity-checklist-item-removed' (sanitize activity.checklist.title) cardLink}}}.
//- comment activity ----------------------------------------------------
if($eq mode 'card')
//- if we are in card mode we display the comment in a way that it
//- can be edited by the owner
if($eq activity.activityType 'addComment')
+inlinedForm(classNames='js-edit-comment')
+editor(autofocus=true)
= activity.comment.text
.edit-controls
button.primary(type="submit") {{_ 'edit'}}
.fa.fa-times-thin.js-close-inlined-form
else
.activity-comment
+viewer
= activity.comment.text
+commentReactions(reactions=activity.comment.reactions commentId=activity.comment._id)
span(title=activity.createdAt).activity-meta {{ moment activity.createdAt }}
if($eq currentUser._id activity.comment.userId)
+editOrDeleteComment
else if currentUser.isBoardAdmin
+editOrDeleteComment
if($eq activity.activityType 'deleteComment')
| {{{_ 'activity-deleteComment' activity.commentId}}}.
if($eq activity.activityType 'deleteComment')
| {{{_ 'activity-deleteComment' activity.commentId}}}.
if($eq activity.activityType 'editComment')
| {{{_ 'activity-editComment' activity.commentId}}}.
if($eq activity.activityType 'editComment')
| {{{_ 'activity-editComment' activity.commentId}}}.
else
//- if we are not in card mode we only display a summary of the comment
if($eq activity.activityType 'addComment')
| {{{_ 'activity-on' cardLink}}}
a.activity-comment(href="{{ activity.card.originRelativeUrl }}")
+viewer
= activity.comment.text
if($eq activity.activityType 'addComment')
| {{{_ 'activity-on' cardLink}}}
a.activity-comment(href="{{ activity.card.originRelativeUrl }}")
+viewer
= activity.comment.text
//- date activity ------------------------------------------------
if($eq activity.activityType 'a-receivedAt')
@@ -208,6 +161,9 @@ template(name="activity")
if($eq activity.activityType 'archivedList')
| {{_ 'activity-archived' (sanitize listLabel)}}.
if($eq activity.activityType 'changedListTitle')
| {{_ 'activity-changedListTitle' (sanitize listLabel) boardLabelLink}}
//- member activity ----------------------------------------------------
if($eq activity.activityType 'joinMember')
if($eq user._id activity.member._id)
@@ -233,14 +189,15 @@ template(name="activity")
if(currentData.timeKey)
| {{_ activity.activityType }}
= ' '
i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }}
i(title=currentData.timeValue).activity-meta {{ displayDate currentData.timeValue 'LLL' }}
if (currentData.timeOldValue)
= ' '
| {{{_ "previous_as" }}}
= ' '
i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }}
i(title=currentData.timeOldValue).activity-meta {{ displayDate currentData.timeOldValue 'LLL' }}
= ' @'
else if(currentData.timeValue)
| {{_ activity.activityType currentData.timeValue}}
span(title=activity.createdAt).activity-meta {{ moment activity.createdAt }}
if($neq mode 'none')
div(title=activity.createdAt).activity-meta {{ displayDate activity.createdAt }}
+141 -128
View File
@@ -1,23 +1,46 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { ReactiveVar } from 'meteor/reactive-var';
import { Template } from 'meteor/templating';
import DOMPurify from 'dompurify';
import { sanitizeHTML, sanitizeText } from '/imports/lib/secureDOMPurify';
import { TAPi18n } from '/imports/i18n';
import { Utils } from '/client/lib/utils';
import { getSidebarInstance } from '/client/features/sidebar/service';
const activitiesPerPage = 500;
BlazeComponent.extendComponent({
onCreated() {
// XXX Should we use ReactiveNumber?
this.page = new ReactiveVar(1);
this.loadNextPageLocked = false;
// TODO is sidebar always available? E.g. on small screens/mobile devices
const sidebar = Sidebar;
sidebar && sidebar.callFirstWith(null, 'resetNextPeak');
this.autorun(() => {
let mode = this.data().mode;
Template.activities.onCreated(function () {
// Register with sidebar so it can call loadNextPage on us
const Sidebar = getSidebarInstance();
if (Sidebar) {
Sidebar.activitiesInstance = this;
}
// XXX Should we use ReactiveNumber?
this.page = new ReactiveVar(1);
this.loadNextPageLocked = false;
this.loadNextPage = () => {
if (this.loadNextPageLocked === false) {
this.page.set(this.page.get() + 1);
this.loadNextPageLocked = true;
}
};
// TODO is sidebar always available? E.g. on small screens/mobile devices
const sidebar = getSidebarInstance();
if (sidebar && sidebar.infiniteScrolling) {
sidebar.infiniteScrolling.resetNextPeak();
}
this.autorun(() => {
const data = Template.currentData();
let mode = data?.mode;
if (mode) {
const capitalizedMode = Utils.capitalize(mode);
let searchId;
const showActivities = _showActivities(data);
if (mode === 'linkedcard' || mode === 'linkedboard') {
searchId = Utils.getCurrentCard().linkedId;
const currentCard = Utils.getCurrentCard();
searchId = currentCard.linkedId;
mode = mode.replace('linked', '');
} else if (mode === 'card') {
searchId = Utils.getCurrentCardId();
@@ -25,129 +48,145 @@ BlazeComponent.extendComponent({
searchId = Session.get(`current${capitalizedMode}`);
}
const limit = this.page.get() * activitiesPerPage;
const user = ReactiveCache.getCurrentUser();
const hideSystem = user ? user.hasHiddenSystemMessages() : false;
if (searchId === null) return;
this.subscribe('activities', mode, searchId, limit, hideSystem, () => {
this.subscribe('activities', mode, searchId, limit, showActivities, () => {
this.loadNextPageLocked = false;
// TODO the guard can be removed as soon as the TODO above is resolved
if (!sidebar) return;
// If the sibear peak hasn't increased, that mean that there are no more
if (!sidebar || !sidebar.infiniteScrolling) return;
// If the sidebar peak hasn't increased, that means that there are no more
// activities, and we can stop calling new subscriptions.
// XXX This is hacky! We need to know excatly and reactively how many
// activities there are, we probably want to denormalize this number
// dirrectly into card and board documents.
const nextPeakBefore = sidebar.callFirstWith(null, 'getNextPeak');
const nextPeakBefore = sidebar.infiniteScrolling.getNextPeak();
sidebar.calculateNextPeak();
const nextPeakAfter = sidebar.callFirstWith(null, 'getNextPeak');
const nextPeakAfter = sidebar.infiniteScrolling.getNextPeak();
if (nextPeakBefore === nextPeakAfter) {
sidebar.callFirstWith(null, 'resetNextPeak');
sidebar.infiniteScrolling.resetNextPeak();
}
});
});
},
loadNextPage() {
if (this.loadNextPageLocked === false) {
this.page.set(this.page.get() + 1);
this.loadNextPageLocked = true;
}
},
}).register('activities');
});
});
function _showActivities(data) {
let ret = false;
let mode = data?.mode;
if (mode) {
if (mode === 'linkedcard' || mode === 'linkedboard') {
const currentCard = Utils.getCurrentCard();
ret = currentCard.showActivities ?? false;
} else if (mode === 'card') {
// For card mode, get showActivities from data context or fallback to current card
const card = data?.card || Utils.getCurrentCard();
ret = card?.showActivities ?? false;
} else {
ret = Utils.getCurrentBoard().showActivities ?? false;
}
}
return ret;
}
Template.activities.helpers({
showActivities() {
const data = Template.currentData();
return _showActivities(data);
},
activities() {
const ret = this.card.activities();
return ret;
const activities = this.card?.activities?.();
return activities || [];
},
});
BlazeComponent.extendComponent({
Template.boardActivities.helpers({
boardActivitiesList() {
const board = Utils.getCurrentBoard();
const activities = board?.activities?.();
return activities || [];
},
});
Template.cardActivities.helpers({
cardActivitiesList() {
const data = Template.currentData();
const card = data?.card;
const activities = card?.activities?.();
return activities || [];
},
});
Template.activity.helpers({
checkItem() {
const checkItemId = this.currentData().activity.checklistItemId;
const checkItemId = this.activity.checklistItemId;
const checkItem = ReactiveCache.getChecklistItem(checkItemId);
return checkItem && checkItem.title;
},
boardLabelLink() {
const data = this.currentData();
const currentBoardId = Session.get('currentBoard');
if (data.mode !== 'board') {
// data.mode: card, linkedcard, linkedboard
return createBoardLink(data.activity.board(), data.activity.listName ? data.activity.listName : null);
if (this.mode !== 'board') {
return createBoardLink(this.activity.board(), this.activity.listName ? this.activity.listName : null);
}
else if (currentBoardId != data.activity.boardId) {
// data.mode: board
// current activitie is linked
return createBoardLink(data.activity.board(), data.activity.listName ? data.activity.listName : null);
else if (currentBoardId != this.activity.boardId) {
return createBoardLink(this.activity.board(), this.activity.listName ? this.activity.listName : null);
}
return TAPi18n.__('this-board');
},
cardLabelLink() {
const data = this.currentData();
const currentBoardId = Session.get('currentBoard');
if (data.mode == 'card') {
// data.mode: card
if (this.mode == 'card') {
return TAPi18n.__('this-card');
}
else if (data.mode !== 'board') {
// data.mode: linkedcard, linkedboard
return createCardLink(data.activity.card(), null);
else if (this.mode !== 'board') {
return createCardLink(this.activity.card(), null);
}
else if (currentBoardId != data.activity.boardId) {
// data.mode: board
// current activitie is linked
return createCardLink(data.activity.card(), data.activity.board().title);
else if (currentBoardId != this.activity.boardId) {
return createCardLink(this.activity.card(), this.activity.board().title);
}
return createCardLink(this.currentData().activity.card(), null);
return createCardLink(this.activity.card(), null);
},
cardLink() {
const data = this.currentData();
const currentBoardId = Session.get('currentBoard');
if (data.mode !== 'board') {
// data.mode: card, linkedcard, linkedboard
return createCardLink(data.activity.card(), null);
if (this.mode !== 'board') {
return createCardLink(this.activity.card(), null);
}
else if (currentBoardId != data.activity.boardId) {
// data.mode: board
// current activitie is linked
return createCardLink(data.activity.card(), data.activity.board().title);
else if (currentBoardId != this.activity.boardId) {
return createCardLink(this.activity.card(), this.activity.board().title);
}
return createCardLink(this.currentData().activity.card(), null);
return createCardLink(this.activity.card(), null);
},
receivedDate() {
const receivedDate = this.currentData().activity.card();
if (!receivedDate) return null;
return receivedDate.receivedAt;
const card = this.activity.card();
if (!card) return null;
return card.receivedAt;
},
startDate() {
const startDate = this.currentData().activity.card();
if (!startDate) return null;
return startDate.startAt;
const card = this.activity.card();
if (!card) return null;
return card.startAt;
},
dueDate() {
const dueDate = this.currentData().activity.card();
if (!dueDate) return null;
return dueDate.dueAt;
const card = this.activity.card();
if (!card) return null;
return card.dueAt;
},
endDate() {
const endDate = this.currentData().activity.card();
if (!endDate) return null;
return endDate.endAt;
const card = this.activity.card();
if (!card) return null;
return card.endAt;
},
lastLabel() {
const lastLabelId = this.currentData().activity.labelId;
const lastLabelId = this.activity.labelId;
if (!lastLabelId) return null;
const lastLabel = ReactiveCache.getBoard(
this.currentData().activity.boardId,
this.activity.boardId,
).getLabelById(lastLabelId);
if (lastLabel && (lastLabel.name === undefined || lastLabel.name === '')) {
return lastLabel.color;
@@ -160,7 +199,7 @@ BlazeComponent.extendComponent({
lastCustomField() {
const lastCustomField = ReactiveCache.getCustomField(
this.currentData().activity.customFieldId,
this.activity.customFieldId,
);
if (!lastCustomField) return null;
return lastCustomField.name;
@@ -168,16 +207,15 @@ BlazeComponent.extendComponent({
lastCustomFieldValue() {
const lastCustomField = ReactiveCache.getCustomField(
this.currentData().activity.customFieldId,
this.activity.customFieldId,
);
if (!lastCustomField) return null;
const value = this.currentData().activity.value;
const value = this.activity.value;
if (
lastCustomField.settings.dropdownItems &&
lastCustomField.settings.dropdownItems.length > 0
) {
const dropDownValue = _.find(
lastCustomField.settings.dropdownItems,
const dropDownValue = lastCustomField.settings.dropdownItems.find(
item => {
return item._id === value;
},
@@ -188,13 +226,13 @@ BlazeComponent.extendComponent({
},
listLabel() {
const activity = this.currentData().activity;
const activity = this.activity;
const list = activity.list();
return (list && list.title) || activity.title;
},
sourceLink() {
const source = this.currentData().activity.source;
const source = this.activity.source;
if (source) {
if (source.url) {
return Blaze.toHTML(
@@ -202,15 +240,11 @@ BlazeComponent.extendComponent({
{
href: source.url,
},
DOMPurify.sanitize(source.system, {
ALLOW_UNKNOWN_PROTOCOLS: true,
}),
sanitizeHTML(source.system),
),
);
} else {
return DOMPurify.sanitize(source.system, {
ALLOW_UNKNOWN_PROTOCOLS: true,
});
return sanitizeHTML(source.system);
}
}
return null;
@@ -218,72 +252,50 @@ BlazeComponent.extendComponent({
memberLink() {
return Blaze.toHTMLWithData(Template.memberName, {
user: this.currentData().activity.member(),
user: this.activity.member(),
});
},
attachmentLink() {
const attachment = this.currentData().activity.attachment();
const attachment = this.activity.attachment();
const attachmentUrl = attachment && typeof attachment.link === 'function'
? attachment.link()
: '';
// trying to display url before file is stored generates js errors
return (
(attachment &&
attachment.path &&
attachmentUrl &&
Blaze.toHTML(
HTML.A(
{
href: `${attachment.link()}?download=true`,
href: `${attachmentUrl}?download=true`,
target: '_blank',
},
DOMPurify.sanitize(attachment.name),
sanitizeText(attachment.name),
),
)) ||
DOMPurify.sanitize(this.currentData().activity.attachmentName)
sanitizeText(this.activity.attachmentName)
);
},
customField() {
const customField = this.currentData().activity.customField();
const customField = this.activity.customField();
if (!customField) return null;
return customField.name;
},
events() {
return [
{
// XXX We should use Popup.afterConfirmation here
'click .js-delete-comment': Popup.afterConfirm('deleteComment', () => {
const commentId = this.data().activity.commentId;
CardComments.remove(commentId);
Popup.back();
}),
'submit .js-edit-comment'(evt) {
evt.preventDefault();
const commentText = this.currentComponent()
.getValue()
.trim();
const commentId = Template.parentData().activity.commentId;
if (commentText) {
CardComments.update(commentId, {
$set: {
text: commentText,
},
});
}
},
},
];
},
}).register('activity');
});
Template.activity.helpers({
sanitize(value) {
return DOMPurify.sanitize(value, { ALLOW_UNKNOWN_PROTOCOLS: true });
return sanitizeHTML(value);
},
});
Template.commentReactions.events({
'click .reaction'(event) {
if (ReactiveCache.getCurrentUser().isBoardMember()) {
const user = ReactiveCache.getCurrentUser();
if (user && user.isBoardMember()) {
const codepoint = event.currentTarget.dataset['codepoint'];
const commentId = Template.instance().data.commentId;
const cardComment = ReactiveCache.getCardComment(commentId);
@@ -295,7 +307,8 @@ Template.commentReactions.events({
Template.addReactionPopup.events({
'click .add-comment-reaction'(event) {
if (ReactiveCache.getCurrentUser().isBoardMember()) {
const user = ReactiveCache.getCurrentUser();
if (user && user.isBoardMember()) {
const codepoint = event.currentTarget.dataset['codepoint'];
const commentId = Template.instance().data.commentId;
const cardComment = ReactiveCache.getCardComment(commentId);
@@ -348,7 +361,7 @@ function createCardLink(card, board) {
href: card.originRelativeUrl(),
class: 'action-card',
},
DOMPurify.sanitize(text, { ALLOW_UNKNOWN_PROTOCOLS: true }),
sanitizeHTML(text),
),
)
);
@@ -365,7 +378,7 @@ function createBoardLink(board, list) {
href: board.originRelativeUrl(),
class: 'action-board',
},
DOMPurify.sanitize(text, { ALLOW_UNKNOWN_PROTOCOLS: true }),
sanitizeHTML(text),
),
)
);
+72
View File
@@ -63,3 +63,75 @@
display: block;
margin: auto;
}
.comments {
clear: both;
}
.comments .comment {
margin: 0.5px 0;
padding: 6px 0;
display: flex;
}
.comments .comment .member {
width: 32px;
height: 32px;
}
.comments .comment .comment-member {
font-weight: 700;
}
.comments .comment .comment-desc {
word-wrap: break-word;
overflow: hidden;
flex: 1;
align-self: center;
margin: 0;
margin-left: 3px;
overflow: hidden;
word-break: break-word;
}
.comments .comment .comment-desc .comment-text {
display: block;
border-radius: 3px;
background: #fff;
text-decoration: none;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
margin-top: 5px;
padding: 5px;
}
.comments .comment .comment-desc .reactions {
display: flex;
margin-top: 5px;
gap: 5px;
}
.comments .comment .comment-desc .reactions .open-comment-reaction-popup {
display: flex;
align-items: center;
text-decoration: none;
height: 24px;
}
.comments .comment .comment-desc .reactions .open-comment-reaction-popup span {
display: inline-block;
font-size: clamp(14px, 2vw, 18px);
font-weight: 500;
line-height: 1;
margin-left: 4px;
}
.comments .comment .comment-desc .reactions .reaction {
cursor: pointer;
border: 1px solid #808080;
border-radius: 15px;
display: flex;
padding: 2px 5px;
}
.comments .comment .comment-desc .reactions .reaction.selected {
background-color: #b0c4de;
}
.comments .comment .comment-desc .reactions .reaction:hover {
background-color: #b0c4de;
}
.comments .comment .comment-desc .reactions .reaction .reaction-count {
font-size: 12px;
}
.comments .comment .comment-desc .comment-meta {
font-size: 0.8em;
color: #999;
}
@@ -7,3 +7,62 @@ template(name="commentForm")
| {{getUnsavedValue 'cardComment' currentCard._id}}
.add-controls
button.primary.confirm.clear.js-add-comment(type="submit") {{_ 'comment'}}
template(name="comments")
.comments
each commentData in getComments
+comment(commentData)
template(name="comment")
.comment
+userAvatar(userId=userId)
p.comment-desc
span.comment-member
+memberName(user=user)
+inlinedForm(classNames='js-edit-comment')
+editor(autofocus=true)
= text
.edit-controls
button.primary(type="submit") {{_ 'edit'}}
a.js-close-inlined-form(title="{{_ 'close' }}")
i.fa.fa-times-thin
else
.comment-text
+viewer
= text
+commentReactions(reactions=reactions commentId=_id)
span(title=createdAt).comment-meta {{ displayDate createdAt }}
if($eq currentUser._id userId)
+editOrDeleteComment
else if currentUser.isBoardAdmin
+editOrDeleteComment
template(name="editOrDeleteComment")
= ' - '
a.js-open-inlined-form {{_ "edit"}}
= ' - '
a.js-delete-comment {{_ "delete"}}
template(name="deleteCommentPopup")
p {{_ "comment-delete"}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
template(name="commentReactions")
.reactions
each reaction in reactions
span.reaction(class="{{#if isSelected reaction.userIds}}selected{{/if}}" data-codepoint="#{reaction.reactionCodepoint}" title="{{userNames reaction.userIds}}")
span.reaction-codepoint !{reaction.reactionCodepoint}
span.reaction-count #{reaction.userIds.length}
if (currentUser.isBoardMember)
unless currentUser.isReadOnly
unless currentUser.isReadAssignedOnly
a.open-comment-reaction-popup(title="{{_ 'addReactionPopup-title'}}")
span(title="{{_ 'reaction' }}") 😀
span(title="{{_ 'add' }}") ➕
template(name="addReactionPopup")
.reactions-popup
each codepoint in codepoints
span.add-comment-reaction(data-codepoint="#{codepoint}") !{codepoint}
+70 -44
View File
@@ -1,59 +1,85 @@
import { ReactiveCache } from '/imports/reactiveCache';
import CardComments from '/models/cardComments';
import { UnsavedEdits } from '/client/lib/unsavedEdits';
import { EscapeActions } from '/client/lib/escapeActions';
import { Utils } from '/client/lib/utils';
import autosize from 'autosize';
const commentFormIsOpen = new ReactiveVar(false);
BlazeComponent.extendComponent({
onDestroyed() {
commentFormIsOpen.set(false);
$('.note-popover').hide();
},
Template.commentForm.onDestroyed(function () {
commentFormIsOpen.set(false);
$('.note-popover').hide();
});
Template.commentForm.helpers({
commentFormIsOpen() {
return commentFormIsOpen.get();
},
});
getInput() {
return this.$('.js-new-comment-input');
Template.commentForm.events({
'submit .js-new-comment-form'(evt, tpl) {
const input = tpl.$('.js-new-comment-input');
const text = input.val().trim();
const card = Template.currentData();
let boardId = card.boardId;
let cardId = card._id;
if (card.isLinkedCard()) {
boardId = ReactiveCache.getCard(card.linkedId).boardId;
cardId = card.linkedId;
} else if (card.isLinkedBoard()) {
boardId = card.linkedId;
}
if (text) {
CardComments.insert({
text,
boardId,
cardId,
});
resetCommentInput(input);
Tracker.flush();
autosize.update(input);
input.trigger('submitted');
}
evt.preventDefault();
},
// Pressing Ctrl+Enter should submit the form
'keydown form textarea'(evt, tpl) {
if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
tpl.find('button[type=submit]').click();
}
},
});
events() {
return [
{
'submit .js-new-comment-form'(evt) {
const input = this.getInput();
const text = input.val().trim();
const card = this.currentData();
let boardId = card.boardId;
let cardId = card._id;
if (card.isLinkedCard()) {
boardId = ReactiveCache.getCard(card.linkedId).boardId;
cardId = card.linkedId;
} else if (card.isLinkedBoard()) {
boardId = card.linkedId;
}
if (text) {
CardComments.insert({
text,
boardId,
cardId,
});
resetCommentInput(input);
Tracker.flush();
autosize.update(input);
input.trigger('submitted');
}
evt.preventDefault();
},
// Pressing Ctrl+Enter should submit the form
'keydown form textarea'(evt) {
if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
this.find('button[type=submit]').click();
}
},
},
];
Template.comments.helpers({
getComments() {
const data = Template.currentData();
if (!data || typeof data.comments !== 'function') return [];
return data.comments();
},
}).register('commentForm');
});
Template.comment.events({
'click .js-delete-comment': Popup.afterConfirm('deleteComment', function () {
const commentId = this._id;
CardComments.remove(commentId);
Popup.back();
}),
'submit .js-edit-comment'(evt, tpl) {
evt.preventDefault();
const textarea = tpl.find('.js-edit-comment textarea,input[type=text]');
const commentText = textarea && textarea.value ? textarea.value.trim() : '';
const commentId = tpl.data._id;
if (commentText) {
CardComments.update(commentId, {
$set: {
text: commentText,
},
});
}
},
});
// XXX This should be a static method of the `commentForm` component
function resetCommentInput(input) {
@@ -0,0 +1,184 @@
/* Board Conversion Progress Styles */
.board-conversion-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
z-index: 9999;
display: none;
align-items: center;
justify-content: center;
}
.board-conversion-overlay.active {
display: flex;
}
.board-conversion-modal {
background: white;
border-radius: 8px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
max-width: 500px;
width: 90%;
max-height: 80vh;
overflow: hidden;
animation: slideIn 0.3s ease-out;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.board-conversion-header {
padding: 20px 24px 16px;
border-bottom: 1px solid #e0e0e0;
text-align: center;
}
.board-conversion-header h3 {
margin: 0 0 8px 0;
color: #333;
font-size: 20px;
font-weight: 500;
}
.board-conversion-header h3 i {
margin-right: 8px;
color: #2196F3;
}
.board-conversion-header p {
margin: 0;
color: #666;
font-size: 14px;
}
.board-conversion-content {
padding: 24px;
}
.conversion-progress {
margin-bottom: 20px;
}
.progress-bar {
width: 100%;
height: 8px;
background-color: #e0e0e0;
border-radius: 4px;
overflow: hidden;
margin-bottom: 8px;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #2196F3, #21CBF3);
border-radius: 4px;
transition: width 0.3s ease;
position: relative;
}
.progress-fill::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent
);
animation: shimmer 2s infinite;
}
@keyframes shimmer {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
.progress-text {
text-align: center;
font-weight: 600;
color: #2196F3;
font-size: 16px;
}
.conversion-status {
text-align: center;
margin-bottom: 16px;
color: #333;
font-size: 16px;
}
.conversion-status i {
margin-right: 8px;
color: #2196F3;
}
.conversion-time {
text-align: center;
color: #666;
font-size: 14px;
background-color: #f5f5f5;
padding: 8px 12px;
border-radius: 4px;
margin-bottom: 16px;
}
.conversion-time i {
margin-right: 6px;
color: #FF9800;
}
.board-conversion-footer {
padding: 16px 24px 20px;
border-top: 1px solid #e0e0e0;
background-color: #f9f9f9;
}
.conversion-info {
text-align: center;
color: #666;
font-size: 13px;
line-height: 1.4;
}
.conversion-info i {
margin-right: 6px;
color: #2196F3;
}
/* Responsive design */
@media (max-width: 600px) {
.board-conversion-modal {
width: 95%;
margin: 20px;
}
.board-conversion-header,
.board-conversion-content,
.board-conversion-footer {
padding-left: 16px;
padding-right: 16px;
}
.board-conversion-header h3 {
font-size: 18px;
}
}
@@ -0,0 +1,27 @@
template(name="boardConversionProgress")
.board-conversion-overlay(class="{{#if isConverting}}active{{/if}}")
.board-conversion-modal
.board-conversion-header
h3
i.fa.fa-cog
| {{_ 'converting-board'}}
p {{_ 'converting-board-description'}}
.board-conversion-content
.conversion-progress
.progress-bar
.progress-fill(style="width: {{conversionProgress}}%")
.progress-text {{conversionProgress}}%
.conversion-status
i.fa.fa-cog
| {{conversionStatus}}
.conversion-time(style="{{#unless conversionEstimatedTime}}display: none;{{/unless}}")
i.fa.fa-clock-o
| {{_ 'estimated-time-remaining'}}: {{conversionEstimatedTime}}
.board-conversion-footer
.conversion-info
i.fa.fa-info-circle
| {{_ 'conversion-info-text'}}
@@ -0,0 +1,37 @@
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import {
boardConverter,
isConverting,
conversionProgress,
conversionStatus,
conversionEstimatedTime
} from '/client/lib/boardConverter';
Template.boardConversionProgress.helpers({
isConverting() {
return isConverting.get();
},
conversionProgress() {
return conversionProgress.get();
},
conversionStatus() {
return conversionStatus.get();
},
conversionEstimatedTime() {
return conversionEstimatedTime.get();
}
});
Template.boardConversionProgress.onCreated(function() {
// Subscribe to conversion state changes
this.autorun(() => {
isConverting.get();
conversionProgress.get();
conversionStatus.get();
conversionEstimatedTime.get();
});
});
+6 -5
View File
@@ -1,20 +1,21 @@
template(name="archivedBoards")
h2
i.fa.fa-archive
span(title="{{_ 'archived-boards'}}")
i.fa.fa-archive
| {{_ 'archived-boards'}}
ul.archived-lists
each archivedBoards
li.archived-lists-item
div.board-header-btns
button.board-header-btn.js-delete-board
i.fa.fa-trash-o
button.primary.board-header-btn.js-delete-board
i.fa.fa-trash
| {{_ 'delete-board'}}
button.board-header-btn.js-restore-board
button.primary.board-header-btn.js-restore-board
i.fa.fa-undo
| {{_ 'restore-board'}}
= title
span {{ moment archivedAt 'LLL' }}
span {{ displayDate archivedAt 'LLL' }}
else
li.no-items-message {{_ 'no-archived-boards'}}
+36 -37
View File
@@ -1,10 +1,13 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
import Boards from '/models/boards';
import { Utils } from '/client/lib/utils';
BlazeComponent.extendComponent({
onCreated() {
this.subscribe('archivedBoards');
},
Template.archivedBoards.onCreated(function () {
this.subscribe('archivedBoards');
});
Template.archivedBoards.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
},
@@ -18,38 +21,34 @@ BlazeComponent.extendComponent({
);
return ret;
},
});
events() {
return [
{
'click .js-restore-board'() {
// TODO : Make isSandstorm variable global
const isSandstorm =
Meteor.settings &&
Meteor.settings.public &&
Meteor.settings.public.sandstorm;
if (isSandstorm && Utils.getCurrentBoardId()) {
const currentBoard = Utils.getCurrentBoard();
currentBoard.archive();
}
const board = this.currentData();
board.restore();
Utils.goBoardId(board._id);
},
'click .js-delete-board': Popup.afterConfirm('boardDelete', function() {
Popup.back();
const isSandstorm =
Meteor.settings &&
Meteor.settings.public &&
Meteor.settings.public.sandstorm;
if (isSandstorm && Utils.getCurrentBoardId()) {
const currentBoard = Utils.getCurrentBoard();
Boards.remove(currentBoard._id);
}
Boards.remove(this._id);
FlowRouter.go('home');
}),
},
];
Template.archivedBoards.events({
async 'click .js-restore-board'() {
// TODO : Make isSandstorm variable global
const isSandstorm =
Meteor.settings &&
Meteor.settings.public &&
Meteor.settings.public.sandstorm;
if (isSandstorm && Utils.getCurrentBoardId()) {
const currentBoard = Utils.getCurrentBoard();
await currentBoard.archive();
}
const board = this;
await board.restore();
Utils.goBoardId(board._id);
},
}).register('archivedBoards');
'click .js-delete-board': Popup.afterConfirm('boardDelete', async function() {
Popup.back();
const isSandstorm =
Meteor.settings &&
Meteor.settings.public &&
Meteor.settings.public.sandstorm;
if (isSandstorm && Utils.getCurrentBoardId()) {
const currentBoard = Utils.getCurrentBoard();
await Boards.removeAsync(currentBoard._id);
}
await Boards.removeAsync(this._id);
FlowRouter.go('home');
}),
});
+355 -6
View File
@@ -6,6 +6,27 @@
bottom: 0;
overflow-x: hidden;
overflow-y: hidden;
width: 100%;
min-width: 100%;
}
/* When zoom is 50% or lower, ensure full width like content */
.board-wrapper[style*="transform: scale(0.5)"] {
width: 100% !important;
max-width: 100% !important;
margin: 0 !important;
}
.board-wrapper[style*="transform: scale(0.4)"] {
width: 100% !important;
max-width: 100% !important;
margin: 0 !important;
}
.board-wrapper[style*="transform: scale(0.3)"] {
width: 100% !important;
max-width: 100% !important;
margin: 0 !important;
}
.board-wrapper .board-canvas {
position: absolute;
@@ -15,9 +36,243 @@
bottom: 0;
transition: margin 0.1s;
overflow-y: auto;
width: 100%;
min-width: 100%;
}
.board-wrapper .board-canvas.is-sibling-sidebar-open {
margin-right: 248px;
/* Ensure horizontal scrollbar is visible for high zoom levels */
.board-wrapper .board-canvas[style*="overflow-x: auto"] {
overflow-x: auto !important;
overflow-y: auto !important;
}
/* Style the scrollbar for better visibility */
.board-wrapper .board-canvas::-webkit-scrollbar {
height: 12px;
width: 12px;
}
.board-wrapper .board-canvas::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 6px;
}
.board-wrapper .board-canvas::-webkit-scrollbar-thumb {
background: #888;
border-radius: 6px;
}
.board-wrapper .board-canvas::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* Ensure content area can scroll horizontally for high zoom levels */
#content[style*="overflow-x: auto"] {
overflow-x: auto !important;
overflow-y: auto !important;
}
/* Style content area scrollbar */
#content::-webkit-scrollbar {
height: 12px;
width: 12px;
}
#content::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 6px;
}
#content::-webkit-scrollbar-thumb {
background: #888;
border-radius: 6px;
}
#content::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* Ensure scrollbars are always visible for high zoom levels */
#content[style*="overflow-x: auto"] {
position: relative;
}
#content[style*="overflow-x: auto"]::-webkit-scrollbar {
height: 12px;
width: 12px;
}
/* Force vertical scrollbar to always be visible */
#content[style*="overflow-y: auto"] {
overflow-y: scroll !important;
}
/* Mobile - make all text 2x bigger inside #content by default (icons stay same size) */
@media screen and (max-width: 800px),
screen and (max-device-width: 800px),
screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 800px),
screen and (max-width: 800px) and (orientation: portrait),
screen and (max-width: 800px) and (orientation: landscape) {
#content {
font-size: 2em !important; /* 2x bigger base font size for content area */
}
/* Make all text elements 2x bigger */
#content h1, #content h2, #content h3, #content h4, #content h5, #content h6,
#content p, #content span, #content div, #content a, #content button,
#content .minicard, #content .list-header-name, #content .board-header-btn,
#content .card-title, #content .card-details, #content .card-description,
#content .swimlane-header, #content .list-title, #content .card-text,
#content .member, #content .member-name, #content .member-initials,
#content .checklist-item, #content .checklist-title, #content .comment,
#content .activity, #content .activity-text, #content .activity-time,
#content .board-title, #content .board-description, #content .list-name,
#content .card-text, #content .card-title, #content .card-description,
#content .swimlane-title, #content .swimlane-description,
#content .board-header-title, #content .board-header-description,
#content .card-detail-title, #content .card-detail-description,
#content .list-header-title, #content .list-header-description,
#content .swimlane-header-title, #content .swimlane-header-description,
#content .minicard-title, #content .minicard-description,
#content .card-comment, #content .card-comment-text,
#content .checklist-item-text, #content .checklist-item-title,
#content .activity-item, #content .activity-item-text,
#content .board-member, #content .board-member-name,
#content .team-member, #content .team-member-name,
#content .org-member, #content .org-member-name,
#content .template-member, #content .template-member-name,
#content .user-name, #content .user-email, #content .user-role,
#content .setting-title, #content .setting-description,
#content .popup-title, #content .popup-description,
#content .modal-title, #content .modal-description,
#content .notification-title, #content .notification-text,
#content .announcement-title, #content .announcement-text,
#content .offline-warning-title, #content .offline-warning-text,
#content .error-title, #content .error-text,
#content .success-title, #content .success-text,
#content .info-title, #content .info-text,
#content .warning-title, #content .warning-text {
font-size: 1em !important; /* Use inherited 2x scaling */
}
/* Keep icons the same size (don't scale them) */
#content .fa, #content .icon, #content i {
font-size: 1em !important; /* Keep original icon size */
}
/* Reset specific icon sizes to prevent double scaling */
#content .fa-home, #content .fa-bars, #content .fa-search,
#content .fa-bell, #content .fa-user, #content .fa-cog,
#content .fa-plus, #content .fa-minus, #content .fa-edit,
#content .fa-trash, #content .fa-save, #content .fa-cancel,
#content .fa-arrow-left, #content .fa-arrow-right,
#content .fa-arrow-up, #content .fa-arrow-down,
#content .fa-check, #content .fa-times, #content .fa-close,
#content .fa-star, #content .fa-heart, #content .fa-thumbs-up,
#content .fa-thumbs-down, #content .fa-comment, #content .fa-reply,
#content .fa-share, #content .fa-download, #content .fa-upload,
#content .fa-copy, #content .fa-paste, #content .fa-cut,
#content .fa-undo, #content .fa-redo, #content .fa-refresh,
#content .fa-sync, #content .fa-spinner, #content .fa-loading,
#content .fa-info, #content .fa-question, #content .fa-exclamation,
#content .fa-warning, #content .fa-error, #content .fa-success,
#content .fa-check-circle, #content .fa-times-circle,
#content .fa-exclamation-circle, #content .fa-question-circle,
#content .fa-info-circle, #content .fa-warning-circle,
#content .fa-error-circle, #content .fa-success-circle {
font-size: 1em !important; /* Keep original icon size */
}
}
/* Fallback for iPhone devices using JavaScript detection */
.iphone-device #content {
font-size: 2em !important; /* 2x bigger base font size for content area */
}
.iphone-device #content h1, .iphone-device #content h2, .iphone-device #content h3, .iphone-device #content h4, .iphone-device #content h5, .iphone-device #content h6,
.iphone-device #content p, .iphone-device #content span, .iphone-device #content div, .iphone-device #content a, .iphone-device #content button,
.iphone-device #content .minicard, .iphone-device #content .list-header-name, .iphone-device #content .board-header-btn,
.iphone-device #content .card-title, .iphone-device #content .card-details, .iphone-device #content .card-description,
.iphone-device #content .swimlane-header, .iphone-device #content .list-title, .iphone-device #content .card-text,
.iphone-device #content .member, .iphone-device #content .member-name, .iphone-device #content .member-initials,
.iphone-device #content .checklist-item, .iphone-device #content .checklist-title, .iphone-device #content .comment,
.iphone-device #content .activity, .iphone-device #content .activity-text, .iphone-device #content .activity-time,
.iphone-device #content .board-title, .iphone-device #content .board-description, .iphone-device #content .list-name,
.iphone-device #content .card-text, .iphone-device #content .card-title, .iphone-device #content .card-description,
.iphone-device #content .swimlane-title, .iphone-device #content .swimlane-description,
.iphone-device #content .board-header-title, .iphone-device #content .board-header-description,
.iphone-device #content .card-detail-title, .iphone-device #content .card-detail-description,
.iphone-device #content .list-header-title, .iphone-device #content .list-header-description,
.iphone-device #content .swimlane-header-title, .iphone-device #content .swimlane-header-description,
.iphone-device #content .minicard-title, .iphone-device #content .minicard-description,
.iphone-device #content .card-comment, .iphone-device #content .card-comment-text,
.iphone-device #content .checklist-item-text, .iphone-device #content .checklist-item-title,
.iphone-device #content .activity-item, .iphone-device #content .activity-item-text,
.iphone-device #content .board-member, .iphone-device #content .board-member-name,
.iphone-device #content .team-member, .iphone-device #content .team-member-name,
.iphone-device #content .org-member, .iphone-device #content .org-member-name,
.iphone-device #content .template-member, .iphone-device #content .template-member-name,
.iphone-device #content .user-name, .iphone-device #content .user-email, .iphone-device #content .user-role,
.iphone-device #content .setting-title, .iphone-device #content .setting-description,
.iphone-device #content .popup-title, .iphone-device #content .popup-description,
.iphone-device #content .modal-title, .iphone-device #content .modal-description,
.iphone-device #content .notification-title, .iphone-device #content .notification-text,
.iphone-device #content .announcement-title, .iphone-device #content .announcement-text,
.iphone-device #content .offline-warning-title, .iphone-device #content .offline-warning-text,
.iphone-device #content .error-title, .iphone-device #content .error-text,
.iphone-device #content .success-title, .iphone-device #content .success-text,
.iphone-device #content .info-title, .iphone-device #content .info-text,
.iphone-device #content .warning-title, .iphone-device #content .warning-text {
font-size: 1em !important; /* Use inherited 2x scaling */
}
/* Keep icons the same size for iPhone devices */
.iphone-device #content .fa, .iphone-device #content .icon, .iphone-device #content i {
font-size: 1em !important; /* Keep original icon size */
}
/* Mobile iPhone: scale card details text and icons to 2x */
body.mobile-mode.iphone-device .card-details {
font-size: 2em !important;
}
body.mobile-mode.iphone-device .card-details .fa,
body.mobile-mode.iphone-device .card-details .icon,
body.mobile-mode.iphone-device .card-details i,
body.mobile-mode.iphone-device .card-details .emoji-icon,
body.mobile-mode.iphone-device .card-details a,
body.mobile-mode.iphone-device .card-details p,
body.mobile-mode.iphone-device .card-details span,
body.mobile-mode.iphone-device .card-details div,
body.mobile-mode.iphone-device .card-details button,
body.mobile-mode.iphone-device .card-details input,
body.mobile-mode.iphone-device .card-details select,
body.mobile-mode.iphone-device .card-details textarea {
font-size: inherit !important;
}
/* Section titles slightly larger than content but not as big as card title */
body.mobile-mode.iphone-device .card-details .card-details-item-title {
font-size: 1.1em !important;
font-weight: bold;
}
/* Ensure scrollbars are positioned correctly */
#content[style*="overflow-x: auto"]::-webkit-scrollbar:vertical {
width: 12px;
}
#content[style*="overflow-x: auto"]::-webkit-scrollbar:horizontal {
height: 12px;
}
/* Force both scrollbars to always be visible for high zoom levels */
#content[style*="overflow-x: auto"][style*="overflow-y: auto"] {
overflow-x: scroll !important;
overflow-y: scroll !important;
}
/* Ensure the right scrollbar is always visible on the inner right edge */
#content[style*="overflow-y: auto"] {
scrollbar-gutter: stable;
}
.board-wrapper .board-canvas .board-overlay {
position: fixed;
@@ -32,19 +287,106 @@
animation: fadeIn 0.2s;
z-index: 16;
}
/* Fix for mobile Safari: ensure overlay stays behind card details */
@media screen and (max-width: 800px) {
.board-wrapper .board-canvas .board-overlay {
z-index: 17 !important;
}
/* In desktop mode on small screens, still keep overlay behind card */
body.desktop-mode .board-wrapper .board-canvas .board-overlay {
z-index: 17 !important;
}
}
/* In mobile mode, lower the overlay z-index to stay behind card details */
body.mobile-mode .board-wrapper .board-canvas .board-overlay {
z-index: 17 !important;
}
/* iPhone in desktop mode: remove overlay to avoid blocking card */
body.desktop-mode.iphone-device .board-wrapper .board-canvas .board-overlay {
display: none !important;
pointer-events: none !important;
}
/* Desktop mode: hide overlay to allow multiple cards and board interaction */
body.desktop-mode .board-wrapper .board-canvas .board-overlay {
display: none !important;
pointer-events: none !important;
}
.board-wrapper .board-canvas.is-dragging-active .open-minicard-composer,
.board-wrapper .board-canvas.is-dragging-active .minicard-wrapper.is-checked {
display: none;
}
@media screen and (max-width: 800px) {
/* Mobile view styles - applied when isMiniScreen is true (iPhone, etc.) */
.board-wrapper.mobile-view {
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
left: 0 !important;
right: 0 !important;
overflow-x: hidden !important;
overflow-y: auto !important;
}
.board-wrapper.mobile-view .board-canvas {
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
left: 0 !important;
right: 0 !important;
overflow-x: hidden !important;
overflow-y: auto !important;
}
.board-wrapper.mobile-view .board-canvas.mobile-view .swimlane {
border-bottom: 1px solid #ccc;
display: block !important;
flex-direction: column;
margin: 0;
padding: 0;
overflow-x: hidden !important;
overflow-y: auto;
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
}
@media screen and (max-width: 800px),
screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) {
.board-wrapper {
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
left: 0 !important;
right: 0 !important;
overflow-x: hidden !important;
overflow-y: auto !important;
}
.board-wrapper .board-canvas {
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
left: 0 !important;
right: 0 !important;
overflow-x: hidden !important;
overflow-y: auto !important;
}
.board-wrapper .board-canvas .swimlane {
border-bottom: 1px solid #ccc;
display: flex;
display: block !important;
flex-direction: column;
margin: 0;
padding: 0 0px 0px 0;
overflow-x: hidden;
padding: 0;
overflow-x: hidden !important;
overflow-y: auto;
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
}
}
.calendar-event-green {
@@ -222,3 +564,10 @@
font-size: 25px;
cursor: pointer;
}
/* Global file drag over state for board canvas */
.board-canvas.file-drag-over {
background-color: rgba(0, 123, 255, 0.05) !important;
border: 2px dashed #007bff !important;
transition: all 0.2s ease;
}
+35 -10
View File
@@ -1,5 +1,8 @@
template(name="board")
if isBoardReady.get
if isConverting
+boardConversionProgress
else if isBoardReady
if currentBoard
if onlyShowCurrentCard
+cardDetails(currentCard)
@@ -16,30 +19,52 @@ template(name="boardBody")
if notDisplayThisBoard
| {{_ 'tableVisibilityMode-allowPrivateOnly'}}
else
.board-wrapper(class=currentBoard.colorClass)
+sidebar
// Debug information (remove in production)
if debugBoardState
.debug-info(style="position: fixed; top: 0; left: 0; background: rgba(0,0,0,0.8); color: white; padding: 10px; z-index: 9999; font-size: 12px;")
| {{_ 'board'}}: {{currentBoard.title}} | {{_ 'view'}}: {{boardView}} | {{_ 'has-swimlanes'}}: {{hasSwimlanes}} | {{_ 'swimlanes'}}: {{currentBoard.swimlanes.length}}
.board-wrapper(class=currentBoard.colorClass class="{{#if isMiniScreen}}mobile-view{{/if}}")
.board-canvas.js-swimlanes(
class="{{#if hasSwimlanes}}dragscroll{{/if}}"
class="{{#if Sidebar.isOpen}}is-sibling-sidebar-open{{/if}}"
class="{{#if MultiSelection.isActive}}is-multiselection-active{{/if}}"
class="{{#if draggingActive.get}}is-dragging-active{{/if}}")
if showOverlay.get
class="{{#if draggingActive}}is-dragging-active{{/if}}"
class="{{#unless isVerticalScrollbars}}no-scrollbars{{/unless}}"
class="{{#if isMiniScreen}}mobile-view{{/if}}")
if showOverlay
.board-overlay
if currentBoard.isTemplatesBoard
each currentBoard.swimlanes
+swimlane(this)
else if isViewSwimlanes
each currentBoard.swimlanes
+swimlane(this)
if hasSwimlanes
each currentBoard.swimlanes
+swimlane(this)
else
// Fallback: If no swimlanes exist, show lists instead of empty message
+listsGroup(currentBoard)
else if isViewLists
+listsGroup(currentBoard)
else if isViewCalendar
+calendarView
else if isViewGantt
+ganttView
else
+listsGroup(currentBoard)
// Default view - show swimlanes if they exist, otherwise show lists
if hasSwimlanes
each currentBoard.swimlanes
+swimlane(this)
else
+listsGroup(currentBoard)
//- Render multiple open cards in desktop mode
unless isMiniScreen
each openCards
+cardDetails(this cardIndex=@index)
+sidebar
template(name="calendarView")
if isViewCalendar
.calendar-view.swimlane
.calendar-view.swimlane.dragscroll
if currentCard
+cardDetails(currentCard)
+fullcalendar(calendarOptions)
+fullcalendar(calendarOptions)
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+923 -7
View File
@@ -1,5 +1,5 @@
.integration-form {
padding: 5px;
padding: 0.7vh 0.7vw;
border-bottom: 1px solid #ccc;
}
.flex,
@@ -12,12 +12,928 @@
display: flex;
}
.option {
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-border-radius: 0.4vw;
border-radius: 0.4vw;
background: #fff;
text-decoration: none;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2);
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
margin-top: 5px;
padding: 5px;
-webkit-box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.2);
box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.2);
margin-top: 0.7vh;
padding: 0.7vh 0.7vw;
}
/* Zoom and Mobile Mode Controls */
.board-header-btns.center {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
}
.zoom-controls {
display: flex;
align-items: center;
gap: 0.5vw;
background: rgba(255, 255, 255, 0.9);
padding: 0.5vh 1vw;
border-radius: 0.5vw;
box-shadow: 0 0.2vh 0.5vh rgba(0,0,0,0.1);
}
.zoom-controls .board-header-btn {
padding: 0.5vh 0.8vw !important;
border-radius: 0.3vw !important;
background: #fff !important;
border: 1px solid #000 !important;
transition: all 0.2s ease !important;
color: #000 !important;
height: auto !important;
line-height: normal !important;
margin: 0 !important;
float: none !important;
overflow: visible !important;
}
.zoom-controls .board-header-btn i {
color: #000 !important;
float: none !important;
display: inline !important;
line-height: normal !important;
margin: 0 !important;
}
.zoom-controls .board-header-btn:hover {
background: #000 !important;
border-color: #000 !important;
color: #fff !important;
}
.zoom-controls .board-header-btn:hover i {
color: #fff !important;
}
.zoom-controls .board-header-btn.is-active {
background: #0079bf;
color: white;
border-color: #005a8a;
}
.zoom-controls .board-header-btn.is-active i {
color: white;
}
.zoom-level {
font-weight: bold;
color: #333;
min-width: 3vw;
text-align: center;
font-size: clamp(12px, 2vw, 14px);
cursor: pointer;
padding: 0.3vh 0.5vw;
border-radius: 0.3vw;
transition: all 0.2s ease;
}
.zoom-level:hover {
background: #f0f0f0;
color: #000;
}
/* Mobile Mode Styles */
.mobile-mode .board-wrapper {
width: 100%;
height: 100%;
}
.mobile-mode .board-canvas {
height: 100%;
}
.mobile-mode .minicard {
font-size: clamp(16px, 4vw, 20px);
padding: 1.2vh 1.5vw 0.5vh;
min-height: 3vh;
}
.mobile-mode .list-header-name {
font-size: clamp(18px, 4.5vw, 24px);
}
.mobile-mode .board-header-btn {
padding: 1vh 1.5vw;
font-size: clamp(14px, 3.5vw, 18px);
}
.mobile-mode .zoom-controls {
padding: 1vh 1.5vw;
gap: 1vw;
}
.mobile-mode .zoom-controls .board-header-btn {
padding: 1vh 1.5vw !important;
font-size: clamp(14px, 3.5vw, 18px) !important;
background: #fff !important;
border: 1px solid #000 !important;
color: #000 !important;
height: auto !important;
line-height: normal !important;
margin: 0 !important;
float: none !important;
overflow: visible !important;
}
.mobile-mode .zoom-controls .board-header-btn i {
color: #000 !important;
float: none !important;
display: inline !important;
line-height: normal !important;
margin: 0 !important;
}
.mobile-mode .zoom-controls .board-header-btn:hover {
background: #000 !important;
border-color: #000 !important;
color: #fff !important;
}
.mobile-mode .zoom-controls .board-header-btn:hover i {
color: #fff !important;
}
.mobile-mode .zoom-level {
font-size: clamp(14px, 3.5vw, 18px);
min-width: 4vw;
}
/* Comprehensive Mobile Mode Styles - Works on all screen sizes */
.mobile-mode .board-wrapper {
width: 100% !important;
height: 100% !important;
transform: none !important;
transform-origin: initial !important;
max-width: 100% !important;
}
.mobile-mode .board-canvas {
height: 100% !important;
overflow-x: hidden !important;
overflow-y: auto !important;
width: 100% !important;
max-width: 100% !important;
}
.mobile-mode .swimlane {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
margin-bottom: 2rem !important;
display: block !important;
float: none !important;
}
.mobile-mode .swimlane-header {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
font-size: clamp(18px, 2.5vw, 32px) !important;
padding: 1rem !important;
margin-bottom: 1rem !important;
display: block !important;
}
.mobile-mode .list {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
display: block !important;
float: none !important;
margin-bottom: 2rem !important;
border-left: none !important;
border-bottom: 2px solid #ccc !important;
clear: both !important;
}
.mobile-mode .list-header {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
padding: 1rem !important;
font-size: clamp(18px, 2.5vw, 32px) !important;
display: grid !important;
grid-template-columns: 30px 1fr auto auto !important;
gap: 10px !important;
align-items: center !important;
position: relative !important;
}
.mobile-mode .list-header .list-header-name {
font-size: clamp(18px, 2.5vw, 32px) !important;
font-weight: bold !important;
grid-row: 1 !important;
grid-column: 2 !important;
align-self: end !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .list-header .cardCount {
font-size: clamp(14px, 2vw, 24px) !important;
grid-row: 2 !important;
grid-column: 2 !important;
align-self: start !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .list-header .list-header-menu-icon {
position: static !important;
right: auto !important;
top: auto !important;
transform: none !important;
grid-row: 1/3 !important;
grid-column: 3 !important;
padding: 14px !important;
font-size: clamp(24px, 3vw, 48px) !important;
text-align: center !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .list-header .list-header-handle {
position: static !important;
right: auto !important;
top: auto !important;
transform: none !important;
grid-row: 1/3 !important;
grid-column: 4 !important;
padding: 14px !important;
font-size: clamp(28px, 3.5vw, 56px) !important;
text-align: center !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .list-body {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
padding: 1rem !important;
display: block !important;
}
.mobile-mode .minicard {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
font-size: clamp(16px, 2vw, 24px) !important;
padding: 1.2vh 1.5vw 0.5vh !important;
min-height: 3vh !important;
margin-bottom: 0.5rem !important;
display: block !important;
float: none !important;
}
.mobile-mode .minicard .minicard-title {
font-size: clamp(16px, 2vw, 24px) !important;
font-weight: bold !important;
}
.mobile-mode .minicard .minicard-members {
font-size: clamp(12px, 1.5vw, 18px) !important;
}
.mobile-mode .minicard .minicard-lists {
font-size: clamp(12px, 1.5vw, 18px) !important;
}
/* Desktop Mode Styles */
.desktop-mode .board-wrapper {
width: auto !important;
height: auto !important;
}
.desktop-mode .swimlane {
width: auto !important;
min-width: auto !important;
}
.desktop-mode .list {
width: auto !important;
min-width: auto !important;
display: flex !important;
float: left !important;
margin-bottom: 0 !important;
border-left: 1px solid #ccc !important;
border-bottom: none !important;
}
.desktop-mode .list-header {
width: auto !important;
min-width: auto !important;
padding: 2.5vh 1.5vw 0.5vh !important;
font-size: clamp(14px, 3vw, 18px) !important;
display: block !important;
}
.desktop-mode .list-header .list-header-name {
font-size: clamp(14px, 3vw, 18px) !important;
display: inline !important;
grid-row: auto !important;
grid-column: auto !important;
align-self: auto !important;
}
.desktop-mode .list-header .cardCount {
font-size: 12px !important;
grid-row: auto !important;
grid-column: auto !important;
align-self: auto !important;
}
.desktop-mode .list-header .list-header-menu-icon {
position: absolute !important;
right: 60px !important;
top: 50% !important;
transform: translateY(-50%) !important;
grid-row: auto !important;
grid-column: auto !important;
padding: 14px !important;
font-size: 40px !important;
}
.desktop-mode .list-header .list-header-handle {
position: absolute !important;
right: 10px !important;
top: 50% !important;
transform: translateY(-50%) !important;
grid-row: auto !important;
grid-column: auto !important;
padding: 7px !important;
font-size: clamp(16px, 3vw, 20px) !important;
}
.desktop-mode .list-body {
width: auto !important;
min-width: auto !important;
padding: 5px 11px !important;
}
.desktop-mode .minicard {
width: auto !important;
min-width: auto !important;
font-size: clamp(12px, 2.5vw, 16px) !important;
padding: 0.5vh 0.8vw !important;
min-height: auto !important;
margin-bottom: 9px !important;
}
.desktop-mode .minicard .minicard-title {
font-size: clamp(12px, 2.5vw, 16px) !important;
}
.desktop-mode .minicard .minicard-members {
font-size: 10px !important;
}
.desktop-mode .minicard .minicard-lists {
font-size: 10px !important;
}
/* Additional Mobile Mode Styles for Other Elements - Works on all screen sizes */
.mobile-mode .swimlane-header .swimlane-title {
font-size: clamp(18px, 2.5vw, 32px) !important;
font-weight: bold !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .swimlane-header .swimlane-description {
font-size: clamp(14px, 2vw, 24px) !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .board-header {
font-size: clamp(18px, 2.5vw, 32px) !important;
padding: 1rem !important;
width: 100% !important;
max-width: 100% !important;
}
.mobile-mode .board-header .board-header-title {
font-size: clamp(18px, 2.5vw, 32px) !important;
font-weight: bold !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .board-header .board-header-description {
font-size: clamp(14px, 2vw, 24px) !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .board-header .board-header-btn {
font-size: clamp(14px, 2vw, 24px) !important;
padding: 1vh 1.5vw !important;
display: inline-block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .board-header .board-header-btn i {
font-size: clamp(14px, 2vw, 24px) !important;
display: inline !important;
visibility: visible !important;
opacity: 1 !important;
}
/* Force mobile mode visibility on all screen sizes */
.mobile-mode .list-header .fa-angle-right,
.mobile-mode .list-header .fa-arrows {
display: block !important;
visibility: visible !important;
opacity: 1 !important;
position: static !important;
right: auto !important;
top: auto !important;
transform: none !important;
}
.mobile-mode .list-header .fa-angle-right {
grid-row: 1/3 !important;
grid-column: 3 !important;
padding: 14px !important;
font-size: clamp(24px, 3vw, 48px) !important;
text-align: center !important;
}
.mobile-mode .list-header .fa-arrows {
grid-row: 1/3 !important;
grid-column: 4 !important;
padding: 14px !important;
font-size: clamp(28px, 3.5vw, 56px) !important;
text-align: center !important;
}
/* Override any media queries that might hide elements in mobile mode */
.mobile-mode * {
max-width: none !important;
}
.mobile-mode .list,
.mobile-mode .swimlane,
.mobile-mode .board-wrapper,
.mobile-mode .board-canvas {
max-width: 100% !important;
width: 100% !important;
min-width: 100% !important;
}
/* Force mobile mode list styling on all screen sizes - override desktop CSS */
.mobile-mode .board-canvas {
display: block !important;
flex-direction: column !important;
flex-wrap: nowrap !important;
align-items: stretch !important;
justify-content: flex-start !important;
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
overflow-x: hidden !important;
overflow-y: auto !important;
}
.mobile-mode .swimlane {
display: block !important;
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
}
.mobile-mode .swimlane .swimlane-header {
display: block !important;
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
margin: 0 0 1rem 0 !important;
padding: 1rem !important;
font-size: clamp(18px, 2.5vw, 32px) !important;
font-weight: bold !important;
border-bottom: 2px solid #ccc !important;
}
.mobile-mode .swimlane .lists {
display: block !important;
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
margin: 0 !important;
padding: 0 !important;
flex-direction: column !important;
flex-wrap: nowrap !important;
align-items: stretch !important;
justify-content: flex-start !important;
}
.mobile-mode .list {
display: block !important;
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
border-bottom: 2px solid #ccc !important;
flex: none !important;
flex-basis: auto !important;
flex-grow: 0 !important;
flex-shrink: 0 !important;
position: static !important;
left: auto !important;
right: auto !important;
top: auto !important;
bottom: auto !important;
transform: none !important;
}
.mobile-mode .list:first-child {
margin-left: 0 !important;
margin-top: 0 !important;
}
.mobile-mode .list:last-child {
margin-right: 0 !important;
margin-bottom: 0 !important;
}
.mobile-mode .list.ui-sortable-helper {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
height: auto !important;
min-height: 60px !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
border-bottom: 2px solid #ccc !important;
flex: none !important;
}
.mobile-mode .list.placeholder {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
height: auto !important;
min-height: 60px !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
border-bottom: 2px solid #ccc !important;
flex: none !important;
}
/* Override any existing responsive CSS that might interfere with mobile mode */
.mobile-mode .board-canvas .swimlane .lists {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 !important;
padding: 0 !important;
flex-direction: column !important;
flex-wrap: nowrap !important;
align-items: stretch !important;
justify-content: flex-start !important;
overflow: visible !important;
}
.mobile-mode .board-canvas .swimlane .lists .list {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
border-bottom: 2px solid #ccc !important;
flex: none !important;
flex-basis: auto !important;
flex-grow: 0 !important;
flex-shrink: 0 !important;
position: static !important;
left: auto !important;
right: auto !important;
top: auto !important;
bottom: auto !important;
transform: none !important;
}
/* Force mobile mode to override any media query styles */
@media screen and (min-width: 801px) {
.mobile-mode .board-canvas {
display: block !important;
flex-direction: column !important;
flex-wrap: nowrap !important;
align-items: stretch !important;
justify-content: flex-start !important;
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
overflow-x: hidden !important;
overflow-y: auto !important;
}
.mobile-mode .swimlane {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
}
.mobile-mode .swimlane .lists {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 !important;
padding: 0 !important;
flex-direction: column !important;
flex-wrap: nowrap !important;
align-items: stretch !important;
justify-content: flex-start !important;
}
.mobile-mode .list {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
border-bottom: 2px solid #ccc !important;
flex: none !important;
flex-basis: auto !important;
flex-grow: 0 !important;
flex-shrink: 0 !important;
position: static !important;
left: auto !important;
right: auto !important;
top: auto !important;
bottom: auto !important;
transform: none !important;
}
}
/* Hide desktop-only elements in mobile mode (like mobile media queries do) */
.mobile-mode .board-header-btn i.fa + span {
display: none !important;
}
.mobile-mode .board-header-btn span {
display: none !important;
}
.mobile-mode .board-header-btn .fa + span {
display: none !important;
}
.mobile-mode .board-header-btn .fa + .board-header-btn-text {
display: none !important;
}
.mobile-mode .board-header-btn .fa + .board-header-btn-label {
display: none !important;
}
/* Show only icons in mobile mode */
.mobile-mode .board-header-btn {
width: auto !important;
min-width: auto !important;
padding: 8px !important;
text-align: center !important;
}
.mobile-mode .board-header-btn i {
display: inline-block !important;
margin: 0 !important;
}
/* Hide desktop-specific elements that shouldn't show in mobile mode */
.mobile-mode .desktop-only,
.mobile-mode .board-header .desktop-only {
display: none !important;
}
.mobile-mode .board-header .board-header-btn.desktop-only {
display: none !important;
}
/* Hide desktop-specific board header buttons in mobile mode */
.mobile-mode .board-header-btns.left {
display: none !important;
}
.mobile-mode .board-header-btns.center {
display: none !important;
}
/* Show only the right section buttons in mobile mode, but hide text labels */
.mobile-mode .board-header-btns.right {
display: block !important;
}
.mobile-mode .board-header-btns.right .board-header-btn span {
display: none !important;
}
.mobile-mode .board-header-btns.right .board-header-btn .fa + span {
display: none !important;
}
.mobile-mode .board-header-btns.right .board-header-btn .fa + .board-header-btn-text {
display: none !important;
}
.mobile-mode .board-header-btns.right .board-header-btn .fa + .board-header-btn-label {
display: none !important;
}
/* Hide specific desktop-only buttons that shouldn't show in mobile mode */
.mobile-mode .board-header-btn.js-star-board span,
.mobile-mode .board-header-btn.js-change-visibility span,
.mobile-mode .board-header-btn.js-watch-board span,
.mobile-mode .board-header-btn.js-sort-cards span {
display: none !important;
}
/* Show only icons for mobile mode buttons */
.mobile-mode .board-header-btns.right .board-header-btn {
width: auto !important;
min-width: auto !important;
padding: 8px !important;
text-align: center !important;
margin: 0 2px !important;
}
.mobile-mode .board-header-btns.right .board-header-btn i {
display: inline-block !important;
margin: 0 !important;
}
/* Ensure mobile mode looks like small screen mobile view */
.mobile-mode .board-header {
height: 40px !important;
}
.mobile-mode .board-header .board-header-btns {
margin-top: 0px !important;
}
.mobile-mode .board-header .board-header-btn {
height: 32px !important;
line-height: 32px !important;
font-size: 15px !important;
}
.mobile-mode .board-header .board-header-btn i.fa {
line-height: 32px !important;
}
/* Copy mobile media query styles to mobile mode for consistent appearance */
.mobile-mode .board-header {
height: 40px !important;
padding: 0 !important;
margin: 0 !important;
}
.mobile-mode .board-header .board-header-btns {
margin-top: 0px !important;
height: 40px !important;
display: flex !important;
align-items: center !important;
justify-content: flex-end !important;
}
.mobile-mode .board-header .board-header-btn {
height: 32px !important;
line-height: 32px !important;
font-size: 15px !important;
margin: 0 2px !important;
padding: 4px 8px !important;
border-radius: 4px !important;
background: rgba(255, 255, 255, 0.1) !important;
border: 1px solid rgba(255, 255, 255, 0.2) !important;
color: #fff !important;
text-decoration: none !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
min-width: 32px !important;
width: auto !important;
}
.mobile-mode .board-header .board-header-btn:hover {
background: rgba(255, 255, 255, 0.2) !important;
border-color: rgba(255, 255, 255, 0.3) !important;
}
.mobile-mode .board-header .board-header-btn i.fa {
line-height: 32px !important;
font-size: 15px !important;
margin: 0 !important;
padding: 0 !important;
}
.mobile-mode .board-header .board-header-btn i.fa + span {
display: none !important;
}
.mobile-mode .board-header .board-header-btn span {
display: none !important;
}
/* Hide the board title in mobile mode to match mobile view */
.mobile-mode .header-board-menu {
display: none !important;
}
/* Ensure the board header takes full width in mobile mode */
.mobile-mode .board-header {
width: 100% !important;
max-width: 100% !important;
display: flex !important;
align-items: center !important;
justify-content: space-between !important;
padding: 0 10px !important;
}
/* Additional Desktop Mode Styles for Other Elements */
.desktop-mode .swimlane-header .swimlane-title {
font-size: clamp(14px, 3vw, 18px) !important;
}
.desktop-mode .swimlane-header .swimlane-description {
font-size: 12px !important;
}
.desktop-mode .board-header {
font-size: clamp(14px, 3vw, 18px) !important;
padding: 2.5vh 1.5vw 0.5vh !important;
}
.desktop-mode .board-header .board-header-title {
font-size: clamp(14px, 3vw, 18px) !important;
}
.desktop-mode .board-header .board-header-description {
font-size: 12px !important;
}
.desktop-mode .board-header .board-header-btn {
font-size: clamp(12px, 2.5vw, 16px) !important;
padding: 0.5vh 0.8vw !important;
}
.desktop-mode .board-header .board-header-btn i {
font-size: clamp(12px, 2.5vw, 16px) !important;
}
+280 -161
View File
@@ -1,154 +1,159 @@
template(name="boardHeaderBar")
h1.header-board-menu
with currentBoard
if $eq title 'Templates'
| {{_ 'templates'}}
else
+viewer
= title
unless notDisplayThisBoard
h1.header-board-menu
with currentBoard
if $eq title 'Templates'
| {{_ 'templates'}}
else
+viewer
= title
.board-header-btns.left
unless isMiniScreen
.board-header-btns.left
unless isMiniScreen
if currentBoard
if currentUser
with currentBoard
if currentUser.isBoardAdmin
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title)
i.fa.fa-pencil-square-o
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
span {{_ currentBoard.permission}}
a.board-header-btn.js-watch-board(
title="{{_ watchLevel }}")
if $eq watchLevel "watching"
i.fa.fa-eye
if $eq watchLevel "tracking"
i.fa.fa-bell
if $eq watchLevel "muted"
i.fa.fa-bell-slash
span {{_ watchLevel}}
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
if showStarCounter
span.board-star-counter {{currentBoard.stars}}
a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}")
i.fa.fa-sort
span {{#if isSortActive }}{{_ 'sort-is-on'}}{{else}}{{_ 'sort-cards'}}{{/if}}
if isSortActive
a.board-header-btn-close.js-sort-reset(title="{{_ 'remove-sort'}}")
i.fa.fa-times-thin
else
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
span {{_ 'log-in'}}
.board-header-btns.center
.board-header-btns.right
if currentBoard
if currentUser
with currentBoard
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title)
i.fa.fa-pencil-square-o
if isMiniScreen
if currentUser
with currentBoard
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title)
i.fa.fa-pencil-square-o
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
if showStarCounter
span
= currentBoard.stars
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
span {{_ currentBoard.permission}}
a.board-header-btn.js-watch-board(
title="{{_ watchLevel }}")
if $eq watchLevel "watching"
i.fa.fa-eye
if $eq watchLevel "tracking"
i.fa.fa-bell
if $eq watchLevel "muted"
i.fa.fa-bell-slash
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}")
i.fa.fa-sort
span {{#if isSortActive }}{{_ 'sort-is-on'}}{{else}}{{_ 'sort-cards'}}{{/if}}
if isSortActive
a.board-header-btn-close.js-sort-reset(title="{{_ 'remove-sort'}}")
i.fa.fa-times-thin
a.board-header-btn.js-watch-board(
title="{{_ watchLevel }}")
if $eq watchLevel "watching"
i.fa.fa-eye
if $eq watchLevel "tracking"
i.fa.fa-bell
if $eq watchLevel "muted"
i.fa.fa-bell-slash
span {{_ watchLevel}}
a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}")
i.fa.fa-sort
span {{#if isSortActive }}{{_ 'sort-is-on'}}{{else}}{{_ 'sort-cards'}}{{/if}}
if isSortActive
a.board-header-btn-close.js-sort-reset(title="{{_ 'remove-sort'}}")
i.fa.fa-times-thin
else
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
else
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
span {{_ 'log-in'}}
if isSandstorm
if currentUser
a.board-header-btn.js-open-archived-board
i.fa.fa-archive
.board-header-btns.right
if currentBoard
if isMiniScreen
if currentUser
with currentBoard
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title)
i.fa.fa-pencil-square-o
//if showSort
//
a.board-header-btn.js-open-sort-view(title="{{_ 'sort-desc'}}")
//
i.fa(class="{{directionClass}}")
//
span {{_ 'sort'}}{{_ listSortShortDesc}}
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
if showStarCounter
span
= currentBoard.stars
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
span {{_ currentBoard.permission}}
a.board-header-btn.js-watch-board(
title="{{_ watchLevel }}")
if $eq watchLevel "watching"
i.fa.fa-eye
if $eq watchLevel "tracking"
i.fa.fa-bell
if $eq watchLevel "muted"
i.fa.fa-bell-slash
span {{_ watchLevel}}
a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}")
i.fa.fa-sort
span {{#if isSortActive }}{{_ 'sort-is-on'}}{{else}}{{_ 'sort-cards'}}{{/if}}
if isSortActive
a.board-header-btn-close.js-sort-reset(title="{{_ 'remove-sort'}}")
i.fa.fa-times-thin
else
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
span {{_ 'log-in'}}
if isSandstorm
if currentUser
a.board-header-btn.js-open-archived-board
i.fa.fa-archive
span {{_ 'archives'}}
//if showSort
// a.board-header-btn.js-open-sort-view(title="{{_ 'sort-desc'}}")
// i.fa(class="{{directionClass}}")
// span {{_ 'sort'}}{{_ listSortShortDesc}}
a.board-header-btn.js-open-filter-view(
title="{{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}"
class="{{#if Filter.isActive}}emphasis{{/if}}")
i.fa.fa-filter
span {{#if Filter.isActive}}{{_ 'filter-on'}}{{else}}{{_ 'filter'}}{{/if}}
if Filter.isActive
a.board-header-btn-close.js-filter-reset(title="{{_ 'filter-clear'}}")
i.fa.fa-times-thin
a.board-header-btn.js-open-search-view(title="{{_ 'search'}}")
i.fa.fa-search
span {{_ 'search'}}
unless currentBoard.isTemplatesBoard
a.board-header-btn.js-toggle-board-view(
title="{{_ 'board-view'}}")
i.fa.fa-caret-down
if $eq boardView 'board-view-swimlanes'
i.fa.fa-th-large
if $eq boardView 'board-view-lists'
i.fa.fa-trello
if $eq boardView 'board-view-cal'
i.fa.fa-calendar
span {{#if boardView}}{{_ boardView}}{{else}}{{_ 'board-view-swimlanes'}}{{/if}}
if canModifyBoard
a.board-header-btn.js-multiselection-activate(
title="{{#if MultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}"
class="{{#if MultiSelection.isActive}}emphasis{{/if}}")
i.fa.fa-check-square-o
span {{#if MultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}
if MultiSelection.isActive
a.board-header-btn-close.js-multiselection-reset(title="{{_ 'filter-clear'}}")
a.board-header-btn.js-open-filter-view(
title="{{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}"
class="{{#if Filter.isActive}}js-filter-active{{/if}}")
i.fa.fa-filter
span {{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}
if Filter.isActive
a.board-header-btn-close.js-filter-reset(title="{{_ 'filter-clear'}}")
i.fa.fa-times-thin
.separator
a.board-header-btn.js-toggle-sidebar(title="{{_ 'sidebar-open'}} {{_ 'or'}} {{_ 'sidebar-close'}}")
i.fa.fa-navicon
a.board-header-btn.js-open-search-view(title="{{_ 'search'}}")
i.fa.fa-search
span {{_ 'search'}}
unless currentBoard.isTemplatesBoard
a.board-header-btn.js-toggle-board-view
i.fa.fa-caret-down
if $eq boardView 'board-view-swimlanes'
i.fa.fa-th-large
if $eq boardView 'board-view-lists'
i.fa.fa-trello
if $eq boardView 'board-view-cal'
i.fa.fa-calendar
if $eq boardView 'board-view-gantt'
i.fa.fa-bar-chart
span
if $eq boardView 'board-view-swimlanes'
| {{_ 'swimlanes'}}
if $eq boardView 'board-view-lists'
| {{_ 'lists'}}
if $eq boardView 'board-view-cal'
| {{_ 'calendar'}}
if $eq boardView 'board-view-gantt'
| {{_ 'gantt'}}
if canModifyBoard
a.board-header-btn.js-multiselection-activate(
title="{{#if MultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}"
class="{{#if MultiSelection.isActive}}emphasis{{/if}}")
i.fa.fa-check-square-o
span {{#if MultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}
if MultiSelection.isActive
a.board-header-btn-close.js-multiselection-reset(title="{{_ 'filter-clear'}}")
i.fa.fa-times-thin
.separator
a.board-header-btn.js-toggle-sidebar(title="{{_ 'sidebar-open'}} {{_ 'or'}} {{_ 'sidebar-close'}}")
i.fa.fa-bars
template(name="boardVisibilityList")
ul.pop-over-list
li
with "private"
a.js-select-visibility
i.fa.fa-lock.colorful
i.fa.fa-lock
| {{_ 'private'}}
if visibilityCheck
i.fa.fa-check
@@ -157,7 +162,7 @@ template(name="boardVisibilityList")
li
with "public"
a.js-select-visibility
i.fa.fa-globe.colorful
i.fa.fa-globe
| {{_ 'public'}}
if visibilityCheck
i.fa.fa-check
@@ -171,7 +176,7 @@ template(name="boardChangeWatchPopup")
li
with "watching"
a.js-select-watch
i.fa.fa-eye.colorful
i.fa.fa-eye
| {{_ 'watching'}}
if watchCheck
i.fa.fa-check
@@ -179,7 +184,7 @@ template(name="boardChangeWatchPopup")
li
with "tracking"
a.js-select-watch
i.fa.fa-bell.colorful
i.fa.fa-bell
| {{_ 'tracking'}}
if watchCheck
i.fa.fa-check
@@ -187,7 +192,7 @@ template(name="boardChangeWatchPopup")
li
with "muted"
a.js-select-watch
i.fa.fa-bell-slash.colorful
i.fa.fa-bell-slash
| {{_ 'muted'}}
if watchCheck
i.fa.fa-check
@@ -198,35 +203,130 @@ template(name="boardChangeViewPopup")
li
with "board-view-swimlanes"
a.js-open-swimlanes-view
i.fa.fa-th-large.colorful
| {{_ 'board-view-swimlanes'}}
i.fa.fa-th-large
| {{_ 'swimlanes'}}
if $eq Utils.boardView "board-view-swimlanes"
i.fa.fa-check
li
with "board-view-lists"
a.js-open-lists-view
i.fa.fa-trello.colorful
i.fa.fa-trello
| {{_ 'board-view-lists'}}
if $eq Utils.boardView "board-view-lists"
i.fa.fa-check
li
with "board-view-cal"
a.js-open-cal-view
i.fa.fa-calendar.colorful
i.fa.fa-calendar
| {{_ 'board-view-cal'}}
if $eq Utils.boardView "board-view-cal"
i.fa.fa-check
li
with "board-view-gantt"
a.js-open-gantt-view
i.fa.fa-bar-chart
| {{_ 'board-view-gantt'}}
if $eq Utils.boardView "board-view-gantt"
i.fa.fa-check
template(name="createBoard")
form
label
| {{_ 'title'}}
input.js-new-board-title(type="text" placeholder="{{_ 'bucket-example'}}" autofocus required)
if visibilityMenuIsOpen.get
if visibilityMenuIsOpen
+boardVisibilityList
else
p.quiet
if $eq visibility.get 'public'
if $eq visibility 'public'
span.fa.fa-globe.colorful
= " "
| {{{_ 'board-public-info'}}}
else
span.fa.fa-lock.colorful
= " "
| {{{_ 'board-private-info'}}}
a.js-change-visibility {{_ 'change'}}.
a.flex.js-toggle-add-template-container
.materialCheckBox#add-template-container
span {{_ 'add-template-container'}}
input.primary.wide(type="submit" value="{{_ 'create'}}")
span.quiet
| {{_ 'or'}}
a.js-import-board {{_ 'import'}}
span.quiet
| /
a.js-board-template {{_ 'template'}}
template(name="createBoardPopup")
form
label
| {{_ 'title'}}
input.js-new-board-title(type="text" placeholder="{{_ 'bucket-example'}}" autofocus required)
if visibilityMenuIsOpen
+boardVisibilityList
else
p.quiet
if $eq visibility 'public'
span.fa.fa-globe.colorful
= " "
| {{{_ 'board-public-info'}}}
else
span.fa.fa-lock.colorful
= " "
| {{{_ 'board-private-info'}}}
a.js-change-visibility {{_ 'change'}}.
a.flex.js-toggle-add-template-container
.materialCheckBox#add-template-container
span {{_ 'add-template-container'}}
input.primary.wide(type="submit" value="{{_ 'create'}}")
span.quiet
| {{_ 'or'}}
a.js-import-board {{_ 'import'}}
span.quiet
| /
a.js-board-template {{_ 'template'}}
template(name="headerBarCreateBoardPopup")
form
label
| {{_ 'title'}}
input.js-new-board-title(type="text" placeholder="{{_ 'bucket-example'}}" autofocus required)
if visibilityMenuIsOpen
+boardVisibilityList
else
p.quiet
if $eq visibility 'public'
span.fa.fa-globe.colorful
= " "
| {{{_ 'board-public-info'}}}
else
span.fa.fa-lock.colorful
= " "
| {{{_ 'board-private-info'}}}
a.js-change-visibility {{_ 'change'}}.
a.flex.js-toggle-add-template-container
.materialCheckBox#add-template-container
span {{_ 'add-template-container'}}
input.primary.wide(type="submit" value="{{_ 'create'}}")
span.quiet
| {{_ 'or'}}
a.js-import-board {{_ 'import'}}
span.quiet
| /
a.js-board-template {{_ 'template'}}
// New popup for Template Container creation; shares the same form content
template(name="createTemplateContainerPopup")
form
label
| {{_ 'title'}}
input.js-new-board-title(type="text" placeholder="{{_ 'bucket-example'}}" autofocus required)
if visibilityMenuIsOpen
+boardVisibilityList
else
p.quiet
if $eq visibility 'public'
span.fa.fa-globe.colorful
= " "
| {{{_ 'board-public-info'}}}
@@ -247,19 +347,30 @@ template(name="createBoard")
a.js-board-template {{_ 'template'}}
//template(name="listsortPopup")
// h2
// | {{_ 'list-sort-by'}}
// hr
// ul.pop-over-list
// each value in allowedSortValues
// li
// a.js-sort-by(name="{{value.name}}")
// if $eq sortby value.name
// i(class="fa {{Direction}}")
// | {{_ value.label }}{{_ value.shortLabel}}
// if $eq sortby value.name
// i(class="fa fa-check")
//
h2
//
| {{_ 'list-sort-by'}}
//
hr
//
ul.pop-over-list
//
each value in allowedSortValues
//
li
//
a.js-sort-by(name="{{value.name}}")
//
if $eq sortby value.name
//
| {{#if $eq Direction "fa-arrow-up"}}⬆️{{else}}⬇️{{/if}}
//
| {{_ value.label }}{{_ value.shortLabel}}
//
if $eq sortby value.name
//
i.fa.fa-check
template(name="boardChangeTitlePopup")
form
label
@@ -278,14 +389,22 @@ template(name="boardCreateRulePopup")
template(name="cardsSortPopup")
ul.pop-over-list
li
a.js-sort-due {{_ 'due-date'}}
a.js-sort-due
i.fa.fa-calendar
| {{_ 'due-date'}}
hr
li
a.js-sort-title {{_ 'title-alphabetically'}}
a.js-sort-title
i.fa.fa-sort-alpha-asc
| {{_ 'title-alphabetically'}}
hr
li
a.js-sort-created-desc {{_ 'created-at-newest-first'}}
a.js-sort-created-desc
i.fa.fa-arrow-down
| {{_ 'created-at-newest-first'}}
hr
li
a.js-sort-created-asc {{_ 'created-at-oldest-first'}}
a.js-sort-created-asc
i.fa.fa-arrow-up
| {{_ 'created-at-oldest-first'}}
+402 -331
View File
@@ -1,45 +1,25 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { TAPi18n } from '/imports/i18n';
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
import dragscroll from '@wekanteam/dragscroll';
import getSlug from 'limax';
import Boards from '/models/boards';
import Swimlanes from '/models/swimlanes';
import TableVisibilityModeSettings from '/models/tableVisibilityModeSettings';
import { Filter } from '/client/lib/filter';
import { MultiSelection } from '/client/lib/multiSelection';
import { getSidebarInstance } from '/client/features/sidebar/service';
import { Utils } from '/client/lib/utils';
/*
const DOWNCLS = 'fa-sort-down';
const UPCLS = 'fa-sort-up';
*/
const sortCardsBy = new ReactiveVar('');
Template.boardMenuPopup.events({
'click .js-rename-board': Popup.open('boardChangeTitle'),
'click .js-custom-fields'() {
Sidebar.setView('customFields');
Popup.back();
},
'click .js-open-archives'() {
Sidebar.setView('archives');
Popup.back();
},
'click .js-change-board-color': Popup.open('boardChangeColor'),
'click .js-change-language': Popup.open('changeLanguage'),
'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function() {
const currentBoard = Utils.getCurrentBoard();
currentBoard.archive();
// XXX We should have some kind of notification on top of the page to
// confirm that the board was successfully archived.
FlowRouter.go('home');
}),
'click .js-delete-board': Popup.afterConfirm('deleteBoard', function() {
const currentBoard = Utils.getCurrentBoard();
Popup.back();
Boards.remove(currentBoard._id);
FlowRouter.go('home');
}),
'click .js-outgoing-webhooks': Popup.open('outgoingWebhooks'),
'click .js-import-board': Popup.open('chooseBoardSource'),
'click .js-subtask-settings': Popup.open('boardSubtaskSettings'),
'click .js-card-settings': Popup.open('boardCardSettings'),
'click .js-minicard-settings': Popup.open('boardMinicardSettings'),
});
Template.boardChangeTitlePopup.events({
submit(event, templateInstance) {
async submit(event, templateInstance) {
event.preventDefault();
const newTitle = templateInstance
.$('.js-board-name')
.val()
@@ -49,15 +29,32 @@ Template.boardChangeTitlePopup.events({
.val()
.trim();
if (newTitle) {
this.rename(newTitle);
this.setDescription(newDesc);
const board = Utils.getCurrentBoard();
if (board) {
await board.rename(newTitle);
await board.setDescription(newDesc);
}
Popup.back();
}
event.preventDefault();
},
});
BlazeComponent.extendComponent({
Template.boardHeaderBar.onCreated(function () {
Meteor.subscribe('tableVisibilityModeSettings');
});
Template.boardHeaderBar.helpers({
notDisplayThisBoard() {
const allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly');
const currentBoard = Utils.getCurrentBoard();
return (
allowPrivateVisibilityOnly !== undefined &&
allowPrivateVisibilityOnly.booleanValue &&
currentBoard &&
currentBoard.permission === 'public'
);
},
watchLevel() {
const currentBoard = Utils.getCurrentBoard();
return currentBoard && currentBoard.getWatchLevel(Meteor.userId());
@@ -74,97 +71,130 @@ BlazeComponent.extendComponent({
const currentBoard = Utils.getCurrentBoard();
return currentBoard && currentBoard.stars >= 2;
},
/*
showSort() {
return ReactiveCache.getCurrentUser().hasSortBy();
},
directionClass() {
return this.currentDirection() === -1 ? DOWNCLS : UPCLS;
},
changeDirection() {
const direction = 0 - this.currentDirection() === -1 ? '-' : '';
Meteor.call('setListSortBy', direction + this.currentListSortBy());
},
currentDirection() {
return ReactiveCache.getCurrentUser().getListSortByDirection();
},
currentListSortBy() {
return ReactiveCache.getCurrentUser().getListSortBy();
},
listSortShortDesc() {
return `list-label-short-${this.currentListSortBy()}`;
},
*/
events() {
return [
{
'click .js-edit-board-title': Popup.open('boardChangeTitle'),
'click .js-star-board'() {
ReactiveCache.getCurrentUser().toggleBoardStar(Session.get('currentBoard'));
},
'click .js-open-board-menu': Popup.open('boardMenu'),
'click .js-change-visibility': Popup.open('boardChangeVisibility'),
'click .js-watch-board': Popup.open('boardChangeWatch'),
'click .js-open-archived-board'() {
Modal.open('archivedBoards');
},
'click .js-toggle-board-view': Popup.open('boardChangeView'),
'click .js-toggle-sidebar'() {
Sidebar.toggle();
},
'click .js-open-filter-view'() {
Sidebar.setView('filter');
},
'click .js-sort-cards': Popup.open('cardsSort'),
/*
'click .js-open-sort-view'(evt) {
const target = evt.target;
if (target.tagName === 'I') {
// click on the text, popup choices
this.changeDirection();
} else {
// change the sort order
Popup.open('listsort')(evt);
}
},
*/
'click .js-filter-reset'(event) {
event.stopPropagation();
Sidebar.setView();
Filter.reset();
},
'click .js-sort-reset'() {
Session.set('sortBy', '');
},
'click .js-open-search-view'() {
Sidebar.setView('search');
},
'click .js-multiselection-activate'() {
const currentCard = Utils.getCurrentCardId();
MultiSelection.activate();
if (currentCard) {
MultiSelection.add(currentCard);
}
},
'click .js-multiselection-reset'(event) {
event.stopPropagation();
MultiSelection.disable();
},
'click .js-log-in'() {
FlowRouter.go('atSignIn');
},
},
];
},
}).register('boardHeaderBar');
Template.boardHeaderBar.helpers({
boardView() {
return Utils.boardView();
},
isSortActive() {
return Session.get('sortBy') ? true : false;
},
sortCardsIcon() {
const sortBy = Session.get('sortBy');
if (!sortBy) {
return '🃏'; // Card icon when nothing is selected
}
// Determine which sort option is active based on sortBy object
if (sortBy.dueAt) {
return '📅'; // Due date icon
} else if (sortBy.title) {
return '🔤'; // Alphabet icon
} else if (sortBy.createdAt) {
return sortBy.createdAt === 1 ? '⬆️' : '⬇️'; // Up/down arrow based on direction
}
return '🃏'; // Default card icon
},
});
Template.boardHeaderBar.events({
'click .js-edit-board-title': Popup.open('boardChangeTitle'),
'click .js-star-board'() {
const boardId = Session.get('currentBoard');
if (boardId) {
Meteor.call('toggleBoardStar', boardId);
}
},
'click .js-open-board-menu': Popup.open('boardMenu'),
'click .js-change-visibility': Popup.open('boardChangeVisibility'),
'click .js-watch-board': Popup.open('boardChangeWatch'),
'click .js-open-archived-board'() {
Modal.open('archivedBoards');
},
'click .js-toggle-board-view': Popup.open('boardChangeView'),
'click .js-toggle-sidebar'() {
if (process.env.DEBUG === 'true') {
console.log('Hamburger menu clicked');
}
// Use the same approach as keyboard shortcuts
const sidebar = getSidebarInstance();
if (sidebar && typeof sidebar.toggle === 'function') {
if (process.env.DEBUG === 'true') {
console.log('Using Sidebar.toggle()');
}
sidebar.toggle();
} else {
if (process.env.DEBUG === 'true') {
console.warn('Sidebar not available, trying alternative approach');
}
// Try to trigger the sidebar through the global Blaze helper
if (typeof Blaze !== 'undefined' && Blaze._globalHelpers && Blaze._globalHelpers.Sidebar) {
const blazeSidebar = Blaze._globalHelpers.Sidebar();
if (blazeSidebar && typeof blazeSidebar.toggle === 'function') {
if (process.env.DEBUG === 'true') {
console.log('Using Blaze helper Sidebar.toggle()');
}
blazeSidebar.toggle();
}
}
}
},
'click .js-open-filter-view'() {
const sidebar = getSidebarInstance();
if (sidebar) {
sidebar.setView('filter');
} else {
console.warn('Sidebar not available for setView');
}
},
'click .js-sort-cards': Popup.open('cardsSort'),
/*
'click .js-open-sort-view'(evt) {
const target = evt.target;
if (target.tagName === 'I') {
// click on the text, popup choices
this.changeDirection();
} else {
// change the sort order
Popup.open('listsort')(evt);
}
},
*/
'click .js-filter-reset'(event) {
event.stopPropagation();
const sidebar = getSidebarInstance();
if (sidebar) {
sidebar.setView();
} else {
console.warn('Sidebar not available for setView');
}
Filter.reset();
},
'click .js-sort-reset'() {
Session.set('sortBy', '');
},
'click .js-open-search-view'() {
const sidebar = getSidebarInstance();
if (sidebar) {
sidebar.setView('search');
} else {
console.warn('Sidebar not available for setView');
}
},
'click .js-multiselection-activate'() {
const currentCard = Utils.getCurrentCardId();
MultiSelection.activate();
if (currentCard) {
MultiSelection.add(currentCard);
}
},
'click .js-multiselection-reset'(event) {
event.stopPropagation();
MultiSelection.disable();
},
'click .js-log-in'() {
FlowRouter.go('atSignIn');
},
});
Template.boardChangeViewPopup.events({
@@ -180,194 +210,241 @@ Template.boardChangeViewPopup.events({
Utils.setBoardView('board-view-cal');
Popup.back();
},
});
const CreateBoard = BlazeComponent.extendComponent({
template() {
return 'createBoard';
},
onCreated() {
this.visibilityMenuIsOpen = new ReactiveVar(false);
this.visibility = new ReactiveVar('private');
this.boardId = new ReactiveVar('');
Meteor.subscribe('tableVisibilityModeSettings');
},
notAllowPrivateVisibilityOnly(){
return !TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly').booleanValue;
},
visibilityCheck() {
return this.currentData() === this.visibility.get();
},
setVisibility(visibility) {
this.visibility.set(visibility);
this.visibilityMenuIsOpen.set(false);
},
toggleVisibilityMenu() {
this.visibilityMenuIsOpen.set(!this.visibilityMenuIsOpen.get());
},
toggleAddTemplateContainer() {
$('#add-template-container').toggleClass('is-checked');
},
onSubmit(event) {
event.preventDefault();
const title = this.find('.js-new-board-title').value;
const addTemplateContainer = $('#add-template-container.is-checked').length > 0;
if (addTemplateContainer) {
//const templateContainerId = Meteor.call('setCreateTemplateContainer');
//Utils.goBoardId(templateContainerId);
//alert('niinku template ' + Meteor.call('setCreateTemplateContainer'));
this.boardId.set(
Boards.insert({
// title: TAPi18n.__('templates'),
title: title,
permission: 'private',
type: 'template-container',
}),
);
// Insert the card templates swimlane
Swimlanes.insert({
// title: TAPi18n.__('card-templates-swimlane'),
title: 'Card Templates',
boardId: this.boardId.get(),
sort: 1,
type: 'template-container',
}),
// Insert the list templates swimlane
Swimlanes.insert(
{
// title: TAPi18n.__('list-templates-swimlane'),
title: 'List Templates',
boardId: this.boardId.get(),
sort: 2,
type: 'template-container',
},
);
// Insert the board templates swimlane
Swimlanes.insert(
{
//title: TAPi18n.__('board-templates-swimlane'),
title: 'Board Templates',
boardId: this.boardId.get(),
sort: 3,
type: 'template-container',
},
);
Utils.goBoardId(this.boardId.get());
} else {
const visibility = this.visibility.get();
this.boardId.set(
Boards.insert({
title,
permission: visibility,
}),
);
Swimlanes.insert({
title: 'Default',
boardId: this.boardId.get(),
});
Utils.goBoardId(this.boardId.get());
}
},
events() {
return [
{
'click .js-select-visibility'() {
this.setVisibility(this.currentData());
},
'click .js-change-visibility': this.toggleVisibilityMenu,
'click .js-import': Popup.open('boardImportBoard'),
submit: this.onSubmit,
'click .js-import-board': Popup.open('chooseBoardSource'),
'click .js-board-template': Popup.open('searchElement'),
'click .js-toggle-add-template-container': this.toggleAddTemplateContainer,
},
];
},
}).register('createBoardPopup');
(class HeaderBarCreateBoard extends CreateBoard {
onSubmit(event) {
super.onSubmit(event);
// Immediately star boards crated with the headerbar popup.
ReactiveCache.getCurrentUser().toggleBoardStar(this.boardId.get());
}
}.register('headerBarCreateBoardPopup'));
BlazeComponent.extendComponent({
notAllowPrivateVisibilityOnly(){
return !TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly').booleanValue;
},
visibilityCheck() {
const currentBoard = Utils.getCurrentBoard();
return this.currentData() === currentBoard.permission;
},
selectBoardVisibility() {
const currentBoard = Utils.getCurrentBoard();
const visibility = this.currentData();
currentBoard.setVisibility(visibility);
'click .js-open-gantt-view'() {
Utils.setBoardView('board-view-gantt');
Popup.back();
},
});
events() {
return [
{
'click .js-select-visibility': this.selectBoardVisibility,
},
];
// Shared setup for all create board popups
function setupCreateBoardState(tpl) {
tpl.visibilityMenuIsOpen = new ReactiveVar(false);
tpl.visibility = new ReactiveVar('private');
tpl.boardId = new ReactiveVar('');
Meteor.subscribe('tableVisibilityModeSettings');
}
function createBoardHelpers() {
return {
visibilityMenuIsOpen() {
return Template.instance().visibilityMenuIsOpen.get();
},
visibility() {
return Template.instance().visibility.get();
},
notAllowPrivateVisibilityOnly() {
return !TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly')?.booleanValue;
},
visibilityCheck() {
return Template.currentData() === Template.instance().visibility.get();
},
};
}
async function createBoardSubmit(tpl, event) {
event.preventDefault();
const title = tpl.find('.js-new-board-title').value;
const slug = getSlug(title) || 'board';
const addTemplateContainer = $('#add-template-container.is-checked').length > 0;
if (addTemplateContainer) {
tpl.boardId.set(
await Meteor.callAsync('createBoardWithInitialSwimlanes', {
title,
slug,
permission: 'private',
type: 'template-container',
migrationVersion: 1,
swimlanes: [
{ title: 'Card Templates', sort: 1, type: 'template-container' },
{ title: 'List Templates', sort: 2, type: 'template-container' },
{ title: 'Board Templates', sort: 3, type: 'template-container' },
],
}),
);
// Assign to space if one was selected
const spaceId = Session.get('createBoardInWorkspace');
if (spaceId) {
Meteor.call('assignBoardToWorkspace', tpl.boardId.get(), spaceId, (err) => {
if (err) console.error('Error assigning board to space:', err);
});
Session.set('createBoardInWorkspace', null); // Clear after use
}
FlowRouter.go('board', { id: tpl.boardId.get(), slug });
} else {
const visibility = tpl.visibility.get();
tpl.boardId.set(
await Meteor.callAsync('createBoardWithInitialSwimlanes', {
title,
slug,
permission: visibility,
migrationVersion: 1,
swimlanes: [{ title: 'Default' }],
}),
);
// Assign to space if one was selected
const spaceId = Session.get('createBoardInWorkspace');
if (spaceId) {
Meteor.call('assignBoardToWorkspace', tpl.boardId.get(), spaceId, (err) => {
if (err) console.error('Error assigning board to space:', err);
});
Session.set('createBoardInWorkspace', null); // Clear after use
}
FlowRouter.go('board', { id: tpl.boardId.get(), slug });
}
}
function createBoardEvents() {
return {
'click .js-select-visibility'(event, tpl) {
tpl.visibility.set(this);
tpl.visibilityMenuIsOpen.set(false);
},
'click .js-change-visibility'(event, tpl) {
tpl.visibilityMenuIsOpen.set(!tpl.visibilityMenuIsOpen.get());
},
'click .js-import': Popup.open('boardImportBoard'),
async 'submit'(event, tpl) {
await createBoardSubmit(tpl, event);
},
'click .js-import-board': Popup.open('chooseBoardSource'),
'click .js-board-template': Popup.open('searchElement'),
'click .js-toggle-add-template-container'() {
$('#add-template-container').toggleClass('is-checked');
},
};
}
// createBoard (non-popup version)
Template.createBoard.onCreated(function () {
setupCreateBoardState(this);
});
Template.createBoard.helpers(createBoardHelpers());
Template.createBoard.events(createBoardEvents());
// createBoardPopup
Template.createBoardPopup.onCreated(function () {
setupCreateBoardState(this);
});
Template.createBoardPopup.helpers(createBoardHelpers());
Template.createBoardPopup.events(createBoardEvents());
// createTemplateContainerPopup
Template.createTemplateContainerPopup.onCreated(function () {
setupCreateBoardState(this);
});
Template.createTemplateContainerPopup.onRendered(function () {
// Always pre-check the template container checkbox for this popup
$('#add-template-container').addClass('is-checked');
});
Template.createTemplateContainerPopup.helpers(createBoardHelpers());
Template.createTemplateContainerPopup.events(createBoardEvents());
// headerBarCreateBoardPopup
Template.headerBarCreateBoardPopup.onCreated(function () {
setupCreateBoardState(this);
});
Template.headerBarCreateBoardPopup.helpers(createBoardHelpers());
Template.headerBarCreateBoardPopup.events({
'click .js-select-visibility'(event, tpl) {
tpl.visibility.set(this);
tpl.visibilityMenuIsOpen.set(false);
},
}).register('boardChangeVisibilityPopup');
'click .js-change-visibility'(event, tpl) {
tpl.visibilityMenuIsOpen.set(!tpl.visibilityMenuIsOpen.get());
},
'click .js-import': Popup.open('boardImportBoard'),
async submit(event, tpl) {
await createBoardSubmit(tpl, event);
// Immediately star boards created with the headerbar popup.
await ReactiveCache.getCurrentUser().toggleBoardStar(tpl.boardId.get());
},
'click .js-import-board': Popup.open('chooseBoardSource'),
'click .js-board-template': Popup.open('searchElement'),
'click .js-toggle-add-template-container'() {
$('#add-template-container').toggleClass('is-checked');
},
});
BlazeComponent.extendComponent({
Template.boardVisibilityList.helpers({
notAllowPrivateVisibilityOnly() {
return !TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly')?.booleanValue;
},
});
Template.boardChangeVisibilityPopup.onCreated(function () {
Meteor.subscribe('tableVisibilityModeSettings');
});
Template.boardChangeVisibilityPopup.helpers({
notAllowPrivateVisibilityOnly(){
return !TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly')?.booleanValue;
},
visibilityCheck() {
const currentBoard = Utils.getCurrentBoard();
return this === currentBoard.permission;
},
});
Template.boardChangeVisibilityPopup.events({
'click .js-select-visibility'() {
const currentBoard = Utils.getCurrentBoard();
const visibility = this;
if (typeof visibility === 'string') {
currentBoard.setVisibility(visibility);
Popup.back();
}
},
});
Template.boardChangeWatchPopup.helpers({
watchLevel() {
const currentBoard = Utils.getCurrentBoard();
return currentBoard.getWatchLevel(Meteor.userId());
},
watchCheck() {
return this.currentData() === this.watchLevel();
const currentBoard = Utils.getCurrentBoard();
return this === currentBoard.getWatchLevel(Meteor.userId());
},
});
events() {
return [
{
'click .js-select-watch'() {
const level = this.currentData();
Meteor.call(
'watch',
'board',
Session.get('currentBoard'),
level,
(err, ret) => {
if (!err && ret) Popup.back();
},
);
Template.boardChangeWatchPopup.events({
'click .js-select-watch'() {
const level = this;
if (typeof level === 'string') {
Meteor.call(
'watch',
'board',
Session.get('currentBoard'),
level,
(err, ret) => {
if (!err && ret) Popup.back();
},
},
];
);
}
},
}).register('boardChangeWatchPopup');
});
/*
BlazeComponent.extendComponent({
// BlazeComponent.extendComponent was removed - this code is unused.
// Original listsortPopup component:
// {
onCreated() {
//this.sortBy = new ReactiveVar();
////this.sortDirection = new ReactiveVar();
@@ -435,46 +512,40 @@ BlazeComponent.extendComponent({
},
];
},
}).register('listsortPopup');
// }.register('listsortPopup');
*/
BlazeComponent.extendComponent({
events() {
return [
{
'click .js-sort-due'() {
const sortBy = {
dueAt: 1,
};
Session.set('sortBy', sortBy);
sortCardsBy.set(TAPi18n.__('due-date'));
Popup.back();
},
'click .js-sort-title'() {
const sortBy = {
title: 1,
};
Session.set('sortBy', sortBy);
sortCardsBy.set(TAPi18n.__('title'));
Popup.back();
},
'click .js-sort-created-asc'() {
const sortBy = {
createdAt: 1,
};
Session.set('sortBy', sortBy);
sortCardsBy.set(TAPi18n.__('date-created-newest-first'));
Popup.back();
},
'click .js-sort-created-desc'() {
const sortBy = {
createdAt: -1,
};
Session.set('sortBy', sortBy);
sortCardsBy.set(TAPi18n.__('date-created-oldest-first'));
Popup.back();
},
},
];
Template.cardsSortPopup.events({
'click .js-sort-due'() {
const sortBy = {
dueAt: 1,
};
Session.set('sortBy', sortBy);
sortCardsBy.set(TAPi18n.__('due-date'));
Popup.back();
},
}).register('cardsSortPopup');
'click .js-sort-title'() {
const sortBy = {
title: 1,
};
Session.set('sortBy', sortBy);
sortCardsBy.set(TAPi18n.__('title'));
Popup.back();
},
'click .js-sort-created-asc'() {
const sortBy = {
createdAt: 1,
};
Session.set('sortBy', sortBy);
sortCardsBy.set(TAPi18n.__('date-created-newest-first'));
Popup.back();
},
'click .js-sort-created-desc'() {
const sortBy = {
createdAt: -1,
};
Session.set('sortBy', sortBy);
sortCardsBy.set(TAPi18n.__('date-created-oldest-first'));
Popup.back();
},
});
File diff suppressed because it is too large. Load diff
+248 -143
View File
@@ -1,154 +1,259 @@
template(name="boardList")
.wrapper
ul.AllBoardTeamsOrgs
li.AllBoardTeams
if userHasTeams
select.js-AllBoardTeams#jsAllBoardTeams("multiple")
option(value="-1") {{_ 'teams'}} :
each teamsDatas
option(value="{{teamId}}") {{_ teamDisplayName}}
.board-list-header
li.AllBoardOrgs
if userHasOrgs
select.js-AllBoardOrgs#jsAllBoardOrgs("multiple")
option(value="-1") {{_ 'organizations'}} :
each orgsDatas
option(value="{{orgId}}") {{orgDisplayName}}
.boards-layout
// Left menu
.boards-left-menu
ul.menu
li(class="menu-item {{#if isSelectedMenu 'starred'}}active{{/if}}")
a.js-select-menu(data-type="starred")
span.menu-label
span.emoji-icon
i.fa.fa-star
| {{_ 'allboards.starred'}}
span.menu-count {{menuItemCount 'starred'}}
li(class="menu-item {{#if isSelectedMenu 'templates'}}active{{/if}}")
a.js-select-menu(data-type="templates")
span.menu-label
span.emoji-icon
i.fa.fa-clipboard
| {{_ 'allboards.templates'}}
span.menu-count {{menuItemCount 'templates'}}
li(class="menu-item {{#if isSelectedMenu 'remaining'}}active{{/if}}")
a.js-select-menu(data-type="remaining")
span.menu-label
span.emoji-icon
i.fa.fa-folder
| {{_ 'allboards.remaining'}}
span.menu-count {{menuItemCount 'remaining'}}
.workspaces-header
span
span.emoji-icon
i.fa.fa-folder-open
| {{_ 'allboards.workspaces'}}
a.js-add-workspace(title="{{_ 'allboards.add-workspace'}}") +
// Workspaces tree
+workspaceTree(nodes=workspacesTree selectedWorkspaceId=selectedWorkspaceId)
//li.AllBoardTemplates
// if userHasTemplates
// select.js-AllBoardTemplates#jsAllBoardTemplates("multiple")
// option(value="-1") {{_ 'templates'}} :
// each templatesDatas
// option(value="{{templateId}}") {{_ templateDisplayName}}
// Existing filter by orgs/teams (kept)
ul.AllBoardTeamsOrgs
li.AllBoardTeams
if userHasTeams
select.js-AllBoardTeams#jsAllBoardTeams("multiple")
option(value="-1") {{_ 'teams'}} :
each teamsDatas
option(value="{{teamId}}") {{_ teamDisplayName}}
li.AllBoardBtns
div.AllBoardButtonsContainer
if userHasOrgsOrTeams
i.fa.fa-filter
input#filterBtn(type="button" value="{{_ 'filter'}}")
input#resetBtn(type="button" value="{{_ 'filter-clear'}}")
li.AllBoardOrgs
if userHasOrgs
select.js-AllBoardOrgs#jsAllBoardOrgs("multiple")
option(value="-1") {{_ 'organizations'}} :
each orgsDatas
option(value="{{orgId}}") {{orgDisplayName}}
ul.board-list.clearfix.js-boards
li.js-add-board
a.board-list-item.label(title="{{_ 'add-board'}}")
| {{_ 'add-board'}}
each boards
li(class="{{_id}}" class="{{#if isStarred}}starred{{/if}}" class=colorClass).js-board
if isInvited
.board-list-item
span.details
span.board-list-item-name= title
i.fa.js-star-board(
class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
title="{{_ 'star-board-title'}}")
p.board-list-item-desc {{_ 'just-invited'}}
button.js-accept-invite.primary {{_ 'accept'}}
button.js-decline-invite {{_ 'decline'}}
else
if $eq type "template-container"
a.js-open-board.template-container.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}")
span.details
span.board-list-item-name(title="{{_ 'template-container'}}")
+viewer
= title
i.fa.js-star-board(
class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
title="{{_ 'star-board-title'}}")
p.board-list-item-desc
+viewer
= description
if hasSpentTimeCards
i.fa.js-has-spenttime-cards(
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
if isTouchScreenOrShowDesktopDragHandles
i.fa.board-handle(
class="fa-arrows"
title="{{_ 'drag-board'}}")
else
if isSandstorm
i.fa.js-clone-board(
class="fa-clone"
title="{{_ 'duplicate-board'}}")
i.fa.js-archive-board(
class="fa-archive"
title="{{_ 'archive-board'}}")
else if isAdministrable
i.fa.js-clone-board(
class="fa-clone"
title="{{_ 'duplicate-board'}}")
i.fa.js-archive-board(
class="fa-archive"
title="{{_ 'archive-board'}}")
else if currentUser.isAdmin
i.fa.js-clone-board(
class="fa-clone"
title="{{_ 'duplicate-board'}}")
i.fa.js-archive-board(
class="fa-archive"
title="{{_ 'archive-board'}}")
li.AllBoardBtns
div.AllBoardButtonsContainer
if userHasOrgsOrTeams
span.emoji-icon
i.fa.fa-search
input#filterBtn(type="button" value="{{_ 'filter'}}")
button#resetBtn.filter-reset-btn
span.reset-icon
span.emoji-icon
i.fa.fa-times-thin
span {{_ 'filter-clear'}}
// Right boards grid
.boards-right-grid
.boards-path-header
.path-left
span.path-icon.emoji-icon {{currentMenuPath.icon}}
span.path-text {{currentMenuPath.text}}
if BoardMultiSelection.isActive
span.multiselection-hint
span.emoji-icon
i.fa.fa-thumb-tack
| {{_ 'multi-selection-active'}}
.path-right
if canModifyBoards
if hasBoardsSelected
button.js-archive-selected-boards.board-header-btn
span.emoji-icon
i.fa.fa-archive
span {{_ 'archive-board'}}
button.js-duplicate-selected-boards.board-header-btn
span.emoji-icon
i.fa.fa-clipboard
span {{_ 'duplicate-board'}}
a.board-header-btn.js-multiselection-activate(
title="{{#if BoardMultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}"
class="{{#if BoardMultiSelection.isActive}}emphasis{{/if}}")
span.emoji-icon
i.fa.fa-check-square-o
if BoardMultiSelection.isActive
a.board-header-btn-close.js-multiselection-reset(title="{{_ 'filter-clear'}}")
span.emoji-icon
i.fa.fa-times
ul.board-list.clearfix.js-boards.dragscroll(class="{{#if isMiniScreen}}mobile-view{{/if}} {{#if BoardMultiSelection.isActive}}is-multiselection-active{{/if}}")
li.js-add-board
if isSelectedMenu 'templates'
a.board-list-item.label(title="{{_ 'add-template-container'}}")
span.emoji-icon
i.fa.fa-plus
| &nbsp;{{_ 'add-template-container'}}
else
a.js-open-board.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}")
span.details
span.board-list-item-name(title="{{_ 'board-drag-drop-reorder-or-click-open'}}")
+viewer
= title
unless currentSetting.hideBoardMemberList
if allowsBoardMemberList
.minicard-members
each member in boardMembers _id
a.name
+userAvatar(userId=member noRemove=true)
unless currentSetting.hideCardCounterList
if allowsCardCounterList
.minicard-lists.flex.flex-wrap
each list in boardLists _id
.item
| {{ list }}
i.fa.js-star-board(
class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
title="{{_ 'star-board-title'}}")
p.board-list-item-desc
+viewer
= description
if hasSpentTimeCards
i.fa.js-has-spenttime-cards(
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
if isTouchScreenOrShowDesktopDragHandles
i.fa.board-handle(
class="fa-arrows"
title="{{_ 'drag-board'}}")
else
if isSandstorm
i.fa.js-clone-board(
class="fa-clone"
title="{{_ 'duplicate-board'}}")
i.fa.js-archive-board(
class="fa-archive"
title="{{_ 'archive-board'}}")
else if isAdministrable
i.fa.js-clone-board(
class="fa-clone"
title="{{_ 'duplicate-board'}}")
i.fa.js-archive-board(
class="fa-archive"
title="{{_ 'archive-board'}}")
else if currentUser.isAdmin
i.fa.js-clone-board(
class="fa-clone"
title="{{_ 'duplicate-board'}}")
i.fa.js-archive-board(
class="fa-archive"
title="{{_ 'archive-board'}}")
a.board-list-item.label(title="{{_ 'add-board'}}")
span.emoji-icon
i.fa.fa-plus
| &nbsp;{{_ 'add-board'}}
each boards
li.js-board(class="{{_id}} {{#if isStarred}}starred{{/if}} {{colorClass}} {{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}", draggable="true")
if isInvited
.board-list-item
if BoardMultiSelection.isActive
.materialCheckBox.multi-selection-checkbox.js-toggle-board-multi-selection(
class="{{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}")
span.details
span.board-list-item-name= title
span.js-star-board(
class="{{#if isStarred}}is-star-active{{else}}is-not-star-active{{/if}}"
title="{{_ 'star-board-title'}}")
span.emoji-icon
| {{#if isStarred}}⭐{{else}}☆{{/if}}
p.board-list-item-desc {{_ 'just-invited'}}
button.js-accept-invite.primary {{_ 'accept'}}
button.js-decline-invite {{_ 'decline'}}
else
if $eq type "template-container"
.template-container.board-list-item
if BoardMultiSelection.isActive
.materialCheckBox.multi-selection-checkbox.js-toggle-board-multi-selection(
class="{{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}")
span.board-handle.nodragscroll(title="{{boardWorkspaceDragHint}}")
span.emoji-icon
i.fa.fa-arrows
a.js-open-board(href="{{pathFor 'board' id=_id slug=slug}}")
span.details
span.board-list-item-name(title="{{_ 'template-container'}}")
+viewer
= title
p.board-list-item-desc
+viewer
= description
if hasSpentTimeCards
span.js-has-spenttime-cards(
class="{{#if hasOvertimeCards}}has-overtime-card-active{{else}}no-overtime-card-active{{/if}}"
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
span.emoji-icon
i.fa.fa-clock-o
span.js-star-board(
class="{{#if isStarred}}is-star-active{{else}}is-not-star-active{{/if}}"
title="{{_ 'star-board-title'}}")
span.emoji-icon
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
else
.board-list-item
if BoardMultiSelection.isActive
.materialCheckBox.multi-selection-checkbox.js-toggle-board-multi-selection(
class="{{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}")
span.board-handle.nodragscroll(title="{{boardWorkspaceDragHint}}")
span.emoji-icon
i.fa.fa-arrows
a.js-open-board(href="{{pathFor 'board' id=_id slug=slug}}")
span.details
span.board-list-item-name(title="{{boardOpenAndMoveHint}}")
+viewer
= title
unless currentSetting.hideBoardMemberList
if allowsBoardMemberList
.minicard-members
each member in boardMembers _id
a.name
+userAvatar(userId=member noRemove=true)
unless currentSetting.hideCardCounterList
if allowsCardCounterList
.minicard-lists.flex.flex-wrap
each list in boardLists _id
.item
| {{ list }}
p.board-list-item-desc
+viewer
= description
if hasSpentTimeCards
span.js-has-spenttime-cards(
class="{{#if hasOvertimeCards}}has-overtime-card-active{{else}}no-overtime-card-active{{/if}}"
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
span.emoji-icon
i.fa.fa-clock-o
a.js-star-board(
class="{{#if isStarred}}is-star-active{{else}}is-not-star-active{{/if}}"
title="{{_ 'star-board-title'}}")
span.emoji-icon
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
template(name="boardListHeaderBar")
h1 {{_ title }}
//.board-header-btns.right
// a.board-header-btn.js-open-archived-board
// i.fa.fa-archive
// span {{_ 'archives'}}
// a.board-header-btn(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}")
// i.fa.fa-clone
// span {{_ 'templates'}}
//
a.board-header-btn.js-open-archived-board
//
i.fa.fa-archive
//
span {{_ 'archives'}}
//
a.board-header-btn(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}")
//
i.fa.fa-clone
//
span {{_ 'templates'}}
// Recursive template for workspaces tree
template(name="workspaceTree")
if nodes
ul.workspace-tree.js-workspace-tree
each nodes
li.workspace-node(class="{{#if $eq id selectedWorkspaceId}}active{{/if}}" data-workspace-id="{{id}}" draggable="true")
.workspace-node-content
span.workspace-drag-handle
span.emoji-icon
i.fa.fa-arrows
a.js-select-workspace.js-select-space(data-id="{{id}}")
span.workspace-icon
if icon
span.workspace-icon-value(style="{{#if iconColor}}color: {{iconColor}};{{/if}}")
+viewer
= icon
else
span.emoji-icon(style="{{#if iconColor}}color: {{iconColor}};{{/if}}")
i.fa.fa-folder
span.workspace-name= name
a.js-open-workspace-menu(data-id="{{id}}" title="{{_ 'allboards.workspace-menu'}}")
span.emoji-icon
i.fa.fa-bars
span.workspace-count {{workspaceCount id}}
if children
+workspaceTree(nodes=children selectedWorkspaceId=selectedWorkspaceId)
template(name="workspaceActionsPopup")
form.workspace-actions-form.js-workspace-actions-form(data-id="{{id}}")
label
| {{_ 'allboards.edit-workspace-name'}}
input.js-workspace-name(type="text" value="{{workspaceName}}" required)
label
| {{_ 'allboards.edit-workspace-icon'}}
input.js-workspace-icon(type="text" value="{{workspaceIcon}}")
input.primary.wide(type="submit" value="{{_ 'save'}}")
hr
form.workspace-subspace-form.js-workspace-subspace-form(data-id="{{id}}")
label
| {{_ 'allboards.add-subworkspace-prompt'}}
input.js-subworkspace-name(type="text")
button.primary.wide(type="submit") {{_ 'allboards.add-subworkspace'}}
hr
.workspace-delete-block
span.js-workspace-delete-error(style="color: #c00; display: block; margin: 4px 0;")
button.js-delete-workspace.negate.wide(type="button" data-id="{{id}}") {{_ 'delete'}}
File diff suppressed because it is too large. Load diff
+43
View File
@@ -0,0 +1,43 @@
.calendar-view .fc {
--fc-button-text-color: #333;
--fc-button-bg-color: #f5f5f5;
--fc-button-border-color: rgba(0, 0, 0, 0.2);
--fc-button-hover-bg-color: #e6e6e6;
--fc-button-hover-border-color: rgba(0, 0, 0, 0.25);
--fc-button-active-bg-color: #d9d9d9;
--fc-button-active-border-color: rgba(0, 0, 0, 0.3);
}
.calendar-view .fc .fc-button-primary {
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
0 1px 2px rgba(0, 0, 0, 0.05);
background-image: linear-gradient(to bottom, #fff 0%, #e6e6e6 100%);
}
.calendar-view .fc .fc-button-primary:focus,
.calendar-view .fc .fc-button-primary:not(:disabled).fc-button-active,
.calendar-view .fc .fc-button-primary:not(:disabled):active {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),
0 1px 2px rgba(0, 0, 0, 0.05);
}
.calendar-create-close {
min-height: auto !important;
min-width: auto !important;
width: 32px;
height: 32px;
padding: 0 !important;
border: 0 !important;
background: transparent !important;
box-shadow: none !important;
color: #666 !important;
opacity: 0.8;
}
.calendar-create-close:hover,
.calendar-create-close:focus {
background: transparent !important;
color: #111 !important;
opacity: 1;
}
+2 -1
View File
@@ -3,6 +3,7 @@ template(name="miniboard")
class="minicard-{{colorClass}}")
.minicard-title
.handle
.fa.fa-arrows
span.drag-handle(title="{{_ 'dragBoard'}}")
i.fa.fa-arrows
+viewer
= title
@@ -0,0 +1,263 @@
/* Original Positions View Styles */
.original-positions-view {
margin: 10px 0;
padding: 15px;
background-color: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 6px;
}
.original-positions-header {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 15px;
}
.original-positions-header .btn {
display: flex;
align-items: center;
gap: 5px;
}
.original-positions-content {
background-color: white;
border: 1px solid #dee2e6;
border-radius: 4px;
padding: 15px;
}
.original-positions-loading {
text-align: center;
padding: 20px;
color: #6c757d;
font-style: italic;
}
.original-positions-loading i {
margin-right: 8px;
}
.original-positions-filters {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #dee2e6;
}
.original-positions-filters .btn-group {
display: flex;
flex-wrap: wrap;
gap: 5px;
}
.original-positions-filters .btn {
display: flex;
align-items: center;
gap: 5px;
white-space: nowrap;
}
.original-positions-list {
max-height: 400px;
overflow-y: auto;
}
.original-position-item {
background-color: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 4px;
margin-bottom: 10px;
padding: 12px;
transition: all 0.2s ease;
}
.original-position-item:hover {
background-color: #e9ecef;
border-color: #ced4da;
}
.original-position-item:last-child {
margin-bottom: 0;
}
.original-position-item-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
font-weight: 600;
color: #495057;
}
.original-position-item-header i {
color: #6c757d;
width: 16px;
text-align: center;
}
.entity-type {
background-color: #007bff;
color: white;
padding: 2px 6px;
border-radius: 3px;
font-size: 11px;
font-weight: 500;
text-transform: uppercase;
}
.entity-name {
color: #212529;
font-weight: 600;
}
.entity-id {
color: #6c757d;
font-size: 11px;
font-family: monospace;
}
.original-position-item-details {
margin-left: 24px;
}
.original-position-description {
color: #495057;
margin-bottom: 6px;
font-size: 13px;
}
.original-title {
color: #6c757d;
font-size: 12px;
margin-bottom: 6px;
padding: 4px 6px;
background-color: #e9ecef;
border-radius: 3px;
}
.original-title strong {
color: #495057;
}
.original-position-date {
color: #6c757d;
font-size: 11px;
}
.no-original-positions {
text-align: center;
padding: 40px 20px;
color: #6c757d;
font-style: italic;
}
.no-original-positions i {
font-size: 24px;
margin-bottom: 10px;
display: block;
color: #adb5bd;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.original-positions-view {
margin: 5px 0;
padding: 10px;
}
.original-positions-header {
flex-direction: column;
align-items: stretch;
gap: 8px;
}
.original-positions-header .btn {
justify-content: center;
}
.original-positions-filters .btn-group {
justify-content: center;
}
.original-position-item-header {
flex-wrap: wrap;
gap: 6px;
}
.entity-name {
flex: 1;
min-width: 0;
word-break: break-word;
}
.original-position-item-details {
margin-left: 0;
margin-top: 8px;
}
}
/* Dark theme support */
@media (prefers-color-scheme: dark) {
.original-positions-view {
background-color: #2d3748;
border-color: #4a5568;
color: #e2e8f0;
}
.original-positions-content {
background-color: #1a202c;
border-color: #4a5568;
}
.original-position-item {
background-color: #2d3748;
border-color: #4a5568;
color: #e2e8f0;
}
.original-position-item:hover {
background-color: #4a5568;
border-color: #718096;
}
.original-position-item-header {
color: #e2e8f0;
}
.original-position-item-header i {
color: #a0aec0;
}
.entity-name {
color: #e2e8f0;
}
.entity-id {
color: #a0aec0;
}
.original-position-description {
color: #e2e8f0;
}
.original-title {
background-color: #4a5568;
color: #a0aec0;
}
.original-title strong {
color: #e2e8f0;
}
.original-position-date {
color: #a0aec0;
}
.no-original-positions {
color: #a0aec0;
}
.no-original-positions i {
color: #718096;
}
}
@@ -0,0 +1,57 @@
template(name="originalPositionsView")
.original-positions-view
.original-positions-header
button.btn.btn-sm.btn-outline-secondary.js-toggle-original-positions
i.fa.fa-history
if isShowingOriginalPositions
| Hide Original Positions
else
| Show Original Positions
if isShowingOriginalPositions
button.btn.btn-sm.btn-outline-primary.js-refresh-history
i.fa.fa-refresh
| Refresh
if isShowingOriginalPositions
.original-positions-content
if isLoading
.original-positions-loading
i.fa.fa-spinner.fa-spin
| Loading original positions...
else
.original-positions-filters
.btn-group.btn-group-sm(role="group")
button.btn.js-filter-type(type="button" class="{{#if isFilterType 'all'}}btn-primary{{else}}btn-outline-secondary{{/if}}" data-filter-type="all")
| All
button.btn.js-filter-type(type="button" class="{{#if isFilterType 'swimlane'}}btn-primary{{else}}btn-outline-secondary{{/if}}" data-filter-type="swimlane")
i.fa.fa-bars
| Swimlanes
button.btn.js-filter-type(type="button" class="{{#if isFilterType 'list'}}btn-primary{{else}}btn-outline-secondary{{/if}}" data-filter-type="list")
i.fa.fa-columns
| Lists
button.btn.js-filter-type(type="button" class="{{#if isFilterType 'card'}}btn-primary{{else}}btn-outline-secondary{{/if}}" data-filter-type="card")
i.fa.fa-sticky-note
| Cards
.original-positions-list
each getFilteredHistory
.original-position-item
.original-position-item-header
i.fa(class="{{getEntityTypeIcon entityType}}")
span.entity-type {{getEntityTypeLabel entityType}}
span.entity-name {{getEntityDisplayName this}}
span.entity-id ({{entityId}})
.original-position-item-details
.original-position-description
| {{getEntityOriginalPositionDescription this}}
if originalTitle
.original-title
strong Original title:
| {{originalTitle}}
.original-position-date
small.text-muted Created: {{formatDate createdAt}}
else
.no-original-positions
i.fa.fa-info-circle
| No original position data available for this board.
@@ -0,0 +1,134 @@
import { ReactiveVar } from 'meteor/reactive-var';
import { Meteor } from 'meteor/meteor';
/**
* Component to display original positions for all entities on a board
*/
Template.originalPositionsView.onCreated(function () {
this.showOriginalPositions = new ReactiveVar(false);
this.boardHistory = new ReactiveVar([]);
this.isLoading = new ReactiveVar(false);
this.filterType = new ReactiveVar('all'); // 'all', 'swimlane', 'list', 'card'
const tpl = this;
this.loadBoardHistory = function () {
const boardId = Session.get('currentBoard');
if (!boardId) return;
tpl.isLoading.set(true);
Meteor.call('positionHistory.getBoardHistory', boardId, (error, result) => {
tpl.isLoading.set(false);
if (error) {
console.error('Error loading board history:', error);
tpl.boardHistory.set([]);
} else {
tpl.boardHistory.set(result);
}
});
};
});
Template.originalPositionsView.onRendered(function () {
this.loadBoardHistory();
});
Template.originalPositionsView.helpers({
isShowingOriginalPositions() {
return Template.instance().showOriginalPositions.get();
},
isLoading() {
return Template.instance().isLoading.get();
},
getBoardHistory() {
return Template.instance().boardHistory.get();
},
getFilteredHistory() {
const tpl = Template.instance();
const history = tpl.boardHistory.get();
const filterType = tpl.filterType.get();
if (filterType === 'all') {
return history;
}
return history.filter(item => item.entityType === filterType);
},
isFilterType(type) {
return Template.instance().filterType.get() === type;
},
getEntityDisplayName(entity) {
const position = entity.originalPosition || {};
return position.title || `Entity ${entity.entityId}`;
},
getEntityOriginalPositionDescription(entity) {
const position = entity.originalPosition || {};
let description = `Position: ${position.sort || 0}`;
if (entity.entityType === 'list' && entity.originalSwimlaneId) {
description += ` in swimlane ${entity.originalSwimlaneId}`;
} else if (entity.entityType === 'card') {
if (entity.originalSwimlaneId) {
description += ` in swimlane ${entity.originalSwimlaneId}`;
}
if (entity.originalListId) {
description += ` in list ${entity.originalListId}`;
}
}
return description;
},
getEntityTypeIcon(entityType) {
switch (entityType) {
case 'swimlane':
return 'fa-bars';
case 'list':
return 'fa-columns';
case 'card':
return 'fa-sticky-note';
default:
return 'fa-question';
}
},
getEntityTypeLabel(entityType) {
switch (entityType) {
case 'swimlane':
return 'Swimlane';
case 'list':
return 'List';
case 'card':
return 'Card';
default:
return 'Unknown';
}
},
formatDate(date) {
return new Date(date).toLocaleString();
},
});
Template.originalPositionsView.events({
'click .js-toggle-original-positions'(evt, tpl) {
tpl.showOriginalPositions.set(!tpl.showOriginalPositions.get());
},
'click .js-refresh-history'(evt, tpl) {
tpl.loadBoardHistory();
},
'click .js-filter-type'(evt, tpl) {
const type = evt.currentTarget.dataset.filterType;
tpl.filterType.set(type);
},
});
+174 -2
View File
@@ -55,6 +55,12 @@
flex-direction: row;
align-items: center;
}
.attachment-actions a {
margin-left: 16px;
}
.attachment-actions a:first-child {
margin-left: 0;
}
.add-attachment {
display: flex;
align-items: center;
@@ -106,9 +112,144 @@
color: white;
cursor: pointer;
font-size: 4em;
top: 0;
right: 8px;
position: absolute;
right: 50px;
top: 16px;
}
/* Upload progress indicators for drag-and-drop uploads */
.minicard-upload-progress,
.card-details-upload-progress {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 4px;
padding: 12px;
margin: 8px 0;
font-size: 14px;
}
.upload-progress-header {
display: flex;
align-items: center;
margin-bottom: 8px;
font-weight: bold;
color: #495057;
}
.upload-progress-header i {
margin-right: 8px;
color: #007bff;
}
.upload-progress-item {
display: flex;
flex-direction: column;
margin-bottom: 8px;
padding: 8px;
background: white;
border-radius: 3px;
border: 1px solid #dee2e6;
}
.upload-progress-item.upload-error {
border-color: #dc3545;
background: #f8d7da;
}
.upload-progress-filename {
font-weight: 500;
margin-bottom: 4px;
color: #495057;
word-break: break-all;
}
.upload-progress-bar {
width: 100%;
height: 6px;
background: #e9ecef;
border-radius: 3px;
overflow: hidden;
margin-bottom: 4px;
}
.upload-progress-fill {
height: 100%;
background: linear-gradient(90deg, #007bff, #0056b3);
transition: width 0.3s ease;
border-radius: 3px;
}
.upload-progress-item.upload-error .upload-progress-fill {
background: #dc3545;
}
.upload-progress-error,
.upload-progress-success {
display: flex;
align-items: center;
font-size: 12px;
font-weight: 500;
}
.upload-progress-error {
color: #dc3545;
}
.upload-progress-success {
color: #28a745;
}
.upload-progress-error i,
.upload-progress-success i {
margin-right: 4px;
}
/* Minicard specific styles */
.minicard-upload-progress {
margin: 4px 0;
padding: 8px;
font-size: 12px;
}
.minicard-upload-progress .upload-progress-item {
padding: 6px;
margin-bottom: 6px;
}
.minicard-upload-progress .upload-progress-filename {
font-size: 11px;
}
/* Card details specific styles */
.card-details-upload-progress {
margin: 12px 0;
padding: 16px;
}
.card-details-upload-progress .upload-progress-header {
font-size: 16px;
margin-bottom: 12px;
}
.card-details-upload-progress .upload-progress-item {
padding: 12px;
margin-bottom: 10px;
}
.card-details-upload-progress .upload-progress-filename {
font-size: 14px;
}
/* Drag over state for minicards */
.minicard.is-dragging-over {
border: 2px dashed #007bff !important;
background: rgba(0, 123, 255, 0.1) !important;
}
/* Drag over state for card details */
.js-card-details.is-dragging-over {
border: 2px dashed #007bff !important;
background: rgba(0, 123, 255, 0.05) !important;
}
.attachment-arrow {
font-size: 4em;
@@ -117,6 +258,20 @@
align-self: center;
margin: 0 20px;
}
#prev-attachment {
font-size: 4em;
color: white;
cursor: pointer;
align-self: center;
margin-left: 70px;
}
#next-attachment {
font-size: 4em;
color: white;
cursor: pointer;
align-self: center;
margin-right: 70px;
}
#viewer-content {
display: flex;
justify-content: center;
@@ -130,6 +285,13 @@
max-width: 100%;
max-height: 100%;
}
#video-viewer {
max-width: 100%;
max-height: 100%;
}
#audio-viewer {
max-width: 100%;
}
#pdf-viewer {
width: 40vw;
height: 100%;
@@ -164,9 +326,19 @@
}
#prev-attachment {
left: 0;
position: absolute;
bottom: 2.2em;
font-size: 1.6em;
padding: 16px;
margin-left: 0;
}
#next-attachment {
right: 0;
position: absolute;
bottom: 2.2em;
font-size: 1.6em;
padding: 16px;
margin-right: 0;
}
#pdf-viewer {
width: 100%;
+25 -37
View File
@@ -34,10 +34,11 @@ template(name="attachmentViewer")
#viewer-overlay.hidden
#viewer-top-bar
span#attachment-name
a#viewer-close.fa.fa-times-thin
a#viewer-close
i.fa.fa-times-thin
#viewer-container
i.fa.fa-chevron-left.attachment-arrow#prev-attachment
i.fa.fa-caret-left#prev-attachment
#viewer-content
img#image-viewer.hidden
video#video-viewer.hidden(controls="true")
@@ -45,7 +46,7 @@ template(name="attachmentViewer")
object#pdf-viewer.hidden(type="application/pdf")
span.pdf-preview-error {{_ 'preview-pdf-not-supported' }}
object#txt-viewer.hidden(type="text/plain")
i.fa.fa-chevron-right.attachment-arrow#next-attachment
i.fa.fa-caret-right#next-attachment
template(name="attachmentGallery")
@@ -53,11 +54,11 @@ template(name="attachmentGallery")
if canModifyCard
a.attachment-item.add-attachment.js-add-attachment
i.fa.fa-plus.icon
i.fa.fa-plus
each attachments
.attachment-item
.attachment-item(class="{{#if isAttachmentMigrating _id}}migrating{{/if}}")
.attachment-thumbnail-container.open-preview(data-attachment-id="{{_id}}" data-card-id="{{ meta.cardId }}")
if link
if(isImage)
@@ -85,30 +86,36 @@ template(name="attachmentGallery")
b
= name
span.file-size ({{fileSize size}})
if uploaderName
div.attachment-uploader {{uploaderName}}
if uploadedAt
div.attachment-uploaded-at {{uploadedAt}}
.attachment-actions
a.js-download(href="{{link}}?download=true", download="{{name}}")
i.fa.fa-download.icon(title="{{_ 'download'}}")
a.js-download(href="{{link}}?download=true", download="{{name}}", title="{{_ 'download'}}")
i.fa.fa-arrow-down
if currentUser.isBoardMember
unless currentUser.isCommentOnly
unless currentUser.isWorker
a.js-rename
i.fa.fa-pencil-square-o.icon(title="{{_ 'rename'}}")
a.js-confirm-delete
i.fa.fa-trash.icon(title="{{_ 'delete'}}")
a.fa.fa-navicon.icon.js-open-attachment-menu(data-attachment-link="{{link}}" title="{{_ 'attachmentActionsPopup-title'}}")
a.js-rename(title="{{_ 'rename'}}")
i.fa.fa-pencil-square-o
a.js-confirm-delete(title="{{_ 'delete'}}")
i.fa.fa-trash
a.js-open-attachment-menu(data-attachment-link="{{link}}", title="{{_ 'attachmentActionsPopup-title'}}")
i.fa.fa-bars
// Migration spinner overlay
if isAttachmentMigrating _id
.attachment-migration-overlay
.migration-spinner
i.fa.fa-cog.fa-spin
.migration-text {{_ 'migrating-attachment'}}
template(name="attachmentActionsPopup")
ul.pop-over-list
li
if isImage
a(class="{{#if isCover}}js-remove-cover{{else}}js-add-cover{{/if}}")
i.fa.fa-book
i.fa.fa-picture-o
if isCover
| {{_ 'remove-cover'}}
else
| {{_ 'add-cover'}}
| {{#if isCover}}{{_ 'remove-cover'}}{{else}}{{_ 'add-cover'}}{{/if}}
if currentUser.isBoardAdmin
if isImage
a(class="{{#if isBackgroundImage}}js-remove-background-image{{else}}js-add-background-image{{/if}}")
@@ -117,25 +124,6 @@ template(name="attachmentActionsPopup")
| {{_ 'remove-background-image'}}
else
| {{_ 'add-background-image'}}
p.attachment-storage
| {{versions.original.storage}}
if $neq versions.original.storage "fs"
a.js-move-storage-fs
i.fa.fa-arrow-right
| {{_ 'attachment-move-storage-fs'}}
if $neq versions.original.storage "gridfs"
if versions.original.storage
a.js-move-storage-gridfs
i.fa.fa-arrow-right
| {{_ 'attachment-move-storage-gridfs'}}
if $neq versions.original.storage "s3"
if versions.original.storage
a.js-move-storage-s3
i.fa.fa-arrow-right
| {{_ 'attachment-move-storage-s3'}}
template(name="attachmentRenamePopup")
input.js-edit-attachment-name(type='text' autofocus value="{{getNameWithoutExtension}}" dir="auto")
+252 -126
View File
@@ -1,9 +1,16 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { ObjectID } from 'bson';
import { ObjectId } from 'bson';
import DOMPurify from 'dompurify';
import { sanitizeHTML, sanitizeText } from '/imports/lib/secureDOMPurify';
import uploadProgressManager from '../../lib/uploadProgressManager';
import { attachmentMigrationManager } from '/client/lib/attachmentMigrationManager';
import Attachments from '/models/attachments';
import { Utils } from '/client/lib/utils';
import { formatDateTime } from '/imports/lib/dateUtils';
import { EscapeActions } from '/client/lib/escapeActions';
const filesize = require('filesize');
const prettyMilliseconds = require('pretty-ms');
const { filesize } = require('filesize');
import prettyMilliseconds from 'pretty-ms';
// We store current card ID and the ID of currently opened attachment in a
// global var. This is used so that we know what's the next attachment to open
@@ -16,7 +23,7 @@ let touchStartCoords = null;
let touchEndCoords = null;
// Stores link to the attachment for which attachment actions popup was opened
attachmentActionsLink = null;
let attachmentActionsLink = null;
Template.attachmentGallery.events({
'click .open-preview'(event) {
@@ -37,9 +44,13 @@ Template.attachmentGallery.events({
attachmentActionsLink = event.currentTarget.getAttribute("data-attachment-link");
},
'click .js-rename': Popup.open('attachmentRename'),
'click .js-confirm-delete': Popup.afterConfirm('attachmentDelete', function() {
Attachments.remove(this._id);
Popup.back(2);
'click .js-confirm-delete': Popup.afterConfirm('attachmentDelete', async function() {
const card = this.meta && this.meta.cardId ? ReactiveCache.getCard(this.meta.cardId) : null;
if (card && card.coverId === this._id) {
await card.unsetCover();
}
await Attachments.removeAsync(this._id);
Popup.back();
}),
});
@@ -78,6 +89,10 @@ function attachmentCanBeOpened(attachment) {
);
}
function getAttachmentUrl(attachment) {
return attachment && typeof attachment.link === 'function' ? attachment.link() : '';
}
function openAttachmentViewer(attachmentId) {
const attachment = ReactiveCache.getAttachment(attachmentId);
@@ -94,18 +109,18 @@ function openAttachmentViewer(attachmentId) {
*/
switch(true){
case (attachment.isImage):
$("#image-viewer").attr("src", attachment.link());
$("#image-viewer").attr("src", getAttachmentUrl(attachment));
$("#image-viewer").removeClass("hidden");
break;
case (attachment.isPDF):
$("#pdf-viewer").attr("data", attachment.link());
$("#pdf-viewer").attr("data", getAttachmentUrl(attachment));
$("#pdf-viewer").removeClass("hidden");
break;
case (attachment.isVideo):
// We have to create a new <source> DOM element and append it to the video
// element, otherwise the video won't load
let videoSource = document.createElement('source');
videoSource.setAttribute('src', attachment.link());
videoSource.setAttribute('src', getAttachmentUrl(attachment));
$("#video-viewer").append(videoSource);
$("#video-viewer").removeClass("hidden");
@@ -114,14 +129,14 @@ function openAttachmentViewer(attachmentId) {
// We have to create a new <source> DOM element and append it to the audio
// element, otherwise the audio won't load
let audioSource = document.createElement('source');
audioSource.setAttribute('src', attachment.link());
audioSource.setAttribute('src', getAttachmentUrl(attachment));
$("#audio-viewer").append(audioSource);
$("#audio-viewer").removeClass("hidden");
break;
case (attachment.isText):
case (attachment.isJSON):
$("#txt-viewer").attr("data", attachment.link());
$("#txt-viewer").attr("data", getAttachmentUrl(attachment));
$("#txt-viewer").removeClass("hidden");
break;
}
@@ -193,8 +208,6 @@ function processTouch(){
xDist = touchEndCoords.x - touchStartCoords.x;
yDist = touchEndCoords.y - touchStartCoords.y;
console.log("xDist: " + xDist);
// Left swipe
if (Math.abs(xDist) > Math.abs(yDist) && xDist < 0) {
openNextAttachment();
@@ -214,14 +227,12 @@ function processTouch(){
Template.attachmentViewer.events({
'touchstart #viewer-container'(event) {
console.log("touchstart")
touchStartCoords = {
x: event.changedTouches[0].screenX,
y: event.changedTouches[0].screenY
}
},
'touchend #viewer-container'(event) {
console.log("touchend")
touchEndCoords = {
x: event.changedTouches[0].screenX,
y: event.changedTouches[0].screenY
@@ -260,6 +271,24 @@ Template.attachmentViewer.events({
});
Template.attachmentGallery.helpers({
attachments() {
const card = Template.currentData();
if (!card) return [];
const cardId = typeof card.getRealId === 'function' ? card.getRealId() : card._id;
if (!cardId) return [];
const filesCursor = Attachments.find(
{ 'meta.cardId': cardId },
{ sort: { uploadedAt: -1 } },
);
// Call fetch() on the underlying Mongo cursor to establish a reactive
// dependency directly inside this Blaze computation. Without this,
// .each() (which calls cursor.map()) would not register reactivity and
// newly-uploaded attachments would not appear until a page reload.
if (filesCursor && filesCursor.cursor) {
filesCursor.cursor.fetch();
}
return filesCursor.each();
},
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
},
@@ -268,7 +297,27 @@ Template.attachmentGallery.helpers({
return ret;
},
sanitize(value) {
return DOMPurify.sanitize(value);
return sanitizeHTML(value);
},
uploaderName() {
const uploaderId = this.userId;
if (!uploaderId) return '';
const uploader = ReactiveCache.getUser(uploaderId);
if (!uploader) return '';
return uploader.profile && uploader.profile.fullname
? uploader.profile.fullname
: uploader.username || '';
},
uploadedAt() {
if (this.uploadedAtOstrio) {
return formatDateTime(this.uploadedAtOstrio);
}
// Fall back to ObjectId timestamp (first 4 bytes = Unix seconds)
try {
const ts = parseInt(this._id.substring(0, 8), 16) * 1000;
if (!isNaN(ts)) return formatDateTime(new Date(ts));
} catch (_) {}
return '';
},
});
@@ -291,49 +340,19 @@ Template.cardAttachmentsPopup.helpers({
});
Template.cardAttachmentsPopup.events({
'change .js-attach-file'(event, templateInstance) {
async 'change .js-attach-file'(event, templateInstance) {
event.stopPropagation();
const card = this;
const files = event.currentTarget.files;
if (files) {
let uploads = [];
for (const file of files) {
const fileId = new ObjectID().toString();
let fileName = DOMPurify.sanitize(file.name);
const uploaders = await handleFileUpload(card, files);
// If sanitized filename is not same as original filename,
// it could be XSS that is already fixed with sanitize,
// or just normal mistake, so it is not a problem.
// That is why here is no warning.
if (fileName !== file.name) {
// If filename is empty, only in that case add some filename
if (fileName.length === 0) {
fileName = 'Empty-filename-after-sanitize.txt';
}
}
const config = {
file: file,
fileId: fileId,
fileName: fileName,
meta: Utils.getCommonAttachmentMetaFrom(card),
chunkSize: 'dynamic',
};
config.meta.fileId = fileId;
const uploader = Attachments.insert(
config,
false,
);
uploaders.forEach(uploader => {
uploader.on('start', function() {
uploads.push(this);
templateInstance.uploads.set(uploads);
});
uploader.on('uploaded', (error, fileRef) => {
if (!error) {
if (fileRef.isImage) {
card.setCover(fileRef._id);
}
}
});
uploader.on('end', (error, fileRef) => {
uploads = uploads.filter(_upload => _upload.config.fileId != fileRef._id);
templateInstance.uploads.set(uploads);
@@ -341,11 +360,14 @@ Template.cardAttachmentsPopup.events({
Popup.back();
}
});
uploader.start();
}
});
}
},
'click .js-computer-upload'(event, templateInstance) {
// Prevent the click fired when the OS file-picker dialog closes from
// triggering EscapeActions and closing the popup before the upload starts.
// Same pattern as swimlanes.js after drag operations.
EscapeActions.preventNextClick();
templateInstance.find('.js-attach-file').click();
event.preventDefault();
},
@@ -356,6 +378,110 @@ const MAX_IMAGE_PIXEL = Utils.MAX_IMAGE_PIXEL;
const COMPRESS_RATIO = Utils.IMAGE_COMPRESS_RATIO;
let pastedResults = null;
// Shared upload logic for drag-and-drop functionality
export async function handleFileUpload(card, files) {
if (!files || files.length === 0) {
return [];
}
// Check if board allows attachments
const board = card.board();
if (!board || !board.allowsAttachments) {
if (process.env.DEBUG === 'true') {
console.warn('Attachments not allowed on this board');
}
return [];
}
// Check if user can modify the card
if (!Utils.canModifyCard()) {
if (process.env.DEBUG === 'true') {
console.warn('User does not have permission to modify this card');
}
return [];
}
const uploads = [];
for (const file of files) {
// Basic file validation
if (!file || !file.name) {
if (process.env.DEBUG === 'true') {
console.warn('Invalid file object');
}
continue;
}
const fileId = new ObjectId().toString();
let fileName = sanitizeText(file.name);
// If sanitized filename is not same as original filename,
// it could be XSS that is already fixed with sanitize,
// or just normal mistake, so it is not a problem.
// That is why here is no warning.
if (fileName !== file.name) {
// If filename is empty, only in that case add some filename
if (fileName.length === 0) {
fileName = 'Empty-filename-after-sanitize.txt';
}
}
const config = {
file: file,
fileId: fileId,
fileName: fileName,
meta: Utils.getCommonAttachmentMetaFrom(card),
chunkSize: 'dynamic',
// Use HTTP transport instead of DDP so file chunks go over a dedicated
// fetch POST rather than flooding the WebSocket/DDP channel. DDP
// upload causes repeated DDP reconnects in Safari, showing the
// "Loading, please wait" offline banner and stalling progress at ~95%.
transport: 'http',
};
config.meta.fileId = fileId;
try {
const uploader = await Attachments.insertAsync(
config,
false,
);
// Add to progress manager for tracking
const uploadId = uploadProgressManager.addUpload(card._id, uploader, file);
uploader.on('uploaded', (error, fileRef) => {
if (!error) {
if (fileRef.isImage) {
card.setCover(fileRef._id);
if (process.env.DEBUG === 'true') {
console.log(`Set cover image for card ${card._id}: ${fileRef.name}`);
}
}
} else {
if (process.env.DEBUG === 'true') {
console.error('Upload error:', error);
}
}
});
uploader.on('error', (error) => {
if (process.env.DEBUG === 'true') {
console.error('Upload error:', error);
}
});
uploads.push(uploader);
uploader.start();
} catch (error) {
if (process.env.DEBUG === 'true') {
console.error('Failed to create uploader:', error);
}
}
}
return uploads;
}
Template.previewClipboardImagePopup.onRendered(() => {
// we can paste image from clipboard
const handle = results => {
@@ -390,21 +516,22 @@ Template.previewClipboardImagePopup.onRendered(() => {
});
Template.previewClipboardImagePopup.events({
'click .js-upload-pasted-image'() {
async 'click .js-upload-pasted-image'() {
const card = this;
if (pastedResults && pastedResults.file) {
const file = pastedResults.file;
window.oPasted = pastedResults;
const fileId = new ObjectID().toString();
const fileId = new ObjectId().toString();
const config = {
file,
fileId: fileId,
meta: Utils.getCommonAttachmentMetaFrom(card),
fileName: file.name || file.type.replace('image/', 'clipboard.'),
chunkSize: 'dynamic',
transport: 'http',
};
config.meta.fileId = fileId;
const uploader = Attachments.insert(
const uploader = await Attachments.insertAsync(
config,
false,
);
@@ -425,9 +552,9 @@ Template.previewClipboardImagePopup.events({
},
});
BlazeComponent.extendComponent({
Template.attachmentActionsPopup.helpers({
isCover() {
const ret = ReactiveCache.getCard(this.data().meta.cardId).coverId == this.data()._id;
const ret = ReactiveCache.getCard(this.meta.cardId).coverId == this._id;
return ret;
},
isBackgroundImage() {
@@ -435,75 +562,74 @@ BlazeComponent.extendComponent({
//return currentBoard.backgroundImageURL === $(".attachment-thumbnail-img").attr("src");
return false;
},
events() {
return [
{
'click .js-add-cover'() {
ReactiveCache.getCard(this.data().meta.cardId).setCover(this.data()._id);
Popup.back();
},
'click .js-remove-cover'() {
ReactiveCache.getCard(this.data().meta.cardId).unsetCover();
Popup.back();
},
'click .js-add-background-image'() {
const currentBoard = Utils.getCurrentBoard();
currentBoard.setBackgroundImageURL(attachmentActionsLink);
Utils.setBackgroundImage(attachmentActionsLink);
Popup.back();
event.preventDefault();
},
'click .js-remove-background-image'() {
const currentBoard = Utils.getCurrentBoard();
currentBoard.setBackgroundImageURL("");
Utils.setBackgroundImage("");
Popup.back();
Utils.reload();
event.preventDefault();
},
'click .js-move-storage-fs'() {
Meteor.call('moveAttachmentToStorage', this.data()._id, "fs");
Popup.back();
},
'click .js-move-storage-gridfs'() {
Meteor.call('moveAttachmentToStorage', this.data()._id, "gridfs");
Popup.back();
},
'click .js-move-storage-s3'() {
Meteor.call('moveAttachmentToStorage', this.data()._id, "s3");
Popup.back();
},
}
]
}
}).register('attachmentActionsPopup');
});
BlazeComponent.extendComponent({
Template.attachmentActionsPopup.events({
'click .js-add-cover'() {
ReactiveCache.getCard(this.meta.cardId).setCover(this._id);
Popup.back();
},
'click .js-remove-cover'() {
ReactiveCache.getCard(this.meta.cardId).unsetCover();
Popup.back();
},
'click .js-add-background-image'(event) {
const currentBoard = Utils.getCurrentBoard();
currentBoard.setBackgroundImageURL(attachmentActionsLink);
Utils.setBackgroundImage(attachmentActionsLink);
Popup.back();
event.preventDefault();
},
'click .js-remove-background-image'(event) {
const currentBoard = Utils.getCurrentBoard();
currentBoard.setBackgroundImageURL("");
Utils.setBackgroundImage("");
Popup.back();
Utils.reload();
event.preventDefault();
},
});
Template.attachmentRenamePopup.helpers({
getNameWithoutExtension() {
const ret = this.data().name.replace(new RegExp("\." + this.data().extension + "$"), "");
const ret = this.name.replace(new RegExp("\\." + this.extension + "$"), "");
return ret;
},
events() {
return [
{
'keydown input.js-edit-attachment-name'(evt) {
// enter = save
if (evt.keyCode === 13) {
this.find('button[type=submit]').click();
}
},
'click button.js-submit-edit-attachment-name'(event) {
// save button pressed
event.preventDefault();
const name = this.$('.js-edit-attachment-name')[0]
.value
.trim() + this.data().extensionWithDot;
if (name === DOMPurify.sanitize(name)) {
Meteor.call('renameAttachment', this.data()._id, name);
}
Popup.back(2);
},
}
]
}
}).register('attachmentRenamePopup');
});
Template.attachmentRenamePopup.events({
'keydown input.js-edit-attachment-name'(evt, tpl) {
// enter = save
if (evt.keyCode === 13) {
tpl.find('button[type=submit]').click();
}
},
'click button.js-submit-edit-attachment-name'(event, tpl) {
// save button pressed
event.preventDefault();
const name = tpl.$('.js-edit-attachment-name')[0]
.value
.trim() + this.extensionWithDot;
if (name === sanitizeText(name)) {
Meteor.call('renameAttachment', this._id, name);
}
Popup.back();
},
});
// Template helpers for attachment migration status
Template.registerHelper('attachmentMigrationStatus', function(attachmentId) {
return attachmentMigrationManager.getAttachmentMigrationStatus(attachmentId);
});
Template.registerHelper('isAttachmentMigrating', function(attachmentId) {
return attachmentMigrationManager.isAttachmentBeingMigrated(attachmentId);
});
Template.registerHelper('attachmentMigrationProgress', function() {
return attachmentMigrationManager.attachmentMigrationProgress.get();
});
Template.registerHelper('attachmentMigrationStatusText', function() {
return attachmentMigrationManager.attachmentMigrationStatus.get();
});
+29 -12
View File
@@ -22,7 +22,7 @@ template(name="cardCustomField-text")
= value
.edit-controls.clearfix
button.primary(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.js-close-inlined-form
else
a.js-open-inlined-form
if value
@@ -41,7 +41,7 @@ template(name="cardCustomField-number")
input(type="number" value=data.value)
.edit-controls.clearfix
button.primary(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.js-close-inlined-form
else
a.js-open-inlined-form
if value
@@ -56,9 +56,9 @@ template(name="cardCustomField-checkbox")
.js-checklist-item.checklist-item(class="{{#if data.value }}is-checked{{/if}}")
if canModifyCard
.check-box-container
.check-box.materialCheckBox(class="{{#if data.value }}is-checked{{/if}}")
.check-box.materialCheckBox(class="{{#if data.value}}is-checked{{/if}}")
else
.materialCheckBox(class="{{#if data.value }}is-checked{{/if}}")
.materialCheckBox(class="{{#if data.value}}is-checked{{/if}}")
template(name="cardCustomField-currency")
if canModifyCard
@@ -66,7 +66,7 @@ template(name="cardCustomField-currency")
input(type="text" value=data.value autofocus)
.edit-controls.clearfix
button.primary(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.js-close-inlined-form
else
a.js-open-inlined-form
if value
@@ -79,13 +79,14 @@ template(name="cardCustomField-currency")
template(name="cardCustomField-date")
if canModifyCard
a.js-edit-date(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
a.js-edit-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
if value
div.card-date
time(datetime="{{showISODate}}")
| {{showDate}}
b
| {{showWeek}}
if showWeekOfYear
b
| {{showWeek}}
else
| {{_ 'edit'}}
else
@@ -93,8 +94,24 @@ template(name="cardCustomField-date")
div.card-date
time(datetime="{{showISODate}}")
| {{showDate}}
b
| {{showWeek}}
if showWeekOfYear
b
| {{showWeek}}
template(name="cardCustomField-datePopup")
.datepicker-container
form.edit-date
.fields
.left
label(for="date") {{_ 'date'}}
input.js-date-field#date(type="date" name="date" value=showDate autofocus)
.right
label(for="time") {{_ 'time'}}
input.js-time-field#time(type="time" name="time" value=showTime)
if error.get
.warning {{_ error.get}}
button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}}
button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}}
template(name="cardCustomField-dropdown")
if canModifyCard
@@ -111,7 +128,7 @@ template(name="cardCustomField-dropdown")
= name
.edit-controls.clearfix
button.primary(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.js-close-inlined-form
else
a.js-open-inlined-form
if value
@@ -132,7 +149,7 @@ template(name="cardCustomField-stringtemplate")
input.js-card-customfield-stringtemplate-item.last(type="text" value="" placeholder="{{_ 'custom-field-stringtemplate-item-placeholder'}}" autofocus)
.edit-controls.clearfix
button.primary(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.js-close-inlined-form
else
a.js-open-inlined-form
if value
+250 -238
View File
@@ -1,12 +1,41 @@
import moment from 'moment/min/moment-with-locales';
import { TAPi18n } from '/imports/i18n';
import { DatePicker } from '/client/lib/datepicker';
import Cards from '/models/cards';
import {
setupDatePicker,
datePickerRendered,
datePickerHelpers,
datePickerEvents,
} from '/client/lib/datepicker';
import { ReactiveCache } from '/imports/reactiveCache';
import {
formatDateTime,
formatDate,
formatDateByUserPreference,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
import { CustomFieldStringTemplate } from '/client/lib/customFields'
import { getCurrentCardFromContext } from '/client/lib/currentCard';
import { EscapeActions } from '/client/lib/escapeActions';
import { getSidebarInstance } from '/client/features/sidebar/service';
Template.cardCustomFieldsPopup.helpers({
hasCustomField() {
const card = Utils.getCurrentCard();
const card = getCurrentCardFromContext();
if (!card) return false;
const customFieldId = this._id;
return card.customFieldIndex(customFieldId) > -1;
},
@@ -14,311 +43,294 @@ Template.cardCustomFieldsPopup.helpers({
Template.cardCustomFieldsPopup.events({
'click .js-select-field'(event) {
const card = Utils.getCurrentCard();
const card = getCurrentCardFromContext();
if (!card) return;
const customFieldId = this._id;
card.toggleCustomField(customFieldId);
event.preventDefault();
},
'click .js-settings'(event) {
EscapeActions.executeUpTo('detailsPane');
Sidebar.setView('customFields');
const sidebar = getSidebarInstance();
if (sidebar) {
sidebar.setView('customFields');
}
event.preventDefault();
},
});
// cardCustomField
const CardCustomField = BlazeComponent.extendComponent({
Template.cardCustomField.helpers({
getTemplate() {
return `cardCustomField-${this.data().definition.type}`;
},
onCreated() {
const self = this;
self.card = Utils.getCurrentCard();
self.customFieldId = this.data()._id;
return `cardCustomField-${this.definition.type}`;
},
});
CardCustomField.register('cardCustomField');
Template.cardCustomField.onCreated(function () {
this.card = getCurrentCardFromContext();
this.customFieldId = Template.currentData()._id;
});
// cardCustomField-text
(class extends CardCustomField {
onCreated() {
super.onCreated();
}
Template['cardCustomField-text'].onCreated(function () {
this.card = getCurrentCardFromContext();
this.customFieldId = Template.currentData()._id;
});
events() {
return [
{
'submit .js-card-customfield-text'(event) {
event.preventDefault();
const value = this.currentComponent().getValue();
this.card.setCustomField(this.customFieldId, value);
},
},
];
}
}.register('cardCustomField-text'));
Template['cardCustomField-text'].events({
'submit .js-card-customfield-text'(event, tpl) {
event.preventDefault();
const value = tpl.currentComponent ? tpl.currentComponent().getValue() : tpl.$('textarea').val();
tpl.card.setCustomField(tpl.customFieldId, value);
},
});
// cardCustomField-number
(class extends CardCustomField {
onCreated() {
super.onCreated();
}
Template['cardCustomField-number'].onCreated(function () {
this.card = getCurrentCardFromContext();
this.customFieldId = Template.currentData()._id;
});
events() {
return [
{
'submit .js-card-customfield-number'(event) {
event.preventDefault();
const value = parseInt(this.find('input').value, 10);
this.card.setCustomField(this.customFieldId, value);
},
},
];
}
}.register('cardCustomField-number'));
Template['cardCustomField-number'].events({
'submit .js-card-customfield-number'(event, tpl) {
event.preventDefault();
const value = parseInt(tpl.find('input').value, 10);
tpl.card.setCustomField(tpl.customFieldId, value);
},
});
// cardCustomField-checkbox
(class extends CardCustomField {
onCreated() {
super.onCreated();
}
Template['cardCustomField-checkbox'].onCreated(function () {
this.card = getCurrentCardFromContext();
this.customFieldId = Template.currentData()._id;
});
toggleItem() {
this.card.setCustomField(this.customFieldId, !this.data().value);
}
events() {
return [
{
'click .js-checklist-item .check-box-container': this.toggleItem,
},
];
}
}.register('cardCustomField-checkbox'));
Template['cardCustomField-checkbox'].events({
'click .js-checklist-item .check-box-container'(event, tpl) {
tpl.card.setCustomField(tpl.customFieldId, !Template.currentData().value);
},
});
// cardCustomField-currency
(class extends CardCustomField {
onCreated() {
super.onCreated();
this.currencyCode = this.data().definition.settings.currencyCode;
}
Template['cardCustomField-currency'].onCreated(function () {
this.card = getCurrentCardFromContext();
this.customFieldId = Template.currentData()._id;
this.currencyCode = Template.currentData().definition.settings.currencyCode;
});
Template['cardCustomField-currency'].helpers({
formattedValue() {
const locale = TAPi18n.getLanguage();
const tpl = Template.instance();
return new Intl.NumberFormat(locale, {
style: 'currency',
currency: this.currencyCode,
}).format(this.data().value);
}
currency: tpl.currencyCode,
}).format(this.value);
},
});
events() {
return [
{
'submit .js-card-customfield-currency'(event) {
event.preventDefault();
// To allow input separated by comma, the comma is replaced by a period.
const value = Number(this.find('input').value.replace(/,/i, '.'), 10);
this.card.setCustomField(this.customFieldId, value);
},
},
];
}
}.register('cardCustomField-currency'));
Template['cardCustomField-currency'].events({
'submit .js-card-customfield-currency'(event, tpl) {
event.preventDefault();
// To allow input separated by comma, the comma is replaced by a period.
const value = Number(tpl.find('input').value.replace(/,/i, '.'), 10);
tpl.card.setCustomField(tpl.customFieldId, value);
},
});
// cardCustomField-date
(class extends CardCustomField {
onCreated() {
super.onCreated();
const self = this;
self.date = ReactiveVar();
self.now = ReactiveVar(moment());
window.setInterval(() => {
self.now.set(moment());
}, 60000);
Template['cardCustomField-date'].onCreated(function () {
this.card = getCurrentCardFromContext();
this.customFieldId = Template.currentData()._id;
const self = this;
self.date = ReactiveVar();
self.now = ReactiveVar(now());
window.setInterval(() => {
self.now.set(now());
}, 60000);
self.autorun(() => {
self.date.set(moment(self.data().value));
});
}
self.autorun(() => {
self.date.set(new Date(Template.currentData().value));
});
});
Template['cardCustomField-date'].helpers({
showWeek() {
return this.date.get().week().toString();
}
return getISOWeek(Template.instance().date.get()).toString();
},
showWeekOfYear() {
const user = ReactiveCache.getCurrentUser();
if (!user) {
return false;
}
return user.isShowWeekOfYear();
},
showDate() {
// this will start working once mquandalle:moment
// is updated to at least moment.js 2.10.5
// until then, the date is displayed in the "L" format
return this.date.get().calendar(null, {
sameElse: 'llll',
});
}
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
return formatDateByUserPreference(Template.instance().date.get(), dateFormat, true);
},
showISODate() {
return this.date.get().toISOString();
}
return Template.instance().date.get().toISOString();
},
classes() {
const tpl = Template.instance();
if (
this.date.get().isBefore(this.now.get(), 'minute') &&
this.now.get().isBefore(this.data().value)
isBefore(tpl.date.get(), tpl.now.get(), 'minute') &&
isBefore(tpl.now.get(), this.value, 'minute')
) {
return 'current';
}
return '';
}
},
showTitle() {
return `${TAPi18n.__('card-start-on')} ${this.date.get().format('LLLL')}`;
}
return `${TAPi18n.__('card-start-on')} ${Template.instance().date.get().toLocaleString()}`;
},
});
events() {
return [
{
'click .js-edit-date': Popup.open('cardCustomField-date'),
},
];
}
}.register('cardCustomField-date'));
Template['cardCustomField-date'].events({
'click .js-edit-date': Popup.open('cardCustomField-date'),
});
// cardCustomField-datePopup
(class extends DatePicker {
onCreated() {
super.onCreated();
const self = this;
self.card = Utils.getCurrentCard();
self.customFieldId = this.data()._id;
this.data().value && this.date.set(moment(this.data().value));
}
Template['cardCustomField-datePopup'].onCreated(function () {
const data = Template.currentData();
setupDatePicker(this, {
initialDate: data.value ? data.value : undefined,
});
// Override card and store customFieldId for store/delete callbacks
this.datePicker.card = getCurrentCardFromContext();
this.customFieldId = data._id;
});
_storeDate(date) {
this.card.setCustomField(this.customFieldId, date);
}
Template['cardCustomField-datePopup'].onRendered(function () {
datePickerRendered(this);
});
_deleteDate() {
this.card.setCustomField(this.customFieldId, '');
}
}.register('cardCustomField-datePopup'));
Template['cardCustomField-datePopup'].helpers(datePickerHelpers());
Template['cardCustomField-datePopup'].events(datePickerEvents({
storeDate(date) {
this.datePicker.card.setCustomField(this.customFieldId, date);
},
deleteDate() {
this.datePicker.card.setCustomField(this.customFieldId, '');
},
}));
// cardCustomField-dropdown
(class extends CardCustomField {
onCreated() {
super.onCreated();
this._items = this.data().definition.settings.dropdownItems;
this.items = this._items.slice(0);
this.items.unshift({
_id: '',
name: TAPi18n.__('custom-field-dropdown-none'),
});
}
Template['cardCustomField-dropdown'].onCreated(function () {
this.card = getCurrentCardFromContext();
this.customFieldId = Template.currentData()._id;
this._items = Template.currentData().definition.settings.dropdownItems;
this.items = this._items.slice(0);
this.items.unshift({
_id: '',
name: TAPi18n.__('custom-field-dropdown-none'),
});
});
Template['cardCustomField-dropdown'].helpers({
items() {
return Template.instance().items;
},
selectedItem() {
const selected = this._items.find(item => {
return item._id === this.data().value;
const tpl = Template.instance();
const selected = tpl._items.find(item => {
return item._id === this.value;
});
return selected
? selected.name
: TAPi18n.__('custom-field-dropdown-unknown');
}
},
});
events() {
return [
{
'submit .js-card-customfield-dropdown'(event) {
event.preventDefault();
const value = this.find('select').value;
this.card.setCustomField(this.customFieldId, value);
},
},
];
}
}.register('cardCustomField-dropdown'));
Template['cardCustomField-dropdown'].events({
'submit .js-card-customfield-dropdown'(event, tpl) {
event.preventDefault();
const value = tpl.find('select').value;
tpl.card.setCustomField(tpl.customFieldId, value);
},
});
// cardCustomField-stringtemplate
class CardCustomFieldStringTemplate extends CardCustomField {
onCreated() {
super.onCreated();
this.customField = new CustomFieldStringTemplate(this.data().definition);
this.stringtemplateItems = new ReactiveVar(this.data().value ?? []);
}
Template['cardCustomField-stringtemplate'].onCreated(function () {
this.card = getCurrentCardFromContext();
this.customFieldId = Template.currentData()._id;
this.customField = new CustomFieldStringTemplate(Template.currentData().definition);
this.stringtemplateItems = new ReactiveVar(Template.currentData().value ?? []);
});
Template['cardCustomField-stringtemplate'].helpers({
formattedValue() {
const ret = this.customField.getFormattedValue(this.data().value);
const tpl = Template.instance();
const ret = tpl.customField.getFormattedValue(this.value);
return ret;
}
},
stringtemplateItems() {
return Template.instance().stringtemplateItems.get();
},
});
getItems() {
return Array.from(this.findAll('input'))
.map(input => input.value)
.filter(value => !!value.trim());
}
Template['cardCustomField-stringtemplate'].events({
'submit .js-card-customfield-stringtemplate'(event, tpl) {
event.preventDefault();
const items = tpl.stringtemplateItems.get();
tpl.card.setCustomField(tpl.customFieldId, items);
},
events() {
return [
{
'submit .js-card-customfield-stringtemplate'(event) {
event.preventDefault();
const items = this.stringtemplateItems.get();
this.card.setCustomField(this.customFieldId, items);
},
'keydown .js-card-customfield-stringtemplate-item'(event, tpl) {
if (event.keyCode === 13) {
event.preventDefault();
'keydown .js-card-customfield-stringtemplate-item'(event) {
if (event.keyCode === 13) {
event.preventDefault();
if (event.target.value.trim() || event.metaKey || event.ctrlKey) {
const inputLast = tpl.find('input.last');
if (event.target.value.trim() || event.metaKey || event.ctrlKey) {
const inputLast = this.find('input.last');
let items = Array.from(tpl.findAll('input'))
.map(input => input.value)
.filter(value => !!value.trim());
let items = this.getItems();
if (event.target === inputLast) {
inputLast.value = '';
} else if (event.target.nextSibling === inputLast) {
inputLast.focus();
} else {
event.target.blur();
if (event.target === inputLast) {
inputLast.value = '';
} else if (event.target.nextSibling === inputLast) {
inputLast.focus();
} else {
event.target.blur();
const idx = Array.from(tpl.findAll('input')).indexOf(
event.target,
);
items.splice(idx + 1, 0, '');
const idx = Array.from(this.findAll('input')).indexOf(
event.target,
);
items.splice(idx + 1, 0, '');
Tracker.afterFlush(() => {
const element = tpl.findAll('input')[idx + 1];
element.focus();
element.value = '';
});
}
Tracker.afterFlush(() => {
const element = this.findAll('input')[idx + 1];
element.focus();
element.value = '';
});
}
tpl.stringtemplateItems.set(items);
}
if (event.metaKey || event.ctrlKey) {
tpl.find('button[type=submit]').click();
}
}
},
this.stringtemplateItems.set(items);
}
if (event.metaKey || event.ctrlKey) {
this.find('button[type=submit]').click();
}
}
},
'blur .js-card-customfield-stringtemplate-item'(event, tpl) {
if (
!event.target.value.trim() ||
event.target === tpl.find('input.last')
) {
const items = Array.from(tpl.findAll('input'))
.map(input => input.value)
.filter(value => !!value.trim());
tpl.stringtemplateItems.set(items);
tpl.find('input.last').value = '';
}
},
'blur .js-card-customfield-stringtemplate-item'(event) {
if (
!event.target.value.trim() ||
event.target === this.find('input.last')
) {
const items = this.getItems();
this.stringtemplateItems.set(items);
this.find('input.last').value = '';
}
},
'click .js-close-inlined-form'(event) {
this.stringtemplateItems.set(this.data().value ?? []);
},
},
];
}
}
CardCustomFieldStringTemplate.register('cardCustomField-stringtemplate');
'click .js-close-inlined-form'(event, tpl) {
tpl.stringtemplateItems.set(Template.currentData().value ?? []);
},
});
+103 -26
View File
@@ -8,57 +8,134 @@
.card-date.is-active {
background-color: #b3b3b3;
}
.card-date.current,
.card-date.almost-due,
.card-date.due,
.card-date.long-overdue {
/* Date status colors - red = overdue, amber = due soon, no shade = not due */
.card-date.overdue {
background-color: #ff4444; /* Red for overdue */
color: #fff;
}
.card-date.overdue:hover,
.card-date.overdue.is-active {
background-color: #cc3333;
}
.card-date.due-soon {
background-color: #ffaa00; /* Amber for due soon */
color: #000;
}
.card-date.due-soon:hover,
.card-date.due-soon.is-active {
background-color: #e69900;
}
.card-date.not-due {
/* No special background - uses default date type colors */
}
.card-date.current {
background-color: #5ba639;
background-color: #5ba639; /* Green for current/active */
color: #fff;
}
.card-date.current:hover,
.card-date.current.is-active {
background-color: #46802c;
}
.card-date.almost-due {
background-color: #edc909;
.card-date.completed {
background-color: #90ee90; /* Light green for completed */
color: #000;
}
.card-date.almost-due:hover,
.card-date.almost-due.is-active {
background-color: #bc9f07;
.card-date.completed:hover,
.card-date.completed.is-active {
background-color: #7dd87d;
}
.card-date.due {
background-color: #fa3f00;
.card-date.completed-early {
background-color: #4caf50; /* Green for completed early */
color: #fff;
}
.card-date.due:hover,
.card-date.due.is-active {
background-color: #c73200;
.card-date.completed-early:hover,
.card-date.completed-early.is-active {
background-color: #45a049;
}
.card-date.long-overdue {
background-color: #fd5d47;
.card-date.completed-late {
background-color: #ff9800; /* Orange for completed late */
color: #fff;
}
.card-date.long-overdue:hover,
.card-date.long-overdue.is-active {
background-color: #fd3e24;
.card-date.completed-late:hover,
.card-date.completed-late.is-active {
background-color: #f57c00;
}
.card-date.completed-on-time {
background-color: #2196f3; /* Blue for completed on time */
color: #fff;
}
.card-date.completed-on-time:hover,
.card-date.completed-on-time.is-active {
background-color: #1976d2;
}
/* Date type specific colors */
.card-date.received-date {
background-color: #dbdbdb; /* Light grey for received */
}
.card-date.received-date:hover,
.card-date.received-date.is-active {
background-color: #b3b3b3;
}
.card-date.start-date {
background-color: #90ee90; /* Light green for start */
color: #000; /* Black text for start */
}
.card-date.start-date:hover,
.card-date.start-date.is-active {
background-color: #7dd87d;
}
.card-date.due-date {
background-color: #ffd700; /* Yellow for due */
color: #000; /* Black text for due */
}
.card-date.due-date:hover,
.card-date.due-date.is-active {
background-color: #e6c200;
}
.card-date.end-date {
background-color: #ffb3b3; /* Light red for end */
color: #000; /* Black text for end */
}
.card-date.end-date:hover,
.card-date.end-date.is-active {
background-color: #ff9999;
}
.card-date.end-date time::before {
content: "\f253";
content: "🏁"; /* Finish flag - represents end/completion */
}
.card-date.due-date time::before {
content: "\f090";
content: "⏰"; /* Alarm clock - represents due/deadline */
}
.card-date.start-date time::before {
content: "\f251";
content: "🚀"; /* Rocket - represents start/launch */
}
.card-date.received-date time::before {
content: "\f08b";
content: "📥"; /* Inbox tray - represents received/incoming */
}
/* Generic date badge and custom field date */
.card-date:not(.received-date):not(.start-date):not(.due-date):not(.end-date) time::before {
/*content: "📅"; // Calendar - represents generic date */
}
.card-date time::before {
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
-webkit-font-smoothing: antialiased;
margin-right: 0.3em;
display: inline-block;
}
.customfield-date {
display: block;
+277 -8
View File
@@ -1,20 +1,289 @@
template(name="dateBadge")
if canModifyCard
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
b
| {{showWeek}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="cardReceivedDate")
if canModifyCard
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="cardStartDate")
if canModifyCard
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="cardDueDate")
if canModifyCard
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="cardEndDate")
if canModifyCard
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="dateCustomField")
a(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="dateCustomField")
a(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
template(name="cardCustomFieldDate")
a(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
b
| {{showWeek}}
if showWeekOfYear
b
| {{showWeek}}
template(name="voteEndDate")
if canModifyCard
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="pokerEndDate")
if canModifyCard
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="minicardReceivedDate")
if canModifyCard
a.js-edit-date.card-date.received-date(title="{{_ 'card-received'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date.received-date(title="{{_ 'card-received'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="minicardStartDate")
if canModifyCard
a.js-edit-date.card-date.start-date(title="{{_ 'card-start'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date.start-date(title="{{_ 'card-start'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="minicardDueDate")
if canModifyCard
a.js-edit-date.card-date.due-date(title="{{_ 'card-due'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date.due-date(title="{{_ 'card-due'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="minicardEndDate")
if canModifyCard
a.js-edit-date.card-date.end-date(title="{{_ 'card-end'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date.end-date(title="{{_ 'card-end'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="minicardCustomFieldDate")
a(title="{{_ 'date'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
if showWeekOfYear
b
| {{showWeek}}
template(name="editCardReceivedDatePopup")
.datepicker-container
form.edit-date
.fields
.left
label(for="date") {{_ 'date'}}
input.js-date-field#date(type="date" name="date" value=showDate autofocus)
.right
label(for="time") {{_ 'time'}}
input.js-time-field#time(type="time" name="time" value=showTime)
if error.get
.warning {{_ error.get}}
button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}}
button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}}
template(name="editCardStartDatePopup")
.datepicker-container
form.edit-date
.fields
.left
label(for="date") {{_ 'date'}}
input.js-date-field#date(type="date" name="date" value=showDate autofocus)
.right
label(for="time") {{_ 'time'}}
input.js-time-field#time(type="time" name="time" value=showTime)
if error.get
.warning {{_ error.get}}
button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}}
button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}}
template(name="editCardDueDatePopup")
.datepicker-container
form.edit-date
.fields
.left
label(for="date") {{_ 'date'}}
input.js-date-field#date(type="date" name="date" value=showDate autofocus)
.right
label(for="time") {{_ 'time'}}
input.js-time-field#time(type="time" name="time" value=showTime)
if error.get
.warning {{_ error.get}}
button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}}
button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}}
template(name="editCardEndDatePopup")
.datepicker-container
form.edit-date
.fields
.left
label(for="date") {{_ 'date'}}
input.js-date-field#date(type="date" name="date" value=showDate autofocus)
.right
label(for="time") {{_ 'time'}}
input.js-time-field#time(type="time" name="time" value=showTime)
if error.get
.warning {{_ error.get}}
button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}}
button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}}
template(name="editVoteEndDatePopup")
.datepicker-container
form.edit-date
.fields
.left
label(for="date") {{_ 'date'}}
input.js-date-field#date(type="date" name="date" value=showDate autofocus)
.right
label(for="time") {{_ 'time'}}
input.js-time-field#time(type="time" name="time" value=showTime)
if error.get
.warning {{_ error.get}}
button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}}
button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}}
template(name="editPokerEndDatePopup")
.datepicker-container
form.edit-date
.fields
.left
label(for="date") {{_ 'date'}}
input.js-date-field#date(type="date" name="date" value=showDate autofocus)
.right
label(for="time") {{_ 'time'}}
input.js-time-field#time(type="time" name="time" value=showTime)
if error.get
.warning {{_ error.get}}
button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}}
button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}}
+591 -340
View File
@@ -1,391 +1,642 @@
import moment from 'moment/min/moment-with-locales';
import { TAPi18n } from '/imports/i18n';
import { DatePicker } from '/client/lib/datepicker';
import { ReactiveCache } from '/imports/reactiveCache';
import {
setupDatePicker,
datePickerRendered,
datePickerHelpers,
datePickerEvents,
} from '/client/lib/datepicker';
import {
formatDateTime,
formatDate,
formatDateByUserPreference,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar,
diff
} from '/imports/lib/dateUtils';
// --- DatePicker popups (edit date forms) ---
// editCardReceivedDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
this.data().getReceived() &&
this.date.set(moment(this.data().getReceived()));
}
_storeDate(date) {
this.card.setReceived(date);
}
_deleteDate() {
this.card.unsetReceived();
}
}.register('editCardReceivedDatePopup'));
// editCardStartDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
this.data().getStart() && this.date.set(moment(this.data().getStart()));
}
onRendered() {
super.onRendered();
if (moment.isDate(this.card.getReceived())) {
this.$('.js-datepicker').datepicker(
'setStartDate',
this.card.getReceived(),
);
}
}
_storeDate(date) {
this.card.setStart(date);
}
_deleteDate() {
this.card.unsetStart();
}
}.register('editCardStartDatePopup'));
// editCardDueDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated('1970-01-01 17:00:00');
this.data().getDue() && this.date.set(moment(this.data().getDue()));
}
onRendered() {
super.onRendered();
if (moment.isDate(this.card.getStart())) {
this.$('.js-datepicker').datepicker('setStartDate', this.card.getStart());
}
}
_storeDate(date) {
this.card.setDue(date);
}
_deleteDate() {
this.card.unsetDue();
}
}.register('editCardDueDatePopup'));
// editCardEndDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
this.data().getEnd() && this.date.set(moment(this.data().getEnd()));
}
onRendered() {
super.onRendered();
if (moment.isDate(this.card.getStart())) {
this.$('.js-datepicker').datepicker('setStartDate', this.card.getStart());
}
}
_storeDate(date) {
this.card.setEnd(date);
}
_deleteDate() {
this.card.unsetEnd();
}
}.register('editCardEndDatePopup'));
// Display received, start, due & end dates
const CardDate = BlazeComponent.extendComponent({
template() {
return 'dateBadge';
},
onCreated() {
const self = this;
self.date = ReactiveVar();
self.now = ReactiveVar(moment());
window.setInterval(() => {
self.now.set(moment());
}, 60000);
},
showWeek() {
return this.date.get().week().toString();
},
showDate() {
// this will start working once mquandalle:moment
// is updated to at least moment.js 2.10.5
// until then, the date is displayed in the "L" format
return this.date.get().calendar(null, {
sameElse: 'llll',
});
},
showISODate() {
return this.date.get().toISOString();
},
Template.editCardReceivedDatePopup.onCreated(function () {
const card = Template.currentData();
setupDatePicker(this, {
defaultTime: formatDateTime(now()),
initialDate: card.getReceived() ? card.getReceived() : undefined,
});
});
class CardReceivedDate extends CardDate {
onCreated() {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getReceived()));
});
}
Template.editCardReceivedDatePopup.onRendered(function () {
datePickerRendered(this);
});
Template.editCardReceivedDatePopup.helpers(datePickerHelpers());
Template.editCardReceivedDatePopup.events(datePickerEvents({
storeDate(date) {
this.datePicker.card.setReceived(date);
},
deleteDate() {
this.datePicker.card.unsetReceived();
},
}));
// editCardStartDatePopup
Template.editCardStartDatePopup.onCreated(function () {
const card = Template.currentData();
setupDatePicker(this, {
defaultTime: formatDateTime(now()),
initialDate: card.getStart() ? card.getStart() : undefined,
});
});
Template.editCardStartDatePopup.onRendered(function () {
datePickerRendered(this);
});
Template.editCardStartDatePopup.helpers(datePickerHelpers());
Template.editCardStartDatePopup.events(datePickerEvents({
storeDate(date) {
this.datePicker.card.setStart(date);
},
deleteDate() {
this.datePicker.card.unsetStart();
},
}));
// editCardDueDatePopup
Template.editCardDueDatePopup.onCreated(function () {
const card = Template.currentData();
setupDatePicker(this, {
defaultTime: '1970-01-01 17:00:00',
initialDate: card.getDue() ? card.getDue() : undefined,
});
});
Template.editCardDueDatePopup.onRendered(function () {
datePickerRendered(this);
});
Template.editCardDueDatePopup.helpers(datePickerHelpers());
Template.editCardDueDatePopup.events(datePickerEvents({
storeDate(date) {
this.datePicker.card.setDue(date);
},
deleteDate() {
this.datePicker.card.unsetDue();
},
}));
// editCardEndDatePopup
Template.editCardEndDatePopup.onCreated(function () {
const card = Template.currentData();
setupDatePicker(this, {
defaultTime: formatDateTime(now()),
initialDate: card.getEnd() ? card.getEnd() : undefined,
});
});
Template.editCardEndDatePopup.onRendered(function () {
datePickerRendered(this);
});
Template.editCardEndDatePopup.helpers(datePickerHelpers());
Template.editCardEndDatePopup.events(datePickerEvents({
storeDate(date) {
this.datePicker.card.setEnd(date);
},
deleteDate() {
this.datePicker.card.unsetEnd();
},
}));
// --- Card date badge display helpers ---
// Shared onCreated logic for card date badge templates
function cardDateOnCreated(tpl) {
tpl.date = new ReactiveVar();
tpl.now = new ReactiveVar(now());
window.setInterval(() => {
tpl.now.set(now());
}, 60000);
}
// Shared helpers for card date badge templates
function cardDateHelpers(extraHelpers) {
const base = {
showWeek() {
return getISOWeek(Template.instance().date.get()).toString();
},
showWeekOfYear() {
const user = ReactiveCache.getCurrentUser();
if (!user) return window.localStorage.getItem('showWeekOfYear') === 'true';
return user.isShowWeekOfYear();
},
showDate() {
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
return formatDateByUserPreference(Template.instance().date.get(), dateFormat, true);
},
showISODate() {
return Template.instance().date.get().toISOString();
},
};
return Object.assign(base, extraHelpers);
}
// cardReceivedDate
Template.cardReceivedDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().getReceived()));
});
});
Template.cardReceivedDate.helpers(cardDateHelpers({
classes() {
const tpl = Template.instance();
let classes = 'received-date ';
const dueAt = this.data().getDue();
const endAt = this.data().getEnd();
const startAt = this.data().getStart();
const theDate = this.date.get();
// if dueAt, endAt and startAt exist & are > receivedAt, receivedAt doesn't need to be flagged
const data = Template.currentData();
const dueAt = data.getDue();
const endAt = data.getEnd();
const startAt = data.getStart();
const theDate = tpl.date.get();
if (
(startAt && theDate.isAfter(startAt)) ||
(endAt && theDate.isAfter(endAt)) ||
(dueAt && theDate.isAfter(dueAt))
)
classes += 'long-overdue';
else classes += 'current';
(startAt && isAfter(theDate, startAt)) ||
(endAt && isAfter(theDate, endAt)) ||
(dueAt && isAfter(theDate, dueAt))
) {
classes += 'overdue';
} else {
classes += 'not-due';
}
return classes;
}
},
showTitle() {
return `${TAPi18n.__('card-received-on')} ${this.date
.get()
.format('LLLL')}`;
}
const tpl = Template.instance();
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
const formattedDate = formatDateByUserPreference(tpl.date.get(), dateFormat, true);
return `${TAPi18n.__('card-received-on')} ${formattedDate}`;
},
}));
events() {
return super.events().concat({
'click .js-edit-date': Popup.open('editCardReceivedDate'),
});
}
}
CardReceivedDate.register('cardReceivedDate');
Template.cardReceivedDate.events({
'click .js-edit-date': Popup.open('editCardReceivedDate'),
});
class CardStartDate extends CardDate {
onCreated() {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getStart()));
});
}
// cardStartDate
Template.cardStartDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().getStart()));
});
});
Template.cardStartDate.helpers(cardDateHelpers({
classes() {
let classes = 'start-date' + ' ';
const dueAt = this.data().getDue();
const endAt = this.data().getEnd();
const theDate = this.date.get();
const now = this.now.get();
// if dueAt or endAt exist & are > startAt, startAt doesn't need to be flagged
if ((endAt && theDate.isAfter(endAt)) || (dueAt && theDate.isAfter(dueAt)))
classes += 'long-overdue';
else if (theDate.isAfter(now)) classes += '';
else classes += 'current';
const tpl = Template.instance();
let classes = 'start-date ';
const data = Template.currentData();
const dueAt = data.getDue();
const endAt = data.getEnd();
const theDate = tpl.date.get();
const nowVal = tpl.now.get();
if ((endAt && isAfter(theDate, endAt)) || (dueAt && isAfter(theDate, dueAt))) {
classes += 'overdue';
} else if (isAfter(theDate, nowVal)) {
classes += 'not-due';
} else {
classes += 'current';
}
return classes;
}
},
showTitle() {
return `${TAPi18n.__('card-start-on')} ${this.date.get().format('LLLL')}`;
}
const tpl = Template.instance();
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
const formattedDate = formatDateByUserPreference(tpl.date.get(), dateFormat, true);
return `${TAPi18n.__('card-start-on')} ${formattedDate}`;
},
}));
events() {
return super.events().concat({
'click .js-edit-date': Popup.open('editCardStartDate'),
});
}
}
CardStartDate.register('cardStartDate');
Template.cardStartDate.events({
'click .js-edit-date': Popup.open('editCardStartDate'),
});
class CardDueDate extends CardDate {
onCreated() {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getDue()));
});
}
// cardDueDate
Template.cardDueDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().getDue()));
});
});
Template.cardDueDate.helpers(cardDateHelpers({
classes() {
let classes = 'due-date' + ' ';
const endAt = this.data().getEnd();
const theDate = this.date.get();
const now = this.now.get();
// if the due date is after the end date, green - done early
if (endAt && theDate.isAfter(endAt)) classes += 'current';
// if there is an end date, don't need to flag the due date
else if (endAt) classes += '';
else if (now.diff(theDate, 'days') >= 2) classes += 'long-overdue';
else if (now.diff(theDate, 'minute') >= 0) classes += 'due';
else if (now.diff(theDate, 'days') >= -1) classes += 'almost-due';
const tpl = Template.instance();
let classes = 'due-date ';
const data = Template.currentData();
const endAt = data.getEnd();
const theDate = tpl.date.get();
const nowVal = tpl.now.get();
if (endAt && isBefore(endAt, theDate)) {
classes += 'completed-early';
} else if (endAt) {
classes += 'completed';
} else {
const daysDiff = diff(theDate, nowVal, 'days');
if (daysDiff < 0) {
classes += 'overdue';
} else if (daysDiff <= 1) {
classes += 'due-soon';
} else {
classes += 'not-due';
}
}
return classes;
}
},
showTitle() {
return `${TAPi18n.__('card-due-on')} ${this.date.get().format('LLLL')}`;
}
const tpl = Template.instance();
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
const formattedDate = formatDateByUserPreference(tpl.date.get(), dateFormat, true);
return `${TAPi18n.__('card-due-on')} ${formattedDate}`;
},
}));
events() {
return super.events().concat({
'click .js-edit-date': Popup.open('editCardDueDate'),
});
}
}
CardDueDate.register('cardDueDate');
Template.cardDueDate.events({
'click .js-edit-date': Popup.open('editCardDueDate'),
});
class CardEndDate extends CardDate {
onCreated() {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getEnd()));
});
}
// cardEndDate
Template.cardEndDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().getEnd()));
});
});
Template.cardEndDate.helpers(cardDateHelpers({
classes() {
let classes = 'end-date' + ' ';
const dueAt = this.data().getDue();
const theDate = this.date.get();
if (!dueAt) classes += '';
else if (theDate.isBefore(dueAt)) classes += 'current';
else if (theDate.isAfter(dueAt)) classes += 'due';
const tpl = Template.instance();
let classes = 'end-date ';
const data = Template.currentData();
const dueAt = data.getDue();
const theDate = tpl.date.get();
if (!dueAt) {
classes += 'completed';
} else if (isBefore(theDate, dueAt)) {
classes += 'completed-early';
} else if (isAfter(theDate, dueAt)) {
classes += 'completed-late';
} else {
classes += 'completed-on-time';
}
return classes;
}
},
showTitle() {
return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
}
const tpl = Template.instance();
return `${TAPi18n.__('card-end-on')} ${format(tpl.date.get(), 'LLLL')}`;
},
}));
events() {
return super.events().concat({
'click .js-edit-date': Popup.open('editCardEndDate'),
});
}
}
CardEndDate.register('cardEndDate');
Template.cardEndDate.events({
'click .js-edit-date': Popup.open('editCardEndDate'),
});
class CardCustomFieldDate extends CardDate {
template() {
return 'dateCustomField';
}
onCreated() {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().value));
});
}
showWeek() {
return this.date.get().week().toString();
}
// cardCustomFieldDate
Template.cardCustomFieldDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().value));
});
});
Template.cardCustomFieldDate.helpers(cardDateHelpers({
showDate() {
const tpl = Template.instance();
// this will start working once mquandalle:moment
// is updated to at least moment.js 2.10.5
// until then, the date is displayed in the "L" format
return this.date.get().calendar(null, {
return tpl.date.get().calendar(null, {
sameElse: 'llll',
});
}
},
showTitle() {
return `${this.date.get().format('LLLL')}`;
}
const tpl = Template.instance();
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
const formattedDate = formatDateByUserPreference(tpl.date.get(), dateFormat, true);
return `${formattedDate}`;
},
classes() {
return 'customfield-date';
}
},
}));
events() {
return [];
}
}
CardCustomFieldDate.register('cardCustomFieldDate');
// --- Minicard date templates ---
(class extends CardReceivedDate {
showDate() {
return this.date.get().format('L');
}
}.register('minicardReceivedDate'));
// minicardReceivedDate
Template.minicardReceivedDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().getReceived()));
});
});
(class extends CardStartDate {
showDate() {
return this.date.get().format('L');
}
}.register('minicardStartDate'));
(class extends CardDueDate {
showDate() {
return this.date.get().format('L');
}
}.register('minicardDueDate'));
(class extends CardEndDate {
showDate() {
return this.date.get().format('L');
}
}.register('minicardEndDate'));
(class extends CardCustomFieldDate {
showDate() {
return this.date.get().format('L');
}
}.register('minicardCustomFieldDate'));
class VoteEndDate extends CardDate {
onCreated() {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getVoteEnd()));
});
}
Template.minicardReceivedDate.helpers(cardDateHelpers({
classes() {
const classes = 'end-date' + ' ';
const tpl = Template.instance();
let classes = 'received-date ';
const data = Template.currentData();
const dueAt = data.getDue();
const endAt = data.getEnd();
const startAt = data.getStart();
const theDate = tpl.date.get();
if (
(startAt && isAfter(theDate, startAt)) ||
(endAt && isAfter(theDate, endAt)) ||
(dueAt && isAfter(theDate, dueAt))
) {
classes += 'overdue';
} else {
classes += 'not-due';
}
return classes;
}
showDate() {
return this.date.get().format('L LT');
}
},
showTitle() {
return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
}
const tpl = Template.instance();
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
const formattedDate = formatDateByUserPreference(tpl.date.get(), dateFormat, true);
return `${TAPi18n.__('card-received-on')} ${formattedDate}`;
},
showDate() {
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
return formatDateByUserPreference(Template.instance().date.get(), dateFormat, true);
},
}));
events() {
return super.events().concat({
'click .js-edit-date': Popup.open('editVoteEndDate'),
});
}
}
VoteEndDate.register('voteEndDate');
Template.minicardReceivedDate.events({
'click .js-edit-date': Popup.open('editCardReceivedDate'),
});
class PokerEndDate extends CardDate {
onCreated() {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getPokerEnd()));
});
}
// minicardStartDate
Template.minicardStartDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().getStart()));
});
});
Template.minicardStartDate.helpers(cardDateHelpers({
classes() {
const classes = 'end-date' + ' ';
return classes;
}
showDate() {
return this.date.get().format('l LT');
}
showTitle() {
return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
}
const tpl = Template.instance();
let classes = 'start-date ';
const data = Template.currentData();
const dueAt = data.getDue();
const endAt = data.getEnd();
const theDate = tpl.date.get();
const nowVal = tpl.now.get();
events() {
return super.events().concat({
'click .js-edit-date': Popup.open('editPokerEndDate'),
});
}
}
PokerEndDate.register('pokerEndDate');
if ((endAt && isAfter(theDate, endAt)) || (dueAt && isAfter(theDate, dueAt))) {
classes += 'overdue';
} else if (isAfter(theDate, nowVal)) {
classes += 'not-due';
} else {
classes += 'current';
}
return classes;
},
showTitle() {
const tpl = Template.instance();
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
const formattedDate = formatDateByUserPreference(tpl.date.get(), dateFormat, true);
return `${TAPi18n.__('card-start-on')} ${formattedDate}`;
},
showDate() {
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
return formatDateByUserPreference(Template.instance().date.get(), dateFormat, true);
},
}));
Template.minicardStartDate.events({
'click .js-edit-date': Popup.open('editCardStartDate'),
});
// minicardDueDate
Template.minicardDueDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().getDue()));
});
});
Template.minicardDueDate.helpers(cardDateHelpers({
classes() {
const tpl = Template.instance();
let classes = 'due-date ';
const data = Template.currentData();
const endAt = data.getEnd();
const theDate = tpl.date.get();
const nowVal = tpl.now.get();
if (endAt && isBefore(endAt, theDate)) {
classes += 'completed-early';
} else if (endAt) {
classes += 'completed';
} else {
const daysDiff = diff(theDate, nowVal, 'days');
if (daysDiff < 0) {
classes += 'overdue';
} else if (daysDiff <= 1) {
classes += 'due-soon';
} else {
classes += 'not-due';
}
}
return classes;
},
showTitle() {
const tpl = Template.instance();
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
const formattedDate = formatDateByUserPreference(tpl.date.get(), dateFormat, true);
return `${TAPi18n.__('card-due-on')} ${formattedDate}`;
},
showDate() {
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
return formatDateByUserPreference(Template.instance().date.get(), dateFormat, true);
},
}));
Template.minicardDueDate.events({
'click .js-edit-date': Popup.open('editCardDueDate'),
});
// minicardEndDate
Template.minicardEndDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().getEnd()));
});
});
Template.minicardEndDate.helpers(cardDateHelpers({
classes() {
const tpl = Template.instance();
let classes = 'end-date ';
const data = Template.currentData();
const dueAt = data.getDue();
const theDate = tpl.date.get();
if (!dueAt) {
classes += 'completed';
} else if (isBefore(theDate, dueAt)) {
classes += 'completed-early';
} else if (isAfter(theDate, dueAt)) {
classes += 'completed-late';
} else {
classes += 'completed-on-time';
}
return classes;
},
showTitle() {
const tpl = Template.instance();
return `${TAPi18n.__('card-end-on')} ${format(tpl.date.get(), 'LLLL')}`;
},
showDate() {
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
return formatDateByUserPreference(Template.instance().date.get(), dateFormat, true);
},
}));
Template.minicardEndDate.events({
'click .js-edit-date': Popup.open('editCardEndDate'),
});
// minicardCustomFieldDate
Template.minicardCustomFieldDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().value));
});
});
Template.minicardCustomFieldDate.helpers(cardDateHelpers({
showDate() {
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
return formatDateByUserPreference(Template.instance().date.get(), dateFormat, true);
},
showTitle() {
const tpl = Template.instance();
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
const formattedDate = formatDateByUserPreference(tpl.date.get(), dateFormat, true);
return `${formattedDate}`;
},
classes() {
return 'customfield-date';
},
}));
// --- Vote and Poker end date badge templates ---
// voteEndDate
Template.voteEndDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().getVoteEnd()));
});
});
Template.voteEndDate.helpers(cardDateHelpers({
classes() {
return 'end-date ';
},
showDate() {
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
return formatDateByUserPreference(Template.instance().date.get(), dateFormat, true);
},
showTitle() {
const tpl = Template.instance();
return `${TAPi18n.__('card-end-on')} ${tpl.date.get().toLocaleString()}`;
},
}));
Template.voteEndDate.events({
'click .js-edit-date': Popup.open('editVoteEndDate'),
});
// pokerEndDate
Template.pokerEndDate.onCreated(function () {
cardDateOnCreated(this);
const self = this;
self.autorun(() => {
self.date.set(new Date(Template.currentData().getPokerEnd()));
});
});
Template.pokerEndDate.helpers(cardDateHelpers({
classes() {
return 'end-date ';
},
showDate() {
const currentUser = ReactiveCache.getCurrentUser();
const dateFormat = currentUser ? currentUser.getDateFormat() : (window.localStorage.getItem('dateFormat') || 'YYYY-MM-DD');
return formatDateByUserPreference(Template.instance().date.get(), dateFormat, true);
},
showTitle() {
const tpl = Template.instance();
return `${TAPi18n.__('card-end-on')} ${format(tpl.date.get(), 'LLLL')}`;
},
}));
Template.pokerEndDate.events({
'click .js-edit-date': Popup.open('editPokerEndDate'),
});
+20 -28
View File
@@ -1,37 +1,29 @@
const descriptionFormIsOpen = new ReactiveVar(false);
BlazeComponent.extendComponent({
onDestroyed() {
descriptionFormIsOpen.set(false);
$('.note-popover').hide();
},
Template.descriptionForm.onDestroyed(function () {
descriptionFormIsOpen.set(false);
$('.note-popover').hide();
});
Template.descriptionForm.helpers({
descriptionFormIsOpen() {
return descriptionFormIsOpen.get();
},
});
getInput() {
return this.$('.js-new-description-input');
Template.descriptionForm.events({
async 'submit .js-card-description'(event, tpl) {
event.preventDefault();
const description = tpl.currentComponent ? tpl.currentComponent().getValue() : tpl.$('textarea').val();
await this.setDescription(description);
},
events() {
return [
{
'submit .js-card-description'(event) {
event.preventDefault();
const description = this.currentComponent().getValue();
this.data().setDescription(description);
},
// Pressing Ctrl+Enter should submit the form
'keydown form textarea'(evt) {
if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
const submitButton = this.find('button[type=submit]');
if (submitButton) {
submitButton.click();
}
}
},
},
];
// Pressing Ctrl+Enter should submit the form
'keydown form textarea'(evt, tpl) {
if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
const submitButton = tpl.find('button[type=submit]');
if (submitButton) {
submitButton.click();
}
}
},
}).register('descriptionForm');
});
+496 -38
View File
@@ -1,16 +1,46 @@
/* Date Format Selector */
.card-details-item-date-format {
margin-bottom: 12px;
}
.card-details-item-date-format .card-details-item-title {
font-size: 15px;
font-weight: bold;
margin-bottom: 6px;
color: #333;
letter-spacing: 0.03em;
}
.card-details-item-date-format .js-date-format-selector {
width: 100%;
padding: 9px 10px;
border: 1px solid #ddd;
border-radius: 5px;
background-color: #fff;
font-size: 15px;
cursor: pointer;
transition: border-color 0.15s, box-shadow 0.15s;
}
.card-details-item-date-format .js-date-format-selector:focus {
outline: none;
border-color: #007cba;
box-shadow: 0 0 0 2px rgba(0, 124, 186, 0.2);
}
.assignee {
border-radius: 3px;
display: block;
position: relative;
float: left;
height: 30px;
width: 30px;
margin: 0 4px 4px 0;
height: clamp(24px, 3.5vw, 36px);
width: clamp(24px, 3.5vw, 36px);
margin: 0.3vh;
cursor: pointer;
user-select: none;
z-index: 1;
text-decoration: none;
border-radius: 50%;
box-shadow: 0 1px 2px 0 rgba(0,0,0,0.04);
}
.assignee .avatar {
overflow: hidden;
@@ -23,12 +53,18 @@
background-color: #dbdbdb;
color: #444;
position: absolute;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
.assignee .avatar.avatar-image {
object-fit: cover;
object-position: center;
height: 100%;
width: 100%;
display: block;
}
.assignee .assignee-presence-status {
background-color: #b3b3b3;
@@ -39,7 +75,6 @@
position: absolute;
right: -1px;
bottom: -1px;
border: 1px solid #fff;
z-index: 15;
}
.assignee .assignee-presence-status.active {
@@ -63,6 +98,7 @@
align-items: center;
justify-content: center;
box-shadow: 0 0 0 2px #bfbfbf inset;
transition: box-shadow 0.12s;
}
.assignee.add-assignee:hover,
.assignee.add-assignee.is-active {
@@ -70,47 +106,137 @@
}
.copied-tooltip {
display: none;
padding: 0px 10px;
padding: 0 1.3vw;
background-color: rgba(0,0,0,0.875);
color: #fff;
border-radius: 5px;
border-radius: 0.7vw;
font-size: 0.98em;
}
.card-details {
padding: 0;
flex-shrink: 0;
flex-basis: 600px;
flex-basis: min(600px, 80vw);
will-change: flex-basis;
overflow-y: scroll;
overflow-y: auto;
overflow-x: hidden;
background: #f7f7f7;
border-radius: bottom 3px;
border-radius: 0 0 0.4vw 0.4vw;
z-index: 30;
animation: flexGrowIn 0.1s;
box-shadow: 0 0 7px 0 #b3b3b3;
transition: flex-basis 0.1s;
box-shadow: 0 0 0.9vh 0 #b3b3b3;
transition: flex-basis 0.1s, box-shadow 0.15s;
box-sizing: border-box;
}
/* Desktop mode: position card below board header */
body.desktop-mode .card-details:not(.card-details-popup) {
position: fixed;
width: auto;
max-width: 800px;
flex-basis: auto;
border-radius: 8px;
z-index: 2001;
}
/* Default position for first card or when dragged */
body.desktop-mode .card-details:not(.card-details-popup):not([style*="left"]):not([style*="top"]) {
top: 8px;
left: 20px;
right: 20px;
bottom: 20px;
}
/* Stagger positions for multiple cards using nth-of-type */
body.desktop-mode .card-details:not(.card-details-popup):nth-of-type(1) {
top: 8px;
left: 20px;
}
body.desktop-mode .card-details:not(.card-details-popup):nth-of-type(2) {
top: 38px;
left: 50px;
}
body.desktop-mode .card-details:not(.card-details-popup):nth-of-type(3) {
top: 68px;
left: 80px;
}
body.desktop-mode .card-details:not(.card-details-popup):nth-of-type(4) {
top: 98px;
left: 110px;
}
body.desktop-mode .card-details:not(.card-details-popup):nth-of-type(5) {
top: 128px;
left: 140px;
}
/* For expanded cards, set dimensions */
body.desktop-mode .card-details:not(.card-details-popup):not(.card-details-collapsed) {
right: 20px;
bottom: 20px;
}
/* Collapsed card state - hide content and set height to title row only */
.card-details.card-details-collapsed .card-details-canvas > *:not(.card-details-header) {
display: none !important;
}
.card-details.card-details-collapsed {
height: auto !important;
bottom: auto !important;
overflow: visible;
}
body.desktop-mode .card-details.card-details-collapsed {
bottom: auto !important;
}
.card-details .mCustomScrollBox {
padding-left: 0;
}
.card-details .card-details-canvas {
width: auto;
padding: 0 20px;
padding: 0 2.5vw;
}
.card-details .card-details-header {
margin: 0 -20px 5px;
padding: 7px 20px;
padding: 8px 20px;
background: #ededed;
border-bottom: 1px solid #dbdbdb;
position: sticky;
top: 0px;
z-index: 500;
display: flow-root;
min-height: 44px;
}
.card-details .card-details-header .card-number {
color: #b3b3b3;
display: inline-block;
margin-right: 5px;
margin-right: 6px;
}
/* Collapse toggle triangle */
.card-details .card-details-header .card-collapse-toggle {
float: left;
font-size: 20px;
padding: 7px 10px;
margin-left: -10px;
margin-right: 5px;
cursor: pointer;
user-select: none;
color: #000;
vertical-align: middle;
line-height: 1.2;
}
.card-details .card-details-header .card-drag-handle {
font-size: 20px;
padding: 8px 10px;
margin-right: 10px;
cursor: move;
user-select: none;
display: inline-block;
float: right;
vertical-align: middle;
line-height: 1.2;
}
.card-details .card-details-header .close-card-details,
.card-details .card-details-header .maximize-card-details,
.card-details .card-details-header .minimize-card-details,
@@ -128,11 +254,19 @@
font-size: 24px;
padding: 5px 10px 5px 10px;
margin-right: -8px;
cursor: pointer;
user-select: none;
vertical-align: middle;
line-height: 1.2;
transition: color 0.13s;
}
.card-details .card-details-header .close-card-details-mobile-web {
.card-details .card-details-header .close-card-details-mobile-web,
.card-details .card-details-header .card-mobile-desktop-toggle {
font-size: 24px;
padding: 5px;
margin-right: 40px;
margin-right: 5px;
cursor: pointer;
user-select: none;
}
.card-details .card-details-header .card-copy-button {
font-size: 17px;
@@ -147,12 +281,44 @@
.card-details .card-details-header .card-details-menu {
font-size: 17px;
padding: 10px;
vertical-align: middle;
line-height: 1.2;
}
.card-details .card-details-header .card-details-menu-mobile-web {
font-size: 17px;
padding: 10px;
margin-right: 30px;
}
.card-details .card-details-header .card-mobile-desktop-toggle,
.card-details .card-details-header .card-zoom-in,
.card-details .card-details-header .card-zoom-out {
font-size: 24px;
padding: 5px 10px 5px 10px;
margin-right: 5px;
cursor: pointer;
user-select: none;
float: right;
}
/* Unify all card text to match title size */
.card-details {
font-size: 1em;
}
.card-details p,
.card-details span,
.card-details div,
.card-details a,
.card-details label,
.card-details input,
.card-details textarea,
.card-details select,
.card-details button,
.card-details .card-details-item-title,
.card-details .card-label,
.card-details .viewer {
font-size: inherit;
line-height: 1.5;
}
.card-details .card-details-header .card-details-watch {
font-size: 17px;
padding-left: 7px;
@@ -160,9 +326,13 @@
}
.card-details .card-details-header .card-details-title {
font-weight: bold;
font-size: 1.33em;
font-size: 1.35em;
margin: 7px 0 0;
padding: 0;
display: inline-block;
vertical-align: middle;
line-height: 1.3;
letter-spacing: 0.01em;
}
.card-details .card-details-header .linked-card-location {
font-style: italic;
@@ -177,10 +347,10 @@
margin-bottom: 10px;
}
.card-details .card-details-header form.inlined-form .copied-tooltip {
padding: 0px 10px;
padding: 0 10px;
}
.card-details .card-details-header .card-details-list {
font-size: 0.85em;
font-size: 0.9em;
margin-bottom: 3px;
}
.card-details .card-details-header .card-details-list a.card-details-list-title {
@@ -190,7 +360,7 @@
display: inline-block;
background: #e6e6e6;
border-radius: 3px;
padding: 0px 5px;
padding: 0 5px;
}
.card-details .card-details-header .copied-tooltip {
margin-right: 10px;
@@ -201,11 +371,13 @@
}
.card-details .card-description textarea {
min-height: 100px;
resize: vertical;
}
.card-details .card-details-items {
display: flex;
flex-wrap: wrap;
margin: 15px 0;
gap: 0.5em;
}
.card-details .card-details-items .card-details-item {
margin-right: 0.5em;
@@ -256,15 +428,28 @@
position: fixed;
resize: both;
}
/* Override for mobile mode even on larger screens */
body.mobile-mode .card-details {
width: 100vw !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
height: 100vh !important;
max-height: 100vh !important;
resize: none !important;
}
.card-details-maximized {
padding: 0;
flex-shrink: 0;
flex-basis: calc(100% - 20px);
will-change: flex-basis;
overflow-y: scroll;
overflow-x: scroll;
overflow-y: auto;
overflow-x: auto;
background: #f7f7f7;
border-radius: bottom 3px;
border-radius: 0 0 3px 3px;
z-index: 100;
animation: flexGrowIn 0.1s;
box-shadow: 0 0 7px 0 #b3b3b3;
@@ -272,7 +457,7 @@
box-sizing: border-box;
top: 97px;
left: 0px;
height: calc(100% - 20px);
height: calc(100% - 100px);
width: calc(100% - 20px);
float: left;
}
@@ -307,19 +492,52 @@ input[type="submit"].attachment-add-link-submit {
}
@media screen and (max-width: 800px) {
.card-details {
width: calc(100% - 1px);
padding: 0px 20px 0px 20px;
margin: 0px;
width: 100% !important;
padding: 0 !important;
margin: 0 !important;
transition: none;
overflow-y: revert;
overflow-x: revert;
overflow-y: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
z-index: 100 !important;
height: 100vh !important;
max-height: 100vh !important;
border-radius: 0 !important;
box-shadow: none !important;
}
/* Ensure card details are above everything on mobile */
body.mobile-mode .card-details {
z-index: 100 !important;
width: 100vw !important;
left: 0 !important;
right: 0 !important;
}
.card-details .card-details-canvas {
width: 100%;
padding-left: 0px;
padding: 0 15px;
}
.card-details .card-details-header .close-card-details {
margin-right: 0px;
display: block !important;
}
.card-details .card-details-header .close-card-details-mobile-web {
display: block !important;
margin-right: 5px !important;
}
.card-details .card-details-header .card-mobile-desktop-toggle {
display: block !important;
margin-right: 5px !important;
}
.card-details .card-details-header .card-mobile-desktop-toggle {
display: block !important;
margin-right: 5px !important;
}
.card-details .card-details-header .card-details-menu {
margin-right: 40px;
@@ -345,6 +563,62 @@ input[type="submit"].attachment-add-link-submit {
.pop-over > .content-wrapper > .popup-container-depth-0 .card-details-header {
margin: 0;
}
/* iPhone mobile: enlarge header buttons and increase spacing */
body.mobile-mode.iphone-device .card-details .card-details-header {
padding-right: 16px;
}
body.mobile-mode.iphone-device .card-details .card-details-header .close-card-details,
body.mobile-mode.iphone-device .card-details .card-details-header .maximize-card-details,
body.mobile-mode.iphone-device .card-details .card-details-header .minimize-card-details,
body.mobile-mode.iphone-device .card-details .card-details-header .card-details-menu-mobile-web,
body.mobile-mode.iphone-device .card-details .card-details-header .card-copy-mobile-button,
body.mobile-mode.iphone-device .card-details .card-details-header .card-mobile-desktop-toggle,
body.mobile-mode.iphone-device .card-details .card-details-header .card-zoom-in,
body.mobile-mode.iphone-device .card-details .card-details-header .card-zoom-out {
font-size: 2em !important; /* 2x bigger */
padding: 0.3em !important;
margin-right: 0.75em !important; /* 2x space compared to default */
margin-left: 0 !important;
}
/* Avoid clipping of the close button on the right edge */
body.mobile-mode.iphone-device .card-details .card-details-header .close-card-details {
margin-right: 0.75em !important;
}
/* Enlarge the header title too */
body.mobile-mode.iphone-device .card-details .card-details-header .card-details-title {
font-size: 1.2em !important;
font-weight: bold;
}
}
/* Mobile mode styles - apply when body has mobile-mode class regardless of screen size */
body.mobile-mode .card-details {
width: 100vw !important;
padding: 0px !important;
margin: 0px !important;
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
z-index: 100 !important;
height: 100vh !important;
max-height: 100vh !important;
border-radius: 0 !important;
box-shadow: none !important;
overflow-y: auto !important;
overflow-x: hidden !important;
-webkit-overflow-scrolling: touch;
}
body.mobile-mode .card-details .card-details-canvas {
width: 100% !important;
padding: 0 15px !important;
}
body.mobile-mode .card-details .card-details-header .close-card-details,
body.mobile-mode .card-details .card-details-header .close-card-details-mobile-web {
display: block !important;
}
.card-details-white {
background: #fff !important;
@@ -453,13 +727,15 @@ input[type="submit"].attachment-add-link-submit {
.vote-title {
display: flex;
justify-content: space-between;
align-items: center;
}
.vote-title .js-edit-date {
align-self: baseline;
margin-left: 5px;
align-self: flex-start;
margin-left: 6px;
}
.vote-result {
display: flex;
gap: 6px;
}
.js-show-positive-votes {
cursor: pointer;
@@ -470,29 +746,33 @@ input[type="submit"].attachment-add-link-submit {
.poker-title {
display: flex;
justify-content: space-between;
align-items: center;
}
.poker-title .js-edit-date {
align-self: baseline;
margin-left: 5px;
align-self: flex-start;
margin-left: 6px;
}
.poker-result {
display: flex;
flex-flow: row wrap;
flex-wrap: wrap;
gap: 7px;
}
.js-show-positive-poker-votes {
cursor: pointer;
}
.poker-deck {
display: grid;
flex-direction: column;
grid-auto-flow: row;
text-align: center;
gap: 6px;
}
.poker-card-result {
width: 32px;
width: 34px;
font-size: 1em;
font-weight: bold;
padding: 4px 2px 4px 2px;
padding: 4px 2px;
cursor: default;
border-radius: 3px;
}
.winner {
font-weight: bold;
@@ -503,6 +783,7 @@ input[type="submit"].attachment-add-link-submit {
}
.responsive-table {
overflow-x: auto;
width: 100%;
}
.poker-table {
display: table;
@@ -565,11 +846,15 @@ input[type="submit"].attachment-add-link-submit {
margin: auto;
margin-right: 10px;
width: 100px;
border-radius: 2px;
padding: 3px 6px;
}
.estimation-add button {
display: inline-block;
float: right;
margin: auto;
border-radius: 2px;
padding: 3px 10px;
}
.poker-card {
width: 48px;
@@ -588,6 +873,7 @@ input[type="submit"].attachment-add-link-submit {
text-align: center;
position: relative;
cursor: pointer;
transition: box-shadow 0.12s;
}
.poker-card .inner {
display: table-cell;
@@ -596,3 +882,175 @@ input[type="submit"].attachment-add-link-submit {
overflow: hidden;
background-color: #cecece;
}
/* Drag and drop file upload visual feedback */
.js-card-details.is-dragging-over {
border: 2px dashed #0079bf;
background-color: #e3f2fd !important;
transform: scale(1.01);
transition: all 0.2s ease;
}
/* Sticker picker + card-detail stickers + due-complete toggle */
.card-stickers-picker {
max-width: 320px;
}
.card-sticker-select {
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
margin: 2px;
border-radius: 3px;
font-size: 18px;
color: #4d4d4d;
cursor: pointer;
position: relative;
}
.card-sticker-select:hover {
background: #e0e0e0;
}
.card-sticker-select.active {
background: #d6ecd2;
color: #3cb500;
}
.card-sticker-select .card-sticker-check {
position: absolute;
bottom: 1px;
right: 2px;
font-size: 10px;
color: #3cb500;
}
.card-stickers .card-sticker {
display: inline-flex;
align-items: center;
margin: 0 8px 4px 0;
font-size: 18px;
}
.card-sticker .card-sticker-remove {
margin-left: 3px;
font-size: 11px;
color: #999;
cursor: pointer;
}
.card-sticker .card-sticker-remove:hover {
color: #eb4646;
}
.card-due-complete-toggle {
display: inline-flex;
align-items: center;
margin-left: 8px;
vertical-align: middle;
}
/* Trello-style "mark complete" toggle, left of the card title */
.card-details-complete-toggle {
float: left;
display: flex;
align-items: center;
/* Title is 1.35em with 1.3 line-height (~28px box) and margin-top 7px; push
the 13px checkbox down so it lands at the vertical middle of the title. */
margin: 14px 10px 0 0;
cursor: pointer;
}
/* Card locations: multiple locations, each editable with a remove button */
.card-details-item-location .card-locations {
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 6px;
}
.card-details-item-location .card-location {
display: flex;
align-items: flex-start;
justify-content: space-between;
background: #fff;
border: 1px solid #e3e3e3;
border-radius: 4px;
padding: 6px 8px;
}
.card-details-item-location .card-location-info {
flex: 1;
}
.card-details-item-location .js-edit-location {
cursor: pointer;
}
.card-details-item-location .card-location-name {
font-weight: bold;
}
.card-details-item-location .card-location-address {
color: #4d4d4d;
}
.card-details-item-location .card-location-remove {
margin-left: 8px;
color: #8c8c8c;
cursor: pointer;
}
.card-details-item-location .card-location-remove:hover {
color: #eb4646;
}
/* Sticker icon highlight styles (used instead of colour): taco pack => underline,
pete pack => round (ring around the icon). Icon keeps its normal colour. */
.card-sticker i.sticker-underline {
border-bottom: 2px solid currentColor;
padding-bottom: 1px;
line-height: 1;
}
.card-sticker i.sticker-round {
border: 1px solid currentColor;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.6em;
height: 1.6em;
line-height: 1;
box-sizing: border-box;
}
/* "Open map links at" provider selector in the location popup */
.js-card-location-form .map-provider-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-bottom: 6px;
}
.js-card-location-form .map-provider-row .js-map-provider {
flex: 0 0 auto;
width: auto;
}
/* Opened card (card details popup) docks to the very top of the window and
overlays the global + board header bars instead of opening below them. The
base .pop-over is position:absolute with a small margin/top offset, which left
the card's top behind the fixed header bars; fix it to the viewport top with a
z-index above every header (headers top out around z-index 1000-2000). */
.pop-over[data-popup="cardDetailsPopup"] {
position: fixed !important;
top: 0 !important;
margin-top: 0 !important;
z-index: 100000 !important;
}
/* Sticker highlight styles inside the sticker picker (mascot = underline,
computer = round), matching how they render on the card. */
.card-sticker-select i.sticker-underline {
border-bottom: 2px solid currentColor;
padding-bottom: 1px;
line-height: 1;
}
.card-sticker-select i.sticker-round {
border: 1px solid currentColor;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.6em;
height: 1.6em;
line-height: 1;
box-sizing: border-box;
}
+495 -176
View File
@@ -5,49 +5,75 @@ template(name="cardDetails")
+attachmentViewer
section.card-details.js-card-details(class='{{#if cardMaximized}}card-details-maximized{{/if}}' class='{{#if isPopup}}card-details-popup{{/if}}'): .card-details-canvas
section.card-details.js-card-details.nodragscroll(class='{{#if cardMaximized}}card-details-maximized{{/if}}' class='{{#if isPopup}}card-details-popup{{/if}}' class='{{#unless isVerticalScrollbars}}no-scrollbars{{/unless}}' class='{{#if cardCollapsed}}card-details-collapsed{{/if}}'): .card-details-canvas
.card-details-header(class='{{#if colorClass}}card-details-{{colorClass}}{{/if}}')
+inlinedForm(classNames="js-card-details-title")
+editCardTitleForm
else
unless isMiniScreen
unless isPopup
a.fa.fa-times-thin.close-card-details.js-close-card-details(title="{{_ 'close-card'}}")
if canModifyCard
if cardMaximized
a.fa.fa-window-minimize.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}")
else
a.fa.fa-window-maximize.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}")
span.card-collapse-toggle.js-card-collapse-toggle(title="{{_ 'collapse-card'}}")
if cardCollapsed
i.fa.fa-caret-right
else
i.fa.fa-caret-down
a.close-card-details.js-close-card-details(title="{{_ 'close-card'}}")
i.fa.fa-times-thin
if cardMaximized
a.fa.fa-window-minimize.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}")
else
a.fa.fa-window-maximize.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}")
a.card-details-menu.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
i.fa.fa-bars
a.card-copy-button.js-copy-link(
id="cardURL_copy"
title="{{_ 'copy-card-link-to-clipboard'}}"
href="{{ originRelativeUrl }}"
)
span.emoji-icon
i.fa.fa-link
if canModifyCard
a.fa.fa-navicon.card-details-menu.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
a.fa.fa-link.card-copy-button.js-copy-link(
id="cardURL_copy"
class="fa-link"
title="{{_ 'copy-card-link-to-clipboard'}}"
href="{{ originRelativeUrl }}"
)
span.copied-tooltip {{_ 'copied'}}
span.card-drag-handle.js-card-drag-handle(title="Drag card")
i.fa.fa-arrows
span.copied-tooltip {{_ 'copied'}}
else
unless isPopup
a.fa.fa-times-thin.close-card-details.js-close-card-details(title="{{_ 'close-card'}}")
if canModifyCard
a.fa.fa-navicon.card-details-menu-mobile-web.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
a.fa.fa-link.card-copy-mobile-button.js-copy-link(
id="cardURL_copy"
class="fa-link"
title="{{_ 'copy-card-link-to-clipboard'}}"
href="{{ originRelativeUrl }}"
)
span.copied-tooltip {{_ 'copied'}}
a.close-card-details.js-close-card-details(title="{{_ 'close-card'}}")
i.fa.fa-times-thin
a.card-zoom-out.js-card-zoom-out(title="{{_ 'zoom-out'}}")
i.fa.fa-search-minus
a.card-zoom-in.js-card-zoom-in(title="{{_ 'zoom-in'}}")
i.fa.fa-search-plus
a.card-mobile-desktop-toggle.js-card-mobile-desktop-toggle(title="{{_ 'mobile-desktop-toggle'}}")
if mobileMode
i.fa.fa-desktop
else
i.fa.fa-mobile
if cardMaximized
a.fa.fa-window-minimize.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}")
else
a.fa.fa-window-maximize.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}")
a.card-details-menu-mobile-web.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
i.fa.fa-bars
a.card-copy-mobile-button.js-copy-link(
id="cardURL_copy"
title="{{_ 'copy-card-link-to-clipboard'}}"
href="{{ originRelativeUrl }}"
)
span.emoji-icon
i.fa.fa-link
span.copied-tooltip {{_ 'copied'}}
if canModifyCard
a.card-details-complete-toggle.js-toggle-due-complete(title="{{#if getDueComplete}}{{_ 'card-mark-incomplete'}}{{else}}{{_ 'card-mark-complete'}}{{/if}}")
.materialCheckBox(class="{{#if getDueComplete}}is-checked{{/if}}")
h2.card-details-title.js-card-title(
class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}")
class="{{#if canModifyCard}}js-open-inlined-form is-editable{{else}}js-card-title-drag-handle{{/if}}")
+viewer
if currentBoard.allowsCardNumber
span.card-number
| ##{getCardNumber}
| ##{getCardNumber} &nbsp;
= getTitle
if isWatching
i.card-details-watch.fa.fa-eye
i.card-details-watch
i.fa.fa-eye
.card-details-path
each parentList
| &nbsp; &gt; &nbsp;
@@ -65,6 +91,26 @@ template(name="cardDetails")
else
p.warning {{_ 'card-archived'}}
// Upload progress indicator for drag-and-drop uploads
if hasActiveUploads
.card-details-upload-progress
.upload-progress-header
i.fa.fa-upload
span {{_ 'uploading-files'}} ({{uploadCount}})
each uploads
.upload-progress-item(class="{{#if $eq status 'error'}}upload-error{{/if}}")
.upload-progress-filename {{file.name}}
.upload-progress-bar
.upload-progress-fill(style="width: {{progress}}%")
if $eq status 'error'
.upload-progress-error
i.fa.fa-exclamation-triangle
span {{_ 'upload-failed'}}
else if $eq status 'completed'
.upload-progress-success
i.fa.fa-check
span {{_ 'upload-completed'}}
.card-details-left
.card-details-items
@@ -83,9 +129,60 @@ template(name="cardDetails")
a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}")
i.fa.fa-plus
.card-details-item.card-details-item-stickers
h3.card-details-item-title
i.fa.fa-sticky-note-o
| {{_ 'stickers'}}
.card-details-item-content.card-stickers
each stickers
span.card-sticker(title="{{#if name}}{{name}}{{else}}{{icon}}{{/if}}")
i.fa(class="fa-{{icon}} {{#if highlight}}sticker-{{highlight}}{{/if}}")
if canModifyCard
a.card-sticker-remove.js-remove-sticker(data-index="{{@index}}" title="{{_ 'remove-sticker'}}")
i.fa.fa-times
if canModifyCard
unless currentUser.isWorker
a.card-label.add-label.js-add-stickers(title="{{_ 'add-sticker'}}")
i.fa.fa-plus
.card-details-item.card-details-item-location
h3.card-details-item-title
i.fa.fa-map-marker
| {{_ 'location'}}
.card-details-item-content.card-locations
each getLocations
.card-location
.card-location-info(class="{{#if canModifyCard}}js-edit-location{{/if}}" data-location-id="{{_id}}")
if name
.card-location-name= name
if address
.card-location-address= address
if hasCoordinates
a.card-location-map(href=mapUrl target="_blank" rel="noopener noreferrer")
i.fa.fa-map-o
= ' '
| {{_ 'location-open-map'}}
if canModifyCard
a.card-location-remove.js-remove-location(data-location-id="{{_id}}" title="{{_ 'delete'}}")
i.fa.fa-times
if canModifyCard
unless currentUser.isWorker
a.card-label.add-label.js-add-location(title="{{_ 'add-location'}}")
i.fa.fa-plus
if currentBoard.hasAnyAllowsDate
hr
.card-details-item.card-details-item-date-format
h3.card-details-item-title
i.fa.fa-calendar
| {{_ 'date-format'}}
.card-details-item-content
select.js-date-format-selector
option(value="YYYY-MM-DD" selected="{{#if isDateFormat 'YYYY-MM-DD'}}selected{{/if}}") {{_ 'date-format-yyyy-mm-dd'}}
option(value="DD-MM-YYYY" selected="{{#if isDateFormat 'DD-MM-YYYY'}}selected{{/if}}") {{_ 'date-format-dd-mm-yyyy'}}
option(value="MM-DD-YYYY" selected="{{#if isDateFormat 'MM-DD-YYYY'}}selected{{/if}}") {{_ 'date-format-mm-dd-yyyy'}}
if currentBoard.allowsReceivedDate
.card-details-item.card-details-item-received
h3.card-details-item-title
@@ -115,7 +212,7 @@ template(name="cardDetails")
if currentBoard.allowsDueDate
.card-details-item.card-details-item-due
h3.card-details-item-title
i.fa.fa-sign-in
i.fa.fa-clock-o
| {{_ 'card-due'}}
if getDue
+cardDueDate
@@ -228,7 +325,7 @@ template(name="cardDetails")
if currentBoard.allowsCardSortingByNumber
.card-details-item.card-details-sort-order
h3.card-details-item-title
i.fa.fa-sort
i.fa.fa-sort-numeric-asc
| {{_ 'sort'}}
if canModifyCard
+inlinedForm(classNames="js-card-details-sort")
@@ -244,7 +341,7 @@ template(name="cardDetails")
i.fa.fa-list
| {{_ 'list'}}
select.js-select-card-details-lists(disabled="{{#unless canModifyCard}}disabled{{/unless}}")
each currentBoard.lists
each currentSwimlaneListsSorted
option(value="{{_id}}" selected="{{#if isCurrentListId _id}}selected{{/if}}") {{title}}
//.card-details-items
@@ -267,7 +364,7 @@ template(name="cardDetails")
hr
.card-details-item.card-details-item-customfield
h3.card-details-item-title
i.fa.fa-list-alt
i.fa.fa-list
= definition.name
+cardCustomField
@@ -278,7 +375,7 @@ template(name="cardDetails")
else
input.toggle-switch(type="checkbox" id="toggleCustomFieldsGridButton")
label.toggle-label(for="toggleCustomFieldsGridButton")
a.fa.fa-plus.js-custom-fields.card-details-item.custom-fields(title="{{_ 'custom-fields'}}")
a.js-custom-fields.card-details-item.custom-fields(title="{{_ 'custom-fields'}}")
if getVoteQuestion
hr
@@ -297,7 +394,8 @@ template(name="cardDetails")
.card-label.card-label-green {{ voteCountPositive }}
.card-label.card-label-red {{ voteCountNegative }}
unless ($and currentBoard.isPublic voteAllowNonBoardMembers )
.card-label.card-label-gray {{ voteCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
.card-label.card-label-gray
| {{ voteCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
+viewer
= getVoteQuestion
if showVotingButtons
@@ -307,7 +405,7 @@ template(name="cardDetails")
| {{_ 'vote-for-it'}}
button.card-details-red.js-vote.js-vote-negative(class="{{#if $eq voteState false}}voted{{/if}}")
if $eq voteState false
i.fa.fa-thumbs-down
| 👎
| {{_ 'vote-against'}}
if getPokerQuestion
@@ -323,7 +421,8 @@ template(name="cardDetails")
.poker-result
if expiredPoker
unless ($and currentBoard.isPublic pokerAllowNonBoardMembers )
.card-label.card-label-gray {{ pokerCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
.card-label.card-label-gray
| {{ pokerCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
if showPlanningPokerButtons
.poker-result
.poker-deck
@@ -515,21 +614,22 @@ template(name="cardDetails")
if currentBoard.allowsDescriptionTitle
hr
h3.card-details-item-title
i.fa.fa-align-left
i.fa.fa-file-text-o
| {{_ 'description'}}
if currentBoard.allowsDescriptionText
+inlinedCardDescription(classNames="card-description js-card-description")
+descriptionForm
.edit-controls.clearfix
button.primary(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.js-close-inlined-form
else
if currentBoard.allowsDescriptionText
a.js-open-inlined-form.right(title="{{_ 'edit'}}" value=title)
a.js-open-inlined-form(title="{{_ 'edit'}}" value=title)
i.fa.fa-pencil-square-o
if getDescription
+viewer
= getDescription
a.js-open-inlined-form(title="{{_ 'edit'}}" value=title)
if getDescription
+viewer
= getDescription
if (hasUnsavedValue 'cardDescription' _id)
p.quiet
| {{_ 'unsaved-description'}}
@@ -548,7 +648,7 @@ template(name="cardDetails")
.card-checklist-attachmentGallery.card-checklists
if currentBoard.allowsChecklists
hr
+checklists(cardId = _id)
+checklists(cardId = _id card = this)
if currentBoard.allowsSubtasks
hr
+subtasks(cardId = _id)
@@ -568,26 +668,36 @@ template(name="cardDetails")
+attachmentGallery
hr
if currentBoard.allowsComments
.comment-title
h3.card-details-item-title
i.fa.fa-comment-o
| {{_ 'comments'}}
if currentUser.isBoardMember
unless currentUser.isNoComments
unless currentUser.isReadOnly
unless currentUser.isReadAssignedOnly
+commentForm
+comments
hr
.card-details-right
unless currentUser.isNoComments
if currentUser.isBoardAdmin
.activity-title
h3.card-details-item-title
i.fa.fa-history
| {{ _ 'activity'}}
| {{ _ 'activities'}}
if currentUser.isBoardMember
.material-toggle-switch(title="{{_ 'hide-system-messages'}}")
//span.toggle-switch-title
if hiddenSystemMessages
input.toggle-switch(type="checkbox" id="toggleButton" checked="checked")
.material-toggle-switch(title="{{_ 'show-activities'}}")
if showActivities
input.toggle-switch(type="checkbox" id="toggleShowActivitiesCard" checked="checked")
else
input.toggle-switch(type="checkbox" id="toggleButton")
label.toggle-label(for="toggleButton")
if currentBoard.allowsComments
if currentUser.isBoardMember
unless currentUser.isNoComments
+commentForm
unless currentUser.isNoComments
input.toggle-switch(type="checkbox" id="toggleShowActivitiesCard")
label.toggle-label(for="toggleShowActivitiesCard")
if currentUser.isBoardAdmin
if isLoaded.get
if isLinkedCard
+activities(card=this mode="linkedcard")
@@ -597,168 +707,339 @@ template(name="cardDetails")
+activities(card=this mode="card")
template(name="editCardTitleForm")
a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}")
a(title="{{_ 'copy-text-to-clipboard'}}")
span.copied-tooltip {{_ 'copied'}}
textarea.js-edit-card-title(rows='1' autofocus dir="auto")
= getTitle
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-title-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.js-close-inlined-form
template(name="editCardRequesterForm")
input.js-edit-card-requester(type='text' autofocus value=getRequestedBy dir="auto")
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-requester-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.js-close-inlined-form
template(name="editCardAssignerForm")
input.js-edit-card-assigner(type='text' autofocus value=getAssignedBy dir="auto")
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-assigner-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.js-close-inlined-form
template(name="editCardSortOrderForm")
input.js-edit-card-sort(type='text' autofocus value=sort dir="auto")
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-sort-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.js-close-inlined-form
template(name="cardDetailsActionsPopup")
ul.pop-over-list
li
a.js-toggle-watch-card
if isWatching
i.fa.fa-eye
| {{_ 'unwatch'}}
else
i.fa.fa-eye-slash
| {{_ 'watch'}}
hr
if canModifyCard
unless currentUser.isWorker
ul.pop-over-list
//li: a.js-members {{_ 'card-edit-members'}}
//li: a.js-labels {{_ 'card-edit-labels'}}
//li: a.js-attachments {{_ 'card-edit-attachments'}}
li
a.js-start-voting
i.fa.fa-thumbs-up
| {{_ 'card-edit-voting'}}
li
a.js-start-planning-poker
i.fa.fa-thumbs-up
| {{_ 'card-edit-planning-poker'}}
if currentUser.isBoardAdmin
if currentUser
ul.pop-over-list
li
a.js-toggle-watch-card
if isWatching
i.fa.fa-eye
| {{_ 'unwatch'}}
else
i.fa.fa-eye
| {{_ 'watch'}}
hr
if canModifyCard
unless currentUser.isWorker
ul.pop-over-list
//li: a.js-members {{_ 'card-edit-members'}}
//li: a.js-labels {{_ 'card-edit-labels'}}
//li: a.js-attachments {{_ 'card-edit-attachments'}}
li
a.js-custom-fields
i.fa.fa-list-alt
| {{_ 'card-edit-custom-fields'}}
//li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}}
//li: a.js-start-date {{_ 'editCardStartDatePopup-title'}}
//li: a.js-due-date {{_ 'editCardDueDatePopup-title'}}
//li: a.js-end-date {{_ 'editCardEndDatePopup-title'}}
li
a.js-spent-time
i.fa.fa-clock-o
| {{_ 'editCardSpentTimePopup-title'}}
li
a.js-set-card-color
i.fa.fa-paint-brush
| {{_ 'setCardColorPopup-title'}}
hr
a.js-start-voting
i.fa.fa-thumbs-up
| {{_ 'card-edit-voting'}}
li
a.js-start-planning-poker
i.fa.fa-thumbs-up
| {{_ 'card-edit-planning-poker'}}
if currentUser.isBoardAdmin
li
a.js-custom-fields
i.fa.fa-list
| {{_ 'card-edit-custom-fields'}}
//li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}}
//li: a.js-start-date {{_ 'editCardStartDatePopup-title'}}
//li: a.js-due-date {{_ 'editCardDueDatePopup-title'}}
//li: a.js-end-date {{_ 'editCardEndDatePopup-title'}}
li
a.js-spent-time
i.fa.fa-clock-o
| {{_ 'editCardSpentTimePopup-title'}}
li
a.js-set-card-color
i.fa.fa-paint-brush
| {{_ 'setCardColorPopup-title'}}
li
a.js-toggle-show-list-on-minicard
if showListOnMinicard
i.fa.fa-eye
| {{_ 'hide-list-on-minicard'}}
else
i.fa.fa-eye
| {{_ 'show-list-on-minicard'}}
if canModifyCard
hr
else
unless currentUser.isReadOnly
unless currentUser.isReadAssignedOnly
hr
ul.pop-over-list
li
a.js-export-card
i.fa.fa-share-alt
i.fa.fa-upload
| {{_ 'export-card'}}
hr
ul.pop-over-list
li
a.js-move-card-to-top
i.fa.fa-arrow-up
| {{_ 'moveCardToTop-title'}}
li
a.js-move-card-to-bottom
i.fa.fa-arrow-down
| {{_ 'moveCardToBottom-title'}}
hr
ul.pop-over-list
if currentUser.isBoardAdmin
li
a.js-move-card
i.fa.fa-arrow-right
| {{_ 'moveCardPopup-title'}}
unless currentUser.isWorker
li
a.js-copy-card
i.fa.fa-copy
| {{_ 'copyCardPopup-title'}}
unless currentUser.isWorker
ul.pop-over-list
li
a.js-copy-checklist-cards
i.fa.fa-copy
i.fa.fa-copy
| {{_ 'copyManyCardsPopup-title'}}
unless archived
if currentUser
unless canModifyCard
unless currentUser.isReadOnly
unless currentUser.isReadAssignedOnly
hr
ul.pop-over-list
li
a.js-move-card-to-top
i.fa.fa-arrow-up
| {{_ 'moveCardToTop-title'}}
li
a.js-move-card-to-bottom
i.fa.fa-arrow-down
| {{_ 'moveCardToBottom-title'}}
hr
ul.pop-over-list
if currentUser.isBoardAdmin
li
a.js-move-card
i.fa.fa-arrow-right
| {{_ 'moveCardPopup-title'}}
unless currentUser.isWorker
li
a.js-copy-card
i.fa.fa-clipboard
| {{_ 'copyCardPopup-title'}}
unless currentUser.isWorker
ul.pop-over-list
li
a.js-copy-checklist-cards
i.fa.fa-copy
| {{_ 'copyManyCardsPopup-title'}}
unless archived
hr
ul.pop-over-list
li
a.js-archive
i.fa.fa-archive
| {{_ 'archive-card'}}
hr
ul.pop-over-list
li
a.js-more
span.emoji-icon
i.fa.fa-link
| {{_ 'cardMorePopup-title'}}
if canModifyCard
hr
ul.pop-over-list
li
a.js-archive
i.fa.fa-arrow-right
i.fa.fa-archive
| {{_ 'archive-card'}}
hr
ul.pop-over-list
li
a.js-more
i.fa.fa-link
| {{_ 'cardMorePopup-title'}}
a.js-move-card-to-top
i.fa.fa-arrow-up
| {{_ 'moveCardToTop-title'}}
li
a.js-move-card-to-bottom
i.fa.fa-arrow-down
| {{_ 'moveCardToBottom-title'}}
hr
ul.pop-over-list
if currentUser.isBoardAdmin
li
a.js-move-card
i.fa.fa-arrow-right
| {{_ 'moveCardPopup-title'}}
unless currentUser.isWorker
li
a.js-copy-card
i.fa.fa-clipboard
| {{_ 'copyCardPopup-title'}}
unless currentUser.isWorker
ul.pop-over-list
li
a.js-copy-checklist-cards
i.fa.fa-copy
| {{_ 'copyManyCardsPopup-title'}}
unless archived
hr
ul.pop-over-list
li
a.js-archive
i.fa.fa-archive
| {{_ 'archive-card'}}
hr
ul.pop-over-list
li
a.js-more
span.emoji-icon
i.fa.fa-link
| {{_ 'cardMorePopup-title'}}
template(name="exportCardPopup")
ul.pop-over-list
li
a(href="{{exportUrlCardPDF}}",, download="{{exportFilenameCardPDF}}")
i.fa.fa-share-alt
a(href="{{exportUrlCardPDF}}", download="{{exportFilenameCardPDF}}")
i.fa.fa-file-pdf-o
| {{_ 'export-card-pdf'}}
hr
p.quiet {{_ 'export-card-excel-fields'}}
ul.pop-over-list
each excelExportFields
li(class="{{#if checked}}active{{/if}}")
a.js-excel-field-toggle(data-field="{{field}}" href="#")
i.fa.fa-check
| {{_ label}}
ul.pop-over-list
li
a(href="{{exportUrlCardExcel}}", download="{{exportFilenameCardExcel}}")
i.fa.fa-file-excel-o
| {{_ 'download'}}
template(name="moveCardPopup")
+copyAndMoveCard
label(for='move-card-title') {{_ 'title'}}:
input#move-card-title.full-line(type="text" value="{{getTitle}}" autofocus)
unless currentUser.isWorker
label {{_ 'boards'}}:
select.js-select-boards(autofocus)
each boards
option(value="{{_id}}" selected="{{#if isDialogOptionBoardId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
label {{_ 'swimlanes'}}:
select.js-select-swimlanes
each swimlanes
option(value="{{_id}}" selected="{{#if isDialogOptionSwimlaneId _id}}selected{{/if}}") {{add @index 1}}. {{isTitleDefault title}}
label {{_ 'lists'}}:
select.js-select-lists
each lists
option(value="{{_id}}" selected="{{#if isDialogOptionListId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
label {{_ 'cards'}}:
select.js-select-cards
each cards
option(value="{{_id}}" selected="{{#if isDialogOptionCardId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
div
input(type="radio" name="position" value="above" checked id="position-above" style="display: inline")
label(for="position-above") {{_ 'above-selected-card'}}
div
input(type="radio" name="position" value="below" id="position-below" style="display: inline")
label(for="position-below") {{_ 'below-selected-card'}}
.edit-controls.clearfix
button.primary.confirm.js-done {{_ 'done'}}
template(name="copyCardPopup")
label(for='copy-card-title') {{_ 'title'}}:
textarea#copy-card-title.minicard-composer-textarea.js-card-title(autofocus)
= getTitle
+copyAndMoveCard
unless currentUser.isWorker
label {{_ 'boards'}}:
select.js-select-boards(autofocus)
each boards
option(value="{{_id}}" selected="{{#if isDialogOptionBoardId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
label {{_ 'swimlanes'}}:
select.js-select-swimlanes
each swimlanes
option(value="{{_id}}" selected="{{#if isDialogOptionSwimlaneId _id}}selected{{/if}}") {{add @index 1}}. {{isTitleDefault title}}
label {{_ 'lists'}}:
select.js-select-lists
each lists
option(value="{{_id}}" selected="{{#if isDialogOptionListId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
label {{_ 'cards'}}:
select.js-select-cards
each cards
option(value="{{_id}}" selected="{{#if isDialogOptionCardId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
div
input(type="radio" name="position" value="above" checked id="position-above" style="display: inline")
label(for="position-above") {{_ 'above-selected-card'}}
div
input(type="radio" name="position" value="below" id="position-below" style="display: inline")
label(for="position-below") {{_ 'below-selected-card'}}
.edit-controls.clearfix
button.primary.confirm.js-done {{_ 'done'}}
template(name="copyManyCardsPopup")
label(for='copy-checklist-cards-title') {{_ 'copyManyCardsPopup-instructions'}}:
textarea#copy-card-title.minicard-composer-textarea.js-card-title(autofocus)
| {{_ 'copyManyCardsPopup-format'}}
+copyAndMoveCard
unless currentUser.isWorker
label {{_ 'boards'}}:
select.js-select-boards(autofocus)
each boards
option(value="{{_id}}" selected="{{#if isDialogOptionBoardId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
label {{_ 'swimlanes'}}:
select.js-select-swimlanes
each swimlanes
option(value="{{_id}}" selected="{{#if isDialogOptionSwimlaneId _id}}selected{{/if}}") {{add @index 1}}. {{isTitleDefault title}}
label {{_ 'lists'}}:
select.js-select-lists
each lists
option(value="{{_id}}" selected="{{#if isDialogOptionListId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
label {{_ 'cards'}}:
select.js-select-cards
each cards
option(value="{{_id}}" selected="{{#if isDialogOptionCardId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
div
input(type="radio" name="position" value="above" checked id="position-above" style="display: inline")
label(for="position-above") {{_ 'above-selected-card'}}
div
input(type="radio" name="position" value="below" id="position-below" style="display: inline")
label(for="position-below") {{_ 'below-selected-card'}}
.edit-controls.clearfix
button.primary.confirm.js-done {{_ 'done'}}
template(name="convertChecklistItemToCardPopup")
label(for='convert-checklist-item-to-card-title') {{_ 'title'}}:
textarea#copy-card-title.minicard-composer-textarea.js-card-title(autofocus)
= item.title
+copyAndMoveCard
template(name="copyAndMoveCard")
unless currentUser.isWorker
label {{_ 'boards'}}:
select.js-select-boards(autofocus)
each boards
option(value="{{_id}}" selected="{{#if isDialogOptionBoardId _id}}selected{{/if}}") {{title}}
option(value="{{_id}}" selected="{{#if isDialogOptionBoardId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
label {{_ 'swimlanes'}}:
select.js-select-swimlanes
each swimlanes
option(value="{{_id}}" selected="{{#if isDialogOptionSwimlaneId _id}}selected{{/if}}") {{title}}
option(value="{{_id}}" selected="{{#if isDialogOptionSwimlaneId _id}}selected{{/if}}") {{add @index 1}}. {{isTitleDefault title}}
label {{_ 'lists'}}:
select.js-select-lists
each lists
option(value="{{_id}}" selected="{{#if isDialogOptionListId _id}}selected{{/if}}") {{title}}
option(value="{{_id}}" selected="{{#if isDialogOptionListId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
label {{_ 'cards'}}:
select.js-select-cards
each cards
option(value="{{_id}}" selected="{{#if isDialogOptionCardId _id}}selected{{/if}}") {{add @index 1}}. {{title}}
div
input(type="radio" name="position" value="above" checked id="position-above" style="display: inline")
label(for="position-above") {{_ 'above-selected-card'}}
div
input(type="radio" name="position" value="below" id="position-below" style="display: inline")
label(for="position-below") {{_ 'below-selected-card'}}
.edit-controls.clearfix
button.primary.confirm.js-done {{_ 'done'}}
@@ -769,13 +1050,13 @@ template(name="cardMembersPopup")
each members
li.item(class="{{#if isCardMember}}active{{/if}}")
a.name.js-select-member(href="#")
+userAvatar(userId=user._id)
+userAvatar(userId=userId)
span.full-name
= user.profile.fullname
| (<span class="username">{{ user.username }}</span>)
= userData.profile.fullname
if userData.username
| (#{userData.username})
if isCardMember
i.fa.fa-check
template(name="cardAssigneesPopup")
input.card-assignees-filter(type="text" placeholder="{{_ 'search'}}")
unless currentUser.isWorker
@@ -783,10 +1064,11 @@ template(name="cardAssigneesPopup")
each members
li.item(class="{{#if isCardAssignee}}active{{/if}}")
a.name.js-select-assignee(href="#")
+userAvatar(userId=user._id)
+userAvatar(userId=userId)
span.full-name
= user.profile.fullname
| (<span class="username">{{ user.username }}</span>)
= userData.profile.fullname
if userData.username
| (#{userData.username})
if isCardAssignee
i.fa.fa-check
if currentUser.isWorker
@@ -796,10 +1078,10 @@ template(name="cardAssigneesPopup")
+userAvatar(userId=currentUser._id)
span.full-name
= currentUser.profile.fullname
| (<span class="username">{{ currentUser.username }}</span>)
if currentUser.username
| (#{currentUser.username})
if currentUser.isCardAssignee
i.fa.fa-check
template(name="cardAssigneePopup")
.board-assignee-menu
.mini-profile-info
@@ -822,7 +1104,7 @@ template(name="cardMorePopup")
span.clearfix
span {{_ 'link-card'}}
= ' '
i.fa.colorful(class="{{#if board.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
input.inline-input(type="text" id="cardURL" readonly value="{{ originRelativeUrl }}" autofocus="autofocus")
button.js-copy-card-link-to-clipboard(class="btn" id="clipboard") {{_ 'copy-card-link-to-clipboard'}}
.copied-tooltip {{_ 'copied'}}
@@ -854,19 +1136,20 @@ template(name="cardMorePopup")
option(value="{{_id}}") {{title}}
br
| {{_ 'added'}}
span.date(title=card.createdAt) {{ moment createdAt 'LLL' }}
span.date(title=card.createdAt) {{ displayDate createdAt 'LLL' }}
if currentUser.isBoardAdmin
a.js-delete(title="{{_ 'card-delete-notice'}}") {{_ 'delete'}}
template(name="setCardColorPopup")
form.edit-label
.palette-colors: each colors
unless $eq color 'white'
span.card-label.palette-color.js-palette-color(class="card-details-{{color}}")
if(isSelected color)
i.fa.fa-check
button.primary.confirm.js-submit {{_ 'save'}}
button.js-remove-color.negate.wide.right {{_ 'unset-color'}}
.palette-colors
each colors
unless $eq color 'white'
span.card-label.palette-color.js-palette-color(class="card-details-{{color}}")
if(isSelected color)
i.fa.fa-check
button.primary.confirm.js-submit {{_ 'save'}}
button.js-remove-color.negate.wide.right {{_ 'unset-color'}}
template(name="cardDeletePopup")
p {{_ "card-delete-pop"}}
@@ -898,7 +1181,7 @@ template(name="cardStartVotingPopup")
.materialCheckBox#vote-public(name="vote-public" class="{{#if votePublic}}is-checked{{/if}}")
span {{_ 'vote-public'}}
.check-div.flex
i.fa.fa-hourglass-end
i.fa.fa-clock-o
a.js-end-date
span
| {{_ 'card-end'}}
@@ -944,7 +1227,7 @@ template(name="cardStartPlanningPokerPopup")
.materialCheckBox#poker-allow-non-members(name="poker-allow-non-members" class="{{#if pokerAllowNonBoardMembers}}is-checked{{/if}}")
span {{_ 'allowNonBoardMembers'}}
.check-div.flex
i.fa.fa-hourglass-end
i.fa.fa-clock-o
a.js-end-date
span
| {{_ 'card-end'}}
@@ -957,3 +1240,39 @@ template(name="cardStartPlanningPokerPopup")
if getPokerQuestion
if currentUser.isBoardAdmin
button.js-remove-poker.negate.wide.right {{_ 'delete'}}
template(name="cardLocationsPopup")
form.js-card-location-form
label
| {{_ 'location-detect-from-map'}}
input.js-location-map-link(type="text" placeholder="https://..." autofocus)
button.primary.js-detect-location(type="button") {{_ 'location-detect'}}
if detectMessage
p.quiet.js-detect-message {{detectMessage}}
hr
label
| {{_ 'location-name'}}
input.js-location-name(type="text" value="{{location.name}}")
label
| {{_ 'location-address'}}
input.js-location-address(type="text" value="{{location.address}}")
label
| {{_ 'location-latitude'}}
input.js-location-latitude(type="number" step="any" value="{{location.latitude}}")
label
| {{_ 'location-longitude'}}
input.js-location-longitude(type="number" step="any" value="{{location.longitude}}")
button.primary.confirm.js-submit-location(type="submit") {{_ 'save'}}
if location._id
button.negate.wide.right.js-delete-location(type="button") {{_ 'delete'}}
hr
.map-provider-row
span.map-provider-label {{_ 'location-open-map-at'}}
select.js-map-provider
option(value="openstreetmap" selected="{{#if isMapProvider 'openstreetmap'}}selected{{/if}}") OpenStreetMap
option(value="google" selected="{{#if isMapProvider 'google'}}selected{{/if}}") Google Maps
option(value="bing" selected="{{#if isMapProvider 'bing'}}selected{{/if}}") Bing Maps
option(value="apple" selected="{{#if isMapProvider 'apple'}}selected{{/if}}") Apple Maps
button.primary.js-save-map-provider(type="button") {{_ 'save'}}
if mapSavedMessage
p.quiet.js-map-saved {{mapSavedMessage}}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,7 @@
template(name="cardStickersPopup")
.card-stickers-picker.clearfix
each stickerIcons
a.card-sticker-select.js-select-sticker(class="{{#if isSelected}}active{{/if}}" title="{{stickerTitle}}")
i.fa(class="fa-{{icon}} {{#if highlight}}sticker-{{highlight}}{{/if}}")
if isSelected
i.fa.fa-check.card-sticker-check
+39
View File
@@ -0,0 +1,39 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { STICKER_PICKER } from '/models/metadata/stickers';
// Picker popup that lets a user add/remove stickers on a card. Each entry is
// { icon, highlight?, name? }: the plain Font Awesome icons plus the mascot
// (underlined) and computer (ringed) highlighted stickers. Opened from the card
// details stickers section with the card as the data context.
Template.cardStickersPopup.onCreated(function () {
const data = Template.currentData();
this.cardId = data && data._id;
});
function pickerCard(tpl) {
return ReactiveCache.getCard(tpl.cardId);
}
Template.cardStickersPopup.helpers({
stickerIcons() {
return STICKER_PICKER;
},
isSelected() {
const card = pickerCard(Template.instance());
return !!(card && card.hasSticker(this.icon, this.highlight));
},
stickerTitle() {
return this.name || this.icon;
},
});
Template.cardStickersPopup.events({
'click .js-select-sticker'(event) {
event.preventDefault();
const card = pickerCard(Template.instance());
if (card) {
card.toggleSticker(this.icon, this.highlight, this.name);
}
},
});
+6 -6
View File
@@ -1,4 +1,4 @@
template(name="editCardSpentTime")
template(name="editCardSpentTimePopup")
.edit-card-time
form.edit-time
.fields
@@ -13,10 +13,10 @@ template(name="editCardSpentTime")
button.primary.wide.left.js-submit-time(type="submit") {{_ 'save'}}
button.js-delete-time.negate.wide.right {{_ 'delete'}}
template(name="timeBadge")
template(name="cardSpentTime")
if canModifyCard
a.js-edit-time.card-time(title="{{showTitle}}" class="{{#if getIsOvertime}}card-label-red{{else}}card-label-green{{/if}}")
| {{showTime}}
a.js-edit-time.card-time(title="{{_ 'time'}}" class="{{#if getIsOvertime}}card-label-red{{else}}card-label-green{{/if}}")
| ⏱️ {{showTime}}
else
a.card-time(title="{{showTitle}}" class="{{#if getIsOvertime}}card-label-red{{else}}card-label-green{{/if}}")
| {{showTime}}
a.card-time(title="{{_ 'time'}}" class="{{#if getIsOvertime}}card-label-red{{else}}card-label-green{{/if}}")
| ⏱️ {{showTime}}
+73 -67
View File
@@ -1,85 +1,91 @@
import { TAPi18n } from '/imports/i18n';
import Cards from '/models/cards';
import { getCurrentCardIdFromContext } from '/client/lib/currentCard';
BlazeComponent.extendComponent({
template() {
return 'editCardSpentTime';
function getCardId() {
return getCurrentCardIdFromContext();
}
Template.editCardSpentTimePopup.onCreated(function () {
this.error = new ReactiveVar('');
this.card = Cards.findOne(getCardId());
});
Template.editCardSpentTimePopup.helpers({
error() {
return Template.instance().error;
},
onCreated() {
this.error = new ReactiveVar('');
this.card = this.data();
card() {
return Cards.findOne(getCardId());
},
toggleOvertime() {
this.card.setIsOvertime(!this.card.getIsOvertime());
getIsOvertime() {
const card = Cards.findOne(getCardId());
return card?.getIsOvertime ? card.getIsOvertime() : false;
},
});
Template.editCardSpentTimePopup.events({
//TODO : need checking this portion
'submit .edit-time'(evt, tpl) {
evt.preventDefault();
const card = Cards.findOne(getCardId());
if (!card) return;
const spentTime = parseFloat(evt.target.time.value);
let isOvertime = false;
if ($('#overtime').attr('class').indexOf('is-checked') >= 0) {
isOvertime = true;
}
if (spentTime >= 0) {
card.setSpentTime(spentTime);
card.setIsOvertime(isOvertime);
Popup.back();
} else {
tpl.error.set('invalid-time');
evt.target.time.focus();
}
},
'click .js-delete-time'(evt) {
evt.preventDefault();
const card = Cards.findOne(getCardId());
if (!card) return;
card.setSpentTime(null);
card.setIsOvertime(false);
Popup.back();
},
'click a.js-toggle-overtime'(evt) {
const card = Cards.findOne(getCardId());
if (!card) return;
card.setIsOvertime(!card.getIsOvertime());
$('#overtime .materialCheckBox').toggleClass('is-checked');
$('#overtime').toggleClass('is-checked');
},
storeTime(spentTime, isOvertime) {
this.card.setSpentTime(spentTime);
this.card.setIsOvertime(isOvertime);
},
deleteTime() {
this.card.setSpentTime(null);
this.card.setIsOvertime(false);
},
events() {
return [
{
//TODO : need checking this portion
'submit .edit-time'(evt) {
evt.preventDefault();
});
const spentTime = parseFloat(evt.target.time.value);
//const isOvertime = this.card.getIsOvertime();
let isOvertime = false;
if ($('#overtime').attr('class').indexOf('is-checked') >= 0) {
isOvertime = true;
}
if (spentTime >= 0) {
this.storeTime(spentTime, isOvertime);
Popup.back();
} else {
this.error.set('invalid-time');
evt.target.time.focus();
}
},
'click .js-delete-time'(evt) {
evt.preventDefault();
this.deleteTime();
Popup.back();
},
'click a.js-toggle-overtime': this.toggleOvertime,
},
];
},
}).register('editCardSpentTimePopup');
BlazeComponent.extendComponent({
template() {
return 'timeBadge';
},
onCreated() {
const self = this;
self.time = ReactiveVar();
},
Template.cardSpentTime.helpers({
showTitle() {
if (this.data().getIsOvertime()) {
const card = Cards.findOne(this._id) || this;
if (card.getIsOvertime && card.getIsOvertime()) {
return `${TAPi18n.__(
'overtime',
)} ${this.data().getSpentTime()} ${TAPi18n.__('hours')}`;
} else {
)} ${card.getSpentTime()} ${TAPi18n.__('hours')}`;
} else if (card.getSpentTime) {
return `${TAPi18n.__(
'card-spent',
)} ${this.data().getSpentTime()} ${TAPi18n.__('hours')}`;
)} ${card.getSpentTime()} ${TAPi18n.__('hours')}`;
}
return '';
},
showTime() {
return this.data().getSpentTime();
const card = Cards.findOne(this._id) || this;
return card.getSpentTime ? card.getSpentTime() : '';
},
events() {
return [
{
'click .js-edit-time': Popup.open('editCardSpentTime'),
},
];
getIsOvertime() {
const card = Cards.findOne(this._id) || this;
return card.getIsOvertime ? card.getIsOvertime() : false;
},
}).register('cardSpentTime');
});
Template.cardSpentTime.events({
'click .js-edit-time': Popup.open('editCardSpentTime'),
});
+7 -18
View File
@@ -8,20 +8,6 @@ textarea.js-edit-checklist-item {
resize: none;
height: 34px;
}
.card-details .text-show-at-minicard {
width: 350px;
text-align: left;
}
.minicard .text-show-at-minicard {
display: none;
}
.text-some-space {
width: 20px;
}
.text-hide-checked-items {
width: 400px;
text-align: left;
}
.delete-text,
.js-delete-checklist-item,
.js-convert-checklist-item-to-card {
@@ -40,8 +26,6 @@ textarea.js-edit-checklist-item {
display: flex;
justify-content: space-between;
}
.checklist-progress-bar-container {
display: flex;
flex-direction: row;
@@ -53,14 +37,19 @@ textarea.js-edit-checklist-item {
.checklist-progress-bar-container .checklist-progress-bar {
width: 80%;
height: 10px;
background-color: #e0e0e0;
border-radius: 16px;
}
.checklist-progress-bar-container .checklist-progress-bar .checklist-progress {
color: #fff !important;
background-color: #2196f3 !important;
color: #fff;
background-color: #666;
padding: 0.01em 16px;
border-radius: 16px;
height: 100%;
}
.checklist-title {
padding: 10px;
}
.checklist-title .checkbox {
float: left;
width: 30px;
+69 -30
View File
@@ -4,15 +4,25 @@ template(name="checklists")
i.fa.fa-check
| {{_ 'checklists'}}
if canModifyCard
+inlinedForm(autoclose=false classNames="js-add-checklist" cardId = cardId position="top")
+inlinedForm(autoclose=false classNames="js-add-checklist" cardId = cardId
position="top")
+addChecklistItemForm
else
a.add-checklist-top.js-open-inlined-form(title="{{_ 'add-checklist'}}")
i.fa.fa-plus
if currentUser.isBoardMember
.material-toggle-switch(title="{{_ 'hide-finished-checklist'}}")
//span.toggle-switch-title
if card.hideFinishedChecklistIfItemsAreHidden
input.toggle-switch(type="checkbox" id="toggleHideFinishedChecklist" checked="checked")
else
input.toggle-switch(type="checkbox" id="toggleHideFinishedChecklist")
label.toggle-label(for="toggleHideFinishedChecklist")
.card-checklist-items
each checklist in checklists
+checklistDetail(checklist=checklist)
if checklist.showChecklist card.hideFinishedChecklistIfItemsAreHidden
+checklistDetail(checklist = checklist card = card)
if canModifyCard
+inlinedForm(autoclose=false classNames="js-add-checklist" cardId = cardId)
@@ -22,9 +32,9 @@ template(name="checklists")
i.fa.fa-plus
template(name="checklistDetail")
.js-checklist.checklist
.js-checklist.checklist.nodragscroll
+inlinedForm(classNames="js-edit-checklist-title" checklist = checklist)
+editChecklistItemForm(checklist = checklist)
+editChecklistForm(checklist = checklist)
else
.checklist-title
span
@@ -47,12 +57,16 @@ template(name="checklistDetail")
.checklist-progress-text {{finishedPercent}}%
.checklist-progress-bar
.checklist-progress(style="width:{{finishedPercent}}%")
+checklistItems(checklist = checklist)
+checklistItems(checklist = checklist card = card)
template(name="checklistDeletePopup")
p {{_ 'confirm-checklist-delete-popup'}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
template(name="checklistItemDeletePopup")
p {{_ 'confirm-checklist-item-delete-popup'}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
template(name="addChecklistItemForm")
a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}")
span.copied-tooltip {{_ 'copied'}}
@@ -64,6 +78,25 @@ template(name="addChecklistItemForm")
.material-toggle-switch(title="{{_ 'newlineBecomesNewChecklistItem'}}")
input.toggle-switch(type="checkbox" id="toggleNewlineBecomesNewChecklistItem")
label.toggle-label(for="toggleNewlineBecomesNewChecklistItem")
| {{_ 'newLineNewItem'}}
if $eq position 'top'
.material-toggle-switch(title="{{_ 'newlineBecomesNewChecklistItemOriginOrder'}}")
input.toggle-switch(type="checkbox" id="toggleNewlineBecomesNewChecklistItemOriginOrder")
label.toggle-label(for="toggleNewlineBecomesNewChecklistItemOriginOrder")
| {{_ 'originOrder'}}
template(name="editChecklistForm")
a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}")
span.copied-tooltip {{_ 'copied'}}
textarea.js-edit-checklist-item(rows='1' autofocus dir="auto")
if $eq type 'item'
= item.title
else
= checklist.title
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-checklist-item-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form(title="{{_ 'close-edit-checklist-item'}}")
span(title=createdAt) {{ displayDate createdAt }}
template(name="editChecklistItemForm")
a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}")
@@ -76,7 +109,7 @@ template(name="editChecklistItemForm")
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-checklist-item-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form(title="{{_ 'close-edit-checklist-item'}}")
span(title=createdAt) {{ moment createdAt }}
span(title=createdAt) {{ displayDate createdAt }}
if canModifyCard
a.js-delete-checklist-item {{_ "delete"}}...
a.js-convert-checklist-item-to-card
@@ -87,7 +120,7 @@ template(name="checklistItems")
if checklist.items.length
if canModifyCard
+inlinedForm(autoclose=false classNames="js-add-checklist-item" checklist = checklist position="top")
+addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=true)
+addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=true position="top")
else
a.add-checklist-item.js-open-inlined-form(title="{{_ 'add-checklist-item'}}")
i.fa.fa-plus
@@ -96,7 +129,7 @@ template(name="checklistItems")
+inlinedForm(classNames="js-edit-checklist-item" item = item checklist = checklist)
+editChecklistItemForm(type = 'item' item = item checklist = checklist)
else
+checklistItemDetail(item = item checklist = checklist)
+checklistItemDetail(item = item checklist = checklist card = card)
if canModifyCard
+inlinedForm(autoclose=false classNames="js-add-checklist-item" checklist = checklist)
+addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=true)
@@ -105,7 +138,7 @@ template(name="checklistItems")
i.fa.fa-plus
template(name='checklistItemDetail')
.js-checklist-item.checklist-item(class="{{#if item.isFinished }}is-checked{{#if hideCheckedItems}} invisible{{/if}}{{/if}}"
.js-checklist-item.checklist-item(class="{{#if item.isFinished }}is-checked{{#if checklist.hideCheckedChecklistItems}} invisible{{/if}}{{/if}}{{#if checklist.hideAllChecklistItems}} is-checked invisible{{/if}}"
role="checkbox" aria-checked="{{#if item.isFinished }}true{{else}}false{{/if}}" tabindex="0")
if canModifyCard
.check-box-container
@@ -122,27 +155,6 @@ template(name='checklistItemDetail')
= item.title
template(name="checklistActionsPopup")
if currentUser.isBoardMember
span.text-show-at-minicard
| {{_ 'show-at-minicard'}}
.material-toggle-switch(title="{{_ 'show-checklist-at-minicard'}}")
if showAtMinicard
input.toggle-switch(type="checkbox" id="toggleShowChecklistAtMinicardButton" checked="checked")
else
input.toggle-switch(type="checkbox" id="toggleShowChecklistAtMinicardButton")
label.toggle-label(for="toggleShowChecklistAtMinicardButton")
hr
span.text-hide-checked-items
| {{_ 'hide-checked-items'}}
.material-toggle-switch(title="{{_ 'hide-checked-items'}}")
//span.toggle-switch-title
//.check-square-icon.i.fa.fa-check-square-o
if hideCheckedItems
input.toggle-switch(type="checkbox" id="toggleHideCheckedItemsButton" checked="checked")
else
input.toggle-switch(type="checkbox" id="toggleHideCheckedItemsButton")
label.toggle-label(for="toggleHideCheckedItemsButton")
hr
ul.pop-over-list
li
a.js-delete-checklist.delete-checklist
@@ -154,6 +166,33 @@ template(name="checklistActionsPopup")
a.js-copy-checklist.copy-checklist
i.fa.fa-copy
| {{_ "copyChecklist"}} ...
a.js-hide-checked-checklist-items
i.fa.fa-eye-slash
| {{_ "hideCheckedChecklistItems"}} ...
.material-toggle-switch(title="{{_ 'hide-checked-items'}}")
if checklist.hideCheckedChecklistItems
input.toggle-switch(type="checkbox" id="toggleHideCheckedChecklistItems_{{checklist._id}}" checked="checked")
else
input.toggle-switch(type="checkbox" id="toggleHideCheckedChecklistItems_{{checklist._id}}")
label.toggle-label(for="toggleHideCheckedChecklistItems_{{checklist._id}}")
a.js-hide-all-checklist-items
i.fa.fa-ban
| {{_ "hideAllChecklistItems"}} ...
.material-toggle-switch(title="{{_ 'hideAllChecklistItems'}}")
if checklist.hideAllChecklistItems
input.toggle-switch(type="checkbox" id="toggleHideAllChecklistItems_{{checklist._id}}" checked="checked")
else
input.toggle-switch(type="checkbox" id="toggleHideAllChecklistItems_{{checklist._id}}")
label.toggle-label(for="toggleHideAllChecklistItems_{{checklist._id}}")
a.js-show-checklist-at-minicard
i.fa.fa-th-list
| {{_ "show-on-minicard"}} ...
.material-toggle-switch(title="{{_ 'show-on-minicard'}}")
if checklist.showChecklistAtMinicard
input.toggle-switch(type="checkbox" id="toggleShowChecklistAtMinicard_{{checklist._id}}" checked="checked")
else
input.toggle-switch(type="checkbox" id="toggleShowChecklistAtMinicard_{{checklist._id}}")
label.toggle-label(for="toggleShowChecklistAtMinicard_{{checklist._id}}")
template(name="copyChecklistPopup")
+copyAndMoveChecklist
+301 -267
View File
@@ -2,10 +2,15 @@ import { ReactiveCache } from '/imports/reactiveCache';
import { TAPi18n } from '/imports/i18n';
import Cards from '/models/cards';
import Boards from '/models/boards';
import { DialogWithBoardSwimlaneListCard } from '/client/lib/dialogWithBoardSwimlaneListCard';
import ChecklistItems from '/models/checklistItems';
import Checklists from '/models/checklists';
import { BoardSwimlaneListCardDialog } from '/client/lib/dialogWithBoardSwimlaneListCard';
import { EscapeActions } from '/client/lib/escapeActions';
import { Utils } from '/client/lib/utils';
import autosize from 'autosize';
const subManager = new SubsManager();
const { calculateIndexData, capitalize } = Utils;
// SubsManager removed for Meteor 3 migration
const { calculateIndexData } = Utils;
function initSorting(items) {
items.sortable({
@@ -45,55 +50,66 @@ function initSorting(items) {
});
}
BlazeComponent.extendComponent({
onRendered() {
const self = this;
self.itemsDom = this.$('.js-checklist-items');
initSorting(self.itemsDom);
self.itemsDom.mousedown(function (evt) {
evt.stopPropagation();
});
Template.checklistDetail.onRendered(function () {
const tpl = this;
tpl.itemsDom = this.$('.js-checklist-items');
initSorting(tpl.itemsDom);
tpl.itemsDom.mousedown(function (evt) {
evt.stopPropagation();
});
function userIsMember() {
return ReactiveCache.getCurrentUser()?.isBoardMember();
}
function userIsMember() {
return ReactiveCache.getCurrentUser()?.isBoardMember();
}
// Disable sorting if the current user is not a board member
self.autorun(() => {
const $itemsDom = $(self.itemsDom);
if ($itemsDom.data('uiSortable') || $itemsDom.data('sortable')) {
$(self.itemsDom).sortable('option', 'disabled', !userIsMember());
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$(self.itemsDom).sortable({
handle: 'span.fa.checklistitem-handle',
});
}
// Disable sorting if the current user is not a board member
tpl.autorun(() => {
const $itemsDom = $(tpl.itemsDom);
if ($itemsDom.data('uiSortable') || $itemsDom.data('sortable')) {
$(tpl.itemsDom).sortable('option', 'disabled', !userIsMember());
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$(tpl.itemsDom).sortable({
handle: 'span.fa.checklistitem-handle',
});
}
});
},
}
});
});
Template.checklistDetail.helpers({
/** returns the finished percent of the checklist */
finishedPercent() {
const ret = this.data().checklist.finishedPercent();
const ret = this.checklist.finishedPercent();
return ret;
},
}).register('checklistDetail');
});
BlazeComponent.extendComponent({
addChecklist(event) {
Template.checklists.helpers({
checklists() {
const card = ReactiveCache.getCard(this.cardId);
if (!card || typeof card.checklists !== 'function') {
return [];
}
const ret = card.checklists();
return ret;
},
});
Template.checklists.events({
'click .js-open-checklist-details-menu': Popup.open('checklistActions'),
'submit .js-add-checklist'(event, tpl) {
event.preventDefault();
const textarea = this.find('textarea.js-add-checklist-item');
const textarea = tpl.find('textarea.js-add-checklist-item');
const title = textarea.value.trim();
let cardId = this.currentData().cardId;
let cardId = Template.currentData().cardId;
const card = ReactiveCache.getCard(cardId);
//if (card.isLinked()) cardId = card.linkedId;
if (card.isLinkedCard()) {
cardId = card.linkedId;
}
let sortIndex;
let checklistItemIndex;
if (this.currentData().position === 'top') {
if (Template.currentData().position === 'top') {
sortIndex = Utils.calculateIndexData(null, card.firstChecklist()).base;
checklistItemIndex = 0;
} else {
@@ -107,75 +123,110 @@ BlazeComponent.extendComponent({
title,
sort: sortIndex,
});
this.closeAllInlinedForms();
tpl.$('.js-close-inlined-form').click();
setTimeout(() => {
this.$('.add-checklist-item')
tpl.$('.add-checklist-item')
.eq(checklistItemIndex)
.click();
}, 100);
}
},
addChecklistItem(event) {
'submit .js-edit-checklist-title'(event, tpl) {
event.preventDefault();
const textarea = this.find('textarea.js-add-checklist-item');
const newlineBecomesNewChecklistItem = this.find('input#toggleNewlineBecomesNewChecklistItem');
const textarea = tpl.find('textarea.js-edit-checklist-item');
const title = textarea.value.trim();
const checklist = this.currentData().checklist;
const formData = Blaze.getData(event.currentTarget) || Blaze.getData(event.target);
const checklist = formData?.checklist;
if (checklist) {
checklist.setTitle(title);
}
},
'submit .js-add-checklist-item'(event, tpl) {
event.preventDefault();
const textarea = tpl.find('textarea.js-add-checklist-item');
if (!textarea) {
return;
}
const newlineBecomesNewChecklistItem = tpl.find('input#toggleNewlineBecomesNewChecklistItem');
const newlineBecomesNewChecklistItemOriginOrder = tpl.find('input#toggleNewlineBecomesNewChecklistItemOriginOrder');
const title = textarea.value.trim();
const currentData = Template.currentData() || {};
let resolvedData = currentData;
let checklist = currentData.checklist;
if (!checklist) {
const form = event.currentTarget?.closest
? event.currentTarget.closest('form')
: $(event.target).closest('form').get(0);
const formData = form ? Blaze.getData(form) : null;
if (formData) {
resolvedData = formData;
}
checklist = formData?.checklist;
}
if (!checklist) {
return;
}
if (title) {
let checklistItems = [title];
if (newlineBecomesNewChecklistItem.checked) {
if (newlineBecomesNewChecklistItem?.checked) {
checklistItems = title.split('\n').map(_value => _value.trim());
if (this.currentData().position === 'top') {
checklistItems = checklistItems.reverse();
if (resolvedData.position === 'top') {
if (newlineBecomesNewChecklistItemOriginOrder?.checked === false) {
checklistItems = checklistItems.reverse();
}
}
}
let addIndex;
let sortIndex;
if (resolvedData.position === 'top') {
sortIndex = Utils.calculateIndexData(null, checklist.firstItem()).base;
addIndex = -1;
} else {
sortIndex = Utils.calculateIndexData(checklist.lastItem(), null).base;
addIndex = 1;
}
for (let checklistItem of checklistItems) {
let sortIndex;
if (this.currentData().position === 'top') {
sortIndex = Utils.calculateIndexData(null, checklist.firstItem()).base;
} else {
sortIndex = Utils.calculateIndexData(checklist.lastItem(), null).base;
}
ChecklistItems.insert({
title: checklistItem,
checklistId: checklist._id,
cardId: checklist.cardId,
sort: sortIndex,
});
sortIndex += addIndex;
}
}
// We keep the form opened, empty it.
textarea.value = '';
textarea.focus();
},
deleteItem() {
const checklist = this.currentData().checklist;
const item = this.currentData().item;
if (checklist && item && item._id) {
ChecklistItems.remove(item._id);
'submit .js-edit-checklist-item'(event, tpl) {
event.preventDefault();
const textarea = tpl.find('textarea.js-edit-checklist-item');
const title = textarea.value.trim();
const formData = Blaze.getData(event.currentTarget) || Blaze.getData(event.target);
const item = formData?.item;
if (item) {
item.setTitle(title);
}
},
editChecklist(event) {
event.preventDefault();
const textarea = this.find('textarea.js-edit-checklist-item');
const title = textarea.value.trim();
const checklist = this.currentData().checklist;
checklist.setTitle(title);
'click .js-convert-checklist-item-to-card': Popup.open('convertChecklistItemToCard'),
'click .js-delete-checklist-item': Popup.afterConfirm('checklistItemDelete', function () {
Popup.back();
const item = this?.item || this;
if (item && item._id) {
ChecklistItems.remove(item._id);
}
}),
// add and delete checklist / checklist-item
'click .js-open-inlined-form'(event, tpl) {
tpl.$('.js-close-inlined-form').click();
},
editChecklistItem(event) {
'click #toggleHideFinishedChecklist'(event) {
event.preventDefault();
const textarea = this.find('textarea.js-edit-checklist-item');
const title = textarea.value.trim();
const item = this.currentData().item;
item.setTitle(title);
Template.currentData().card.toggleHideFinishedChecklist();
},
pressKey(event) {
'keydown textarea.js-add-checklist-item'(event) {
//If user press enter key inside a form, submit it
//Unless the user is also holding down the 'shift' key
if (event.keyCode === 13 && !event.shiftKey) {
@@ -184,223 +235,206 @@ BlazeComponent.extendComponent({
$form.find('button[type=submit]').click();
}
},
});
focusChecklistItem(event) {
// If a new checklist is created, pre-fill the title and select it.
const checklist = this.currentData().checklist;
if (!checklist) {
const textarea = event.target;
textarea.value = capitalize(TAPi18n.__('r-checklist'));
textarea.select();
}
},
// NOTE: boardsSwimlanesAndLists template was removed from jade but JS was left behind.
// This is dead code — the template no longer exists in any jade file.
/** closes all inlined forms (checklist and checklist-item input fields) */
closeAllInlinedForms() {
this.$('.js-close-inlined-form').click();
},
Template.addChecklistItemForm.onRendered(function () {
autosize(this.$('textarea.js-add-checklist-item'));
});
events() {
const events = {
};
Template.addChecklistItemForm.events({
'click a.fa.fa-copy'(event, tpl) {
const $editor = tpl.$('textarea');
const promise = Utils.copyTextToClipboard($editor[0].value);
return [
{
...events,
'click .js-open-checklist-details-menu': Popup.open('checklistActions'),
'submit .js-add-checklist': this.addChecklist,
'submit .js-edit-checklist-title': this.editChecklist,
'submit .js-add-checklist-item': this.addChecklistItem,
'submit .js-edit-checklist-item': this.editChecklistItem,
'click .js-convert-checklist-item-to-card': Popup.open('convertChecklistItemToCard'),
'click .js-delete-checklist-item': this.deleteItem,
'focus .js-add-checklist-item': this.focusChecklistItem,
// add and delete checklist / checklist-item
'click .js-open-inlined-form': this.closeAllInlinedForms,
keydown: this.pressKey,
},
];
},
}).register('checklists');
BlazeComponent.extendComponent({
onCreated() {
subManager.subscribe('board', Session.get('currentBoard'), false);
this.selectedBoardId = new ReactiveVar(Session.get('currentBoard'));
},
boards() {
const ret = ReactiveCache.getBoards(
{
archived: false,
'members.userId': Meteor.userId(),
_id: { $ne: ReactiveCache.getCurrentUser().getTemplatesBoardId() },
},
{
sort: { sort: 1 /* boards default sorting */ },
},
);
return ret;
},
swimlanes() {
const board = ReactiveCache.getBoard(this.selectedBoardId.get());
return board.swimlanes();
},
aBoardLists() {
const board = ReactiveCache.getBoard(this.selectedBoardId.get());
return board.lists();
},
events() {
return [
{
'change .js-select-boards'(event) {
this.selectedBoardId.set($(event.currentTarget).val());
subManager.subscribe('board', this.selectedBoardId.get(), false);
},
},
];
},
}).register('boardsSwimlanesAndLists');
Template.checklists.helpers({
checklists() {
const card = ReactiveCache.getCard(this.cardId);
const ret = card.checklists();
return ret;
},
showAtMinicard() {
const card = ReactiveCache.getCard(this.cardId);
const ret = card.checklists({'showAtMinicard':1});
return ret;
},
hideCheckedItems() {
const currentUser = ReactiveCache.getCurrentUser();
if (currentUser) return currentUser.hasHideCheckedItems();
return false;
const $tooltip = tpl.$('.copied-tooltip');
Utils.showCopied(promise, $tooltip);
},
});
BlazeComponent.extendComponent({
onRendered() {
autosize(this.$('textarea.js-add-checklist-item'));
},
events() {
return [
{
'click a.fa.fa-copy'(event) {
const $editor = this.$('textarea');
const promise = Utils.copyTextToClipboard($editor[0].value);
const $tooltip = this.$('.copied-tooltip');
Utils.showCopied(promise, $tooltip);
},
}
];
}
}).register('addChecklistItemForm');
BlazeComponent.extendComponent({
toggleItem() {
const checklist = this.currentData().checklist;
const item = this.currentData().item;
if (checklist && item && item._id) {
item.toggleItem();
Template.checklistActionsPopup.events({
'click .js-delete-checklist': Popup.afterConfirm('checklistDelete', function () {
Popup.back(2);
const checklist = this.checklist;
if (checklist && checklist._id) {
Checklists.remove(checklist._id);
}
}),
'click .js-move-checklist': Popup.open('moveChecklist'),
'click .js-copy-checklist': Popup.open('copyChecklist'),
'click .js-hide-checked-checklist-items'(event) {
event.preventDefault();
Template.currentData().checklist.toggleHideCheckedChecklistItems();
Popup.back();
},
events() {
return [
{
'click .js-checklist-item .check-box-container': this.toggleItem,
'click #toggleShowChecklistAtMinicardButton'() {
const checklist = this.checklist;
if (checklist && checklist._id) {
Meteor.call('toggleShowChecklistAtMinicard', checklist._id);
}
},
'click #toggleHideCheckedItemsButton'() {
Meteor.call('toggleHideCheckedItems');
},
'click .js-delete-checklist': Popup.afterConfirm('checklistDelete', function () {
Popup.back(2);
const checklist = this.checklist;
if (checklist && checklist._id) {
Checklists.remove(checklist._id);
}
}),
'click .js-move-checklist': Popup.open('moveChecklist'),
'click .js-copy-checklist': Popup.open('copyChecklist'),
}
]
}
}).register('checklistActionsPopup');
BlazeComponent.extendComponent({
onRendered() {
autosize(this.$('textarea.js-edit-checklist-item'));
'click .js-hide-all-checklist-items'(event) {
event.preventDefault();
Template.currentData().checklist.toggleHideAllChecklistItems();
Popup.back();
},
events() {
return [
{
'click a.fa.fa-copy'(event) {
const $editor = this.$('textarea');
const promise = Utils.copyTextToClipboard($editor[0].value);
'click .js-show-checklist-at-minicard'(event) {
event.preventDefault();
Template.currentData().checklist.toggleShowChecklistAtMinicard();
Popup.back();
},
});
const $tooltip = this.$('.copied-tooltip');
Utils.showCopied(promise, $tooltip);
},
}
];
}
}).register('editChecklistItemForm');
Template.editChecklistItemForm.onRendered(function () {
autosize(this.$('textarea.js-edit-checklist-item'));
});
Template.editChecklistItemForm.events({
'click a.fa.fa-copy'(event, tpl) {
const $editor = tpl.$('textarea');
const promise = Utils.copyTextToClipboard($editor[0].value);
const $tooltip = tpl.$('.copied-tooltip');
Utils.showCopied(promise, $tooltip);
},
});
Template.checklistItemDetail.helpers({
hideCheckedItems() {
const user = ReactiveCache.getCurrentUser();
if (user) return user.hasHideCheckedItems();
return false;
},
});
BlazeComponent.extendComponent({
toggleItem() {
const checklist = this.currentData().checklist;
const item = this.currentData().item;
Template.checklistItemDetail.events({
'click .js-checklist-item .check-box-container'() {
const checklist = Template.currentData().checklist;
const item = Template.currentData().item;
if (checklist && item && item._id) {
item.toggleItem();
}
},
events() {
return [
{
'click .js-checklist-item .check-box-container': this.toggleItem,
},
];
});
/**
* Helper to find the dialog instance from a parent popup template.
* copyAndMoveChecklist is included inside moveChecklistPopup / copyChecklistPopup,
* so we traverse up the view hierarchy to find the parent template's dialog.
*/
function getParentDialog(tpl) {
let view = tpl.view.parentView;
while (view) {
if (view.templateInstance && view.templateInstance() && view.templateInstance().dialog) {
return view.templateInstance().dialog;
}
view = view.parentView;
}
return null;
}
/** Shared helpers for copyAndMoveChecklist sub-template */
Template.copyAndMoveChecklist.helpers({
boards() {
const dialog = getParentDialog(Template.instance());
return dialog ? dialog.boards() : [];
},
}).register('checklistItemDetail');
swimlanes() {
const dialog = getParentDialog(Template.instance());
return dialog ? dialog.swimlanes() : [];
},
lists() {
const dialog = getParentDialog(Template.instance());
return dialog ? dialog.lists() : [];
},
cards() {
const dialog = getParentDialog(Template.instance());
return dialog ? dialog.cards() : [];
},
isDialogOptionBoardId(boardId) {
const dialog = getParentDialog(Template.instance());
return dialog ? dialog.isDialogOptionBoardId(boardId) : false;
},
isDialogOptionSwimlaneId(swimlaneId) {
const dialog = getParentDialog(Template.instance());
return dialog ? dialog.isDialogOptionSwimlaneId(swimlaneId) : false;
},
isDialogOptionListId(listId) {
const dialog = getParentDialog(Template.instance());
return dialog ? dialog.isDialogOptionListId(listId) : false;
},
isDialogOptionCardId(cardId) {
const dialog = getParentDialog(Template.instance());
return dialog ? dialog.isDialogOptionCardId(cardId) : false;
},
isTitleDefault(title) {
const dialog = getParentDialog(Template.instance());
return dialog ? dialog.isTitleDefault(title) : title;
},
});
/**
* Helper: register standard card dialog events on a checklist popup template.
* Events bubble up from the copyAndMoveChecklist sub-template to the parent popup.
*/
function registerChecklistDialogEvents(templateName) {
Template[templateName].events({
async 'click .js-done'(event, tpl) {
const dialog = tpl.dialog;
const boardSelect = tpl.$('.js-select-boards')[0];
const boardId = boardSelect.options[boardSelect.selectedIndex].value;
const listSelect = tpl.$('.js-select-lists')[0];
const listId = listSelect.options[listSelect.selectedIndex].value;
const swimlaneSelect = tpl.$('.js-select-swimlanes')[0];
const swimlaneId = swimlaneSelect.options[swimlaneSelect.selectedIndex].value;
const cardSelect = tpl.$('.js-select-cards')[0];
const cardId = cardSelect.options.length > 0
? cardSelect.options[cardSelect.selectedIndex].value
: null;
const options = { boardId, swimlaneId, listId, cardId };
try {
await dialog.setDone(cardId, options);
} catch (e) {
console.error('Error in card dialog operation:', e);
}
Popup.back(2);
},
'change .js-select-boards'(event, tpl) {
tpl.dialog.getBoardData($(event.currentTarget).val());
},
'change .js-select-swimlanes'(event, tpl) {
tpl.dialog.selectedSwimlaneId.set($(event.currentTarget).val());
tpl.dialog.setFirstListId();
},
'change .js-select-lists'(event, tpl) {
tpl.dialog.selectedListId.set($(event.currentTarget).val());
tpl.dialog.selectedCardId.set('');
},
'change .js-select-cards'(event, tpl) {
tpl.dialog.selectedCardId.set($(event.currentTarget).val());
},
});
}
/** Move Checklist Dialog */
(class extends DialogWithBoardSwimlaneListCard {
getDialogOptions() {
const ret = ReactiveCache.getCurrentUser().getMoveChecklistDialogOptions();
return ret;
}
setDone(cardId, options) {
ReactiveCache.getCurrentUser().setMoveChecklistDialogOption(this.currentBoardId, options);
this.data().checklist.move(cardId);
}
}).register('moveChecklistPopup');
Template.moveChecklistPopup.onCreated(function () {
this.dialog = new BoardSwimlaneListCardDialog(this, {
getDialogOptions() {
return ReactiveCache.getCurrentUser().getMoveChecklistDialogOptions();
},
async setDone(cardId, options) {
ReactiveCache.getCurrentUser().setMoveChecklistDialogOption(this.currentBoardId, options);
await Template.currentData().checklist.move(cardId);
},
});
});
registerChecklistDialogEvents('moveChecklistPopup');
/** Copy Checklist Dialog */
(class extends DialogWithBoardSwimlaneListCard {
getDialogOptions() {
const ret = ReactiveCache.getCurrentUser().getCopyChecklistDialogOptions();
return ret;
}
setDone(cardId, options) {
ReactiveCache.getCurrentUser().setCopyChecklistDialogOption(this.currentBoardId, options);
this.data().checklist.copy(cardId);
}
}).register('copyChecklistPopup');
Template.copyChecklistPopup.onCreated(function () {
this.dialog = new BoardSwimlaneListCardDialog(this, {
getDialogOptions() {
return ReactiveCache.getCurrentUser().getCopyChecklistDialogOptions();
},
async setDone(cardId, options) {
ReactiveCache.getCurrentUser().setCopyChecklistDialogOption(this.currentBoardId, options);
await Template.currentData().checklist.copy(cardId);
},
});
});
registerChecklistDialogEvents('copyChecklistPopup');
@@ -0,0 +1,6 @@
template(name='inlinedCardDescription')
if isOpen.get
form.inlined-form.js-inlined-form(id=id class=classNames)
+Template.contentBlock
else
+Template.elseBlock
+7 -2
View File
@@ -38,6 +38,7 @@
.palette-colors {
display: flex;
flex-wrap: wrap;
justify-content: flex-start; /* left-align color chips in wider popovers */
}
.palette-colors .palette-color {
flex-grow: 1;
@@ -222,9 +223,13 @@
.card-label-edit-button:hover {
background: #dbdbdb;
}
ul.edit-labels-pop-over span.fa.label-handle {
ul.edit-labels-pop-over span.label-handle {
padding-right: 10px;
display: inline-block;
width: 1.2em;
text-align: center;
color: #999;
}
ul.edit-labels-pop-over span.fa.label-handle + .card-label {
ul.edit-labels-pop-over span.label-handle + .card-label {
max-width: 180px;
}
+1 -2
View File
@@ -37,5 +37,4 @@ template(name="cardLabelsPopup")
= name
if(isLabelSelected ../_id)
i.card-label-selectable-icon.fa.fa-check
if currentUser.isBoardAdmin
a.quiet-button.full.js-add-label {{_ 'label-create'}}
a.quiet-button.full.js-add-label {{_ 'label-create'}}
+104 -96
View File
@@ -1,119 +1,117 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { LABEL_COLORS } from '/models/metadata/colors';
import { EscapeActions } from '/client/lib/escapeActions';
import { Utils } from '/client/lib/utils';
let labelColors;
Meteor.startup(() => {
labelColors = Boards.simpleSchema()._schema['labels.$.color'].allowedValues;
labelColors = LABEL_COLORS;
});
BlazeComponent.extendComponent({
onCreated() {
this.currentColor = new ReactiveVar(this.data().color);
},
const getFallbackLabelColor = () => {
if (Array.isArray(labelColors) && labelColors.length > 0) {
return labelColors[0];
}
return 'green';
};
Template.formLabel.onCreated(function () {
const initialColor = this.data?.color || getFallbackLabelColor();
this.currentColor = new ReactiveVar(initialColor);
});
Template.formLabel.helpers({
labels() {
return labelColors.map(color => ({ color, name: '' }));
const colors = Array.isArray(labelColors) ? labelColors : [getFallbackLabelColor()];
return colors.map(color => ({ color, name: '' }));
},
isSelected(color) {
return this.currentColor.get() === color;
return Template.instance().currentColor.get() === color;
},
});
events() {
return [
{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
},
},
];
Template.formLabel.events({
'click .js-palette-color'(event, tpl) {
const paletteData = Blaze.getData(event.currentTarget);
const selectedColor = paletteData?.color || Template.currentData()?.color || getFallbackLabelColor();
tpl.currentColor.set(selectedColor);
},
}).register('formLabel');
});
Template.createLabelPopup.helpers({
// This is the default color for a new label. We search the first color that
// is not already used in the board (although it's not a problem if two
// labels have the same color).
defaultColor() {
const labels = Utils.getCurrentBoard().labels;
const usedColors = _.pluck(labels, 'color');
const availableColors = _.difference(labelColors, usedColors);
return availableColors.length > 1 ? availableColors[0] : labelColors[0];
const board = Utils.getCurrentBoard();
const colors = Array.isArray(labelColors) ? labelColors : [getFallbackLabelColor()];
const labels = Array.isArray(board?.labels) ? board.labels : [];
const usedColors = labels.map(l => l.color);
const availableColors = colors.filter(c => !usedColors.includes(c));
return availableColors.length > 0 ? availableColors[0] : colors[0];
},
});
BlazeComponent.extendComponent({
onRendered() {
const itemsSelector = 'li.js-card-label-item:not(.placeholder)';
const $labels = this.$('.edit-labels-pop-over');
Template.cardLabelsPopup.onRendered(function () {
const tpl = this;
const itemsSelector = 'li.js-card-label-item:not(.placeholder)';
const $labels = tpl.$('.edit-labels-pop-over');
$labels.sortable({
connectWith: '.edit-labels-pop-over',
tolerance: 'pointer',
appendTo: '.edit-labels-pop-over',
helper(element, currentItem) {
let ret = currentItem.clone();
if (currentItem.closest('.popup-container-depth-0').length == 0)
{ // only set css transform at every sub-popup, not at the main popup
const content = currentItem.closest('.content')[0]
const offsetLeft = content.offsetLeft;
const offsetTop = $('.pop-over > .header').height() * -1;
ret.css("transform", `translate(${offsetLeft}px, ${offsetTop}px)`);
}
return ret;
},
distance: 7,
items: itemsSelector,
placeholder: 'card-label-wrapper placeholder',
start(evt, ui) {
ui.helper.css('z-index', 1000);
ui.placeholder.height(ui.helper.height());
EscapeActions.clickExecute(evt.target, 'inlinedForm');
},
stop(evt, ui) {
const newLabelOrderOnlyIds = ui.item.parent().children().toArray().map(_element => Blaze.getData(_element)._id)
const card = Blaze.getData(this);
card.board().setNewLabelOrder(newLabelOrderOnlyIds);
},
});
// Disable drag-dropping if the current user is not a board member or is comment only
this.autorun(() => {
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$labels.sortable({
handle: '.label-handle',
});
$labels.sortable({
connectWith: '.edit-labels-pop-over',
tolerance: 'pointer',
appendTo: '.edit-labels-pop-over',
helper(element, currentItem) {
let ret = currentItem.clone();
if (currentItem.closest('.popup-container-depth-0').length == 0)
{ // only set css transform at every sub-popup, not at the main popup
const content = currentItem.closest('.content')[0]
const offsetLeft = content.offsetLeft;
const offsetTop = $('.pop-over > .header').height() * -1;
ret.css("transform", `translate(${offsetLeft}px, ${offsetTop}px)`);
}
});
return ret;
},
distance: 7,
items: itemsSelector,
placeholder: 'card-label-wrapper placeholder',
start(evt, ui) {
ui.helper.css('z-index', 1000);
ui.placeholder.height(ui.helper.height());
EscapeActions.clickExecute(evt.target, 'inlinedForm');
},
stop(evt, ui) {
const newLabelOrderOnlyIds = ui.item.parent().children().toArray().map(_element => Blaze.getData(_element)._id)
const card = Blaze.getData(this);
card.board().setNewLabelOrder(newLabelOrderOnlyIds);
},
});
// Disable drag-dropping if the current user is not a board member or is comment only
tpl.autorun(() => {
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$labels.sortable({
handle: '.label-handle',
});
}
});
});
Template.cardLabelsPopup.helpers({
isLabelSelected(cardId) {
return (ReactiveCache.getCard(cardId).labelIds || []).includes(this._id);
},
events() {
return [
{
'click .js-select-label'(event) {
const card = this.data();
const labelId = this.currentData()._id;
card.toggleLabel(labelId);
event.preventDefault();
},
'click .js-edit-label': Popup.open('editLabel'),
'click .js-add-label': Popup.open('createLabel'),
}
];
}
}).register('cardLabelsPopup');
});
Template.cardLabelsPopup.events({
});
Template.formLabel.events({
'click .js-palette-color'(event) {
const $this = $(event.currentTarget);
// hide selected ll colors
$('.js-palette-select').addClass('hide');
// show select color
$this.find('.js-palette-select').removeClass('hide');
'click .js-select-label'(event) {
const card = Template.currentData();
const labelId = this._id;
card.toggleLabel(labelId);
event.preventDefault();
},
'click .js-edit-label': Popup.open('editLabel'),
'click .js-add-label': Popup.open('createLabel'),
});
Template.createLabelPopup.events({
@@ -121,11 +119,19 @@ Template.createLabelPopup.events({
'submit .create-label'(event, templateInstance) {
event.preventDefault();
const board = Utils.getCurrentBoard();
if (!board) {
return;
}
const name = templateInstance
.$('#labelName')
.val()
.trim();
const color = Blaze.getData(templateInstance.find('.fa-check')).color;
const selectedColorIcon = templateInstance.find('.js-palette-color .fa-check');
const selectedPaletteNode = selectedColorIcon?.closest
? selectedColorIcon.closest('.js-palette-color')
: null;
const selectedColorData = selectedPaletteNode && Blaze.getData(selectedPaletteNode);
const color = selectedColorData?.color || getFallbackLabelColor();
board.addLabel(name, color);
Popup.back();
},
@@ -140,18 +146,20 @@ Template.editLabelPopup.events({
'submit .edit-label'(event, templateInstance) {
event.preventDefault();
const board = Utils.getCurrentBoard();
if (!board) {
return;
}
const name = templateInstance
.$('#labelName')
.val()
.trim();
const color = Blaze.getData(templateInstance.find('.fa-check')).color;
const selectedColorIcon = templateInstance.find('.js-palette-color .fa-check');
const selectedPaletteNode = selectedColorIcon?.closest
? selectedColorIcon.closest('.js-palette-color')
: null;
const selectedColorData = selectedPaletteNode && Blaze.getData(selectedPaletteNode);
const color = selectedColorData?.color || getFallbackLabelColor();
board.editLabel(this._id, name, color);
Popup.back();
},
});
Template.cardLabelsPopup.helpers({
isLabelSelected(cardId) {
return _.contains(ReactiveCache.getCard(cardId).labelIds, this._id);
},
});
+344 -74
View File
@@ -1,22 +1,13 @@
.minicard .checklists-title,
.minicard .add-checklist,
.minicard .add-checklist-item,
.minicard .checklist-details-menu {
display: none;
}
.minicard .checklist-progress-bar-container {
width: 190px; /* TODO: Add adjustable width https://github.com/wekan/wekan/pull/4964 */
}
.minicard-wrapper {
cursor: pointer;
position: relative;
display: flex;
align-items: center;
margin-bottom: 9px;
margin-bottom: 8px;
}
.minicard-wrapper.placeholder {
background: #ccc;
border-radius: 9px;
border-radius: 1.2vw;
}
.minicard-wrapper.ui-sortable-helper {
cursor: grabbing;
@@ -25,28 +16,40 @@
}
.minicard-wrapper.ui-sortable-helper .and-n-other {
width: 100%;
height: 16px;
padding: 4px;
height: 25px;
padding: 5px;
background-color: #f2f2f2;
text-align: center;
border-radius: 3px;
border-radius: 0.4vw;
}
.minicard-wrapper.ui-sortable-helper .multi-selection-checkbox {
display: none;
}
.minicard-wrapper .multi-selection-checkbox + .minicard {
margin-left: 8px;
margin-left: 1vw;
}
/* Enlarge the clickable area of the small selection checkbox so it can be
reliably clicked at the left side of the minicard. The visible 13px box (and
its rotated is-checked checkmark) keep their size; an invisible overlay only
extends the hit target. */
.minicard-wrapper .multi-selection-checkbox::before {
content: "";
position: absolute;
top: -8px;
left: -8px;
right: -8px;
bottom: -8px;
}
@media only screen {
.minicard {
padding: 6px 8px 2px;
padding: 8px 1vw 3px;
position: relative;
flex: 1;
flex-wrap: wrap;
background-color: #fff;
min-height: 20px;
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
border-radius: 2px;
min-height: 25px;
box-shadow: 0 2px 3px rgba(0,0,0,0.15);
border-radius: 0.3vw;
color: #4d4d4d;
overflow: hidden;
transition: transform 0.2s, border-radius 0.2s;
@@ -54,12 +57,15 @@
}
.minicard-details-menu-with-handle {
float: right;
font-size: 18px;
padding-right: 30px;
padding-left: 0.7vw;
font-size: clamp(14px, 3vw, 18px);
padding: 0;
z-index: 1;
}
.minicard-details-menu {
float: right;
font-size: 18px;
font-size: clamp(14px, 3vw, 18px);
padding-left: 0.7vw;
}
@media print {
.minicard-details-menu,
@@ -70,7 +76,7 @@
.minicard.linked-board .linked-icon,
.minicard.linked-card .linked-icon {
display: inline-block;
margin-right: 11px;
margin-right: 1.5vw;
vertical-align: baseline;
font-size: 0.9em;
}
@@ -79,11 +85,11 @@
color: #937760;
}
.is-selected .minicard {
transform: translateX(11px);
transform: translateX(1.5vw);
border-bottom-right-radius: 0;
border-top-right-radius: 0;
z-index: 25;
box-shadow: -2px 1px 2px rgba(0,0,0,0.2);
box-shadow: -0.3vw 2px 3px rgba(0,0,0,0.2);
}
.minicard:hover:not(.minicard-composer),
.is-selected .minicard,
@@ -97,20 +103,21 @@
background-position: center;
background-repeat: no-repeat;
background-size: contain;
height: 145px;
height: 150px;
user-select: none;
margin: -6px -8px 6px -8px;
border-radius: top 2px;
margin: 8px -1vw 8px -1vw;
border-radius: top 0.3vw;
}
.minicard .minicard-labels {
float: none;
margin-right: 6vw;
}
.minicard .minicard-labels .minicard-label {
width: 11px;
height: 11px;
border-radius: 2px;
margin-right: 3px;
margin-bottom: 3px;
width: clamp(12px, 1.5vw, 16px);
height: clamp(12px, 1.5vw, 16px);
border-radius: 0.3vw;
margin-right: 0.4vw;
margin-bottom: 4px;
}
.minicard .minicard-labels-no-text {
display: flex;
@@ -118,6 +125,7 @@
}
.minicard .minicard-custom-fields {
display: block;
margin-right: 6vw;
}
.minicard .minicard-custom-field {
display: flex;
@@ -126,45 +134,44 @@
flex-grow: 1;
display: block;
word-wrap: break-word;
max-width: 100px;
margin-right: 4px;
max-width: 13vw;
margin-right: 0.5vw;
}
.minicard .minicard-custom-field-item-fullwidth {
flex-grow: 1;
display: block;
word-wrap: break-word;
max-width: 100%;
margin-right: 4px;
margin-right: 0.5vw;
}
/*
.minicard .checklists-title,
.minicard .add-checklist,
.minicard .add-checklist-item,
.minicard .checklist-details-menu {
display: none;
}
*/
.minicard .handle {
width: 20px;
height: 20px;
width: clamp(20px, 2.5vw, 28px);
height: clamp(20px, 2.5vw, 28px);
position: absolute;
right: 5px;
top: 5px;
right: 0vw;
top: 28px;
display: none;
z-index: 1;
}
@media only screen {
.minicard .handle {
display: block;
}
}
.minicard .handle .fa-arrows {
font-size: 20px;
.minicard .handle .drag-handle {
font-size: clamp(16px, 3vw, 20px);
color: #ccc;
display: inline-block;
width: 1.4em;
text-align: center;
}
.minicard .minicard-title {
margin-right: 1.5vw;
}
.minicard .minicard-title .card-number {
color: #b3b3b3;
display: inline-block;
margin-right: 5px;
margin-right: 0.7vw;
}
@media only screen {
.minicard .minicard-title p:last-child {
@@ -173,20 +180,152 @@
.minicard .minicard-title .viewer {
display: block;
word-wrap: break-word;
max-width: 230px;
}
}
.minicard .dates {
display: flex;
flex-direction: row;
flex-wrap: wrap;
position: relative;
z-index: 5;
margin-right: 6vw;
clear: both;
}
.minicard .date {
margin-right: 3px;
margin-right: 0.4vw;
}
/* Unicode icons for minicard dates - matching cardDate.css */
.minicard .card-date.end-date time::before {
content: "🏁"; /* Finish flag - represents end/completion */
}
.minicard .card-date.due-date time::before {
content: "⏰"; /* Alarm clock - represents due/deadline */
}
.minicard .card-date.start-date time::before {
content: "🚀"; /* Rocket - represents start/launch */
}
.minicard .card-date.received-date time::before {
content: "📥"; /* Inbox tray - represents received/incoming */
}
.minicard .card-date time::before {
font-size: inherit;
margin-right: 0.3em;
display: inline-block;
}
/* Date type specific colors for minicards - matching cardDate.css */
.minicard .card-date.received-date {
background-color: #dbdbdb; /* Grey for received - same as base card-date */
}
.minicard .card-date.received-date:hover,
.minicard .card-date.received-date.is-active {
background-color: #b3b3b3;
}
.minicard .card-date.start-date {
background-color: #90ee90; /* Light green for start */
color: #000; /* Black text for start */
}
.minicard .card-date.start-date:hover,
.minicard .card-date.start-date.is-active {
background-color: #7dd87d;
}
.minicard .card-date.due-date {
background-color: #ffd700; /* Yellow for due */
color: #000; /* Black text for due */
}
.minicard .card-date.due-date:hover,
.minicard .card-date.due-date.is-active {
background-color: #e6c200;
}
.minicard .card-date.end-date {
background-color: #ffb3b3; /* Light red for end */
color: #000; /* Black text for end */
}
.minicard .card-date.end-date:hover,
.minicard .card-date.end-date.is-active {
background-color: #ff9999;
}
/* Date status colors for minicards - matching cardDate.css */
.minicard .card-date.overdue {
background-color: #ff4444 !important; /* Red for overdue */
color: #fff !important;
}
.minicard .card-date.overdue:hover,
.minicard .card-date.overdue.is-active {
background-color: #cc3333 !important;
}
.minicard .card-date.due-soon {
background-color: #ffaa00 !important; /* Amber for due soon */
color: #000 !important;
}
.minicard .card-date.due-soon:hover,
.minicard .card-date.due-soon.is-active {
background-color: #e69900 !important;
}
.minicard .card-date.not-due {
/* No special background - uses default date type colors */
}
.minicard .card-date.current {
background-color: #5ba639 !important; /* Green for current/active */
color: #fff !important;
}
.minicard .card-date.current:hover,
.minicard .card-date.current.is-active {
background-color: #46802c !important;
}
.minicard .card-date.completed {
background-color: #90ee90 !important; /* Light green for completed */
color: #000 !important;
}
.minicard .card-date.completed:hover,
.minicard .card-date.completed.is-active {
background-color: #7dd87d !important;
}
.minicard .card-date.completed-early {
background-color: #4caf50 !important; /* Green for completed early */
color: #fff !important;
}
.minicard .card-date.completed-early:hover,
.minicard .card-date.completed-early.is-active {
background-color: #45a049 !important;
}
.minicard .card-date.completed-late {
background-color: #ff9800 !important; /* Orange for completed late */
color: #fff !important;
}
.minicard .card-date.completed-late:hover,
.minicard .card-date.completed-late.is-active {
background-color: #f57c00 !important;
}
.minicard .card-date.completed-on-time {
background-color: #2196f3 !important; /* Blue for completed on time */
color: #fff !important;
}
.minicard .card-date.completed-on-time:hover,
.minicard .card-date.completed-on-time.is-active {
background-color: #1976d2 !important;
}
.minicard .badges {
float: left;
margin-top: 7px;
margin-top: 8px;
color: #808080;
}
.minicard .badges:empty {
@@ -194,14 +333,14 @@
}
.minicard .badges .badge {
float: left;
margin-right: 11px;
margin-bottom: 3px;
margin-right: 1.5vw;
margin-bottom: 4px;
font-size: 0.9em;
}
.minicard .badges .badge.is-finished {
background: #3cb500;
padding: 0px 3px;
border-radius: 3px;
padding: 0 0.4vw;
border-radius: 0.4vw;
color: #fff;
}
.minicard .badges .badge:last-of-type {
@@ -217,18 +356,18 @@
}
.minicard .badges .badge .badge-text {
font-size: 0.9em;
padding-left: 2px;
line-height: 14px;
padding-left: 0.3vw;
line-height: 1.2;
}
.minicard .badges .badge .check-list-text {
padding-left: 0px;
line-height: 12px;
line-height: 1.1;
}
.minicard .minicard-members,
.minicard .minicard-assignees,
.minicard .minicard-creator {
float: right;
margin-left: 5px;
margin-left: 0.7vw;
margin-bottom: 4px;
}
.minicard .minicard-members .member,
@@ -236,8 +375,8 @@
.minicard .minicard-creator .member {
float: right;
border-radius: 50%;
height: 28px;
width: 28px;
height: clamp(24px, 3.5vw, 32px);
width: clamp(24px, 3.5vw, 32px);
margin-bottom: 4px;
}
.minicard .minicard-members .assignee,
@@ -245,13 +384,13 @@
.minicard .minicard-creator .assignee {
float: right;
border-radius: 50%;
height: 28px;
width: 28px;
height: clamp(24px, 3.5vw, 32px);
width: clamp(24px, 3.5vw, 32px);
}
.minicard .minicard-members + .badges,
.minicard .minicard-assignees + .badges,
.minicard .minicard-creator + .badges {
margin-top: 5px;
margin-top: 6px;
}
.minicard .minicard-assignees {
border-bottom: 1px solid #f00;
@@ -264,13 +403,13 @@
display: none;
}
.minicard .minicard-description {
padding: 6px 0 0 8px;
padding: 8px 0 0 1vw;
color: #000;
background-color: #eee;
width: 100%;
margin-bottom: 2px;
margin-left: -4px;
border-radius: 3px;
margin-bottom: 3px;
margin-left: -0.5vw;
border-radius: 0.4vw;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
@@ -278,7 +417,7 @@
-webkit-box-orient: vertical;
}
.minicard.minicard-composer {
margin-bottom: 10px;
margin-bottom: 12px;
}
.minicard.minicard-composer textarea.minicard-composer-textarea,
.minicard.minicard-composer textarea.minicard-composer-textarea:focus {
@@ -289,8 +428,8 @@
height: auto;
margin: 0;
padding: 0;
max-height: 162px;
min-height: 36px;
max-height: 200px;
min-height: 50px;
margin-bottom: 20px;
overflow-y: auto;
}
@@ -596,3 +735,134 @@
.text-green {
color: #008000;
}
/* Drag and drop file upload visual feedback */
.minicard.is-dragging-over {
border: 2px dashed #0079bf;
background-color: #e3f2fd !important;
transform: scale(1.02);
transition: all 0.2s ease;
}
/* List name display on minicard */
.minicard-list-name {
font-size: 0.75em;
color: #8c8c8c;
margin-top: 2px;
display: flex;
align-items: center;
gap: 0.3vw;
}
/* Checklist display on minicard */
.minicard-checklist {
width: 100%;
box-sizing: border-box;
clear: both;
margin-top: 2px;
margin-bottom: 5px;
padding: 3px 0.5vw;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 0.3vw;
border: 1px solid #e0e0e0;
}
.minicard-checklist .checklist-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 3px;
}
.minicard-checklist .checklist-title {
font-size: 0.8em;
font-weight: bold;
color: #4d4d4d;
flex: 1;
margin: 0;
}
.minicard-checklist .checklist-menu {
font-size: 1.2em;
color: #666;
cursor: pointer;
padding: 0 0.3vw;
border-radius: 0.2vw;
transition: background-color 0.2s;
}
.minicard-checklist .checklist-menu:hover {
background-color: rgba(0, 0, 0, 0.1);
}
.minicard-checklist .checklist-item {
font-size: 0.75em;
color: #666;
margin-bottom: 2px;
display: flex;
align-items: flex-start;
gap: 0.3vw;
line-height: 1.2;
cursor: pointer;
padding: 2px 0;
border-radius: 0.2vw;
transition: background-color 0.2s;
}
.minicard-checklist .checklist-item:hover {
background-color: rgba(0, 0, 0, 0.05);
}
.minicard-checklist .checklist-item.is-checked {
text-decoration: line-through;
color: #999;
}
.minicard-checklist .checklist-item .check-box-unicode {
flex-shrink: 0;
font-size: 0.8em;
margin-top: 1px;
transition: transform 0.2s;
}
.minicard-checklist .checklist-item:hover .check-box-unicode {
transform: scale(1.1);
}
.minicard-checklist .checklist-item .item-title {
flex: 1;
word-wrap: break-word;
overflow-wrap: break-word;
}
/* Trello-style "mark complete" toggle, left of the minicard title */
.minicard-title .minicard-complete-toggle {
display: inline-flex;
align-items: center;
vertical-align: middle;
/* Nudge down so the checkmark sits at the vertical middle of the title text
(the checked materialCheckBox is shifted up 4px by its own positioning). */
position: relative;
top: 4px;
margin-right: 6px;
cursor: pointer;
}
/* Sticker icon highlight styles (used instead of colour): taco pack => underline,
pete pack => round (ring around the icon). Icon keeps its normal colour. */
.minicard-sticker i.sticker-underline {
border-bottom: 2px solid currentColor;
padding-bottom: 1px;
line-height: 1;
}
.minicard-sticker i.sticker-round {
border: 1px solid currentColor;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.6em;
height: 1.6em;
line-height: 1;
box-sizing: border-box;
}
+133 -110
View File
@@ -1,37 +1,62 @@
template(name="minicard")
.minicard(
.minicard.nodragscroll(
class="{{#if isLinkedCard}}linked-card{{/if}}"
class="{{#if isLinkedBoard}}linked-board{{/if}}"
class="{{#if colorClass}}minicard-{{colorClass}}{{/if}}")
if canModifyCard
if canMoveCard
if isTouchScreenOrShowDesktopDragHandles
a.fa.fa-navicon.minicard-details-menu-with-handle.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
.handle
.fa.fa-arrows
else
a.fa.fa-navicon.minicard-details-menu.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
i.fa.fa-arrows
if canModifyCard
a.minicard-details-menu-with-handle.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
i.fa.fa-bars
.dates
if getReceived
unless getStart
unless getDue
unless getEnd
.date
+minicardReceivedDate
if getStart
.date
+minicardStartDate
if getDue
.date
+minicardDueDate
if getEnd
+minicardEndDate
if showReceived
if getReceived
.date
+minicardReceivedDate
if showStart
if getStart
.date
+minicardStartDate
if showDue
if getDue
.date(class="{{#if getDueComplete}}due-complete{{/if}}")
+minicardDueDate
if showEnd
if getEnd
+minicardEndDate
if getSpentTime
.date
+cardSpentTime
if cover
if currentBoard.allowsCoverAttachmentOnMinicard
.minicard-cover(style="background-image: url('{{cover.link 'original'}}?dummyReloadAfterSessionEstablished={{sess}}');")
// Upload progress indicator for drag-and-drop uploads
if hasActiveUploads
.minicard-upload-progress
.upload-progress-header
i.fa.fa-upload
span {{_ 'uploading-files'}} ({{uploadCount}})
each uploads
.upload-progress-item(class="{{#if $eq status 'error'}}upload-error{{/if}}")
.upload-progress-filename {{file.name}}
.upload-progress-bar
.upload-progress-fill(style="width: {{progress}}%")
if $eq status 'error'
.upload-progress-error
i.fa.fa-warning
span {{_ 'upload-failed'}}
else if $eq status 'completed'
.upload-progress-success
i.fa.fa-check
span {{_ 'upload-completed'}}
.minicard-title
if canModifyCard
a.minicard-complete-toggle.js-toggle-card-complete(title="{{#if getDueComplete}}{{_ 'card-mark-incomplete'}}{{else}}{{_ 'card-mark-complete'}}{{/if}}")
.materialCheckBox(class="{{#if getDueComplete}}is-checked{{/if}}")
if $eq 'prefix-with-full-path' currentBoard.presentParentTask
.parent-prefix
| {{ parentString ' > ' }}
@@ -40,32 +65,30 @@ template(name="minicard")
| {{ parentCardName }}
if isLinkedBoard
a.js-linked-link
span.linked-icon.fa.fa-folder
span.linked-icon
i.fa.fa-folder
else if isLinkedCard
a.js-linked-link
span.linked-icon.fa.fa-id-card
span.linked-icon
i.fa.fa-id-card
if getArchived
span.linked-icon.linked-archived.fa.fa-archive
span.linked-icon.linked-archived
i.fa.fa-archive
+viewer
if currentBoard.allowsCardNumber
if showCardNumber
span.card-number
| ##{getCardNumber}
| ##{getCardNumber} &nbsp;
= getTitle
if $eq 'subtext-with-full-path' currentBoard.presentParentTask
.parent-subtext
| {{ parentString ' > ' }}
if $eq 'subtext-with-parent' currentBoard.presentParentTask
.parent-subtext
| {{ parentCardName }}
if labels
.minicard-labels(class="{{#if hiddenMinicardLabelText}}minicard-labels-no-text{{/if}}")
each labels
unless hiddenMinicardLabelText
span.js-card-label.card-label(class="card-label-{{color}}" title=name)
+viewer
= name
if hiddenMinicardLabelText
.minicard-label(class="card-label-{{color}}" title="{{name}}")
if showLabels
if labels
.minicard-labels(class="{{#if hiddenMinicardLabelText}}minicard-labels-no-text{{/if}}")
each labels
unless hiddenMinicardLabelText
span.js-card-label.card-label(class="card-label-{{color}}" title=name)
+viewer
= name
if hiddenMinicardLabelText
.minicard-label(class="card-label-{{color}}" title="{{name}}")
.minicard-custom-fields
each customFieldsWD
@@ -112,12 +135,6 @@ template(name="minicard")
+viewer
= trueValue
.card-checklist-attachmentGalleries
.card-checklist-attachmentGallery.card-checklists
if currentBoard.allowsChecklists
//hr
//+checklists(cardId=_id showAtMinicard=true)
if showAssignee
if getAssignees
.minicard-assignees.js-minicard-assignees
@@ -134,100 +151,106 @@ template(name="minicard")
.minicard-creator
+userAvatar(userId=this.userId noRemove=true)
if shouldShowChecklistAtMinicard
each shouldShowChecklistAtMinicard
+minicardChecklist(checklist=. card=..)
.badges
if canModifyCard
if comments.length
.badge(title="{{_ 'card-comments-title' comments.length }}")
span.badge-icon.fa.fa-comment-o.badge-comment.badge-text
= ' '
= comments.length
if stickers.length
.badge.badge-state-image-only.minicard-stickers
each stickers
span.badge-icon.minicard-sticker(title="{{#if name}}{{name}}{{else}}{{icon}}{{/if}}")
i.fa(class="fa-{{icon}} {{#if highlight}}sticker-{{highlight}}{{/if}}")
if comments.length
.badge(title="{{_ 'card-comments-title' comments.length }}")
span.badge-icon.badge-comment.badge-text
i.fa.fa-comment-o
= ' '
= comments.length
//span.badge-comment.badge-text
//| {{_ 'comment'}}
//|
{{_ 'comment'}}
if getDescription
unless currentBoard.allowsDescriptionTextOnMinicard
.badge.badge-state-image-only(title=getDescription)
span.badge-icon.fa.fa-align-left
span.badge-icon
i.fa.fa-file-text-o
if getVoteQuestion
.badge.badge-state-image-only(title=getVoteQuestion)
span.badge-icon.fa.fa-thumbs-up(class="{{#if voteState}}text-green{{/if}}")
span.badge-icon(class="{{#if voteState}}text-green{{/if}}")
i.fa.fa-thumbs-up
span.badge-text {{ voteCountPositive }}
span.badge-icon.fa.fa-thumbs-down(class="{{#if $eq voteState false}}text-red{{/if}}")
span.badge-icon(class="{{#if $eq voteState false}}text-red{{/if}}")
i.fa.fa-thumbs-down
span.badge-text {{ voteCountNegative }}
if getPokerQuestion
.badge.badge-state-image-only(title=getPokerQuestion)
span.badge-icon.fa.fa-check(class="{{#if pokerState}}text-green{{/if}}")
span.badge-icon(class="{{#if pokerState}}text-green{{/if}}")
i.fa.fa-check-square
if expiredPoker
span.badge-text {{ getPokerEstimation }}
if attachments.length
if currentBoard.allowsBadgeAttachmentOnMinicard
.badge
span.badge-icon.fa.fa-paperclip
span.badge-icon
i.fa.fa-paperclip
span.badge-text= attachments.length
if checklists.length
.badge(class="{{#if checklistFinished}}is-finished{{/if}}")
span.badge-icon.fa.fa-check-square-o
span.badge-text.check-list-text {{checklistFinishedCount}}/{{checklistItemCount}}
if allSubtasks.count
.badge
span.badge-icon.fa.fa-sitemap
span.badge-text.check-list-text {{subtasksFinishedCount}}/{{allSubtasksCount}}
//{{subtasksFinishedCount}}/{{subtasksCount}} does not work because when a subtaks is archived, the count goes down
if showSubtasks
if allSubtasks.count
.badge
span.badge-icon
i.fa.fa-globe
span.badge-text.check-list-text {{subtasksFinishedCount}}/{{allSubtasksCount}}
//{{subtasksFinishedCount}}/{{subtasksCount}} does not work because when a subtaks is archived, the count goes down
if currentBoard.allowsCardSortingByNumber
if currentBoard.allowsCardSortingByNumberOnMinicard
.badge
span.badge-icon.fa.fa-sort
span.badge-icon
i.fa.fa-sort-numeric-asc
span.badge-text.check-list-sort {{ sort }}
if currentBoard.allowsDescriptionTextOnMinicard
if getDescription
.minicard-description
+viewer
| {{ getDescription }}
if shouldShowListOnMinicard
.minicard-list-name
i.fa.fa-list
| {{ listName }}
if $eq 'subtext-with-full-path' currentBoard.presentParentTask
.parent-subtext
| {{ parentString ' > ' }}
if $eq 'subtext-with-parent' currentBoard.presentParentTask
.parent-subtext
| {{ parentCardName }}
template(name="editCardSortOrderPopup")
input.js-edit-card-sort-popup(type='text' autofocus value=sort dir="auto")
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-sort-popup(type="submit") {{_ 'save'}}
template(name="minicardDetailsActionsPopup")
ul.pop-over-list
template(name="minicardChecklist")
.minicard-checklist
.checklist-header
if canModifyCard
+inlinedForm(classNames="js-edit-checklist-title" checklist=checklist)
+editChecklistForm(checklist=checklist)
else
h4.checklist-title.js-open-inlined-form.is-editable= checklist.title
else
h4.checklist-title= checklist.title
if canModifyCard
a.checklist-menu.js-open-checklist-menu(title="{{_ 'checklistActionsPopup-title'}}")
i.fa.fa-bars
.checklist-items.js-checklist-items
each visibleItems
+inlinedForm(classNames="js-edit-checklist-item" item=. checklist=checklist)
+editChecklistItemForm(type='item' item=. checklist=checklist)
else
+checklistItemDetail(item=. checklist=checklist card=card)
if canModifyCard
li
a.js-move-card
i.fa.fa-arrow-right
| {{_ 'moveCardPopup-title'}}
li
a.js-copy-card
i.fa.fa-copy
| {{_ 'copyCardPopup-title'}}
hr
li
a.js-archive
i.fa.fa-arrow-right
i.fa.fa-archive
| {{_ 'archive-card'}}
hr
li
a.js-move-card-to-top
i.fa.fa-arrow-up
| {{_ 'moveCardToTop-title'}}
li
a.js-move-card-to-bottom
i.fa.fa-arrow-down
| {{_ 'moveCardToBottom-title'}}
hr
li
a.js-add-labels
i.fa.fa-tags
| {{_ 'card-edit-labels'}}
li
a.js-due-date
i.fa.fa-sign-in
| {{_ 'editCardDueDatePopup-title'}}
li
a.js-set-card-color
i.fa.fa-paint-brush
| {{_ 'setCardColorPopup-title'}}
li
a.js-link
i.fa.fa-link
| {{_ 'link-card'}}
+inlinedForm(autoclose=false classNames="js-add-checklist-item" checklist=checklist)
+addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=false)
else
a.add-checklist-item.js-open-inlined-form(title="{{_ 'add-checklist-item'}}")
i.fa.fa-plus
+318 -125
View File
@@ -1,18 +1,29 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { TAPi18n } from '/imports/i18n';
import { CustomFieldStringTemplate } from '/client/lib/customFields'
import { CustomFieldStringTemplate } from '/client/lib/customFields';
import { handleFileUpload } from './attachments';
import uploadProgressManager from '../../lib/uploadProgressManager';
import { Utils } from '/client/lib/utils';
import ChecklistItems from '/models/checklistItems';
function getMinicardFlag(board, onMinicardField, legacyField, defaultValue) {
if (!board) return false;
if (board[onMinicardField] !== null && board[onMinicardField] !== undefined) {
return board[onMinicardField];
}
if (legacyField && board[legacyField] !== null && board[legacyField] !== undefined) {
return board[legacyField];
}
return defaultValue;
}
// Template.cards.events({
// 'click .member': Popup.open('cardMember')
// });
BlazeComponent.extendComponent({
template() {
return 'minicard';
},
Template.minicard.helpers({
formattedCurrencyCustomFieldValue(definition) {
const customField = this.data()
const customField = this
.customFieldsWD()
.find(f => f._id === definition._id);
const customFieldTrueValue =
@@ -26,7 +37,7 @@ BlazeComponent.extendComponent({
},
formattedStringtemplateCustomFieldValue(definition) {
const customField = this.data()
const customField = this
.customFieldsWD()
.find(f => f._id === definition._id);
@@ -39,85 +50,55 @@ BlazeComponent.extendComponent({
showCreatorOnMinicard() {
// cache "board" to reduce the mini-mongodb access
const board = this.data().board();
const board = this.board();
let ret = false;
if (board) {
ret =
board.allowsCreatorOnMinicard === null ||
board.allowsCreatorOnMinicard === undefined ||
board.allowsCreatorOnMinicard
;
ret = board.allowsCreatorOnMinicard ?? false;
}
return ret;
},
isWatching() {
return this.findWatcher(Meteor.userId());
},
showMembers() {
// cache "board" to reduce the mini-mongodb access
const board = this.data().board();
let ret = false;
if (board) {
ret =
board.allowsMembers === null ||
board.allowsMembers === undefined ||
board.allowsMembers
;
}
return ret;
const board = this.board();
return getMinicardFlag(board, 'allowsMembersOnMinicard', 'allowsMembers', true);
},
showAssignee() {
// cache "board" to reduce the mini-mongodb access
const board = this.data().board();
let ret = false;
if (board) {
ret =
board.allowsAssignee === null ||
board.allowsAssignee === undefined ||
board.allowsAssignee
;
}
return ret;
const board = this.board();
return getMinicardFlag(board, 'allowsAssigneeOnMinicard', 'allowsAssignee', true);
},
showReceived() {
const board = this.board();
return getMinicardFlag(board, 'allowsReceivedDateOnMinicard', 'allowsReceivedDate', true);
},
showStart() {
const board = this.board();
return getMinicardFlag(board, 'allowsStartDateOnMinicard', 'allowsStartDate', true);
},
showDue() {
const board = this.board();
return getMinicardFlag(board, 'allowsDueDateOnMinicard', 'allowsDueDate', true);
},
showEnd() {
const board = this.board();
return getMinicardFlag(board, 'allowsEndDateOnMinicard', 'allowsEndDate', true);
},
showLabels() {
const board = this.board();
return getMinicardFlag(board, 'allowsLabelsOnMinicard', 'allowsLabels', true);
},
showCardNumber() {
const board = this.board();
return getMinicardFlag(board, 'allowsCardNumberOnMinicard', 'allowsCardNumber', false);
},
showSubtasks() {
const board = this.board();
return getMinicardFlag(board, 'allowsSubtasksOnMinicard', 'allowsSubtasks', true);
},
/** opens the card label popup only if clicked onto a label
* <li> this is necessary to have the data context of the minicard.
* if .js-card-label is used at click event, then only the data context of the label itself is available at this.currentData()
*/
cardLabelsPopup(event) {
if (this.find('.js-card-label:hover')) {
Popup.open("cardLabels")(event, {dataContextIfCurrentDataIsUndefined: this.currentData()});
}
},
events() {
return [
{
'click .minicard-checklists'() {
// Prevents clicking checklist at minicard from opening card details,
// while still allowing checking checlist items.
event.preventDefault();
},
'click .js-linked-link'() {
if (this.data().isLinkedCard()) Utils.goCardId(this.data().linkedId);
else if (this.data().isLinkedBoard())
Utils.goBoardId(this.data().linkedId);
},
'click .js-toggle-minicard-label-text'() {
if (window.localStorage.getItem('hiddenMinicardLabelText')) {
window.localStorage.removeItem('hiddenMinicardLabelText'); //true
} else {
window.localStorage.setItem('hiddenMinicardLabelText', 'true'); //true
}
},
'click span.badge-icon.fa.fa-sort, click span.badge-text.check-list-sort' : Popup.open("editCardSortOrder"),
'click .minicard-labels' : this.cardLabelsPopup,
'click .js-open-minicard-details-menu': Popup.open('minicardDetailsActions'),
}
];
},
}).register('minicard');
Template.minicard.helpers({
hiddenMinicardLabelText() {
const currentUser = ReactiveCache.getCurrentUser();
if (currentUser) {
@@ -128,63 +109,275 @@ Template.minicard.helpers({
return false;
}
},
cover() {
if (!this.coverId) return null;
const attachment = ReactiveCache.getAttachment(this.coverId);
if (!attachment) return null;
const coverLink = typeof attachment.link === 'function' ? attachment.link() : '';
if (!coverLink) return null;
return {
link() {
return coverLink;
},
};
},
// XXX resolve this nasty hack for https://github.com/veliovgroup/Meteor-Files/issues/763
sess() {
return Meteor.connection && Meteor.connection._lastSessionId
? Meteor.connection._lastSessionId
: null;
},
});
// Upload progress helpers
hasActiveUploads() {
return uploadProgressManager.hasActiveUploads(this._id);
},
uploads() {
return uploadProgressManager.getUploadsForCard(this._id);
},
uploadCount() {
return uploadProgressManager.getUploadCountForCard(this._id);
},
listName() {
const list = this.list();
return list ? list.title : '';
},
BlazeComponent.extendComponent({
events() {
return [
{
'keydown input.js-edit-card-sort-popup'(evt) {
// enter = save
if (evt.keyCode === 13) {
this.find('button[type=submit]').click();
}
},
'click button.js-submit-edit-card-sort-popup'(event) {
// save button pressed
event.preventDefault();
const sort = this.$('.js-edit-card-sort-popup')[0]
.value
.trim();
if (!Number.isNaN(sort)) {
let card = this.data();
card.move(card.boardId, card.swimlaneId, card.listId, sort);
Popup.back();
}
},
shouldShowListOnMinicard() {
// Show list name if either:
// 1. Board-wide setting is enabled, OR
// 2. This specific card has the setting enabled
const currentBoard = this.board();
if (!currentBoard) return false;
return currentBoard.allowsShowListsOnMinicard || this.showListOnMinicard;
},
shouldShowChecklistAtMinicard() {
// Return checklists that should be shown on minicard
const currentBoard = this.board();
if (!currentBoard) return [];
const checklists = this.checklists();
const visibleChecklists = [];
checklists.forEach(checklist => {
// Show checklist if either:
// 1. Board-wide setting is enabled, OR
// 2. This specific checklist has the setting enabled
if (currentBoard.allowsChecklistAtMinicard || checklist.showChecklistAtMinicard) {
visibleChecklists.push(checklist);
}
]
}
}).register('editCardSortOrderPopup');
});
Template.minicardDetailsActionsPopup.events({
'click .js-due-date': Popup.open('editCardDueDate'),
'click .js-move-card': Popup.open('moveCard'),
'click .js-copy-card': Popup.open('copyCard'),
'click .js-set-card-color': Popup.open('setCardColor'),
'click .js-add-labels': Popup.open('cardLabels'),
'click .js-link': Popup.open('linkCard'),
'click .js-move-card-to-top'(event) {
event.preventDefault();
const minOrder = this.getMinSort();
this.move(this.boardId, this.swimlaneId, this.listId, minOrder - 1);
Popup.back();
},
'click .js-move-card-to-bottom'(event) {
event.preventDefault();
const maxOrder = this.getMaxSort();
this.move(this.boardId, this.swimlaneId, this.listId, maxOrder + 1);
Popup.back();
},
'click .js-archive': Popup.afterConfirm('cardArchive', function () {
Popup.close();
this.archive();
Utils.goBoardId(this.boardId);
}),
return visibleChecklists;
}
});
Template.minicard.events({
'click .js-linked-link'() {
if (this.isLinkedCard()) Utils.goCardId(this.linkedId);
else if (this.isLinkedBoard())
Utils.goBoardId(this.linkedId);
},
'click .js-toggle-card-complete'(event) {
// Trello-style "mark complete" toggle (left of the title). Don't let the
// click open the card.
event.preventDefault();
event.stopPropagation();
if (!Utils.canModifyCard()) {
return;
}
this.setDueComplete(!this.getDueComplete());
},
'click .js-toggle-minicard-label-text'() {
if (window.localStorage.getItem('hiddenMinicardLabelText')) {
window.localStorage.removeItem('hiddenMinicardLabelText'); //true
} else {
window.localStorage.setItem('hiddenMinicardLabelText', 'true'); //true
}
},
'click span.badge-icon.fa.fa-sort, click span.badge-text.check-list-sort' : Popup.open("editCardSortOrder"),
'click .minicard-labels'(event, tpl) {
if (tpl.find('.js-card-label:hover')) {
Popup.open("cardLabels")(event, {dataContextIfCurrentDataIsUndefined: Template.currentData()});
}
},
'click .js-open-minicard-details-menu'(event, tpl) {
event.preventDefault();
event.stopPropagation();
const card = Template.currentData();
Popup.open('cardDetailsActions').call({currentData: () => card}, event);
},
// Drag and drop file upload handlers
'dragover .minicard'(event) {
// Only prevent default for file drags to avoid interfering with sortable
const dataTransfer = event.originalEvent.dataTransfer;
if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) {
event.preventDefault();
event.stopPropagation();
}
},
'dragenter .minicard'(event) {
const dataTransfer = event.originalEvent.dataTransfer;
if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) {
event.preventDefault();
event.stopPropagation();
const card = this;
const board = card.board();
// Only allow drag-and-drop if user can modify card and board allows attachments
if (Utils.canModifyCard() && board && board.allowsAttachments) {
$(event.currentTarget).addClass('is-dragging-over');
}
}
},
'dragleave .minicard'(event) {
const dataTransfer = event.originalEvent.dataTransfer;
if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) {
event.preventDefault();
event.stopPropagation();
$(event.currentTarget).removeClass('is-dragging-over');
}
},
'drop .minicard'(event) {
const dataTransfer = event.originalEvent.dataTransfer;
if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) {
event.preventDefault();
event.stopPropagation();
$(event.currentTarget).removeClass('is-dragging-over');
const card = this;
const board = card.board();
// Check permissions
if (!Utils.canModifyCard() || !board || !board.allowsAttachments) {
return;
}
// Check if this is a file drop (not a card reorder)
if (!dataTransfer.files || dataTransfer.files.length === 0) {
return;
}
const files = dataTransfer.files;
if (files && files.length > 0) {
handleFileUpload(card, files);
}
}
},
});
Template.minicardChecklist.helpers({
visibleItems() {
const checklist = this.checklist || this;
const items = checklist.items();
return items.filter(item => {
// Hide finished items if hideCheckedChecklistItems is true
if (item.isFinished && checklist.hideCheckedChecklistItems) {
return false;
}
// Hide all items if hideAllChecklistItems is true
if (checklist.hideAllChecklistItems) {
return false;
}
return true;
});
},
});
Template.minicardChecklist.events({
'click .js-convert-checklist-item-to-card'(event) {
event.stopPropagation();
const formData = Blaze.getData(event.currentTarget);
if (!formData) return;
const context = { currentData: () => formData };
Popup.open('convertChecklistItemToCard').call(context, event);
},
'click .js-open-checklist-menu'(event) {
const data = Template.currentData();
const checklist = data.checklist || data;
const card = data.card || this;
const context = { currentData: () => ({ checklist, card }) };
Popup.open('checklistActions').call(context, event);
},
'click .js-checklist-item .check-box-container'(event) {
event.stopPropagation();
event.preventDefault();
const data = Blaze.getData(event.target) || Blaze.getData(event.currentTarget);
const item = data && data.item;
if (item && item._id) {
item.toggleItem();
}
},
'click .js-submit-edit-checklist-item-form'(event) {
event.preventDefault();
event.stopPropagation();
const $btn = $(event.currentTarget);
const $form = $btn.closest('form');
const textarea = $form.find('textarea.js-edit-checklist-item')[0];
if (!textarea) return;
const title = textarea.value.trim();
if (!title) return;
const formData = Blaze.getData($form[0]);
if (formData && formData.item && formData.item._id) {
formData.item.setTitle(title);
} else if (formData && formData.checklist && formData.checklist._id) {
formData.checklist.setTitle(title);
}
$form.find('.js-close-inlined-form').trigger('click');
},
'submit .js-add-checklist-item'(event, tpl) {
event.preventDefault();
const textarea = tpl.find('textarea.js-add-checklist-item');
if (!textarea) return;
const title = textarea.value.trim();
const data = Template.currentData() || {};
const checklist = data.checklist;
if (!checklist || !title) return;
const items = checklist.items();
const lastItem = items[items.length - 1] || null;
const sortIndex = Utils.calculateIndexData(lastItem, null).base;
ChecklistItems.insert({
title,
checklistId: checklist._id,
cardId: checklist.cardId,
sort: sortIndex,
});
textarea.value = '';
textarea.focus();
},
'click .js-delete-checklist-item': Popup.afterConfirm('checklistItemDelete', function () {
Popup.back();
const item = this && this.item ? this.item : this;
if (item && item._id) {
ChecklistItems.remove(item._id);
}
}),
'keydown textarea.js-add-checklist-item'(event) {
if (event.keyCode === 13 && !event.shiftKey) {
event.preventDefault();
const $form = $(event.currentTarget).closest('form');
$form.find('button[type=submit]').click();
}
},
});
Template.editCardSortOrderPopup.events({
'keydown input.js-edit-card-sort-popup'(evt, tpl) {
// enter = save
if (evt.keyCode === 13) {
tpl.find('button[type=submit]').click();
}
},
'click button.js-submit-edit-card-sort-popup'(event, tpl) {
// save button pressed
event.preventDefault();
const sort = tpl.$('.js-edit-card-sort-popup')[0]
.value
.trim();
if (!Number.isNaN(sort)) {
let card = this;
card.move(card.boardId, card.swimlaneId, card.listId, sort);
Popup.back();
}
},
});
@@ -0,0 +1,3 @@
.minicard-title .minicard-complete-toggle {
display: none;
}
+3 -3
View File
@@ -11,7 +11,7 @@ template(name="resultCard")
= getBoard.title
else
.broken-cards-null
| NULL
| {{_ 'no-name'}}
if getBoard.archived
i.fa.fa-archive
li.result-card-context.result-card-context-separator
@@ -25,7 +25,7 @@ template(name="resultCard")
= getSwimlane.title
else
.broken-cards-null
| NULL
| {{_ 'no-name'}}
if getSwimlane.archived
i.fa.fa-archive
li.result-card-context.result-card-context-separator
@@ -39,6 +39,6 @@ template(name="resultCard")
= getList.title
else
.broken-cards-null
| NULL
| {{_ 'no-name'}}
if getList.archived
i.fa.fa-archive
+54 -22
View File
@@ -1,35 +1,67 @@
import { ReactiveCache } from '/imports/reactiveCache';
Template.resultCard.helpers({
userId() {
return Meteor.userId();
},
getBoard() {
const card = Template.currentData();
try {
if (card && card.boardId) {
const board = ReactiveCache.getBoard(card.boardId);
return board || null;
}
} catch (err) {
// Silently handle errors
}
return null;
},
getSwimlane() {
const card = Template.currentData();
try {
if (card && card.swimlaneId) {
const swimlane = ReactiveCache.getSwimlane(card.swimlaneId);
return swimlane || null;
}
} catch (err) {
// Silently handle errors
}
return null;
},
getList() {
const card = Template.currentData();
try {
if (card && card.listId) {
const list = ReactiveCache.getList(card.listId);
return list || null;
}
} catch (err) {
// Silently handle errors
}
return null;
},
originRelativeUrl() {
const card = Template.currentData();
if (card && card.boardId && card._id) {
return `/board/${card.boardId}?cardId=${card._id}`;
}
return '#';
},
});
BlazeComponent.extendComponent({
clickOnMiniCard(evt) {
evt.preventDefault();
const this_ = this;
const cardId = this.currentData()._id;
const boardId = this.currentData().boardId;
Template.resultCard.events({
'click .js-minicard'(event) {
event.preventDefault();
const cardId = Template.currentData()._id;
const boardId = Template.currentData().boardId;
Meteor.subscribe('popupCardData', cardId, {
onReady() {
Session.set('popupCardId', cardId);
Session.set('popupCardBoardId', boardId);
this_.cardDetailsPopup(evt);
if (!Popup.isOpen()) {
Popup.open("cardDetails")(event);
}
},
});
},
cardDetailsPopup(event) {
if (!Popup.isOpen()) {
Popup.open("cardDetails")(event);
}
},
events() {
return [
{
'click .js-minicard': this.clickOnMiniCard,
},
];
},
}).register('resultCard');
});
+46 -4
View File
@@ -15,7 +15,7 @@ textarea.js-edit-subtask-item {
color: #8c8c8c;
text-decoration: underline;
word-wrap: break-word;
float: right;
flex-shrink: 0;
padding-top: 6px;
}
.delete-text:hover,
@@ -24,8 +24,13 @@ textarea.js-edit-subtask-item {
.js-delete-subtask-item:hover {
color: inherit;
}
.subtask-title {
display: flex;
align-items: center;
width: 100%;
}
.subtask-title .checkbox {
float: left;
flex-shrink: 0;
width: 30px;
height: 30px;
font-size: 18px;
@@ -34,10 +39,12 @@ textarea.js-edit-subtask-item {
.subtask-title .title {
font-size: 18px;
line-height: 25px;
flex: 1;
order: 1;
}
.subtask-title .subtasks-stat {
margin: 0 0.5em;
float: right;
flex-shrink: 0;
padding-top: 6px;
}
.subtask-title .subtasks-stat.is-finished {
@@ -46,6 +53,9 @@ textarea.js-edit-subtask-item {
.subtask-title .js-delete-subtask {
margin: 0 0.5em;
}
.subtask-title .js-view-subtask {
margin: 0 0.5em;
}
.js-confirm-subtask-delete {
background-color: #f7f7f7;
position: absolute;
@@ -87,6 +97,15 @@ textarea.js-edit-subtask-item {
top: 0;
bottom: -600px;
right: 0;
z-index: 15;
}
/* Fix for mobile Safari: ensure this doesn't block card interaction */
@media screen and (max-width: 800px) {
#card-details-overlay {
z-index: 15;
pointer-events: none;
}
}
.subtasks {
background: #f7f7f7;
@@ -120,6 +139,9 @@ textarea.js-edit-subtask-item {
.subtasks-item:hover {
background-color: #ebebeb;
}
.subtasks-item .check-box-container {
padding-right: 10px;
}
.subtasks-item .check-box {
margin: 0.1em 0 0 0;
}
@@ -127,6 +149,25 @@ textarea.js-edit-subtask-item {
border-bottom: 2px solid #3cb500;
border-right: 2px solid #3cb500;
}
/* Unicode checkbox icons styling */
.subtasks-item .check-box-unicode {
font-size: 1.3em;
margin-right: 8px;
cursor: pointer;
display: inline-block;
vertical-align: middle;
line-height: 1;
}
/* Grey checkmarks when grey icons setting is enabled */
body.grey-icons-enabled .subtasks-item .check-box.is-checked {
border-bottom: 2px solid #7a7a7a;
border-right: 2px solid #7a7a7a;
}
body.grey-icons-enabled .subtasks-item .check-box-unicode {
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
opacity: 0.85;
}
.subtasks-item .item-title {
flex: 1;
padding-left: 10px;
@@ -147,6 +188,7 @@ textarea.js-edit-subtask-item {
display: inline-block;
}
.subtask-details-menu {
float: right;
flex-shrink: 0;
padding: 6px 10px 6px 10px;
order: 2;
}
+11 -6
View File
@@ -1,6 +1,6 @@
template(name="subtasks")
h3.card-details-item-title
i.fa.fa-sitemap
i.fa.fa-globe
| {{_ 'subtasks'}}
if currentUser.isBoardAdmin
if toggleDeleteDialog.get
@@ -40,7 +40,7 @@ template(name="addSubtaskItemForm")
textarea.js-add-subtask-item(rows='1' autofocus dir="auto")
.edit-controls.clearfix
button.primary.confirm.js-submit-add-subtask-item-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
a.fa.fa-times-thin.js-close-inlined-form(title="{{_ 'close-add-checklist-item'}}")
template(name="editSubtaskItemForm")
textarea.js-edit-subtask-item(rows='1' autofocus dir="auto")
@@ -50,8 +50,8 @@ template(name="editSubtaskItemForm")
= subtask.title
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-subtask-item-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
span(title=createdAt) {{ moment createdAt }}
a.fa.fa-times-thin.js-close-inlined-form(title="{{_ 'close-edit-checklist-item'}}")
span(title=createdAt) {{ displayDate createdAt }}
if canModifyCard
if currentUser.isBoardAdmin
a.js-delete-subtask-item {{_ "delete"}}...
@@ -74,12 +74,13 @@ template(name="subtasksItems")
template(name='subtaskItemDetail')
.js-subtasks-item.subtasks-item
if canModifyCard
.check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
.check-box-container
.check-box.materialCheckBox(class="{{#if item.isFinished}}is-checked{{/if}}")
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
+viewer
= item.title
else
.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
.materialCheckBox(class="{{#if item.isFinished}}is-checked{{/if}}")
.item-title(class="{{#if item.isFinished }}is-checked{{/if}}")
+viewer
= item.title
@@ -94,6 +95,10 @@ template(name="subtaskActionsPopup")
a.js-view-subtask(title="{{ subtask.title }}")
i.fa.fa-eye
| {{_ "view-it"}}
li
a.js-go-to-subtask-board
i.fa.fa-folder
| {{_ "go-to-board"}}
if currentUser.isBoardAdmin
a.js-delete-subtask.delete-subtask
i.fa.fa-trash
+100 -75
View File
@@ -1,16 +1,35 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
import Cards from '/models/cards';
import { Filter } from '/client/lib/filter';
BlazeComponent.extendComponent({
addSubtask(event) {
Template.subtasks.events({
'click .js-open-subtask-details-menu'(event) {
// Close any existing popup first to avoid accumulating content
if (Popup.isOpen()) {
Popup.close();
}
// Now open the popup for this specific subtask
Popup.open('subtaskActions').call(this, event);
},
async 'submit .js-add-subtask'(event, tpl) {
event.preventDefault();
const textarea = this.find('textarea.js-add-subtask-item');
const textarea = tpl.find('textarea.js-add-subtask-item');
const title = textarea.value.trim();
const cardId = this.currentData().cardId;
const cardId = Template.currentData().cardId;
const card = ReactiveCache.getCard(cardId);
const sortIndex = -1;
const crtBoard = ReactiveCache.getBoard(card.boardId);
const targetBoard = crtBoard.getDefaultSubtasksBoard();
const listId = targetBoard.getDefaultSubtasksListId();
const targetBoard = await crtBoard.getDefaultSubtasksBoardAsync();
if (!targetBoard) {
return;
}
const targetList = await targetBoard.getDefaultSubtasksListAsync();
if (!targetList) {
return;
}
const listId = targetList._id;
//Get the full swimlane data for the parent task.
const parentSwimlane = ReactiveCache.getSwimlane({
@@ -18,20 +37,22 @@ BlazeComponent.extendComponent({
_id: card.swimlaneId,
});
//find the swimlane of the same name in the target board.
const targetSwimlane = ReactiveCache.getSwimlane({
boardId: targetBoard._id,
title: parentSwimlane.title,
});
const targetSwimlane = parentSwimlane
? ReactiveCache.getSwimlane({
boardId: targetBoard._id,
title: parentSwimlane.title,
})
: undefined;
//If no swimlane with a matching title exists in the target board, fall back to the default swimlane.
const swimlaneId =
targetSwimlane === undefined
? targetBoard.getDefaultSwimline()._id
: targetSwimlane._id;
const nextCardNumber = targetBoard.getNextCardNumber();
const nextCardNumber = await targetBoard.getNextCardNumber();
if (title) {
const _id = Cards.insert({
const _id = await Cards.insertAsync({
title,
parentId: cardId,
members: [],
@@ -42,7 +63,7 @@ BlazeComponent.extendComponent({
sort: sortIndex,
swimlaneId,
type: 'cardType-card',
cardNumber: nextCardNumber
cardNumber: nextCardNumber,
});
// In case the filter is active we need to add the newly inserted card in
@@ -52,7 +73,7 @@ BlazeComponent.extendComponent({
Filter.addException(_id);
setTimeout(() => {
this.$('.add-subtask-item')
tpl.$('.add-subtask-item')
.last()
.click();
}, 100);
@@ -60,27 +81,20 @@ BlazeComponent.extendComponent({
textarea.value = '';
textarea.focus();
},
deleteSubtask() {
const subtask = this.currentData().subtask;
if (subtask && subtask._id) {
subtask.archive();
}
},
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
},
editSubtask(event) {
'submit .js-edit-subtask-title'(event, tpl) {
event.preventDefault();
const textarea = this.find('textarea.js-edit-subtask-item');
const textarea = tpl.find('textarea.js-edit-subtask-item');
const title = textarea.value.trim();
const subtask = this.currentData().subtask;
const subtask = Template.currentData().subtask;
subtask.setTitle(title);
},
pressKey(event) {
async 'click .js-delete-subtask-item'() {
const subtask = Template.currentData().subtask;
if (subtask && subtask._id) {
await subtask.archive();
}
},
keydown(event) {
//If user press enter key inside a form, submit it
//Unless the user is also holding down the 'shift' key
if (event.keyCode === 13 && !event.shiftKey) {
@@ -89,53 +103,66 @@ BlazeComponent.extendComponent({
$form.find('button[type=submit]').click();
}
},
});
events() {
return [
{
'click .js-open-subtask-details-menu': Popup.open('subtaskActions'),
'submit .js-add-subtask': this.addSubtask,
'submit .js-edit-subtask-title': this.editSubtask,
'click .js-delete-subtask-item': this.deleteSubtask,
keydown: this.pressKey,
},
];
},
}).register('subtasks');
Template.subtasks.onCreated(function () {
this.toggleDeleteDialog = new ReactiveVar(false);
});
BlazeComponent.extendComponent({
// ...
}).register('subtaskItemDetail');
BlazeComponent.extendComponent({
Template.subtasks.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
},
events() {
return [
{
'click .js-view-subtask'(event) {
if ($(event.target).hasClass('js-view-subtask')) {
const subtask = this.currentData().subtask;
const board = subtask.board();
FlowRouter.go('card', {
boardId: board._id,
slug: board.slug,
cardId: subtask._id,
});
}
},
'click .js-delete-subtask' : Popup.afterConfirm('subtaskDelete', function () {
Popup.back(2);
const subtask = this.subtask;
if (subtask && subtask._id) {
subtask.archive();
}
}),
}
]
}
}).register('subtaskActionsPopup');
toggleDeleteDialog() {
return Template.instance().toggleDeleteDialog;
},
});
Template.subtaskItemDetail.events({
async 'click .js-subtasks-item .check-box-container'() {
const item = Template.currentData().item;
if (item && item._id) {
await item.toggleItem();
}
},
});
Template.subtaskActionsPopup.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
},
});
Template.subtaskActionsPopup.events({
'click .js-view-subtask'(event) {
if ($(event.target).hasClass('js-view-subtask')) {
const subtask = Template.currentData().subtask;
const board = subtask.board();
FlowRouter.go('card', {
boardId: board._id,
slug: board.slug,
cardId: subtask._id,
swimlaneId: subtask.swimlaneId,
listId: subtask.listId,
});
}
},
'click .js-go-to-subtask-board'() {
const subtask = Template.currentData().subtask;
const board = subtask.board();
if (board) {
Popup.close();
FlowRouter.go('board', { id: board._id, slug: board.slug });
}
},
'click .js-delete-subtask' : Popup.afterConfirm('subtaskDelete', async function () {
Popup.back(2);
const subtask = this.subtask;
if (subtask && subtask._id) {
await subtask.archive();
}
}),
});
Template.editSubtaskItemForm.helpers({
user() {
@@ -145,5 +172,3 @@ Template.editSubtaskItemForm.helpers({
return ReactiveCache.getCurrentUser().isBoardAdmin();
},
});
Loaded 100 of 2049 files, more files were not shown because too many files have changed in this diff. Show more