Compare commits

...
51 Commits
Author SHA1 Message Date
Lauri Ojansivu c62396e389 v4.92 2021-02-03 02:32:00 +02:00
Lauri Ojansivu d52e85f298 Updated ChangeLog. 2021-02-03 02:27:18 +02:00
Lauri Ojansivu 05ebae7329 Updated dependencies.
Thanks to developers of dependencies !
2021-02-03 02:25:37 +02:00
Lauri Ojansivu b697bb656e Updated ChangeLog. 2021-02-03 01:50:52 +02:00
Lauri Ojansivu 4d7de2adce Merge pull request #3523 from mfilser/notifications_overlap_avatar_mobile_view
Notifications avatar overlaped at mobile view
2021-02-03 01:49:32 +02:00
Lauri Ojansivu 8a9528e787 Updated README 2021-02-03 01:45:52 +02:00
Martin Filser 6c6cba51fa Notification trash link was not visible if actifity text is too long 2021-02-03 00:20:56 +01:00
Martin Filser 28e23f9d87 Notification, each notification has now more space at top 2021-02-02 23:07:28 +01:00
Martin Filser e31192e97e Notification, split line was missing at mobile view 2021-02-02 23:02:45 +01:00
Martin Filser 26b7137b5c Notification, Avatar overlaped at mobile view 2021-02-02 23:02:33 +01:00
Lauri Ojansivu 912200a2ec Updated ChangeLog.
Related https://github.com/wekan/wekan/discussions/3496
2021-02-02 21:12:56 +02:00
Lauri Ojansivu c42d0d7423 Merge branch 'bronger-sorted-archives' 2021-02-02 21:09:41 +02:00
Lauri Ojansivu 3da66a0fe3 Sorted archives Part 2.
Thanks to xet7 !
2021-02-02 21:08:34 +02:00
Lauri Ojansivu 41e1f8fbc3 Merge branch 'sorted-archives' of https://github.com/bronger/wekan into bronger-sorted-archives 2021-02-02 20:56:09 +02:00
Lauri Ojansivu 130ac3c917 Updated ChangeLog. 2021-02-02 20:55:25 +02:00
Lauri Ojansivu 3774060d32 Createtoken API: Added better description and deleted extra file.
Thanks to magicbelette and xet7 !

Fixes #2887
2021-02-02 20:51:41 +02:00
Lauri Ojansivu d8c8856548 Merge pull request #3520 from messagerie-melanie2/master
Add createtoken API
2021-02-02 20:48:00 +02:00
Lauri Ojansivu efec00a550 Updated ChangeLog. 2021-02-02 20:30:22 +02:00
Lauri Ojansivu 3d3cf1d551 Merge pull request #3521 from mfilser/master
Cards, CustomFields sorted alphabetically, fixes #3517
2021-02-02 20:28:35 +02:00
Lauri Ojansivu c52d17b6fb Updated translations. 2021-02-02 18:47:08 +02:00
Martin Filser c0b9ef5990 Cards, CustomFields sorted alphabetically #3517
- last fix didn't work and disabled alphabetic sorting
- also works with linked cards
2021-02-02 17:45:43 +01:00
Lauri Ojansivu e303159b98 Updated ChangeLog. 2021-02-02 18:40:12 +02:00
Lauri Ojansivu f274b3c26b Try fix removed nonexistent document error.
Thanks to xet7 !

Related #3203,
related #3252,
related #2230
related #1629
2021-02-02 18:36:21 +02:00
Lauri Ojansivu 81fdc9a865 Updated ChangeLog. 2021-02-02 18:33:23 +02:00
Lauri Ojansivu f40c9804f8 Disable some console.log code, that is only needed while developing.
Thanks to xet7 !
2021-02-02 18:31:13 +02:00
Lauri Ojansivu 4d13d51038 Updated ChangeLog. 2021-02-02 18:14:18 +02:00
magicbelette 5c4421dc38 Delete test file 2021-02-02 17:12:57 +01:00
Lauri Ojansivu 76ef6a81ab Merge pull request #3519 from jrsupplee/issue-2074
Hopeful fix for i18n not working in `onRendered()`
2021-02-02 18:07:25 +02:00
magicbelette a7b43d5b57 Add createtoken API 2021-02-02 17:06:06 +01:00
John R. Supplee e4f50d4713 Hopeful fix for i18n not working in onRendered()
* Remove the i18n initialization code from an `autorun()` block
* Add some console statements to help with debugging production.
* Add functions to `Boards` for label colors and color mapping
2021-02-02 17:56:18 +02:00
Lauri Ojansivu 1e71237627 Merge pull request #3516 from mfilser/notifications_overlap_avatar
Avatar overlaped notifications
2021-02-02 16:50:24 +02:00
Torsten Bronger 678c8f6bf6 Printed archivedAt under every item in the archive. 2021-02-02 14:52:14 +01:00
Torsten Bronger 786c27bbec Added sorting by archivedAt in the archive.
I use modifiedAt as a fall back for legacy cards which don't have archivedAt
set yet.
2021-02-02 14:52:12 +01:00
Torsten Bronger 710643d8cb Added field archivedAt to cards, lists, swimlanes, and boards. 2021-02-02 14:52:08 +01:00
Martin Filser e595aba189 Minicard, assignee and red line now aligned again 2021-02-02 09:24:26 +01:00
Martin Filser ea67e94c47 Notification, fixed avatar icon (was an ellipse) 2021-02-02 08:45:37 +01:00
Martin Filser b2c2067f7d Avatar overlaped notifications #3515 2021-02-01 18:26:18 +01:00
Lauri Ojansivu 4fc2d7b935 Updated translations. 2021-01-31 01:26:51 +02:00
Lauri Ojansivu b1b9dd208b Updated ChangeLog. 2021-01-30 20:54:54 +02:00
Lauri Ojansivu ee2f7c077f Added badge for CII Best Practices.
Thanks to CII and xet7 !
2021-01-30 20:51:36 +02:00
Lauri Ojansivu a385d6f4fd Added PGP public key for sending security vulnerability reports. 2021-01-30 20:15:52 +02:00
Lauri Ojansivu 7031b7a3c7 Updated security report email address. 2021-01-30 20:07:03 +02:00
Lauri Ojansivu 0f0a5fba1f Merge branch 'master' of github.com:wekan/wekan 2021-01-30 18:23:00 +02:00
Lauri Ojansivu 1d7af3f011 Updated translations. 2021-01-30 18:22:40 +02:00
Lauri Ojansivu 6fd85f97b3 Updated ChangeLog. 2021-01-30 18:18:54 +02:00
Lauri Ojansivu a6d17f3813 Merge pull request #3509 from jrsupplee/fix-2
Don't reload page when returning default sort
2021-01-30 18:17:39 +02:00
Lauri Ojansivu 4e830ea416 Updated ChangeLog. 2021-01-30 18:15:48 +02:00
Lauri Ojansivu fc5c936272 Merge pull request #3510 from jrsupplee/import-user-mapping
Import user mapping
2021-01-30 18:04:30 +02:00
John R. Supplee b2af684c4d JSON import: add note about unmapped members 2021-01-30 11:44:53 +02:00
John R. Supplee 0446999c63 Add new importUsernames field for import user mapping 2021-01-30 02:35:29 +02:00
John R. Supplee 6920c39752 Don't reload page when returning default sort 2021-01-29 21:09:28 +02:00
96 changed files with 56881 additions and 56198 deletions

