mirror of
https://github.com/wekan/wekan.git
synced 2026-11-10 05:44:59 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f6832845d | ||
|
|
1ca199b607 | ||
|
|
63c6f42495 | ||
|
|
0fbef8936f | ||
|
|
0905de097b | ||
|
|
679ea9e63a | ||
|
|
d08f658dea | ||
|
|
dcd9fec925 | ||
|
|
8b4fe0e737 |
No files matched your search
@@ -103,7 +103,7 @@ jobs:
|
||||
app/.tools/meteor-bun/dev_bundle
|
||||
app/.tools/meteor-bun/.babel-cache
|
||||
app/.tools/meteor-bun/packages/*/.npm
|
||||
key: bun-meteor-${{ runner.os }}-${{ hashFiles('app/.meteor/release', 'app/.meteor/versions', 'build-tools/releases/bun/meteor-3.6-rc.1.patch') }}
|
||||
key: bun-meteor-${{ runner.os }}-${{ hashFiles('app/.meteor/release', 'app/.meteor/versions', 'build-tools/releases/bun/meteor-3.6.patch') }}
|
||||
- name: Build the release's ESM application once
|
||||
working-directory: app
|
||||
env:
|
||||
|
||||
+27
-27
@@ -6,12 +6,12 @@
|
||||
meteor-base@1.5.2
|
||||
|
||||
# Build system
|
||||
ecmascript@0.19.2-rc360.1
|
||||
standard-minifier-js@3.3.0-rc360.1
|
||||
rspack@1.4.0-rc360.1
|
||||
ecmascript@0.19.2
|
||||
standard-minifier-js@3.3.0
|
||||
rspack@1.4.0
|
||||
# Declared explicitly because server/modernBrowsers.js imports it, to say that
|
||||
# Yandex Browser is modern and must not be served the legacy bundle (#6557).
|
||||
modern-browsers@0.2.4-rc360.1
|
||||
modern-browsers@0.2.4
|
||||
|
||||
blaze@3.0.2
|
||||
|
||||
@@ -19,11 +19,11 @@ blaze@3.0.2
|
||||
aldeed:collection2
|
||||
aldeed:schema-index@4.0.0-beta.5
|
||||
reywood:publish-composite
|
||||
mongo@2.5.2-rc360.1
|
||||
mongo@2.6.0
|
||||
|
||||
# Account system
|
||||
accounts-password@3.3.2-rc360.1
|
||||
accounts-2fa@3.1.1-rc360.1
|
||||
accounts-password@3.3.2
|
||||
accounts-2fa@3.1.1
|
||||
accounts-express@1.0.0
|
||||
communitypackages:core
|
||||
communitypackages:unstyled
|
||||
@@ -39,19 +39,19 @@ wekan-oidc
|
||||
wekan-accounts-oidc
|
||||
|
||||
# Utilities
|
||||
check@1.5.1-rc360.1
|
||||
random@1.2.3-rc360.1
|
||||
reactive-dict@1.3.3-rc360.1
|
||||
session@1.2.4-rc360.1
|
||||
tracker@1.3.5-rc360.1
|
||||
check@1.5.1
|
||||
random@1.2.3
|
||||
reactive-dict@1.3.3
|
||||
session@1.2.4
|
||||
tracker@1.3.5
|
||||
audit-argument-checks@1.0.8
|
||||
|
||||
# UI components
|
||||
ostrio:i18n
|
||||
reactive-var@1.0.13
|
||||
shell-server@0.7.2-rc360.1
|
||||
email@3.2.1-rc360.1
|
||||
dynamic-import@0.8.1-rc360.1
|
||||
shell-server@0.7.2
|
||||
email@3.2.1
|
||||
dynamic-import@0.8.1
|
||||
wekan-markdown
|
||||
quave:synced-cron
|
||||
ostrio:cookies
|
||||
@@ -59,21 +59,21 @@ ostrio:files
|
||||
# lmieulet:meteor-coverage
|
||||
meteortesting:mocha@3.0.0
|
||||
matb33:collection-hooks
|
||||
service-configuration@1.3.6-rc360.1
|
||||
service-configuration@1.3.6
|
||||
minifier-css@2.0.2
|
||||
ejson@1.4.1-rc360.1
|
||||
logging@1.3.7-rc360.1
|
||||
ejson@1.4.1
|
||||
logging@1.3.7
|
||||
wekan-fullcalendar
|
||||
wekan-fontawesome
|
||||
accounts-google@1.4.2-rc360.1
|
||||
accounts-github@1.5.2-rc360.1
|
||||
accounts-facebook@1.3.5-rc360.1
|
||||
accounts-twitter@1.5.3-rc360.1
|
||||
accounts-meteor-developer@1.5.2-rc360.1
|
||||
accounts-weibo@1.4.2-rc360.1
|
||||
accounts-meetup@1.5.2-rc360.1
|
||||
accounts-passwordless@3.1.2-rc360.1
|
||||
instrumentation@0.0.1-rc360.1
|
||||
accounts-google@1.4.2
|
||||
accounts-github@1.5.2
|
||||
accounts-facebook@1.3.5
|
||||
accounts-twitter@1.5.3
|
||||
accounts-meteor-developer@1.5.2
|
||||
accounts-weibo@1.4.2
|
||||
accounts-meetup@1.5.2
|
||||
accounts-passwordless@3.1.2
|
||||
instrumentation@0.0.1
|
||||
|
||||
# Prevent Meteor build/run tools from sending application package statistics.
|
||||
package-stats-opt-out@1.0.8
|
||||
+1
-1
@@ -1 +1 @@
|
||||
METEOR@3.6-rc.1
|
||||
METEOR@3.6
|
||||
+74
-74
@@ -1,130 +1,130 @@
|
||||
accounts-2fa@3.1.1-rc360.1
|
||||
accounts-base@3.4.0-rc360.1
|
||||
accounts-2fa@3.1.1
|
||||
accounts-base@3.4.0
|
||||
accounts-express@1.0.0
|
||||
accounts-facebook@1.3.5-rc360.1
|
||||
accounts-github@1.5.2-rc360.1
|
||||
accounts-google@1.4.2-rc360.1
|
||||
accounts-meetup@1.5.2-rc360.1
|
||||
accounts-meteor-developer@1.5.2-rc360.1
|
||||
accounts-oauth@1.4.8-rc360.1
|
||||
accounts-password@3.3.2-rc360.1
|
||||
accounts-passwordless@3.1.2-rc360.1
|
||||
accounts-twitter@1.5.3-rc360.1
|
||||
accounts-weibo@1.4.2-rc360.1
|
||||
accounts-facebook@1.3.5
|
||||
accounts-github@1.5.2
|
||||
accounts-google@1.4.2
|
||||
accounts-meetup@1.5.2
|
||||
accounts-meteor-developer@1.5.2
|
||||
accounts-oauth@1.4.8
|
||||
accounts-password@3.3.2
|
||||
accounts-passwordless@3.1.2
|
||||
accounts-twitter@1.5.3
|
||||
accounts-weibo@1.4.2
|
||||
aldeed:collection2@4.2.2
|
||||
aldeed:schema-index@4.0.0
|
||||
aldeed:simple-schema@1.13.1
|
||||
allow-deny@2.1.2-rc360.1_1
|
||||
allow-deny@2.1.2_1
|
||||
audit-argument-checks@1.0.8
|
||||
autoupdate@2.0.2-rc360.1
|
||||
babel-compiler@7.15.2-rc360.1
|
||||
autoupdate@2.0.2
|
||||
babel-compiler@7.15.2
|
||||
babel-runtime@1.5.2
|
||||
base64@1.0.15-rc360.1
|
||||
binary-heap@1.0.14-rc360.1
|
||||
base64@1.0.15
|
||||
binary-heap@1.0.14
|
||||
blaze@3.0.3
|
||||
blaze-tools@2.0.1
|
||||
boilerplate-generator@2.2.0-rc360.1
|
||||
boilerplate-generator@2.2.0
|
||||
caching-compiler@2.0.1
|
||||
caching-html-compiler@2.0.1
|
||||
callback-hook@1.8.1-rc360.1
|
||||
check@1.5.1-rc360.1
|
||||
callback-hook@1.8.1
|
||||
check@1.5.1
|
||||
communitypackages:core@2.0.3
|
||||
communitypackages:flow-routing@2.1.0
|
||||
communitypackages:unstyled@2.0.1
|
||||
core-runtime@1.0.0
|
||||
ddp@1.4.3-rc360.1
|
||||
ddp-client@3.4.2-rc360.1
|
||||
ddp-common@1.4.6-rc360.1
|
||||
ddp-rate-limiter@1.3.1-rc360.1
|
||||
ddp-server@3.6.0-rc360.1_1
|
||||
diff-sequence@1.2.1-rc360.1
|
||||
dynamic-import@0.8.1-rc360.1_1
|
||||
ecmascript@0.19.2-rc360.1
|
||||
ddp@1.4.3
|
||||
ddp-client@3.4.2
|
||||
ddp-common@1.4.6
|
||||
ddp-rate-limiter@1.3.1
|
||||
ddp-server@3.6.0_1
|
||||
diff-sequence@1.2.1
|
||||
dynamic-import@0.8.1_1
|
||||
ecmascript@0.19.2
|
||||
ecmascript-runtime@0.8.3
|
||||
ecmascript-runtime-client@0.13.0
|
||||
ecmascript-runtime-server@0.11.1
|
||||
ejson@1.4.1-rc360.1
|
||||
email@3.2.1-rc360.1
|
||||
ejson@1.4.1
|
||||
email@3.2.1
|
||||
es5-shim@4.8.1
|
||||
facebook-oauth@1.12.1-rc360.1_1
|
||||
facts-base@1.0.3-rc360.1
|
||||
fetch@0.2.1-rc360.1
|
||||
geojson-utils@1.0.13-rc360.1
|
||||
github-oauth@1.4.3-rc360.1
|
||||
google-oauth@1.5.1-rc360.1_1
|
||||
facebook-oauth@1.12.1_1
|
||||
facts-base@1.0.3
|
||||
fetch@0.2.1
|
||||
geojson-utils@1.0.13
|
||||
github-oauth@1.4.3
|
||||
google-oauth@1.5.1_1
|
||||
hot-code-push@1.0.5
|
||||
html-tools@2.0.1
|
||||
htmljs@2.0.2
|
||||
id-map@1.2.1-rc360.1
|
||||
instrumentation@0.0.1-rc360.1
|
||||
inter-process-messaging@0.1.4-rc360.1
|
||||
id-map@1.2.1
|
||||
instrumentation@0.0.1
|
||||
inter-process-messaging@0.1.4
|
||||
jquery@3.0.2
|
||||
lai:collection-extensions@1.0.0
|
||||
localstorage@1.2.1
|
||||
logging@1.3.7-rc360.1
|
||||
logging@1.3.7
|
||||
matb33:collection-hooks@2.1.0
|
||||
meetup-oauth@1.1.4-rc360.1
|
||||
meteor@2.3.2-rc360.1
|
||||
meetup-oauth@1.1.4
|
||||
meteor@2.3.2
|
||||
meteor-base@1.5.2
|
||||
meteor-developer-oauth@1.3.4-rc360.1
|
||||
meteor-developer-oauth@1.3.4
|
||||
meteortesting:browser-tests@1.8.0
|
||||
meteortesting:mocha@3.4.0
|
||||
meteortesting:mocha-core@8.2.0
|
||||
minifier-css@2.0.2
|
||||
minifier-js@3.3.2-rc360.1
|
||||
minimongo@2.2.1-rc360.1
|
||||
modern-browsers@0.2.4-rc360.1
|
||||
minifier-js@3.3.2
|
||||
minimongo@2.2.1
|
||||
modern-browsers@0.2.4
|
||||
modules@0.20.3
|
||||
modules-runtime@0.13.2
|
||||
mongo@2.5.2-rc360.1
|
||||
mongo@2.6.0
|
||||
mongo-decimal@0.2.0
|
||||
mongo-dev-server@1.1.1
|
||||
mongo-id@1.0.10-rc360.1
|
||||
npm-mongo@6.18.1-rc360.1
|
||||
oauth@3.0.5-rc360.1
|
||||
oauth1@1.5.4-rc360.1
|
||||
mongo-id@1.0.10
|
||||
npm-mongo@6.18.1
|
||||
oauth@3.0.5
|
||||
oauth1@1.5.4
|
||||
oauth2@1.3.3
|
||||
observe-sequence@2.0.1
|
||||
ordered-dict@1.2.1-rc360.1
|
||||
ordered-dict@1.2.1
|
||||
ostrio:cookies@2.9.2
|
||||
ostrio:cstorage@4.0.1
|
||||
ostrio:files@3.0.1
|
||||
ostrio:flow-router-extra@3.15.3
|
||||
ostrio:i18n@3.2.1
|
||||
package-stats-opt-out@1.0.8
|
||||
promise@1.0.1-rc360.1
|
||||
promise@1.0.1
|
||||
quave:synced-cron@2.4.0
|
||||
raix:eventemitter@1.0.0
|
||||
random@1.2.3-rc360.1
|
||||
rate-limit@1.2.1-rc360.1
|
||||
random@1.2.3
|
||||
rate-limit@1.2.1
|
||||
react-fast-refresh@0.3.0
|
||||
reactive-dict@1.3.3-rc360.1
|
||||
reactive-dict@1.3.3
|
||||
reactive-var@1.0.13
|
||||
reload@1.3.3-rc360.1
|
||||
retry@1.1.2-rc360.1
|
||||
reload@1.3.3
|
||||
retry@1.1.2
|
||||
reywood:publish-composite@1.9.0
|
||||
routepolicy@1.1.3-rc360.1
|
||||
rspack@1.4.0-rc360.1
|
||||
service-configuration@1.3.6-rc360.1
|
||||
session@1.2.4-rc360.1
|
||||
sha@1.0.11-rc360.1
|
||||
shell-server@0.7.2-rc360.1_1
|
||||
socket-stream-client@0.7.2-rc360.1
|
||||
routepolicy@1.1.3
|
||||
rspack@1.4.0
|
||||
service-configuration@1.3.6
|
||||
session@1.2.4
|
||||
sha@1.0.11
|
||||
shell-server@0.7.2_1
|
||||
socket-stream-client@0.7.2
|
||||
spacebars@2.0.1
|
||||
spacebars-compiler@2.0.1
|
||||
standard-minifier-js@3.3.0-rc360.1
|
||||
standard-minifier-js@3.3.0
|
||||
templating@1.4.5
|
||||
templating-compiler@2.0.1
|
||||
templating-runtime@2.0.2
|
||||
templating-tools@2.0.1
|
||||
tools-core@1.4.0-rc360.1
|
||||
tracker@1.3.5-rc360.1
|
||||
twitter-oauth@1.3.5-rc360.1
|
||||
typescript@5.11.2-rc360.1
|
||||
url@1.3.7-rc360.1
|
||||
webapp@2.3.1-rc360.1
|
||||
webapp-hashing@1.1.3-rc360.1
|
||||
weibo-oauth@1.3.4-rc360.1
|
||||
tools-core@1.4.0
|
||||
tracker@1.3.5
|
||||
twitter-oauth@1.3.5
|
||||
typescript@5.11.2
|
||||
url@1.3.7
|
||||
webapp@2.4.0
|
||||
webapp-hashing@1.1.3
|
||||
weibo-oauth@1.3.4
|
||||
wekan-accounts-cas@0.2.0
|
||||
wekan-accounts-lockout@1.1.0
|
||||
wekan-accounts-oidc@1.0.10
|
||||
|
||||
@@ -124,6 +124,65 @@ its reason.
|
||||
|
||||
</details>
|
||||
|
||||
# v13.05 2026-11-10 WeKan ® release
|
||||
|
||||
**In short:** WeKan is updated to **Meteor 3.6**. The **Android** bundles
|
||||
build again, after v13.04's npm retry broke their install, and the **Super
|
||||
Productivity** export no longer fails for a board with a card whose list is
|
||||
archived.
|
||||
|
||||
This release updates the following dependencies:
|
||||
|
||||
<details>
|
||||
<summary><a href="https://github.com/wekan/wekan/commit/0fbef8936fa2524d21048669e4c41be15e4e3f38">Updated to Meteor 3.6</a>. Thanks to xet7.</summary>
|
||||
|
||||
From 3.6-rc.1. `meteor update` refused it, because WeKan's forks of six Meteor
|
||||
packages in `packages/` declared 3.6-rc.1's versions, and a local package
|
||||
overrides the release's. Meteor 3.6 changed those six only in their version
|
||||
line, so each fork now declares 3.6's version with its `_1` wrap number. The
|
||||
Dockerfile builds with Meteor 3.6, and the Bun build's patch applies unchanged
|
||||
to it as `meteor-3.6.patch`. WeKan builds with Meteor 3.6, and the node suites
|
||||
pass.
|
||||
|
||||
</details>
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
**Release builds** - what the release workflow builds.
|
||||
|
||||
<details>
|
||||
<summary><a href="https://github.com/wekan/wekan/commit/d08f658deae3b8369b75f1c54371ad8c1cf9367d">The Android bundles build again: npm-retry.sh is given Android's node and npm</a>. Thanks to xet7.</summary>
|
||||
|
||||
v13.04's four Android bundle jobs all failed with "environment: node: unbound
|
||||
variable". v13.04 sent the Android npm installs through
|
||||
`releases/npm-retry.sh` by the name of `build-bundle.sh`'s own `npm` shell
|
||||
function. `npm-retry.sh` is a new bash with `set -u`: the exported function
|
||||
reached it, but the `$node` and `$npm_cli` it reads did not, so it failed before
|
||||
npm ran. The two installs now give `npm-retry.sh` the program itself, still
|
||||
retried on a network error. `tests/npmRetry.test.cjs` fails when any
|
||||
`releases/` script gives `npm-retry.sh` one of its own shell functions, and
|
||||
reproduces the failure.
|
||||
|
||||
</details>
|
||||
|
||||
**Exports** - a board in another tool's format.
|
||||
|
||||
<details>
|
||||
<summary><a href="https://github.com/wekan/wekan/commit/8b4fe0e7376194c498219a0b496340a94020098a">The Super Productivity export no longer fails on a card whose list is archived</a>. Thanks to xet7.</summary>
|
||||
|
||||
A card whose list is archived is collected with an empty list title. The
|
||||
Super Productivity formatter tagged that card with a tag that did not exist, so
|
||||
the export threw "Cannot read properties of undefined (reading 'taskIds')" and
|
||||
the whole board's export failed. That list is now "Untitled", for its tag and
|
||||
its panel alike, so the panel shows its cards and every tag a task names
|
||||
exists. `tests/superProductivityFormat.test.cjs` fails with that error on the
|
||||
old formatter. It was found while checking Weddy's Super Productivity export
|
||||
against WeKan's formatter.
|
||||
|
||||
</details>
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v13.04 2026-11-09 WeKan ® release
|
||||
|
||||
**In short:** **ListLockBleed** is fixed: when a list refuses a role write
|
||||
|
||||
+9
-10
@@ -5,6 +5,15 @@ each one changed and the project status are in
|
||||
Written by `node releases/changelog-short.mjs` from CHANGELOG-big.md:
|
||||
make changes there.
|
||||
|
||||
# v13.05 2026-11-10 WeKan ® release
|
||||
|
||||
WeKan is updated to **Meteor 3.6**. The **Android** bundles
|
||||
build again, after v13.04's npm retry broke their install, and the **Super
|
||||
Productivity** export no longer fails for a board with a card whose list is
|
||||
archived.
|
||||
|
||||
[All changes in v13.05](CHANGELOG-big.md#v1305-2026-11-10-wekan--release)
|
||||
|
||||
# v13.04 2026-11-09 WeKan ® release
|
||||
|
||||
**ListLockBleed** is fixed: when a list refuses a role write
|
||||
@@ -38,13 +47,3 @@ Arabic** is Darija instead of Persian. Dependabot's updates of **mailparser**,
|
||||
with the S3 client brought to the version the upload library needs.
|
||||
|
||||
[All changes in v13.01](CHANGELOG-big.md#v1301-2026-11-08-wekan--release)
|
||||
|
||||
# v13.00 2026-11-07 WeKan ® release
|
||||
|
||||
**CreateBleed** is fixed: "Only admins can create boards" now
|
||||
holds on every path that creates a board - the browser console, the REST API,
|
||||
imports, copies, clones and cards - not only on the Add Board form. The **REST
|
||||
API documentation** spells the name **WeKan**, so the API pages published on
|
||||
wekan.fi pass its brand-spelling check again.
|
||||
|
||||
[All changes in v13.00](CHANGELOG-big.md#v1300-2026-11-07-wekan--release)
|
||||
+2
-2
@@ -38,7 +38,7 @@ FROM --platform=$BUILDPLATFORM debian:trixie AS bundle
|
||||
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
ARG VERSION=13.04
|
||||
ARG VERSION=13.05
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
COPY --chmod=755 releases/check-telemetry.py /tmp/check-telemetry.py
|
||||
@@ -149,7 +149,7 @@ ENV \
|
||||
DEBUG=false \
|
||||
DDP_TRANSPORT=sockjs \
|
||||
NODE_VERSION=v26.13.0 \
|
||||
METEOR_RELEASE=METEOR@3.6-rc.1 \
|
||||
METEOR_RELEASE=METEOR@3.6 \
|
||||
USE_EDGE=false \
|
||||
NPM_VERSION=12.2.2 \
|
||||
SRC_PATH=./ \
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
|
||||
appVersion: "v13.04.0"
|
||||
appVersion: "v13.05.0"
|
||||
files:
|
||||
userUploads:
|
||||
- README.md
|
||||
|
||||
@@ -10,7 +10,7 @@ This is without container (without Docker or Snap).
|
||||
|
||||
Right click and download files 1-4:
|
||||
|
||||
1. [wekan-13.04-win64.zip](https://github.com/wekan/wekan/releases/download/v13.04/wekan-13.04-win64.zip) or newest available at https://github.com/wekan/wekan/releases/
|
||||
1. [wekan-13.05-win64.zip](https://github.com/wekan/wekan/releases/download/v13.05/wekan-13.05-win64.zip) or newest available at https://github.com/wekan/wekan/releases/
|
||||
|
||||
2. [node.exe](https://nodejs.org/dist/latest-v26.x/win-x64/node.exe)
|
||||
|
||||
@@ -22,7 +22,7 @@ Right click and download files 1-4:
|
||||
|
||||
6. Double click `mongodb-windows-x86_64-7.0.34-signed.msi` . In installer, uncheck downloading MongoDB compass.
|
||||
|
||||
7. Unzip `wekan-13.04-win64.zip` , inside it is directory `bundle`, to it copy other files:
|
||||
7. Unzip `wekan-13.05-win64.zip` , inside it is directory `bundle`, to it copy other files:
|
||||
|
||||
```
|
||||
bundle (directory)
|
||||
|
||||
@@ -352,6 +352,10 @@ export function formatSuperProductivity({ board, lists, swimlanes, items } = {},
|
||||
}
|
||||
return tagIdByTitle.get(name);
|
||||
};
|
||||
// A list's own tag. A list with no title - a card whose list is archived
|
||||
// is collected with listTitle '' - is "Untitled", as its panel is named,
|
||||
// so the panel shows its cards and every task's tags exist.
|
||||
const listTag = title => tagFor(String(title || '').trim() || 'Untitled');
|
||||
const inProgressTag = () => {
|
||||
if (!tagState.entities[SP_IN_PROGRESS_TAG_ID]) {
|
||||
tagState.ids.push(SP_IN_PROGRESS_TAG_ID);
|
||||
@@ -398,7 +402,7 @@ export function formatSuperProductivity({ board, lists, swimlanes, items } = {},
|
||||
const isDone = kind === 'done' || ended !== undefined;
|
||||
const tagIds = (Array.isArray(item.labels) ? item.labels : []).map(tagFor).filter(Boolean);
|
||||
if (kind === 'progress' && !isDone) tagIds.push(inProgressTag());
|
||||
if (kind === 'other') tagIds.push(tagFor(item.listTitle));
|
||||
if (kind === 'other') tagIds.push(listTag(item.listTitle));
|
||||
const notes = [String(item.description || '').trim(), checklistMarkdown(item.checklists)].filter(Boolean).join('\n\n');
|
||||
const created = msOf(item.createdAt) || now;
|
||||
const spent = Number(item.spentTime);
|
||||
@@ -449,7 +453,7 @@ export function formatSuperProductivity({ board, lists, swimlanes, items } = {},
|
||||
});
|
||||
|
||||
// One board, one panel per list, filtering the way the list decides.
|
||||
const otherTags = listTitles.filter(title => listKind(title) === 'other').map(tagFor);
|
||||
const otherTags = listTitles.filter(title => listKind(title) === 'other').map(listTag);
|
||||
const panel = (title, index, filter) => ({
|
||||
id: `wekan-panel-${index + 1}`, title: title || 'Untitled', taskIds: panelTasks.get(title) || [],
|
||||
includedTagIds: [], excludedTagIds: [], projectIds: [''],
|
||||
@@ -464,7 +468,7 @@ export function formatSuperProductivity({ board, lists, swimlanes, items } = {},
|
||||
excludedTagIds: [...(tagState.entities[SP_IN_PROGRESS_TAG_ID] ? [SP_IN_PROGRESS_TAG_ID] : []), ...otherTags],
|
||||
backlogState: backlogUsed ? 2 : 1,
|
||||
});
|
||||
default: return panel(title, index, { includedTagIds: [tagFor(title)] });
|
||||
default: return panel(title, index, { includedTagIds: [listTag(title)] });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Generated
+6
-6
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v13.04.0",
|
||||
"version": "v13.05.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wekan",
|
||||
"version": "v13.04.0",
|
||||
"version": "v13.05.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -80,7 +80,7 @@
|
||||
"yjs": "13.6.33"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@meteorjs/rspack": "^3.0.0-rc.2",
|
||||
"@meteorjs/rspack": "^3.0.0",
|
||||
"@rsdoctor/rspack-plugin": "^1.6.4",
|
||||
"@rspack/cli": "^2.2.9",
|
||||
"@rspack/core": "^2.2.9",
|
||||
@@ -2973,9 +2973,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@meteorjs/rspack": {
|
||||
"version": "3.0.0-rc.2",
|
||||
"resolved": "https://registry.npmjs.org/@meteorjs/rspack/-/rspack-3.0.0-rc.2.tgz",
|
||||
"integrity": "sha512-0YwVxT5X7dBSrBOoQTXWdiWStnAHg7IYIs229TBxVifCfEHulxsGkuV+OIgz1arZWUQACOyZxQIUdS3aR4fK8w==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@meteorjs/rspack/-/rspack-3.0.0.tgz",
|
||||
"integrity": "sha512-INccdjjsdxUzwgeColyJY3pNBO2h3auag7XikHmuNKDiNqKbt5pIP2Ky1+10NoiiLZIQo8EL17zsGoCinvM2TQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v13.04.0",
|
||||
"version": "v13.05.0",
|
||||
"description": "Open-Source kanban",
|
||||
"private": true,
|
||||
"repository": {
|
||||
@@ -38,7 +38,7 @@
|
||||
"postinstall": "node scripts/patch-yargs-dirname.cjs && node scripts/patch-pdfkit-entry.cjs && node scripts/patch-meteor-node-stubs-pbkdf2.cjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@meteorjs/rspack": "^3.0.0-rc.2",
|
||||
"@meteorjs/rspack": "^3.0.0",
|
||||
"@rsdoctor/rspack-plugin": "^1.6.4",
|
||||
"@rspack/cli": "^2.2.9",
|
||||
"@rspack/core": "^2.2.9",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: 'allow-deny',
|
||||
version: '2.1.2-rc360.1_1',
|
||||
version: '2.1.2_1',
|
||||
// Brief, one-line summary of the package.
|
||||
summary: 'Implements functionality for allow/deny and client-side db operations',
|
||||
// URL to the Git repository containing the source code for this package.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Package.describe({
|
||||
summary: "Meteor's latency-compensated distributed data server",
|
||||
version: '3.6.0-rc360.1_1',
|
||||
version: '3.6.0_1',
|
||||
documentation: null,
|
||||
});
|
||||
|
||||
// WeKan fork of Meteor 3.6-rc.1's ddp-server, for the Admin Panel / Problems
|
||||
// WeKan fork of Meteor 3.6's ddp-server, for the Admin Panel / Problems
|
||||
// report of a refused DDP message. uWebSockets.js is left out, as Meteor's
|
||||
// published 3.4.1-rc360.0 isopack had no copy of it either: it is only loaded
|
||||
// for the opt-in "uws" transport, and it would be fetched from a git URL at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: "dynamic-import",
|
||||
version: '0.8.1-rc360.1_1',
|
||||
version: '0.8.1_1',
|
||||
summary: "Runtime support for Meteor 1.5 dynamic import(...) syntax",
|
||||
documentation: "README.md"
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: "Facebook OAuth flow",
|
||||
version: '1.12.1-rc360.1_1',
|
||||
version: '1.12.1_1',
|
||||
});
|
||||
|
||||
Package.onUse(api => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: "Google OAuth flow",
|
||||
version: '1.5.1-rc360.1_1',
|
||||
version: '1.5.1_1',
|
||||
});
|
||||
|
||||
Cordova.depends({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: "shell-server",
|
||||
version: '0.7.2-rc360.1_1',
|
||||
version: '0.7.2_1',
|
||||
summary: "Server-side component of the `meteor shell` command.",
|
||||
documentation: "README.md",
|
||||
devOnly: true,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf8" />
|
||||
<title>WeKan REST API v13.04</title>
|
||||
<title>WeKan REST API v13.05</title>
|
||||
<!-- needed for adaptive design -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
@@ -484,11 +484,11 @@ data-styled.g658[id="sc-hHttOM"]{content:"dKSNwp,"}/*!sc*/
|
||||
|
||||
<body>
|
||||
|
||||
<div id="redoc"><div hidden=""><script>try{var m=localStorage.getItem("redoc.colorMode");if(m!=="light"&&m!=="dark")m=matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";document.documentElement.classList.add(m)}catch(e){}</script></div><div style="--navbar-height:0px;--navbar-stack-height:0px" class="sc-kIbBWU fFQMWf"><div class="sc-cjUTkN dGsweu menu-content"><div class="sc-jqwVmx jjzLa-d"><div data-testid="search-trigger" class="sc-cToEys dffrbr"><div class="sc-cRcubC ddjiE"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" data-component-name="icons/SearchIcon/SearchIcon" class="sc-cHazmW gTzQi"><path d="M14.5 13.7931L10.724 10.017C11.6313 8.9277 12.0838 7.5305 11.9872 6.11608C11.8907 4.70165 11.2525 3.37891 10.2055 2.423C9.15857 1.4671 7.78336 0.951637 6.36602 0.983845C4.94867 1.01605 3.5983 1.59345 2.59582 2.59593C1.59335 3.5984 1.01595 4.94877 0.983738 6.36612C0.95153 7.78347 1.46699 9.15867 2.4229 10.2057C3.3788 11.2526 4.70155 11.8908 6.11597 11.9873C7.53039 12.0839 8.92759 11.6314 10.0169 10.7241L13.793 14.5001L14.5 13.7931ZM2.00001 6.50012C2.00001 5.6101 2.26393 4.74007 2.7584 4.00005C3.25286 3.26003 3.95567 2.68325 4.77794 2.34266C5.6002 2.00207 6.505 1.91295 7.37792 2.08658C8.25083 2.26022 9.05266 2.6888 9.68199 3.31814C10.3113 3.94747 10.7399 4.7493 10.9135 5.62221C11.0872 6.49513 10.9981 7.39993 10.6575 8.22219C10.3169 9.04446 9.7401 9.74726 9.00008 10.2417C8.26006 10.7362 7.39003 11.0001 6.50001 11.0001C5.30694 10.9988 4.16312 10.5243 3.31949 9.68064C2.47587 8.83701 2.00133 7.69319 2.00001 6.50012Z"></path></svg><span>Loading...</span></div></div></div><div class="sc-dNLPWG dtcefb"><ul data-component-name="Menu/Menu" class="sc-kBPbfe ctPApS"><div data-component-name="Menu/MenuItem" class="sc-gwVKcS fGSWQx menu-item-type-default" role="listitem"><a class="sc-iJONRL iBHKJo" href="/" data-discover="true"><li role="none" data-testid="menu-item-label" data-active="true" class="sc-epufQc fYmDZR"><div class="sc-boLXHU jshptd"><span class="sc-bcyEQV hrIrOF"><span data-text="WeKan REST API" class="sc-eStdmu iyAVQU">WeKan REST API</span></span></div></li></a></div><div data-component-name="Menu/MenuItem" class="sc-gwVKcS fGSWQx menu-item-type-default" role="listitem"><a class="sc-iJONRL iBHKJo" href="/section/production-security-concerns" data-discover="true"><li role="none" data-testid="menu-item-label" data-active="false" class="sc-epufQc itBMtf"><div class="sc-boLXHU jshptd"><span class="sc-bcyEQV hrIrOF"><span data-text="Production Security Concerns" class="sc-eStdmu liVEkC">Production Security Concerns</span></span></div></li></a></div><div data-component-name="Menu/MenuItem" class="sc-gwVKcS fGSWQx menu-item-type-group" role="listitem"><a class="sc-iJONRL iBHKJo" href="/login" data-discover="true"><li role="none" data-testid="menu-item-label" data-active="false" class="sc-epufQc hKPPiy"><div class="sc-jokKPH jtaKKl"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" color="--tree-content-color-default" data-component-name="icons/ChevronRightIcon/ChevronRightIcon" class="sc-iUlCMS kEEIsB"><path d="M11 8L6.00002 13L5.30002 12.3L9.60002 8L5.30002 3.7L6.00002 3L11 8Z"></path></svg></div><div class="sc-boLXHU jshptd"><span class="sc-bcyEQV hrIrOF"><span data-text="Login" class="sc-eStdmu liVEkC">Login</span></span></div></li></a><div style="display:none;height:0px;overflow:hidden" class="sc-hgJgCR dlNiXx"></div></div><div data-component-name="Menu/MenuItem" class="sc-gwVKcS fGSWQx menu-item-type-group" role="listitem"><a class="sc-iJONRL iBHKJo" href="/attachmentstoragesettings" data-discover="true"><li role="none" data-testid="menu-item-label" data-active="false" class="sc-epufQc hKPPiy"><div class="sc-jokKPH jtaKKl"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" color="--tree-content-color-default" data-component-name="icons/ChevronRightIcon/ChevronRightIcon" class="sc-iUlCMS kEEIsB"><path d="M11 8L6.00002 13L5.30002 12.3L9.60002 8L5.30002 3.7L6.00002 3L11 8Z"></path></svg></div><div class="sc-boLXHU jshptd"><span class="sc-bcyEQV hrIrOF"><span data-text="AttachmentStorageSettings" class="sc-eStdmu liVEkC">AttachmentStorageSettings</span></span></div></li></a><div style="display:none;height:0px;overflow:hidden" class="sc-hgJgCR dlNiXx"></div></div><div data-component-name="Menu/MenuItem" class="sc-gwVKcS fGSWQx menu-item-type-group" role="listitem"><a class="sc-iJONRL iBHKJo" href="/settings" data-discover="true"><li role="none" data-testid="menu-item-label" data-active="false" class="sc-epufQc hKPPiy"><div class="sc-jokKPH jtaKKl"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" color="--tree-content-color-default" data-component-name="icons/ChevronRightIcon/ChevronRightIcon" class="sc-iUlCMS kEEIsB"><path d="M11 8L6.00002 13L5.30002 12.3L9.60002 8L5.30002 3.7L6.00002 3L11 8Z"></path></svg></div><div class="sc-boLXHU jshptd"><span class="sc-bcyEQV hrIrOF"><span data-text="Settings" classLine truncated
|
||||
<div id="redoc"><div hidden=""><script>try{var m=localStorage.getItem("redoc.colorMode");if(m!=="light"&&m!=="dark")m=matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";document.documentElement.classList.add(m)}catch(e){}</script></div><div style="--navbar-height:0px;--navbar-stack-height:0px" class="sc-kIbBWU fFQMWf"><div class="sc-cjUTkN dGsweu menu-content"><div class="sc-jqwVmx jjzLa-d"><div data-testid="search-trigger" class="sc-cToEys dffrbr"><div class="sc-cRcubC ddjiE"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" data-component-name="icons/SearchIcon/SearchIcon" class="sc-cHazmW gTzQi"><path d="M14.5 13.7931L10.724 10.017C11.6313 8.9277 12.0838 7.5305 11.9872 6.11608C11.8907 4.70165 11.2525 3.37891 10.2055 2.423C9.15857 1.4671 7.78336 0.951637 6.36602 0.983845C4.94867 1.01605 3.5983 1.59345 2.59582 2.59593C1.59335 3.5984 1.01595 4.94877 0.983738 6.36612C0.95153 7.78347 1.46699 9.15867 2.4229 10.2057C3.3788 11.2526 4.70155 11.8908 6.11597 11.9873C7.53039 12.0839 8.92759 11.6314 10.0169 10.7241L13.793 14.5001L14.5 13.7931ZM2.00001 6.50012C2.00001 5.6101 2.26393 4.74007 2.7584 4.00005C3.25286 3.26003 3.95567 2.68325 4.77794 2.34266C5.6002 2.00207 6.505 1.91295 7.37792 2.08658C8.25083 2.26022 9.05266 2.6888 9.68199 3.31814C10.3113 3.94747 10.7399 4.7493 10.9135 5.62221C11.0872 6.49513 10.9981 7.39993 10.6575 8.22219C10.3169 9.04446 9.7401 9.74726 9.00008 10.2417C8.26006 10.7362 7.39003 11.0001 6.50001 11.0001C5.30694 10.9988 4.16312 10.5243 3.31949 9.68064C2.47587 8.83701 2.00133 7.69319 2.00001 6.50012Z"></path></svg><span>Loading...</span></div></div></div><div class="sc-dNLPWG dtcefb"><ul data-component-name="Menu/Menu" class="sc-kBPbfe ctPApS"><div data-component-name="Menu/MenuItem" class="sc-gwVKcS fGSWQx menu-item-type-default" role="listitem"><a class="sc-iJONRL iBHKJo" href="/" data-discover="true"><li role="none" data-testid="menu-item-label" data-active="true" class="sc-epufQc fYmDZR"><div class="sc-boLXHU jshptd"><span class="sc-bcyEQV hrIrOF"><span data-text="WeKan REST API" class="sc-eStdmu iyAVQU">WeKan REST API</span></span></div></li></a></div><div data-component-name="Menu/MenuItem" class="sc-gwVKcS fGSWQx menu-item-type-default" role="listitem"><a class="sc-iJONRL iBHKJo" href="/section/production-security-concerns" data-discover="true"><li role="none" data-testid="menu-item-label" data-active="false" class="sc-epufQc itBMtf"><div class="sc-boLXHU jshptd"><span class="sc-bcyEQV hrIrOF"><span data-text="Production Security Concerns" class="sc-eStdmu liVEkC">Production Security Concerns</span></span></div></li></a></div><div data-component-name="Menu/MenuItem" class="sc-gwVKcS fGSWQx menu-item-type-group" role="listitem"><a class="sc-iJONRL iBHKJo" href="/login" data-discover="true"><li role="none" data-testid="menu-item-label" data-active="false" class="sc-epufQc hKPPiy"><div class="sc-jokKPH jtaKKl"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" color="--tree-content-color-default" data-component-name="icons/ChevronRightIcon/ChevronRightIcon" class="sc-iUlCMS kEEIsB"><path d="M11 8L6.00002 13L5.30002 12.3L9.60002 8L5.30002 3.7L6.00002 3L11 8Z"></path></svg></div><div class="sc-boLXHU jshptd"><span class="sc-bcyEQV hrIrOF"><span data-text="Login" class="sc-eStdmu liVEkC">Login</span></span></div></li></a><div style="display:none;height:0px;overflow:hidden" class="sc-hgJgCR dlNiXx"></div></div><div data-component-name="Menu/MenuItem" class="sc-gwVKcS fGSWQx menu-item-type-group" role="listitem"><a class="sc-iJONRL iBHKJo" href="/attachmentstoragesettings" data-discover="true"><li role="none" data-testid="menu-item-label" data-active="false" class="sc-epufQc hKPPiy"><div class="sc-jokKPH jtaKKl"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" color="--tree-content-color-default" data-component-name="icons/ChevronRightIcon/ChevronRightIcon" class="sc-iUlCMS kEEIsB"><path d="M11 8L6.00002 13L5.30002 12.3L9.60002 8L5.30002 3.7L6.00002 3L11 8Z"></path></svg></div><div class="sc-boLXHU jshptd"><span class="sc-bcyEQV hrIrOF"><span data-text="AttachmentStorageSettings" class="sc-eStdmu liVEkC">AttachmentStorageSettings</span></span></div></li></a><div style="display:none;height:0px;overflow:hidden" class="sc-hgJgCR dlNiXx"></div></div><div data-component-name="Menu/MenuItem" class="sc-gwVKcS fGSWQx menu-item-type-group" role="listitem"><a class="sc-iJONRL iBHKJo" href="/settings" data-discover="true"><li role="none" data-testid="menu-item-label" data-active="false" class="sc-epufQc hKPPiy"><div class="sc-jokKPH jtaKKl"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" color="--tree-content-color-default" data-component-name="icons/ChevronRightIcon/ChevronRightIcon" class="sc-iUlCMS kEEIsB"><path d="M11 8L6.00002 13L5.30002 12.3L9.60002 8L5.30002 3.7L6.00002 3L11 8Z"></path></svg></div><div class="sc-boLXHU jshptd"><span class="sc-bcyEQV hrIrOF"><span data-text="Settings" classLine truncated
|
||||
<script type="module">
|
||||
import { hydrate } from "https://cdn.redocly.com/redoc/v3.0.1/bundles/redoc.standalone.js";
|
||||
|
||||
const __redoc_definition = {"openapi":"3.2.0","info":{"title":"WeKan REST API","version":"v13.04","description":"The REST API allows you to control and extend WeKan with ease.\n\nIf you are an end-user and not a dev or a tester, [create an issue](https://github.com/wekan/wekan/issues/new) to request new APIs.\n\n> All API calls in the documentation are made using `curl`. However, you are free to use Java / Python / PHP / Golang / Ruby / Swift / Objective-C / Rust / Scala / C# or any other programming languages.\n\n# Production Security Concerns\nWhen calling a production WeKan server, ensure it is running via HTTPS and has a valid SSL Certificate. The login method requires you to post your username and password in plaintext, which is why we highly suggest only calling the REST login api over HTTPS. Also, few things to note:\n\n* Only call via HTTPS\n* Implement a timed authorization token expiration strategy\n* Ensure the calling user only has permissions for what they are calling and no more\n"},"paths":{"/users/login":{"post":{"operationId":"login","summary":"Login with REST API","tags":["Login"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"}}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"}}}}},"description":"Login credentials","required":true},"responses":{"200":{"description":"Successful authentication","content":{"*/*":{"schema":{"type":"object","required":["id","token","tokenExpires"],"properties":{"id":{"type":"string","description":"User ID"},"token":{"type":"string","description":"Authentication token\n"},"tokenExpires":{"type":"string","format":"date-time","description":"Token expiration date\n"}}}}}},"400":{"description":"Error in authentication\n","content":{"*/*":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}}}}}},"default":{"description":"Error in authentication\n"}}}},"/users/register":{"post":{"operationId":"register","summary":"Register with REST API","description":"Notes:\n - You will need to provide the token for any of the authenticated methods.\n","tags":["Login"],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"},"email":{"description":"Your email\n","type":"string"}},"required":["username","password","email"]}}},"required":true},"responses":{"200":{"description":"Successful registration","content":{"*/*":{"schema":{"items":{"properties":{"id":{"type":"string"},"token":{"type":"string"},"tokenExpires":{"type":"string"}}}}}}},"400":{"description":"Error in registration\n","content":{"*/*":{"schema":{"items":{"properties":{"error":{"type":"number"},"reason":{"type":"string"}}}}}}},"default":{"description":"Error in registration\n"}}}},"/api/admin/attachment-settings":{"get":{"operationId":"get_attachment_settings","summary":"Get the attachment storage / upload-block settings (GlobalAdmin)","description":"Only the global admin can call this. Returns the Admin Panel >\n Attachments settings document, including `limitSettings.attachmentsUploadBlocked`\n and `limitSettings.avatarsUploadBlocked` plus the size limits. Cloud-storage\n secret keys (S3 secretAccessKey, Azure accountKey/connectionString, GCS\n credentials) are masked and never returned; a boolean `\u003cfield>Set` marker\n shows whether a value exists.\n","tags":["AttachmentStorageSettings","Settings"],"security":[{"UserSecurity":[]}],"responses":{"200":{"description":"200 response","content":{"application/json":{"schema":{"type":"Object"}}}}}},"put":{"operationId":"update_attachment_settings","summary":"Update the attachment storage / upload-block settings (GlobalAdmin)","description":"Only the global admin can call this. The request body is a\n partial settings object (for example\n `{\"limitSettings\": {\"avatarsUploadBlocked\": true}}`). It is applied through\n the same update path as the `updateAttachmentStorageSettings` Meteor method,\n so validation and `$set` semantics are identical: cloud-storage secrets left\n blank are preserved. The masked, updated settings document is returned.\n","tags":["AttachmentStorageSettings","Settings"],"security":[{"UserSecurity":[]}],"responses":{"200":{"description":"200 response","content":{"application/json":{"schema":{"type":"Object"}}}}}}},"/api/admin/domains":{"get":{"operationId":"get_admin_domains","summary":"List email domains with their user counts (GlobalAdmin)","description":"Only the global admin can call this. CountsLine truncated
|
||||
const __redoc_definition = {"openapi":"3.2.0","info":{"title":"WeKan REST API","version":"v13.05","description":"The REST API allows you to control and extend WeKan with ease.\n\nIf you are an end-user and not a dev or a tester, [create an issue](https://github.com/wekan/wekan/issues/new) to request new APIs.\n\n> All API calls in the documentation are made using `curl`. However, you are free to use Java / Python / PHP / Golang / Ruby / Swift / Objective-C / Rust / Scala / C# or any other programming languages.\n\n# Production Security Concerns\nWhen calling a production WeKan server, ensure it is running via HTTPS and has a valid SSL Certificate. The login method requires you to post your username and password in plaintext, which is why we highly suggest only calling the REST login api over HTTPS. Also, few things to note:\n\n* Only call via HTTPS\n* Implement a timed authorization token expiration strategy\n* Ensure the calling user only has permissions for what they are calling and no more\n"},"paths":{"/users/login":{"post":{"operationId":"login","summary":"Login with REST API","tags":["Login"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"}}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"}}}}},"description":"Login credentials","required":true},"responses":{"200":{"description":"Successful authentication","content":{"*/*":{"schema":{"type":"object","required":["id","token","tokenExpires"],"properties":{"id":{"type":"string","description":"User ID"},"token":{"type":"string","description":"Authentication token\n"},"tokenExpires":{"type":"string","format":"date-time","description":"Token expiration date\n"}}}}}},"400":{"description":"Error in authentication\n","content":{"*/*":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}}}}}},"default":{"description":"Error in authentication\n"}}}},"/users/register":{"post":{"operationId":"register","summary":"Register with REST API","description":"Notes:\n - You will need to provide the token for any of the authenticated methods.\n","tags":["Login"],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"},"email":{"description":"Your email\n","type":"string"}},"required":["username","password","email"]}}},"required":true},"responses":{"200":{"description":"Successful registration","content":{"*/*":{"schema":{"items":{"properties":{"id":{"type":"string"},"token":{"type":"string"},"tokenExpires":{"type":"string"}}}}}}},"400":{"description":"Error in registration\n","content":{"*/*":{"schema":{"items":{"properties":{"error":{"type":"number"},"reason":{"type":"string"}}}}}}},"default":{"description":"Error in registration\n"}}}},"/api/admin/attachment-settings":{"get":{"operationId":"get_attachment_settings","summary":"Get the attachment storage / upload-block settings (GlobalAdmin)","description":"Only the global admin can call this. Returns the Admin Panel >\n Attachments settings document, including `limitSettings.attachmentsUploadBlocked`\n and `limitSettings.avatarsUploadBlocked` plus the size limits. Cloud-storage\n secret keys (S3 secretAccessKey, Azure accountKey/connectionString, GCS\n credentials) are masked and never returned; a boolean `\u003cfield>Set` marker\n shows whether a value exists.\n","tags":["AttachmentStorageSettings","Settings"],"security":[{"UserSecurity":[]}],"responses":{"200":{"description":"200 response","content":{"application/json":{"schema":{"type":"Object"}}}}}},"put":{"operationId":"update_attachment_settings","summary":"Update the attachment storage / upload-block settings (GlobalAdmin)","description":"Only the global admin can call this. The request body is a\n partial settings object (for example\n `{\"limitSettings\": {\"avatarsUploadBlocked\": true}}`). It is applied through\n the same update path as the `updateAttachmentStorageSettings` Meteor method,\n so validation and `$set` semantics are identical: cloud-storage secrets left\n blank are preserved. The masked, updated settings document is returned.\n","tags":["AttachmentStorageSettings","Settings"],"security":[{"UserSecurity":[]}],"responses":{"200":{"description":"200 response","content":{"application/json":{"schema":{"type":"Object"}}}}}}},"/api/admin/domains":{"get":{"operationId":"get_admin_domains","summary":"List email domains with their user counts (GlobalAdmin)","description":"Only the global admin can call this. CountsLine truncated
|
||||
const __redoc_options = {"skipBundle":true,"disableTelemetry":false};
|
||||
|
||||
hydrate(__redoc_definition, __redoc_options, document.getElementById('redoc'));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
swagger: '2.0'
|
||||
info:
|
||||
title: WeKan REST API
|
||||
version: v13.04
|
||||
version: v13.05
|
||||
description: |
|
||||
The REST API allows you to control and extend WeKan with ease.
|
||||
|
||||
|
||||
@@ -61,6 +61,10 @@ npm_cli="$(dirname "$(readlink -f "$(command -v npm)")")/npm-cli.js"
|
||||
[ -f "$npm_cli" ] || npm_cli="$PREFIX/lib/node_modules/npm/bin/npm-cli.js"
|
||||
npm() { "$node" "$npm_cli" "$@"; }
|
||||
export -f npm 2>/dev/null || true
|
||||
# npm-retry.sh is a new bash: it is given the command itself, "$node"
|
||||
# "$npm_cli", never the npm function above. The function reaches it through
|
||||
# export -f, but $node and $npm_cli do not, and under its set -u v13.04's
|
||||
# Android bundles all died there with "environment: node: unbound variable".
|
||||
|
||||
server="$root/bundle/programs/server"
|
||||
appmods="$server/npm/node_modules"
|
||||
@@ -76,7 +80,7 @@ fi
|
||||
# have no Android prebuild, were never compiled, and WeKan did not start. It
|
||||
# is idempotent, so a bundle already prepared is left as it is.
|
||||
"$node" "$root/releases/prepare-bundle-npm.mjs" "$root/bundle"
|
||||
(cd "$server" && bash "$root/releases/npm-retry.sh" npm install)
|
||||
(cd "$server" && bash "$root/releases/npm-retry.sh" "$node" "$npm_cli" install)
|
||||
# accounts-password requires both at startup with no fallback. Load them here
|
||||
# with Android's Node.js, so a missing addon stops the build with its name -
|
||||
# check-addon-arch below passes Linux prebuilds, which Android does not load.
|
||||
@@ -86,7 +90,7 @@ for (const name of ["argon2", "bcrypt"]) {
|
||||
catch (error) { console.error(`::error::${name} has no Android addon: ${error.message.split("\n")[0]}`); process.exit(1); }
|
||||
}')
|
||||
# sharp has no Android prebuilt: built from source against Termux's libvips.
|
||||
if ! (cd "$appmods/sharp" && bash "$root/releases/npm-retry.sh" npm install --no-save --omit=dev node-addon-api node-gyp && "$node" install/build.js); then
|
||||
if ! (cd "$appmods/sharp" && bash "$root/releases/npm-retry.sh" "$node" "$npm_cli" install --no-save --omit=dev node-addon-api node-gyp && "$node" install/build.js); then
|
||||
echo "::warning::sharp could not be built against Termux's libvips here; it runs as WebAssembly (@img/sharp-wasm32)."
|
||||
fi
|
||||
"$node" "$root/releases/prune-build-only-modules.mjs" "$root/bundle"
|
||||
|
||||
@@ -55,10 +55,11 @@ against its assets: new or removed OS/CPU targets fail planning visibly.
|
||||
Meteor's Bun/ESM support is still proposed in
|
||||
[meteor/meteor#14751](https://github.com/meteor/meteor/pull/14751).
|
||||
The workflow clones the app's exact Meteor release into `.tools/meteor-bun`.
|
||||
For Meteor 3.6-rc.1 it applies `meteor-3.6-rc.1.patch`, ported from
|
||||
For Meteor 3.6 it applies `meteor-3.6.patch`, ported from
|
||||
`dupontbertrand/meteor` commit `c0ab9318822f36f902da6124c1356ede58b71a4e` onto
|
||||
Meteor 3.6-rc.0 (`cc8cf7d21d24da5f4a4fd456527225bc5ce0e721`); it applies
|
||||
unchanged to 3.6-rc.1 (`311f5cd2d26f74ce187dc2e639bd57aab81929e4`).
|
||||
unchanged to 3.6-rc.1 (`311f5cd2d26f74ce187dc2e639bd57aab81929e4`) and to 3.6
|
||||
(`e730097ce42a0dbc4c134aeb1706147b02112844`).
|
||||
|
||||
The port preserves the 3.6 transport documentation and Rspack's await of the
|
||||
server bundle's exported promise. It does not downgrade package pins, change
|
||||
|
||||
File renamed without changes.
@@ -12,9 +12,9 @@ meteor_dir="$root/.tools/meteor-bun"
|
||||
git clone --depth 1 --branch "release/METEOR@$release" https://github.com/meteor/meteor.git "$meteor_dir"
|
||||
if [ ! -f "$meteor_dir/tools/static-assets/server/esm-loader.mjs" ]; then
|
||||
# Do not silently downgrade core packages to the PR's older 3.5 base.
|
||||
[ "$release" = 3.6-rc.1 ] || { echo "Port the Bun patch to Meteor $release before building"; exit 1; }
|
||||
[ "$(git -C "$meteor_dir" rev-parse HEAD)" = 311f5cd2d26f74ce187dc2e639bd57aab81929e4 ] || exit 1
|
||||
git -C "$meteor_dir" apply --check "$root/releases/bun/meteor-3.6-rc.1.patch"
|
||||
git -C "$meteor_dir" apply "$root/releases/bun/meteor-3.6-rc.1.patch"
|
||||
[ "$release" = 3.6 ] || { echo "Port the Bun patch to Meteor $release before building"; exit 1; }
|
||||
[ "$(git -C "$meteor_dir" rev-parse HEAD)" = e730097ce42a0dbc4c134aeb1706147b02112844 ] || exit 1
|
||||
git -C "$meteor_dir" apply --check "$root/releases/bun/meteor-3.6.patch"
|
||||
git -C "$meteor_dir" apply "$root/releases/bun/meteor-3.6.patch"
|
||||
fi
|
||||
printf '%s\n' "$meteor_dir" >> "$GITHUB_PATH"
|
||||
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
|
||||
appTitle = (defaultText = "Wekan"),
|
||||
# The name of the app as it is displayed to the user.
|
||||
|
||||
appVersion = 1304,
|
||||
appVersion = 1305,
|
||||
# Increment this for every release.
|
||||
|
||||
appMarketingVersion = (defaultText = "13.04~2026-11-09"),
|
||||
appMarketingVersion = (defaultText = "13.05~2026-11-10"),
|
||||
# Human-readable presentation of the app version.
|
||||
|
||||
minUpgradableAppVersion = 0,
|
||||
|
||||
+5
-5
@@ -7,7 +7,7 @@
|
||||
# FOUR channels — stable, candidate, beta and edge. Every snap job does exactly
|
||||
# that (snap-native, snap-launchpad and snap-variants all publish
|
||||
# `stable,candidate,beta,edge`), for the default snap and for the wekan-ondra and
|
||||
# wekan-gantt-gpl variants alike. It ships the newest WeKan (Meteor 3.6-rc.1,
|
||||
# wekan-gantt-gpl variants alike. It ships the newest WeKan (Meteor 3.6,
|
||||
# Node.js 26, FerretDB v1, MongoDB 7, Caddy 2).
|
||||
#
|
||||
# snapcraft-core26.yaml is the SAME WeKan on `base: core26`, kept for testing the
|
||||
@@ -19,7 +19,7 @@
|
||||
# base: core24 (not core26) · no build-base: devel · grade: stable
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
name: wekan
|
||||
version: '13.04'
|
||||
version: '13.05'
|
||||
base: core24
|
||||
confinement: strict
|
||||
grade: stable
|
||||
@@ -703,18 +703,18 @@ parts:
|
||||
armhf) WEKAN_ARCH="armhf" ;;
|
||||
*) echo "Unsupported architecture: ${CRAFT_ARCH_BUILD_FOR}"; exit 1 ;;
|
||||
esac
|
||||
WEKAN_ZIP="wekan-13.04-${WEKAN_ARCH}.zip"
|
||||
WEKAN_ZIP="wekan-13.05-${WEKAN_ARCH}.zip"
|
||||
echo "Cleaning environment first"
|
||||
rm -rf .build
|
||||
mkdir .build
|
||||
cd .build
|
||||
#wget https://github.com/wekan/wekan/releases/download/v13.04/wekan-13.04-amd64.zip
|
||||
#wget https://github.com/wekan/wekan/releases/download/v13.05/wekan-13.05-amd64.zip
|
||||
# Retry: a release asset can 404 for a short while right after it is
|
||||
# uploaded (CDN/propagation lag), and a plain wget treated that as
|
||||
# fatal. --retry-on-http-error covers the 404/5xx window; a genuinely
|
||||
# missing bundle still fails after the tries are spent.
|
||||
wget --tries=20 --waitretry=20 --retry-on-http-error=404,403,500,502,503 \
|
||||
"https://github.com/wekan/wekan/releases/download/v13.04/${WEKAN_ZIP}"
|
||||
"https://github.com/wekan/wekan/releases/download/v13.05/${WEKAN_ZIP}"
|
||||
unzip "${WEKAN_ZIP}"
|
||||
python3 ../releases/check-telemetry.py --bundle bundle
|
||||
rm "${WEKAN_ZIP}"
|
||||
|
||||
@@ -37,7 +37,7 @@ test('the bundle is rebuilt by the Android Node.js itself, checked and started',
|
||||
// happened in programs/server/node_modules, where sharp is not.
|
||||
assert.match(build, /appmods="\$server\/npm\/node_modules"\nrm -rf "\$appmods\/@img\/sharp-linux-"\*/);
|
||||
assert.doesNotMatch(build, /rm -rf "\$server\/node_modules\/@img/, 'not the wrong directory');
|
||||
assert.match(build, /cd "\$appmods\/sharp" && bash "\$root\/releases\/npm-retry\.sh" npm install --no-save --omit=dev node-addon-api node-gyp && "\$node" install\/build\.js/);
|
||||
assert.match(build, /cd "\$appmods\/sharp" && bash "\$root\/releases\/npm-retry\.sh" "\$node" "\$npm_cli" install --no-save --omit=dev node-addon-api node-gyp && "\$node" install\/build\.js/);
|
||||
assert.match(build, /::warning::sharp could not be built[^\n]*WebAssembly/);
|
||||
// Termux's user does not own the bind mount: chmod only what is not
|
||||
// already executable (v12.43-v12.44 stopped at "Operation not permitted").
|
||||
@@ -59,7 +59,7 @@ test('argon2 and bcrypt are compiled for Android and must load before the bundle
|
||||
const prepare = build.indexOf('"$node" "$root/releases/prepare-bundle-npm.mjs" "$root/bundle"');
|
||||
// Through npm-retry.sh since v13.03's Sandstorm .spk was lost to a 504 from
|
||||
// github.com (tests/npmRetry.test.cjs): the same install, retried on outage.
|
||||
const install = build.indexOf('(cd "$server" && bash "$root/releases/npm-retry.sh" npm install)');
|
||||
const install = build.indexOf('(cd "$server" && bash "$root/releases/npm-retry.sh" "$node" "$npm_cli" install)');
|
||||
const loads = build.indexOf('for (const name of ["argon2", "bcrypt"])');
|
||||
assert.ok(prepare > 0 && prepare < install, 'the bundle declares its installers before npm installs');
|
||||
assert.ok(loads > install && loads < build.indexOf('check-addon-arch.mjs'), 'loaded with Android Node.js right after the install');
|
||||
@@ -105,7 +105,7 @@ test('termux-exec is preloaded before npm, so #!/usr/bin/env scripts run', () =>
|
||||
assert(preload > 0, 'LD_PRELOAD is exported');
|
||||
assert.match(build, /"\$PREFIX\/lib\/libtermux-exec-ld-preload\.so" "\$PREFIX\/lib\/libtermux-exec\.so"/, 'both termux-exec generations, newest first, as login does');
|
||||
assert.match(build, /LD_PRELOAD="\$lib" sh -c true/, 'kept only if a program still starts with it');
|
||||
assert(preload < build.indexOf('(cd "$server" && bash "$root/releases/npm-retry.sh" npm install)'), 'before npm runs any install script');
|
||||
assert(preload < build.indexOf('(cd "$server" && bash "$root/releases/npm-retry.sh" "$node" "$npm_cli" install)'), 'before npm runs any install script');
|
||||
});
|
||||
|
||||
test('negative: an LD_PRELOAD already set is not replaced', () => {
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
// Meteor 3.5.3's six security fixes, in WeKan's forks of Meteor's own
|
||||
// packages in packages/ (a local package overrides the release's). The forks
|
||||
// were made because Meteor 3.6-rc.0 lacked the fixes; 3.6-rc.1 carries them,
|
||||
// and the forks are rebased onto it for what is WeKan's own: the Admin Panel /
|
||||
// and the forks are rebased onto it - and onto Meteor 3.6, whose six packages
|
||||
// differ from 3.6-rc.1's only in their version line - for what is WeKan's own: the Admin Panel /
|
||||
// Problems reports and the crypto-RNG keys (tests/meteorForkRandomKeys.test.cjs).
|
||||
// This suite keeps checking that the fixes are there, whichever side has them.
|
||||
// Run: node tests/meteor353SecurityFixes.test.cjs
|
||||
@@ -25,9 +26,9 @@ const { METEOR_SECURITY_KEYS, meteorSecurityEvent } = require('../models/lib/met
|
||||
const { CATALOG } = require('../models/lib/securityCategories.js');
|
||||
|
||||
const { METEOR_PACKAGE_FORKS: FORKS } = require('./lib/meteorPackageForks.cjs');
|
||||
const BASE_RELEASE = 'METEOR@3.6-rc.1';
|
||||
const BASE_RELEASE = 'METEOR@3.6';
|
||||
// The wrap number a fork adds to the release's own version of the package.
|
||||
const FORK_VERSION = /-rc360\.1_1$/;
|
||||
const FORK_VERSION = /^\d+\.\d+\.\d+_1$/;
|
||||
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
@@ -70,7 +71,7 @@ const SOURCES = ['packages', 'server', 'models', 'imports', 'client']
|
||||
|
||||
test(`the forks are for ${BASE_RELEASE}, and none outlives it`, () => {
|
||||
// A local package overrides the release's own SILENTLY. Moved to another
|
||||
// Meteor release, these would keep 3.6-rc.1's code under the new release's
|
||||
// Meteor release, these would keep 3.6's code under the new release's
|
||||
// name. So this fails the moment .meteor/release changes: check whether the
|
||||
// new release has the 3.5.3 fixes (the GitHub release notes list them) and
|
||||
// delete packages/<name> for each that does, or rebase the fork onto it.
|
||||
@@ -83,7 +84,7 @@ test('every fork is marked as one, and .meteor/versions resolves to it', () => {
|
||||
const versions = read('.meteor/versions');
|
||||
for (const name of FORKS) {
|
||||
const version = read(`packages/${name}/package.js`).match(/version:\s*'([^']+)'/)[1];
|
||||
assert.match(version, FORK_VERSION, `${name}'s fork keeps 3.6-rc.1's version with a _1 wrap number: ${version}`);
|
||||
assert.match(version, FORK_VERSION, `${name}'s fork keeps 3.6's version with a _1 wrap number: ${version}`);
|
||||
assert.ok(versions.split('\n').includes(`${name}@${version}`),
|
||||
`.meteor/versions must resolve ${name} to the fork ${version}`);
|
||||
}
|
||||
|
||||
@@ -181,6 +181,53 @@ test('every npm install in a script a workflow runs goes through it too', () =>
|
||||
'these npm commands, run by a workflow, can lose a release to a five-minute outage');
|
||||
});
|
||||
|
||||
test('npm-retry.sh is given a program, never a shell function of the caller', () => {
|
||||
// npm-retry.sh is a new bash with set -u. A function of the script that
|
||||
// calls it reaches it only through export -f, and the variables that
|
||||
// function reads do not: v13.04's Android bundles all died with
|
||||
// "environment: node: unbound variable" when build-bundle.sh handed it its
|
||||
// npm() { "$node" "$npm_cli" ...; }. So, for every releases/ script, no
|
||||
// function it defines is the command it gives npm-retry.sh.
|
||||
const dir = path.join(repoRoot, 'releases');
|
||||
const scripts = [];
|
||||
const walk = d => fs.readdirSync(d, { withFileTypes: true }).forEach(e => {
|
||||
const p = path.join(d, e.name);
|
||||
if (e.isDirectory()) walk(p); else if (/\.sh$/.test(e.name)) scripts.push(p);
|
||||
});
|
||||
walk(dir);
|
||||
const bad = [];
|
||||
for (const file of scripts) {
|
||||
const text = fs.readFileSync(file, 'utf8');
|
||||
const functions = [...text.matchAll(/^\s*(?:function\s+)?([A-Za-z_][\w-]*)\s*\(\)\s*\{/gm)].map(m => m[1]);
|
||||
text.split('\n').forEach((line, i) => {
|
||||
if (/^\s*#/.test(line)) return;
|
||||
const m = /npm-retry\.sh"?\s+"?([^\s"]+)/.exec(line);
|
||||
if (m && functions.includes(m[1])) bad.push(`${path.relative(repoRoot, file)}:${i + 1}: ${line.trim()}`);
|
||||
});
|
||||
}
|
||||
assert.deepStrictEqual(bad, [], 'npm-retry.sh runs these as a program in a new bash, where the function has no variables');
|
||||
// The Android installs still go through it, as the program they are.
|
||||
const android = fs.readFileSync(path.join(dir, 'android/build-bundle.sh'), 'utf8');
|
||||
assert.strictEqual((android.match(/npm-retry\.sh" "\$node" "\$npm_cli" install/g) || []).length, 2,
|
||||
'both Android npm installs are retried, given Android\'s node and npm-cli.js');
|
||||
});
|
||||
|
||||
test('a caller\'s function in npm-retry.sh fails as it did, and its program works', () => {
|
||||
// The failure itself, so the rule above has a reason a test shows: a
|
||||
// function exported with export -f reaches npm-retry.sh, its variable does not.
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'npmretry-'));
|
||||
const prog = path.join(dir, 'fake-npm');
|
||||
fs.writeFileSync(prog, '#!/bin/sh\necho "installed $*"\n', { mode: 0o755 });
|
||||
const run = body => spawnSync('bash', ['-c', `set -u; node_bin=${JSON.stringify(prog)}; npm() { "$node_bin" "$@"; }; export -f npm; ${body}`],
|
||||
{ encoding: 'utf8', env: { ...process.env, NPM_RETRY_SLEEPS: '0' } });
|
||||
const viaFunction = run(`bash ${JSON.stringify(script)} npm install`);
|
||||
assert.notStrictEqual(viaFunction.status, 0, 'the function, without its variable, fails');
|
||||
assert.match(viaFunction.stdout + viaFunction.stderr, /node_bin: unbound variable/);
|
||||
const viaProgram = run(`bash ${JSON.stringify(script)} "$node_bin" install`);
|
||||
assert.strictEqual(viaProgram.status, 0, viaProgram.stdout + viaProgram.stderr);
|
||||
assert.match(viaProgram.stdout, /installed install/);
|
||||
});
|
||||
|
||||
test('the containers can reach the script that retries for them', () => {
|
||||
// Two of these installs run inside `docker run`, where the repository is not
|
||||
// present unless it is mounted. A call to /releases/npm-retry.sh in a
|
||||
|
||||
@@ -297,6 +297,29 @@ async function main() {
|
||||
assert.equal(empty.data.project.entities['wekan-project-1'].title, 'Empty');
|
||||
});
|
||||
|
||||
// A card whose list is archived is collected with listTitle '': the export
|
||||
// threw "Cannot read properties of undefined (reading 'taskIds')" on its
|
||||
// missing tag. It is the "Untitled" list now, its tag and its panel alike.
|
||||
test('a card with no list title exports into the Untitled list', () => {
|
||||
const backup = JSON.parse(formatSuperProductivity({ board: { title: 'B' }, lists: [{ title: 'Doing' }], swimlanes: [],
|
||||
items: [{ cardId: 'a', title: 'Orphan', listTitle: '', labels: [] }, { cardId: 'b', title: 'Kept', listTitle: 'Doing', labels: [] }] }, { now: 1 }));
|
||||
assertSuperProductivityAccepts(backup);
|
||||
const orphan = backup.data.task.entities.a;
|
||||
const untitled = Object.values(backup.data.tag.entities).find(t => t.title === 'Untitled');
|
||||
assert.ok(untitled, 'the Untitled list has its tag');
|
||||
assert.deepEqual(orphan.tagIds, [untitled.id]);
|
||||
assert.deepEqual(untitled.taskIds, ['a']);
|
||||
const panel = backup.data.boards.boardCfgs[0].panels.find(p => p.title === 'Untitled');
|
||||
assert.deepEqual(panel.includedTagIds, [untitled.id], 'its panel filters by that tag');
|
||||
// Negative: no task names a tag that does not exist, and no panel a null tag.
|
||||
for (const task of Object.values(backup.data.task.entities)) {
|
||||
for (const id of task.tagIds) assert.ok(backup.data.tag.entities[id], `${task.id} names ${id}`);
|
||||
}
|
||||
for (const p of backup.data.boards.boardCfgs[0].panels) {
|
||||
assert.ok(!p.includedTagIds.includes(null) && !p.excludedTagIds.includes(null), `${p.title} names no null tag`);
|
||||
}
|
||||
});
|
||||
|
||||
test('the format is wired into import, export, the import page and the export menu', () => {
|
||||
assert.equal(EXTERNAL_PARSERS.superproductivity, parseSuperProductivity);
|
||||
assert.equal(typeof formatters.superproductivity, 'function');
|
||||
|
||||
Reference in new issue
Block a user