No files matched your search

+48
View File
@@ -1,3 +1,51 @@
# v4.92 2021-02-03 Wekan release
This release adds the following improvements:
- [Import user mapping improvements](https://github.com/wekan/wekan/pull/3510).
Thanks to jrsupplee.
- Added Createtoken API.
[Part 1](https://github.com/wekan/wekan/pull/3520),
[Part 2](https://github.com/wekan/wekan/commit/3774060d32abcfee17dc1c31958d4673794d8619).
Thanks to magicbelette and xet7.
- Sorted archives.
[Part 1](https://github.com/wekan/wekan/pull/3518),
[Part 2](https://github.com/wekan/wekan/commit/3da66a0fe30c2b54b63e5d098232b375d899925e).
Thanks to bronger, jrsupplee and xet7.
and adds the following updates:
- [Updated dependencies](https://github.com/wekan/wekan/commit/05ebae7329ba0dd3fe9b04cd63b1f983830cdeee).
Thanks to developers of dependencies.
and fixes the following bugs:
- [Don't reload page when returning default sort](https://github.com/wekan/wekan/pull/3509).
Thanks to jrsupplee.
- [Avatar overlaped notifications](https://github.com/wekan/wekan/pull/3516).
Thanks to mfilser.
- [Hopeful fix for i18n not working in `onRendered()`](https://github.com/wekan/wekan/pull/3519).
Thanks to jrsupplee.
- [Disable some console.log code, that is only needed while developing](https://github.com/wekan/wekan/commit/f40c9804f848fdb91229c5718ad97495337109ba).
Thanks to xet7.
- [Try fix removed nonexistent document error](https://github.com/wekan/wekan/commit/f274b3c26be60813829dcf2b0e68a8dd876ff614).
Thanks to Brulf, TheMasterFX and xet7.
- [Fixed Cards and CustomFields sorted alphabetically](https://github.com/wekan/wekan/pull/3521).
Thanks to mfilser.
- [Notifications avatar overlaped at mobile view](https://github.com/wekan/wekan/pull/3523).
Thanks to mfilser.
and improves some security related info:
- [Added badge for CII Best Practices](https://github.com/wekan/wekan/commit/ee2f7c077fe56d6fedb8b75ae3cba6bab56f9363).
Thanks to CII and xet7.
- [Added PGP public key for sending security vulnerability reports](https://github.com/wekan/wekan/commit/a385d6f4fd76e2bb0f374963848513b9373d6b5a).
Thanks to xet7.
- [Updated security report email address](https://github.com/wekan/wekan/commit/7031b7a3c77acc0ddeabe436572dd4057001e9f5).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.91 2021-01-29 Wekan release
This release fixes the following bugs:
+1
View File
@@ -12,6 +12,7 @@
[![Project Dependencies](https://david-dm.org/wekan/wekan.svg "Project Dependencies")](https://david-dm.org/wekan/wekan)
[![Code analysis at Open Hub](https://img.shields.io/badge/code%20analysis-at%20Open%20Hub-brightgreen.svg "Code analysis at Open Hub")](https://www.openhub.net/p/wekan)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwekan%2Fwekan.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fwekan%2Fwekan?ref=badge_shield)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4619/badge)](https://bestpractices.coreinfrastructure.org/projects/4619)
## [Translate Wekan at Transifex](https://transifex.com/wekan/wekan)
+3 -3
View File
@@ -1,10 +1,10 @@
Security is very important to us. If you discover any issue regarding security, please disclose
the information responsibly by sending an email to security (at) wekan.team and not by
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.
We thank you with a place at our hall of fame page, that is
at https://wekan.github.io/hall-of-fame . Others have just posted public GitHub issue,
so they are not at that hall-of-fame page.
at https://wekan.github.io/hall-of-fame
## How should reports be formatted?
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v4.91.0"
appVersion: "v4.92.0"
files:
userUploads:
- README.md
+1 -1
View File
@@ -11,7 +11,7 @@ BlazeComponent.extendComponent({
return Boards.find(
{ archived: true },
{
sort: { sort: 1 /* boards default sorting */ },
sort: { archivedAt: -1, modifiedAt: -1 },
},
);
},
+1
View File
@@ -176,6 +176,7 @@
border-radius: 50%
height: 28px
width: @height
margin: 0px 0px 4px 0px
.assignee
float: right
+2
View File
@@ -22,6 +22,8 @@ template(name="importMapMembers")
if usersLoaded.get
.map-members
p {{_ 'import-members-map'}}
p.import-members-map-note
| {{_ 'import-members-map-note' }}
.mapping-list
each members
a.mapping-item.js-select-member(class="{{#if wekanId}}filled{{/if}}")
+5 -2
View File
@@ -169,10 +169,13 @@ BlazeComponent.extendComponent({
this._refreshMembers(
this.members().map(member => {
if (!member.wekanId) {
const user = Users.findOne({ username: member.username });
let user = Users.findOne({ username: member.username });
if (!user) {
user = Users.findOne({ importUsernames: member.username });
}
if (user) {
// eslint-disable-next-line no-console
console.log('found username:', user.username);
// console.log('found username:', user.username);
member.wekanId = user._id;
}
}
+4
View File
@@ -47,3 +47,7 @@
a.show-mapping
text-decoration underline
.import-members-map-note
font-size: 90%
font-weight: bold
+1 -1
View File
@@ -60,7 +60,7 @@ BlazeComponent.extendComponent({
dueCardsView() {
// eslint-disable-next-line no-console
console.log('sort:', Utils.dueCardsView());
//console.log('sort:', Utils.dueCardsView());
return Utils.dueCardsView();
},
+9 -10
View File
@@ -78,12 +78,10 @@ BlazeComponent.extendComponent({
onRendered() {
Meteor.subscribe('setting');
this.colorMap = {};
for (const color of Boards.simpleSchema()._schema['labels.$.color']
.allowedValues) {
this.colorMap[TAPi18n.__(`color-${color}`)] = color;
}
// // eslint-disable-next-line no-console
// eslint-disable-next-line no-console
//console.log('lang:', TAPi18n.getLanguage());
this.colorMap = Boards.colorMap();
// eslint-disable-next-line no-console
// console.log('colorMap:', this.colorMap);
if (Session.get('globalQuery')) {
@@ -116,7 +114,7 @@ BlazeComponent.extendComponent({
if (this.queryParams) {
const sessionData = this.getSessionData();
// eslint-disable-next-line no-console
console.log('selector:', sessionData.getSelector());
// console.log('selector:', sessionData.getSelector());
// console.log('session data:', sessionData);
const cards = Cards.find({ _id: { $in: sessionData.cards } });
this.queryErrors = sessionData.errors;
@@ -178,7 +176,7 @@ BlazeComponent.extendComponent({
searchAllBoards(query) {
query = query.trim();
// eslint-disable-next-line no-console
console.log('query:', query);
//console.log('query:', query);
this.query.set(query);
@@ -296,13 +294,14 @@ BlazeComponent.extendComponent({
if (m.groups.operator) {
op = m.groups.operator.toLowerCase();
} else {
op = m.groups.abbrev;
op = m.groups.abbrev.toLowerCase();
}
if (operatorMap.hasOwnProperty(op)) {
let value = m.groups.value;
if (operatorMap[op] === 'labels') {
if (value in this.colorMap) {
value = this.colorMap[value];
// console.log('found color:', value);
}
} else if (
['dueAt', 'createdAt', 'modifiedAt'].includes(operatorMap[op])
@@ -388,7 +387,7 @@ BlazeComponent.extendComponent({
params.text = text;
// eslint-disable-next-line no-console
// console.log('params:', params);
console.log('params:', params);
this.queryParams = params;
@@ -5,7 +5,7 @@
.notification
display: flex
float: none
padding: 12px 8px 8px
padding: 15px 8px 8px
color: black
border-bottom: 1px solid #dbdbdb
@@ -14,6 +14,7 @@
.read-status
width: 30px
padding: 0px 10px 0px 0px
input
width: 24px
@@ -28,13 +29,19 @@
color: #bbb
.details
width: calc(100% - 30px)
.activity
display: flex
a.member
margin: 0px 0px 0px 0px
padding: 0px
svg
padding: 3px
.activity-desc
width: 100%;
margin: 0px 0px 0px 5px
.activity-comment
display: block
@@ -55,3 +62,14 @@
.remove
a:hover
color #eb4646 !important
@media screen and (max-width: 800px)
#notifications-drawer
.notification
height: auto
.details
.activity
a.member
height: 36px
width: 36px
@@ -2,7 +2,7 @@ belize = #2980b9
section#notifications-drawer
position: fixed
top: 28px
top: 48px
right: 0
width: 400px
background-color: #fafafa
@@ -17,7 +17,7 @@ section#notifications-drawer
.header
position: fixed
top 28px
top 48px
right 0
width calc(400px - 32px)
padding: 8px 16px
@@ -63,7 +63,7 @@ section#notifications-drawer
ul.notifications
display: block
padding: 0px 16px
padding: 0px 16px 0px 16px
margin: 0
height: calc(100vh - 102px)
height: calc(100vh - 122px)
overflow-y: scroll
@@ -110,6 +110,7 @@ template(name="peopleGeneral")
th {{_ 'createdAt'}}
th {{_ 'active'}}
th {{_ 'authentication-method'}}
th {{_ 'import-usernames'}}
th
+newUserRow
each user in peopleList
@@ -257,6 +258,10 @@ template(name="peopleRow")
td <s>{{_ userData.authenticationMethod }}</s>
else
td {{_ userData.authenticationMethod }}
if userData.loginDisabled
td <s>{{ userData.importUsernamesString }}</s>
else
td {{ userData.importUsernamesString }}
td
a.edit-user
i.fa.fa-edit
@@ -346,6 +351,9 @@ template(name="editUserPopup")
input.js-profile-email(type="email" value="{{user.emails.[0].address}}" readonly)
else
input.js-profile-email(type="email" value="{{user.emails.[0].address}}" required)
label
| {{_ 'import-usernames'}}
input.js-import-usernames(type="text" value=user.importUsernames)
label
| {{_ 'verified'}}
select.select-verified.js-profile-email-verified
@@ -444,6 +452,9 @@ template(name="newUserPopup")
// input.js-profile-email(type="email" value="{{user.emails.[0].address}}" readonly)
//else
input.js-profile-email(type="email" value="" required)
label
| {{_ 'import-usernames'}}
input.js-import-usernames(type="text" value="")
label
| {{_ 'admin'}}
select.select-role.js-profile-isadmin
+9 -1
View File
@@ -143,7 +143,7 @@ BlazeComponent.extendComponent({
const orgs = Org.find(this.findOrgsOptions.get(), {
fields: { _id: true },
});
this.numberOrgs.set(org.count(false));
this.numberOrgs.set(orgs.count(false));
return orgs;
},
teamList() {
@@ -421,6 +421,9 @@ Template.editUserPopup.events({
const authentication = templateInstance
.find('.js-authenticationMethod')
.value.trim();
const importUsernames = templateInstance
.find('.js-import-usernames')
.value.trim();
const isChangePassword = password.length > 0;
const isChangeUserName = username !== user.username;
@@ -441,6 +444,7 @@ Template.editUserPopup.events({
isAdmin: isAdmin === 'true',
loginDisabled: isActive === 'true',
authenticationMethod: authentication,
importUsernames: Users.parseImportUsernames(importUsernames),
},
});
@@ -563,6 +567,9 @@ Template.newUserPopup.events({
const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
const isActive = templateInstance.find('.js-profile-isactive').value.trim();
const email = templateInstance.find('.js-profile-email').value.trim();
const importUsernames = templateInstance
.find('.js-import-usernames')
.value.trim();
Meteor.call(
'setCreateUser',
@@ -572,6 +579,7 @@ Template.newUserPopup.events({
isAdmin,
isActive,
email.toLowerCase(),
importUsernames,
function(error) {
const usernameMessageElement = templateInstance.$('.username-taken');
const emailMessageElement = templateInstance.$('.email-taken');
@@ -14,6 +14,11 @@ template(name="archivesSidebar")
if currentUser.isBoardMember
unless isWorker
p.quiet
if this.archivedAt
| {{_ 'archived-at' }}
|
| {{ moment this.archivedAt 'LLL' }}
br
a.js-restore-card {{_ 'restore'}}
if currentUser.isBoardAdmin
| -
@@ -37,6 +42,11 @@ template(name="archivesSidebar")
if currentUser.isBoardMember
unless isWorker
p.quiet
if this.archivedAt
| {{_ 'archived-at' }}
|
| {{ moment this.archivedAt 'LLL' }}
br
a.js-restore-list {{_ 'restore'}}
if currentUser.isBoardAdmin
| -
@@ -58,6 +68,11 @@ template(name="archivesSidebar")
if currentUser.isBoardMember
unless isWorker
p.quiet
if this.archivedAt
| {{_ 'archived-at' }}
|
| {{ moment this.archivedAt 'LLL' }}
br
a.js-restore-swimlane {{_ 'restore'}}
if currentUser.isBoardAdmin
| -
@@ -34,6 +34,8 @@ BlazeComponent.extendComponent({
return Cards.find({
archived: true,
boardId: Session.get('currentBoard'),
}, {
sort: { archivedAt: -1, modifiedAt: -1 },
});
},
@@ -41,6 +43,8 @@ BlazeComponent.extendComponent({
return Lists.find({
archived: true,
boardId: Session.get('currentBoard'),
}, {
sort: { archivedAt: -1, modifiedAt: -1 },
});
},
@@ -48,6 +52,8 @@ BlazeComponent.extendComponent({
return Swimlanes.find({
archived: true,
boardId: Session.get('currentBoard'),
}, {
sort: { archivedAt: -1, modifiedAt: -1 },
});
},
+17 -17
View File
@@ -4,24 +4,24 @@
Meteor.startup(() => {
TAPi18n.conf.i18n_files_route = Meteor._relativeToSiteRootUrl('/tap-i18n');
Tracker.autorun(() => {
const currentUser = Meteor.user();
let language;
if (currentUser) {
language = currentUser.profile && currentUser.profile.language;
}
const currentUser = Meteor.user();
let language;
if (currentUser) {
language = currentUser.profile && currentUser.profile.language;
}
if (!language) {
if (navigator.languages) {
language = navigator.languages[0];
} else {
language = navigator.language || navigator.userLanguage;
}
if (!language) {
if (navigator.languages) {
language = navigator.languages[0];
} else {
language = navigator.language || navigator.userLanguage;
}
}
if (language) {
TAPi18n.setLanguage(language);
T9n.setLanguage(language);
}
});
if (language) {
TAPi18n.setLanguage(language);
// eslint-disable-next-line no-console
// console.log('language set!');
T9n.setLanguage(language);
}
});
-4
View File
@@ -48,8 +48,6 @@ Utils = {
let sort = window.localStorage.getItem('myCardsSort');
if (!sort || !['board', 'dueAt'].includes(sort)) {
window.localStorage.setItem('myCardsSort', 'board');
location.reload();
sort = 'board';
}
@@ -81,8 +79,6 @@ Utils = {
let view = window.localStorage.getItem('dueCardsView');
if (!view || !['me', 'all'].includes(view)) {
window.localStorage.setItem('dueCardsView', 'me');
location.reload();
view = 'me';
}
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+4 -1
View File
@@ -384,6 +384,7 @@
"import-csv-placeholder": "Paste your valid CSV/TSV data here",
"import-map-members": "Map members",
"import-members-map": "Your imported board has some members. Please map the members you want to import to your users",
"import-members-map-note": "Note: Unmapped members will be assigned to the current user.",
"import-show-user-mapping": "Review members mapping",
"import-user-select": "Pick your existing user you want to use as this member",
"importMapMembersAddPopup-title": "Select member",
@@ -530,6 +531,7 @@
"custom-login-logo-link-url": "Custom Login Logo Link URL",
"text-below-custom-login-logo": "Text below Custom Login Logo",
"username": "Username",
"import-usernames": "Import Usernames",
"view-it": "View it",
"warn-list-archived": "warning: this card is in an list at Archive",
"watch": "Watch",
@@ -949,5 +951,6 @@
"excel-font": "Arial",
"number": "Number",
"label-colors": "Label Colors",
"label-names": "Label Names"
"label-names": "Label Names",
"archived-at": "archived at"
}
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+953 -951
View File
File diff suppressed because it is too large. Load diff
+20 -1
View File
@@ -43,6 +43,13 @@ Boards.attachSchema(
}
},
},
archivedAt: {
/**
* Latest archiving time of the board
*/
type: Date,
optional: true,
},
createdAt: {
/**
* Creation time of the board
@@ -1042,7 +1049,7 @@ Boards.helpers({
Boards.mutations({
archive() {
return { $set: { archived: true } };
return { $set: { archived: true, archivedAt: new Date() } };
},
restore() {
@@ -1318,6 +1325,18 @@ Boards.userBoardIds = (userId, archived = false, selector = {}) => {
});
};
Boards.colorMap = () => {
const colors = {};
for (const color of Boards.labelColors()) {
colors[TAPi18n.__(`color-${color}`)] = color;
}
return colors;
};
Boards.labelColors = () => {
return _.clone(Boards.simpleSchema()._schema['labels.$.color'].allowedValues);
};
if (Meteor.isServer) {
Boards.allow({
insert: Meteor.userId,
-3
View File
@@ -168,9 +168,6 @@ if (Meteor.isServer) {
listId: card.listId,
swimlaneId: card.swimlaneId,
});
});
CardComments.after.remove((userId, doc) => {
const activity = Activities.findOne({ commentId: doc._id });
if (activity) {
Activities.remove(activity._id);
+14 -3
View File
@@ -26,6 +26,13 @@ Cards.attachSchema(
}
},
},
archivedAt: {
/**
* latest archiving date
*/
type: Date,
optional: true,
},
parentId: {
/**
* ID of the parent card
@@ -724,9 +731,12 @@ Cards.helpers({
definition,
};
});
if (ret.definition !== undefined) {
ret.sort((a, b) => a.definition.name.localeCompare(b.definition.name));
}
ret.sort(
(a, b) =>
a.definition.name !== undefined &&
b.definition.name !== undefined &&
a.definition.name.localeCompare(b.definition.name),
);
return ret;
},
@@ -1446,6 +1456,7 @@ Cards.mutations({
return {
$set: {
archived: true,
archivedAt: new Date(),
},
};
},
+2 -2
View File
@@ -385,8 +385,8 @@ export class ExporterExcel {
}
//add data +8 hours
function addTZhours(jdate) {
let curdate = new Date(jdate);
let checkCorrectDate = moment(curdate);
const curdate = new Date(jdate);
const checkCorrectDate = moment(curdate);
if (checkCorrectDate.isValid()) {
return curdate;
} else {
+9 -1
View File
@@ -32,6 +32,13 @@ Lists.attachSchema(
}
},
},
archivedAt: {
/**
* latest archiving date
*/
type: Date,
optional: true,
},
boardId: {
/**
* the board associated to this list
@@ -292,7 +299,7 @@ Lists.mutations({
return card.archive();
});
}
return { $set: { archived: true } };
return { $set: { archived: true, archivedAt: new Date() } };
},
restore() {
@@ -384,6 +391,7 @@ if (Meteor.isServer) {
Meteor.startup(() => {
Lists._collection._ensureIndex({ modifiedAt: -1 });
Lists._collection._ensureIndex({ boardId: 1 });
Lists._collection._ensureIndex({ archivedAt: -1 });
});
Lists.after.insert((userId, doc) => {
+8 -1
View File
@@ -23,6 +23,13 @@ Swimlanes.attachSchema(
}
},
},
archivedAt: {
/**
* latest archiving date of the swimlane
*/
type: Date,
optional: true,
},
boardId: {
/**
* the ID of the board the swimlane is attached to
@@ -259,7 +266,7 @@ Swimlanes.mutations({
return list.archive();
});
}
return { $set: { archived: true } };
return { $set: { archived: true, archivedAt: new Date() } };
},
restore() {
+62 -3
View File
@@ -338,6 +338,13 @@ Users.attachSchema(
type: Number,
optional: true,
},
importUsernames: {
/**
* username for imported
*/
type: [String],
optional: true,
},
}),
);
@@ -433,7 +440,18 @@ if (Meteor.isClient) {
});
}
Users.parseImportUsernames = usernamesString => {
return usernamesString.trim().split(new RegExp('\\s*[,;]\\s*'));
};
Users.helpers({
importUsernamesString() {
if (this.importUsernames) {
return this.importUsernames.join(', ');
}
return '';
},
boards() {
return Boards.find(
{ 'members.userId': this._id },
@@ -779,7 +797,15 @@ Meteor.methods({
if (Meteor.isServer) {
Meteor.methods({
setCreateUser(fullname, username, password, isAdmin, isActive, email) {
setCreateUser(
fullname,
username,
password,
isAdmin,
isActive,
email,
importUsernames,
) {
if (Meteor.user() && Meteor.user().isAdmin) {
check(fullname, String);
check(username, String);
@@ -787,6 +813,7 @@ if (Meteor.isServer) {
check(isAdmin, String);
check(isActive, String);
check(email, String);
check(importUsernames, Array);
const nUsersWithUsername = Users.find({ username }).count();
const nUsersWithEmail = Users.find({ email }).count();
@@ -803,10 +830,10 @@ if (Meteor.isServer) {
email: email.toLowerCase(),
from: 'admin',
});
user = Users.findOne(username) || Users.findOne({ username });
const user = Users.findOne(username) || Users.findOne({ username });
if (user) {
Users.update(user._id, {
$set: { 'profile.fullname': fullname },
$set: { 'profile.fullname': fullname, importUsernames },
});
}
}
@@ -1733,6 +1760,38 @@ if (Meteor.isServer) {
});
}
});
/**
* @operation create_user_token
*
* @summary Create a user token
*
* @description Only the admin user (the first user) can call the REST API.
*
* @param {string} userId the ID of the user to create token for.
* @return_type {_id: string}
*/
JsonRoutes.add('POST', '/api/createtoken/:userId', function(req, res) {
try {
Authentication.checkUserId(req.userId);
const id = req.params.userId;
const token = Accounts._generateStampedLoginToken();
Accounts._insertLoginToken(id, token);
JsonRoutes.sendResult(res, {
code: 200,
data: {
_id: id,
authToken: token.token,
},
});
} catch (error) {
JsonRoutes.sendResult(res, {
code: 200,
data: error,
});
}
});
}
export default Users;
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v4.91.0",
"version": "v4.92.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -819,9 +819,9 @@
"dev": true
},
"ajv": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz",
"integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==",
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.4.tgz",
"integrity": "sha512-xzzzaqgEQfmuhbhAoqjJ8T/1okb6gAzXn/eQRNpAN1AEUoHJTNF9xCDRTtf/s3SKldtZfa+RJeTs+BQq+eZ/sw==",
"requires": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -4324,9 +4324,9 @@
"optional": true
},
"mongodb": {
"version": "3.6.3",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.3.tgz",
"integrity": "sha512-rOZuR0QkodZiM+UbQE5kDsJykBqWi0CL4Ec2i1nrGrUI3KO11r6Fbxskqmq3JK2NH7aW4dcccBuUujAP0ERl5w==",
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.4.tgz",
"integrity": "sha512-Y+Ki9iXE9jI+n9bVtbTOOdK0B95d6wVGSucwtBkvQ+HIvVdTCfpVRp01FDC24uhC/Q2WXQ8Lpq3/zwtB5Op9Qw==",
"requires": {
"bl": "^2.2.1",
"bson": "^1.1.4",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v4.91.0",
"version": "v4.92.0",
"description": "Open-Source kanban",
"private": true,
"scripts": {
@@ -57,7 +57,7 @@
"@babel/core": "^7.12.10",
"@babel/runtime": "^7.12.5",
"@root/request": "^1.7.0",
"ajv": "^7.0.3",
"ajv": "^7.0.4",
"babel-runtime": "^6.26.0",
"bcrypt": "^5.0.0",
"bson": "^4.2.2",
@@ -72,7 +72,7 @@
"markdown-it": "^12.0.4",
"markdown-it-emoji": "^2.0.0",
"meteor-node-stubs": "^1.0.1",
"mongodb": "^3.6.3",
"mongodb": "^3.6.4",
"os": "^0.1.1",
"page": "^1.11.5",
"papaparse": "^5.3.0",
+265 -5
View File
@@ -1524,7 +1524,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<ul class="toc-list-h1">
<li>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v4.91">Wekan REST API v4.91</a>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v4.92">Wekan REST API v4.92</a>
</li>
@@ -1854,6 +1854,11 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
</li>
<li>
<a href="#create_user_token" class="toc-h2 toc-link" data-title="create_user_token">create_user_token</a>
</li>
<li>
<a href="#get_current_user" class="toc-h2 toc-link" data-title="get_current_user">get_current_user</a>
@@ -2037,7 +2042,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<div class="page-wrapper">
<div class="dark-box"></div>
<div class="content">
<h1 id="wekan-rest-api">Wekan REST API v4.91</h1>
<h1 id="wekan-rest-api">Wekan REST API v4.92</h1>
<blockquote>
<p>Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.</p>
</blockquote>
@@ -3282,6 +3287,7 @@ System.out.println(response.toString());
<span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"slug"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"archived"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archivedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"createdAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"modifiedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"stars"</span>: <span class="hljs-number">0</span>,
@@ -8086,6 +8092,7 @@ System.out.println(response.toString());
<pre class="highlight tab tab-json"><code>{
<span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"archived"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archivedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"parentId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"listId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"swimlaneId"</span>: <span class="hljs-string">"string"</span>,
@@ -12192,6 +12199,7 @@ System.out.println(response.toString());
<span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"starred"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archived"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archivedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"boardId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"swimlaneId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"createdAt"</span>: <span class="hljs-string">"string"</span>,
@@ -12968,6 +12976,209 @@ System.out.println(response.toString());
To perform this operation, you must be authenticated by means of one of the following methods:
UserSecurity
</aside>
<h2 id="create_user_token">create_user_token</h2>
<p><a id="opIdcreate_user_token"></a></p>
<blockquote>
<p>Code samples</p>
</blockquote>
<pre class="highlight tab tab-shell"><code><span class="hljs-comment"># You can also use wget</span>
curl -X POST /api/createtoken/{user} \
-H <span class="hljs-string">'Accept: application/json'</span> \
-H <span class="hljs-string">'Authorization: API_KEY'</span>
</code></pre>
<pre class="highlight tab tab-http"><code><span class="hljs-keyword">POST</span> <span class="hljs-string">/api/createtoken/{user}</span> HTTP/1.1
<span class="http"><span class="hljs-attribute">Accept</span>: application/json
<span class="undefined"></span></span></code></pre>
<pre class="highlight tab tab-javascript"><code><span class="hljs-keyword">var</span> headers = {
<span class="hljs-string">'Accept'</span>:<span class="hljs-string">'application/json'</span>,
<span class="hljs-string">'Authorization'</span>:<span class="hljs-string">'API_KEY'</span>
};
$.ajax({
<span class="hljs-attr">url</span>: <span class="hljs-string">'/api/createtoken/{user}'</span>,
<span class="hljs-attr">method</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">headers</span>: headers,
<span class="hljs-attr">success</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>) </span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">JSON</span>.stringify(data));
}
})
</code></pre>
<pre class="highlight tab tab-javascript--nodejs"><code><span class="hljs-keyword">const</span> fetch = <span class="hljs-built_in">require</span>(<span class="hljs-string">'node-fetch'</span>);
<span class="hljs-keyword">const</span> headers = {
<span class="hljs-string">'Accept'</span>:<span class="hljs-string">'application/json'</span>,
<span class="hljs-string">'Authorization'</span>:<span class="hljs-string">'API_KEY'</span>
};
fetch(<span class="hljs-string">'/api/createtoken/{user}'</span>,
{
<span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
<span class="hljs-attr">headers</span>: headers
})
.then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">res</span>) </span>{
<span class="hljs-keyword">return</span> res.json();
}).then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">body</span>) </span>{
<span class="hljs-built_in">console</span>.log(body);
});
</code></pre>
<pre class="highlight tab tab-ruby"><code><span class="hljs-keyword">require</span> <span class="hljs-string">'rest-client'</span>
<span class="hljs-keyword">require</span> <span class="hljs-string">'json'</span>
headers = {
<span class="hljs-string">'Accept'</span> =&gt; <span class="hljs-string">'application/json'</span>,
<span class="hljs-string">'Authorization'</span> =&gt; <span class="hljs-string">'API_KEY'</span>
}
result = RestClient.post <span class="hljs-string">'/api/createtoken/{user}'</span>,
<span class="hljs-symbol">params:</span> {
}, <span class="hljs-symbol">headers:</span> headers
p JSON.parse(result)
</code></pre>
<pre class="highlight tab tab-python"><code><span class="hljs-keyword">import</span> requests
headers = {
<span class="hljs-string">'Accept'</span>: <span class="hljs-string">'application/json'</span>,
<span class="hljs-string">'Authorization'</span>: <span class="hljs-string">'API_KEY'</span>
}
r = requests.post(<span class="hljs-string">'/api/createtoken/{user}'</span>, params={
}, headers = headers)
<span class="hljs-keyword">print</span> r.json()
</code></pre>
<pre class="highlight tab tab-java"><code>URL obj = <span class="hljs-keyword">new</span> URL(<span class="hljs-string">"/api/createtoken/{user}"</span>);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod(<span class="hljs-string">"POST"</span>);
<span class="hljs-keyword">int</span> responseCode = con.getResponseCode();
BufferedReader in = <span class="hljs-keyword">new</span> BufferedReader(
<span class="hljs-keyword">new</span> InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = <span class="hljs-keyword">new</span> StringBuffer();
<span class="hljs-keyword">while</span> ((inputLine = in.readLine()) != <span class="hljs-keyword">null</span>) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
</code></pre>
<pre class="highlight tab tab-go"><code><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
<span class="hljs-string">"bytes"</span>
<span class="hljs-string">"net/http"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
headers := <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>][]<span class="hljs-keyword">string</span>{
<span class="hljs-string">"Accept"</span>: []<span class="hljs-keyword">string</span>{<span class="hljs-string">"application/json"</span>},
<span class="hljs-string">"Authorization"</span>: []<span class="hljs-keyword">string</span>{<span class="hljs-string">"API_KEY"</span>},
}
data := bytes.NewBuffer([]<span class="hljs-keyword">byte</span>{jsonReq})
req, err := http.NewRequest(<span class="hljs-string">"POST"</span>, <span class="hljs-string">"/api/createtoken/{user}"</span>, data)
req.Header = headers
client := &amp;http.Client{}
resp, err := client.Do(req)
<span class="hljs-comment">// ...</span>
}
</code></pre>
<p><code>POST /api/createtoken/{user}</code></p>
<p><em>Create a user token</em></p>
<p>Only the admin user (the first user) can call the REST API.</p>
<h3 id="create_user_token-parameters">Parameters</h3>
<table>
<thead>
<tr>
<th>Name</th>
<th>In</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>user</td>
<td>path</td>
<td>string</td>
<td>true</td>
<td>the ID of the user to create token for.</td>
</tr>
</tbody>
</table>
<h4 id="detailed-descriptions">Detailed descriptions</h4>
<p><strong>user</strong>: the ID of the user to create token for.</p>
<blockquote>
<p>Example responses</p>
</blockquote>
<blockquote>
<p>200 Response</p>
</blockquote>
<pre class="highlight tab tab-json"><code>{
<span class="hljs-attr">"_id"</span>: <span class="hljs-string">"string"</span>
}
</code></pre>
<h3 id="create_user_token-responses">Responses</h3>
<table>
<thead>
<tr>
<th>Status</th>
<th>Meaning</th>
<th>Description</th>
<th>Schema</th>
</tr>
</thead>
<tbody>
<tr>
<td>200</td>
<td><a href="https://tools.ietf.org/html/rfc7231#section-6.3.1">OK</a></td>
<td>200 response</td>
<td>Inline</td>
</tr>
</tbody>
</table>
<h3 id="create_user_token-responseschema">Response Schema</h3>
<p>Status Code <strong>200</strong></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Restrictions</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>» _id</td>
<td>string</td>
<td>false</td>
<td>none</td>
<td>none</td>
</tr>
</tbody>
</table>
<aside class="warning">
To perform this operation, you must be authenticated by means of one of the following methods:
UserSecurity
</aside>
<h2 id="get_current_user">get_current_user</h2>
<p><a id="opIdget_current_user"></a></p>
<blockquote>
@@ -13148,7 +13359,10 @@ System.out.println(response.toString());
<span class="hljs-attr">"sessionData"</span>: {
<span class="hljs-attr">"totalHits"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"lastHit"</span>: <span class="hljs-number">0</span>
}
},
<span class="hljs-attr">"importUsernames"</span>: [
<span class="hljs-string">"string"</span>
]
}
</code></pre>
<h3 id="get_current_user-responses">Responses</h3>
@@ -13809,7 +14023,10 @@ System.out.println(response.toString());
<span class="hljs-attr">"sessionData"</span>: {
<span class="hljs-attr">"totalHits"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"lastHit"</span>: <span class="hljs-number">0</span>
}
},
<span class="hljs-attr">"importUsernames"</span>: [
<span class="hljs-string">"string"</span>
]
}
</code></pre>
<h3 id="get_user-responses">Responses</h3>
@@ -14892,6 +15109,7 @@ System.out.println(response.toString());
<pre class="highlight tab tab-json"><code>{
<span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"archived"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archivedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"boardId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"createdAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"sort"</span>: <span class="hljs-number">0</span>,
@@ -15142,6 +15360,7 @@ UserSecurity
<span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"slug"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"archived"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archivedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"createdAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"modifiedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"stars"</span>: <span class="hljs-number">0</span>,
@@ -15231,6 +15450,13 @@ UserSecurity
<td>Is the board archived?</td>
</tr>
<tr>
<td>archivedAt</td>
<td>string|null</td>
<td>false</td>
<td>none</td>
<td>Latest archiving time of the board</td>
</tr>
<tr>
<td>createdAt</td>
<td>string</td>
<td>true</td>
@@ -15880,6 +16106,7 @@ UserSecurity
<pre class="highlight tab tab-json"><code>{
<span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"archived"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archivedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"parentId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"listId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"swimlaneId"</span>: <span class="hljs-string">"string"</span>,
@@ -15957,6 +16184,13 @@ UserSecurity
<td>is the card archived</td>
</tr>
<tr>
<td>archivedAt</td>
<td>string|null</td>
<td>false</td>
<td>none</td>
<td>latest archiving date</td>
</tr>
<tr>
<td>parentId</td>
<td>string|null</td>
<td>false</td>
@@ -16787,6 +17021,7 @@ UserSecurity
<span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"starred"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archived"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archivedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"boardId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"swimlaneId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"createdAt"</span>: <span class="hljs-string">"string"</span>,
@@ -16838,6 +17073,13 @@ UserSecurity
<td>is the list archived</td>
</tr>
<tr>
<td>archivedAt</td>
<td>string|null</td>
<td>false</td>
<td>none</td>
<td>latest archiving date</td>
</tr>
<tr>
<td>boardId</td>
<td>string</td>
<td>true</td>
@@ -17058,6 +17300,7 @@ UserSecurity
<pre class="highlight tab tab-json"><code>{
<span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"archived"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archivedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"boardId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"createdAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"sort"</span>: <span class="hljs-number">0</span>,
@@ -17096,6 +17339,13 @@ UserSecurity
<td>is the swimlane archived?</td>
</tr>
<tr>
<td>archivedAt</td>
<td>string|null</td>
<td>false</td>
<td>none</td>
<td>latest archiving date of the swimlane</td>
</tr>
<tr>
<td>boardId</td>
<td>string</td>
<td>true</td>
@@ -17305,7 +17555,10 @@ UserSecurity
<span class="hljs-attr">"sessionData"</span>: {
<span class="hljs-attr">"totalHits"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"lastHit"</span>: <span class="hljs-number">0</span>
}
},
<span class="hljs-attr">"importUsernames"</span>: [
<span class="hljs-string">"string"</span>
]
}
</code></pre>
@@ -17406,6 +17659,13 @@ UserSecurity
<td>none</td>
<td>profile settings</td>
</tr>
<tr>
<td>importUsernames</td>
<td>[string]|null</td>
<td>false</td>
<td>none</td>
<td>username for imported</td>
</tr>
</tbody>
</table>
<h2 id="tocsusersemails">UsersEmails</h2>
+60 -1
View File
@@ -1,7 +1,7 @@
swagger: '2.0'
info:
title: Wekan REST API
version: v4.91
version: v4.92
description: |
The REST API allows you to control and extend Wekan with ease.
@@ -2136,6 +2136,37 @@ paths:
type: string
listId:
type: string
/api/createtoken/{user}:
post:
operationId: create_user_token
summary: Create a user token
description: |
Only the admin user (the first user) can call the REST API.
tags:
- Users
consumes:
- multipart/form-data
- application/json
parameters:
- name: user
in: path
description: |
the ID of the user to create token for.
type: string
required: true
produces:
- application/json
security:
- UserSecurity: []
responses:
'200':
description: |-
200 response
schema:
type: object
properties:
_id:
type: string
/api/user:
get:
operationId: get_current_user
@@ -2361,6 +2392,11 @@ definitions:
description: |
Is the board archived?
type: boolean
archivedAt:
description: |
Latest archiving time of the board
type: string
x-nullable: true
createdAt:
description: |
Creation time of the board
@@ -2702,6 +2738,11 @@ definitions:
description: |
is the card archived
type: boolean
archivedAt:
description: |
latest archiving date
type: string
x-nullable: true
parentId:
description: |
ID of the parent card
@@ -3122,6 +3163,11 @@ definitions:
description: |
is the list archived
type: boolean
archivedAt:
description: |
latest archiving date
type: string
x-nullable: true
boardId:
description: |
the board associated to this list
@@ -3224,6 +3270,11 @@ definitions:
description: |
is the swimlane archived?
type: boolean
archivedAt:
description: |
latest archiving date of the swimlane
type: string
x-nullable: true
boardId:
description: |
the ID of the board the swimlane is attached to
@@ -3346,6 +3397,14 @@ definitions:
profile settings
$ref: "#/definitions/UsersSessiondata"
x-nullable: true
importUsernames:
description: |
username for imported
type: array
items:
type: string
x-nullable: true
x-nullable: true
required:
- createdAt
- modifiedAt
+2 -2
View File
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
appTitle = (defaultText = "Wekan"),
# The name of the app as it is displayed to the user.
appVersion = 491,
appVersion = 492,
# Increment this for every release.
appMarketingVersion = (defaultText = "4.91.0~2021-01-29"),
appMarketingVersion = (defaultText = "4.92.0~2021-02-03"),
# Human-readable presentation of the app version.
minUpgradableAppVersion = 0,
+4 -1
View File
@@ -63,8 +63,11 @@ Meteor.publish('archivedBoards', function() {
archived: 1,
slug: 1,
title: 1,
createdAt: 1,
modifiedAt: 1,
archivedAt: 1,
},
sort: { sort: 1 /* boards default sorting */ },
sort: { archivedAt: -1, modifiedAt: -1 },
},
);
});
+6 -6
View File
@@ -200,11 +200,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
comments: [],
};
this.colorMap = {};
for (const color of Boards.simpleSchema()._schema['labels.$.color']
.allowedValues) {
this.colorMap[TAPi18n.__(`color-${color}`)] = color;
}
this.colorMap = Boards.colorMap();
}
hasErrors() {
@@ -234,7 +230,11 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
});
});
this.notFound.labels.forEach(label => {
messages.push({ tag: 'label-not-found', value: label, color: true });
messages.push({
tag: 'label-not-found',
value: label,
color: Boards.labelColors().includes(label),
});
});
this.notFound.users.forEach(user => {
messages.push({ tag: 'user-username-not-found', value: user });
+1
View File
@@ -20,6 +20,7 @@ Meteor.publish('people', function(query, limit) {
createdAt: 1,
loginDisabled: 1,
authenticationMethod: 1,
importUsernames: 1,
},
});
}
+12 -2
View File
@@ -4,8 +4,18 @@ Meteor.publish('user-miniprofile', function(usernames) {
// eslint-disable-next-line no-console
// console.log('usernames:', usernames);
return Users.find(
{ username: { $in: usernames } },
{ fields: Users.safeFields },
{
$or: [
{ username: { $in: usernames } },
{ importUsernames: { $in: usernames } },
],
},
{
fields: {
...Users.safeFields,
importUsernames: 1,
},
},
);
});
+16
View File
@@ -0,0 +1,16 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: OpenPGP.js v4.10.8
Comment: https://openpgpjs.org
xjMEX3HbABYJKwYBBAHaRw8BAQdAQ2UBWCK1H3/z7gMgwVudRL+NlwJVCPw+
Vsp9PGSLh9jNJ3N1cHBvcnRAd2VrYW4udGVhbSA8c3VwcG9ydEB3ZWthbi50
ZWFtPsKPBBAWCgAgBQJfcdsABgsJBwgDAgQVCAoCBBYCAQACGQECGwMCHgEA
IQkQRkG8ZpPn6f4WIQRI5gPihwJLiXfveDBGQbxmk+fp/kCXAQD/JXsgVq4d
9sKmYDGHpCaIfsO//6cmiCGz3Mf5SDc0ygD/WpJO31Fyu6pfr3nWe4n50H93
lXXz937+K1bB9rfqugDOOARfcdsAEgorBgEEAZdVAQUBAQdALydXPub/n7hx
8qYjZa2tzBvcz5KkdnIxOoB+vaQZFQwDAQgHwngEGBYIAAkFAl9x2wACGwwA
IQkQRkG8ZpPn6f4WIQRI5gPihwJLiXfveDBGQbxmk+fp/uyXAQCRLPksHCJ6
RTl7HrtSS9lkeOmh32u+Rnjijn970PYIIQEAiGgXoJGBTzyVil9aPeqfWFK+
0hvTsnNY3JT3K84OmQQ=
=SNk3
-----END PGP PUBLIC KEY BLOCK-----