Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62ba8ed8d8 | ||
|
|
6eeef96886 | ||
|
|
4acf852650 | ||
|
|
9b3f1562a5 | ||
|
|
49774e46a3 | ||
|
|
ae2447393d | ||
|
|
3435192640 | ||
|
|
6ba4da9711 | ||
|
|
010a1d07d9 | ||
|
|
94d09b0014 | ||
|
|
d6ff442622 | ||
|
|
f7cc1abc8e | ||
|
|
bf7b1789ec | ||
|
|
cf9b482546 | ||
|
|
ad6da9bf37 | ||
|
|
d647884b91 | ||
|
|
0adde3e06d |
No files matched your search
@@ -1,3 +1,30 @@
|
||||
# v4.91 2021-01-29 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Use `new RegExp(...)` to define a regex](https://github.com/wekan/wekan/pull/3505).
|
||||
Thanks to jrsupplee.
|
||||
- [Fixed typos in docker-compose.yml](https://github.com/wekan/wekan/commit/4acf8526509ffe852e6e48e3503560448239d8cd).
|
||||
Thanks to farfoodyou and xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.90 2021-01-28 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Create unique board names when importing](https://github.com/wekan/wekan/pull/3499).
|
||||
Thanks to jrsupplee.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Added missing backtick quotes](https://github.com/wekan/wekan/commit/bf7b1789ec16e3c52397318c799ec5a0fc2de3a5).
|
||||
Thanks to xet7.
|
||||
- [Fix some bugs when importing Wekan JSON](https://github.com/wekan/wekan/pull/3500).
|
||||
Thanks to jrsupplee.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.89 2021-01-28 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
|
||||
appVersion: "v4.89.0"
|
||||
appVersion: "v4.91.0"
|
||||
files:
|
||||
userUploads:
|
||||
- README.md
|
||||
|
||||
@@ -129,7 +129,7 @@ BlazeComponent.extendComponent({
|
||||
{
|
||||
sort: Boards.find({ archived: false }).count(),
|
||||
type: 'board',
|
||||
title: Boards.findOne(this.currentData()._id).copyTitle(),
|
||||
title: Boards.findOne(this.currentData()._id).title,
|
||||
},
|
||||
(err, res) => {
|
||||
if (err) {
|
||||
|
||||
@@ -13,38 +13,41 @@ template(name="import")
|
||||
template(name="importTextarea")
|
||||
form
|
||||
p: label(for='import-textarea') {{_ instruction}} {{_ 'import-board-instruction-about-errors'}}
|
||||
textarea.js-import-json(placeholder="{{_ importPlaceHolder}}" autofocus)
|
||||
textarea.js-import-json(id='import-textarea' placeholder="{{_ importPlaceHolder}}" autofocus)
|
||||
| {{jsonText}}
|
||||
input.primary.wide(type="submit" value="{{_ 'import'}}")
|
||||
|
||||
template(name="importMapMembers")
|
||||
h2 {{_ 'import-map-members'}}
|
||||
.map-members
|
||||
p {{_ 'import-members-map'}}
|
||||
.mapping-list
|
||||
each members
|
||||
a.mapping-item.js-select-member(class="{{#if wekanId}}filled{{/if}}")
|
||||
.profile-source
|
||||
.full-name= fullName
|
||||
.username
|
||||
| ({{username}})
|
||||
.wekan
|
||||
if wekanId
|
||||
+userAvatar(userId=wekanId)
|
||||
else
|
||||
a.member.add-member
|
||||
i.fa.fa-plus
|
||||
//-
|
||||
Due to the way the flewbox layout is working, we need to set some
|
||||
invisible items so that the last row items have a consistent width.
|
||||
See http://jsfiddle.net/Ln4h3c4n/ for an minimal example of the issue.
|
||||
.mapping-item.ghost-item
|
||||
.mapping-item.ghost-item
|
||||
.mapping-item.ghost-item
|
||||
.mapping-item.ghost-item
|
||||
.mapping-item.ghost-item
|
||||
form
|
||||
input.primary.wide(type="submit" value="{{_ 'done'}}")
|
||||
if usersLoaded.get
|
||||
.map-members
|
||||
p {{_ 'import-members-map'}}
|
||||
.mapping-list
|
||||
each members
|
||||
a.mapping-item.js-select-member(class="{{#if wekanId}}filled{{/if}}")
|
||||
.profile-source
|
||||
.full-name= fullName
|
||||
.username
|
||||
| ({{username}})
|
||||
.wekan
|
||||
if wekanId
|
||||
+userAvatar(userId=wekanId)
|
||||
else
|
||||
a.member.add-member
|
||||
i.fa.fa-plus
|
||||
//-
|
||||
Due to the way the flewbox layout is working, we need to set some
|
||||
invisible items so that the last row items have a consistent width.
|
||||
See http://jsfiddle.net/Ln4h3c4n/ for an minimal example of the issue.
|
||||
.mapping-item.ghost-item
|
||||
.mapping-item.ghost-item
|
||||
.mapping-item.ghost-item
|
||||
.mapping-item.ghost-item
|
||||
.mapping-item.ghost-item
|
||||
form
|
||||
input.primary.wide(type="submit" value="{{_ 'done'}}")
|
||||
else
|
||||
+spinner
|
||||
|
||||
template(name="importMapMembersAddPopup")
|
||||
.select-member
|
||||
|
||||
@@ -150,14 +150,39 @@ BlazeComponent.extendComponent({
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.usersLoaded = new ReactiveVar(false);
|
||||
|
||||
this.autorun(() => {
|
||||
this.parentComponent()
|
||||
.membersToMap.get()
|
||||
.forEach(({ wekanId }) => {
|
||||
if (wekanId) {
|
||||
this.subscribe('user-miniprofile', wekanId);
|
||||
const handle = this.subscribe(
|
||||
'user-miniprofile',
|
||||
this.members().map(member => {
|
||||
return member.username;
|
||||
}),
|
||||
);
|
||||
Tracker.nonreactive(() => {
|
||||
Tracker.autorun(() => {
|
||||
if (
|
||||
handle.ready() &&
|
||||
!this.usersLoaded.get() &&
|
||||
this.members().length
|
||||
) {
|
||||
this._refreshMembers(
|
||||
this.members().map(member => {
|
||||
if (!member.wekanId) {
|
||||
const user = Users.findOne({ username: member.username });
|
||||
if (user) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('found username:', user.username);
|
||||
member.wekanId = user._id;
|
||||
}
|
||||
}
|
||||
return member;
|
||||
}),
|
||||
);
|
||||
}
|
||||
this.usersLoaded.set(handle.ready());
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -190,10 +190,19 @@ BlazeComponent.extendComponent({
|
||||
|
||||
this.searching.set(true);
|
||||
|
||||
const reOperator1 = `/^((?<operator>[\p{Letter}\p{Mark}]+):|(?<abbrev>[#@]))(?<value>[\p{Letter}\p{Mark}]+)(\s+|$)/iu`;
|
||||
const reOperator2 = `/^((?<operator>[\p{Letter}\p{Mark}]+):|(?<abbrev>[#@]))(?<quote>["']*)(?<value>.*?)\k<quote>(\s+|$)/iu`;
|
||||
const reText = `/^(?<text>\S+)(\s+|$)/u`;
|
||||
const reQuotedText = `/^(?<quote>["'])(?<text>[\w\p{L}]+)\k<quote>(\s+|$)/u`;
|
||||
const reOperator1 = new RegExp(
|
||||
'^((?<operator>[\\p{Letter}\\p{Mark}]+):|(?<abbrev>[#@]))(?<value>[\\p{Letter}\\p{Mark}]+)(\\s+|$)',
|
||||
'iu',
|
||||
);
|
||||
const reOperator2 = new RegExp(
|
||||
'^((?<operator>[\\p{Letter}\\p{Mark}]+):|(?<abbrev>[#@]))(?<quote>["\']*)(?<value>.*?)\\k<quote>(\\s+|$)',
|
||||
'iu',
|
||||
);
|
||||
const reText = new RegExp('^(?<text>\\S+)(\\s+|$)', 'u');
|
||||
const reQuotedText = new RegExp(
|
||||
'^(?<quote>["\'])(?<text>.*?)\\k<quote>(\\s+|$)',
|
||||
'u',
|
||||
);
|
||||
|
||||
const operators = {
|
||||
'operator-board': 'boards',
|
||||
|
||||
+5
-5
@@ -95,9 +95,9 @@ services:
|
||||
# 2020-12-03:
|
||||
# - Mongo image copied from Docker Hub mongo:4.4.2-bionic to Quay
|
||||
# to avoid Docker Hub rate limits.
|
||||
# Quay image
|
||||
# Quay image does work:
|
||||
# image: quay.io/wekan/mongo:4.4.2-bionic
|
||||
# Docker Hub MongoDB image works:
|
||||
# Docker Hub MongoDB image does work:
|
||||
image: mongo:4.4
|
||||
#-------------------------------------------------------------------------------------
|
||||
container_name: wekan-db
|
||||
@@ -117,12 +117,12 @@ services:
|
||||
wekan:
|
||||
#-------------------------------------------------------------------------------------
|
||||
# ==== MONGODB AND METEOR VERSION ====
|
||||
# a) Quay automatic builds do not currently work, https://quay.io/wekan/wekan
|
||||
# a) Quay automatic builds do work work, https://quay.io/wekan/wekan
|
||||
# image: quay.io/wekan/wekan
|
||||
# b) Using specific version tag:
|
||||
# image: quay.io/wekan/wekan:v4.52
|
||||
c) Docker Hub builds do work https://hub.docker.com/r/wekanteam/wekan
|
||||
# image: wekanteam/wekan
|
||||
# c) Docker Hub builds do work https://hub.docker.com/r/wekanteam/wekan
|
||||
image: wekanteam/wekan
|
||||
#-------------------------------------------------------------------------------------
|
||||
container_name: wekan-app
|
||||
restart: always
|
||||
|
||||
+2
-2
@@ -916,8 +916,8 @@
|
||||
"operator-number-expected": "סימון הפעולה __operator__ ציפה למספר, קיבל ‚__value__’",
|
||||
"operator-sort-invalid": "sort of '%s' is invalid",
|
||||
"operator-status-invalid": "'%s' is not a valid status",
|
||||
"next-page": "Next Page",
|
||||
"previous-page": "Previous Page",
|
||||
"next-page": "העמוד הבא",
|
||||
"previous-page": "העמוד הקודם",
|
||||
"heading-notes": "הערות",
|
||||
"globalSearch-instructions-heading": "הנחיות לחיפוש",
|
||||
"globalSearch-instructions-description": "חיפושים יכולים לכלול סימוני פעולה כדי לחדד את החיפוש. ניתן לציין סימוני פעולה על ידי כתיבת שם הפעולה והערך מופרדים בנקודתיים. למשל, ציון סימון פעולה של `list:חסומים` יגביל את החיפוש לכרטיסים שבתוך רשימה בשם *חסומים*. אם הערך מכיל רווחים או תווים מיוחדים יש לתחום אותו בסימני ציטוט (למשל: `__operator_list__:\"לסקירה\"`).",
|
||||
|
||||
+9
-9
@@ -925,23 +925,23 @@
|
||||
"globalSearch-instructions-operator-board": "`__operator_board__:title` - карточки на досках с названием соответствующим \"title\"",
|
||||
"globalSearch-instructions-operator-list": "`__operator_list__:title` - карточки в списках соответствующих \"title\"",
|
||||
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:title` - карточки в дорожках соответствующих заданному \"title\"",
|
||||
"globalSearch-instructions-operator-comment": "`__operator_comment__:text` - cards with with a comment containing *text*.",
|
||||
"globalSearch-instructions-operator-comment": "`__operator_comment__:text` - карточки с комментарием содержащим текст *text*.",
|
||||
"globalSearch-instructions-operator-label": "`__operator_label__:color` `__operator_label__:name` - карточки, которые имеют метки соответствующие заданным \"color\" или \"name\"",
|
||||
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__label` - сокращенный вариант `__operator_label__:label`",
|
||||
"globalSearch-instructions-operator-user": "`__operator_user__:username` - карточки, где указанный пользователь является участником или исполнителем",
|
||||
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - сокращенный вариант `user:username`",
|
||||
"globalSearch-instructions-operator-member": "`__operator_member__:username` - карточки, где указанный пользователь является участником",
|
||||
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:username` - карточка назначенная указанному пользователю",
|
||||
"globalSearch-instructions-operator-due": "`__operator_due__:n` - cards which are due *n* days from now. `__operator_due__:__predicate_overdue__ lists all cards past their due date.",
|
||||
"globalSearch-instructions-operator-created": "`__operator_created__:n` - cards which which were created *n* days ago",
|
||||
"globalSearch-instructions-operator-modified": "`__operator_modified__:n` - cards which which were modified *n* days ago",
|
||||
"globalSearch-instructions-status-archived": "`__operator_status__:__predicate_archived__` - cards that are archived.",
|
||||
"globalSearch-instructions-status-all": "`__operator_status__:__predicate_all__` - all archived and unarchived cards.",
|
||||
"globalSearch-instructions-status-ended": "`__operator_status__:__predicate_ended__` - cards with an end date.",
|
||||
"globalSearch-instructions-operator-due": "`__operator_due__:n` - карточки с датой завершения *n* дней от текущей даты. `__operator_due__:__predicate_overdue__ выводит все карточки с просроченной датой завершения.",
|
||||
"globalSearch-instructions-operator-created": "`__operator_created__:n` - карточки, которые были созданы *n* дней назад",
|
||||
"globalSearch-instructions-operator-modified": "`__operator_modified__:n` - карточки, которые были изменены *n* дней назад",
|
||||
"globalSearch-instructions-status-archived": "`__operator_status__:__predicate_archived__` - карточки, которые были архивированы.",
|
||||
"globalSearch-instructions-status-all": "`__operator_status__:__predicate_all__` - все карточки, включая архивированные.",
|
||||
"globalSearch-instructions-status-ended": "`__operator_status__:__predicate_ended__` - карточки с датой завершения.",
|
||||
"globalSearch-instructions-notes-1": "Может быть задано несколько операторов.",
|
||||
"globalSearch-instructions-notes-2": "Одинаковые операторы объединяются логическим \"ИЛИ\", например:\n`__operator_list__:Available __operator_list__:Blocked` вернет карточки, которые содержатся в списке *Blocked* или *Available*.",
|
||||
"globalSearch-instructions-notes-3": "Differing operators are *AND*ed together. Only cards that match all of the differing operators are returned. `__operator_list__:Available __operator_label__:red` returns only cards in the list *Available* with a *red* label.",
|
||||
"globalSearch-instructions-notes-3-2": "Days can be specified as an integer or using `__predicate_week__`, `__predicate_month__`, `__predicate_quarter__` or `__predicate_year__`",
|
||||
"globalSearch-instructions-notes-3": "Разные операторы объединяются логическим \"И\". Возвращаются только объекты удовлетворяющие всем заданным условиям.`__operator_list__:Available __operator_label__:red` вернет карточки, которые содержатся в списке *Available* и имеют метку *red*.",
|
||||
"globalSearch-instructions-notes-3-2": "Длительность может быть задана числом в днях или используя `__predicate_week__`, `__predicate_month__`, `__predicate_quarter__` или `__predicate_year__`",
|
||||
"globalSearch-instructions-notes-4": "Текстовый поиск нечувствителен к регистру символов.",
|
||||
"globalSearch-instructions-notes-5": "В архивированных карточках поиск не производится.",
|
||||
"link-to-search": "Ссылка на этот поиск",
|
||||
|
||||
+23
-14
@@ -510,6 +510,7 @@ Boards.helpers({
|
||||
const oldId = this._id;
|
||||
delete this._id;
|
||||
delete this.slug;
|
||||
this.title = this.copyTitle();
|
||||
const _id = Boards.insert(this);
|
||||
|
||||
// Copy all swimlanes in board
|
||||
@@ -569,20 +570,7 @@ Boards.helpers({
|
||||
* @returns {string|null}
|
||||
*/
|
||||
copyTitle() {
|
||||
const m = this.title.match(/^(?<title>.*?)\s*(\[(?<num>\d+)]\s*$|\s*$)/);
|
||||
const title = escapeForRegex(m.groups.title);
|
||||
let num = 0;
|
||||
Boards.find({ title: new RegExp(`^${title}\\s*\\[\\d+]\\s*$`) }).forEach(
|
||||
board => {
|
||||
const m = board.title.match(/^(?<title>.*?)\s*\[(?<num>\d+)]\s*$/);
|
||||
if (m) {
|
||||
const n = parseInt(m.groups.num, 10);
|
||||
num = num < n ? n : num;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return `${title} [${num + 1}]`;
|
||||
return Boards.uniqueTitle(this.title);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1274,6 +1262,27 @@ function boardRemover(userId, doc) {
|
||||
);
|
||||
}
|
||||
|
||||
Boards.uniqueTitle = title => {
|
||||
const m = title.match(
|
||||
new RegExp('^(?<title>.*?)\\s*(\\[(?<num>\\d+)]\\s*$|\\s*$)'),
|
||||
);
|
||||
const base = escapeForRegex(m.groups.title);
|
||||
let num = 0;
|
||||
Boards.find({ title: new RegExp(`^${base}\\s*\\[\\d+]\\s*$`) }).forEach(
|
||||
board => {
|
||||
const m = board.title.match(
|
||||
new RegExp('^(?<title>.*?)\\s*\\[(?<num>\\d+)]\\s*$'),
|
||||
);
|
||||
if (m) {
|
||||
const n = parseInt(m.groups.num, 10);
|
||||
num = num < n ? n : num;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return `${base} [${num + 1}]`;
|
||||
};
|
||||
|
||||
Boards.userSearch = (
|
||||
userId,
|
||||
selector = {},
|
||||
|
||||
@@ -69,24 +69,28 @@ CustomFields.attachSchema(
|
||||
* should we show on the cards this custom field
|
||||
*/
|
||||
type: Boolean,
|
||||
defaultValue: false,
|
||||
},
|
||||
automaticallyOnCard: {
|
||||
/**
|
||||
* should the custom fields automatically be added on cards?
|
||||
*/
|
||||
type: Boolean,
|
||||
defaultValue: false,
|
||||
},
|
||||
alwaysOnCard: {
|
||||
/**
|
||||
* should the custom field be automatically added to all cards?
|
||||
*/
|
||||
type: Boolean,
|
||||
defaultValue: false,
|
||||
},
|
||||
showLabelOnMiniCard: {
|
||||
/**
|
||||
* should the label of the custom field be shown on minicards?
|
||||
*/
|
||||
type: Boolean,
|
||||
defaultValue: false,
|
||||
},
|
||||
createdAt: {
|
||||
type: Date,
|
||||
|
||||
@@ -177,7 +177,7 @@ export class TrelloCreator {
|
||||
permission: this.getPermission(trelloBoard.prefs.permissionLevel),
|
||||
slug: getSlug(trelloBoard.name) || 'board',
|
||||
stars: 0,
|
||||
title: trelloBoard.name,
|
||||
title: Boards.uniqueTitle(trelloBoard.name),
|
||||
};
|
||||
// now add other members
|
||||
if (trelloBoard.memberships) {
|
||||
|
||||
@@ -253,13 +253,14 @@ export class WekanCreator {
|
||||
permission: boardToImport.permission,
|
||||
slug: getSlug(boardToImport.title) || 'board',
|
||||
stars: 0,
|
||||
title: boardToImport.title,
|
||||
title: Boards.uniqueTitle(boardToImport.title),
|
||||
};
|
||||
// now add other members
|
||||
if (boardToImport.members) {
|
||||
boardToImport.members.forEach(wekanMember => {
|
||||
// do we already have it in our list?
|
||||
// is it defined and do we already have it in our list?
|
||||
if (
|
||||
wekanMember.wekanId &&
|
||||
!boardToCreate.members.some(
|
||||
member => member.wekanId === wekanMember.wekanId,
|
||||
)
|
||||
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v4.89.0",
|
||||
"version": "v4.91.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v4.89.0",
|
||||
"version": "v4.91.0",
|
||||
"description": "Open-Source kanban",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
+2696
-183
File diff suppressed because it is too large.
Load diff
+624
-1
@@ -1,7 +1,7 @@
|
||||
swagger: '2.0'
|
||||
info:
|
||||
title: Wekan REST API
|
||||
version: v4.89
|
||||
version: v4.91
|
||||
description: |
|
||||
The REST API allows you to control and extend Wekan with ease.
|
||||
|
||||
@@ -134,6 +134,198 @@ paths:
|
||||
description: |
|
||||
Error in registration
|
||||
|
||||
/api/boards:
|
||||
get:
|
||||
operationId: get_public_boards
|
||||
summary: Get all public boards
|
||||
tags:
|
||||
- Boards
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
post:
|
||||
operationId: new_board
|
||||
summary: Create a board
|
||||
description: |
|
||||
This allows to create a board.
|
||||
|
||||
The color has to be chosen between `belize`, `nephritis`, `pomegranate`,
|
||||
`pumpkin`, `wisteria`, `moderatepink`, `strongcyan`,
|
||||
`limegreen`, `midnight`, `dark`, `relax`, `corteza`:
|
||||
|
||||
<img src="https://wekan.github.io/board-colors.png" width="40%" alt="Wekan logo" />
|
||||
tags:
|
||||
- Boards
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: title
|
||||
in: formData
|
||||
description: |
|
||||
the new title of the board
|
||||
type: string
|
||||
required: true
|
||||
- name: owner
|
||||
in: formData
|
||||
description: |
|
||||
"ABCDE12345" <= User ID in Wekan.
|
||||
(Not username or email)
|
||||
type: string
|
||||
required: true
|
||||
- name: isAdmin
|
||||
in: formData
|
||||
description: |
|
||||
is the owner an admin of the board (default true)
|
||||
type: boolean
|
||||
required: false
|
||||
- name: isActive
|
||||
in: formData
|
||||
description: |
|
||||
is the board active (default true)
|
||||
type: boolean
|
||||
required: false
|
||||
- name: isNoComments
|
||||
in: formData
|
||||
description: |
|
||||
disable comments (default false)
|
||||
type: boolean
|
||||
required: false
|
||||
- name: isCommentOnly
|
||||
in: formData
|
||||
description: |
|
||||
only enable comments (default false)
|
||||
type: boolean
|
||||
required: false
|
||||
- name: isWorker
|
||||
in: formData
|
||||
description: |
|
||||
only move cards, assign himself to card and comment (default false)
|
||||
type: boolean
|
||||
required: false
|
||||
- name: permission
|
||||
in: formData
|
||||
description: |
|
||||
"private" board <== Set to "public" if you
|
||||
want public Wekan board
|
||||
type: string
|
||||
required: false
|
||||
- name: color
|
||||
in: formData
|
||||
description: |
|
||||
the color of the board
|
||||
type: string
|
||||
required: false
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
defaultSwimlaneId:
|
||||
type: string
|
||||
/api/boards/{board}:
|
||||
get:
|
||||
operationId: get_board
|
||||
summary: Get the board with that particular ID
|
||||
tags:
|
||||
- Boards
|
||||
parameters:
|
||||
- name: board
|
||||
in: path
|
||||
description: |
|
||||
the ID of the board to retrieve the data
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
$ref: "#/definitions/Boards"
|
||||
delete:
|
||||
operationId: delete_board
|
||||
summary: Delete a board
|
||||
tags:
|
||||
- Boards
|
||||
parameters:
|
||||
- name: board
|
||||
in: path
|
||||
description: |
|
||||
the ID of the board
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
/api/boards/{board}/attachments:
|
||||
get:
|
||||
operationId: get_board_attachments
|
||||
summary: Get the list of attachments of a board
|
||||
tags:
|
||||
- Boards
|
||||
parameters:
|
||||
- name: board
|
||||
in: path
|
||||
description: |
|
||||
the board ID
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
attachmentId:
|
||||
type: string
|
||||
attachmentName:
|
||||
type: string
|
||||
attachmentType:
|
||||
type: string
|
||||
cardId:
|
||||
type: string
|
||||
listId:
|
||||
type: string
|
||||
swimlaneId:
|
||||
type: string
|
||||
/api/boards/{board}/cards/{card}/checklists:
|
||||
get:
|
||||
operationId: get_all_checklists
|
||||
@@ -1096,6 +1288,40 @@ paths:
|
||||
200 response
|
||||
schema:
|
||||
$ref: "#/definitions/Integrations"
|
||||
/api/boards/{board}/labels:
|
||||
put:
|
||||
operationId: add_board_label
|
||||
summary: Add a label to a board
|
||||
description: |
|
||||
If the board doesn't have the name/color label, this function
|
||||
adds the label to the board.
|
||||
tags:
|
||||
- Boards
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: label
|
||||
in: formData
|
||||
description: the label value
|
||||
type: string
|
||||
required: true
|
||||
- name: board
|
||||
in: path
|
||||
description: |
|
||||
the board
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: string
|
||||
/api/boards/{board}/lists:
|
||||
get:
|
||||
operationId: get_all_lists
|
||||
@@ -1577,6 +1803,61 @@ paths:
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
/api/boards/{board}/members/{member}:
|
||||
post:
|
||||
operationId: set_board_member_permission
|
||||
summary: Change the permission of a member of a board
|
||||
tags:
|
||||
- Boards
|
||||
- Users
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: isAdmin
|
||||
in: formData
|
||||
description: |
|
||||
admin capability
|
||||
type: boolean
|
||||
required: true
|
||||
- name: isNoComments
|
||||
in: formData
|
||||
description: |
|
||||
NoComments capability
|
||||
type: boolean
|
||||
required: true
|
||||
- name: isCommentOnly
|
||||
in: formData
|
||||
description: |
|
||||
CommentsOnly capability
|
||||
type: boolean
|
||||
required: true
|
||||
- name: isWorker
|
||||
in: formData
|
||||
description: |
|
||||
Worker capability
|
||||
type: boolean
|
||||
required: true
|
||||
- name: board
|
||||
in: path
|
||||
description: |
|
||||
the ID of the board that we are changing
|
||||
type: string
|
||||
required: true
|
||||
- name: member
|
||||
in: path
|
||||
description: |
|
||||
the ID of the user to change permissions
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
/api/boards/{board}/members/{user}/add:
|
||||
post:
|
||||
operationId: add_board_member
|
||||
@@ -2033,7 +2314,349 @@ paths:
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
/api/users/{user}/boards:
|
||||
get:
|
||||
operationId: get_boards_from_user
|
||||
summary: Get all boards attached to a user
|
||||
tags:
|
||||
- Boards
|
||||
parameters:
|
||||
- name: user
|
||||
in: path
|
||||
description: |
|
||||
the ID of the user to retrieve the data
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
definitions:
|
||||
Boards:
|
||||
type: object
|
||||
description: This is a Board.
|
||||
properties:
|
||||
title:
|
||||
description: |
|
||||
The title of the board
|
||||
type: string
|
||||
slug:
|
||||
description: |
|
||||
The title slugified.
|
||||
type: string
|
||||
archived:
|
||||
description: |
|
||||
Is the board archived?
|
||||
type: boolean
|
||||
createdAt:
|
||||
description: |
|
||||
Creation time of the board
|
||||
type: string
|
||||
modifiedAt:
|
||||
description: |
|
||||
Last modification time of the board
|
||||
type: string
|
||||
x-nullable: true
|
||||
stars:
|
||||
description: |
|
||||
How many stars the board has
|
||||
type: number
|
||||
labels:
|
||||
description: |
|
||||
List of labels attached to a board
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/BoardsLabels"
|
||||
members:
|
||||
description: |
|
||||
List of members of a board
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/BoardsMembers"
|
||||
permission:
|
||||
description: |
|
||||
visibility of the board
|
||||
type: string
|
||||
enum:
|
||||
- public
|
||||
- private
|
||||
color:
|
||||
description: |
|
||||
The color of the board.
|
||||
type: string
|
||||
enum:
|
||||
- belize
|
||||
- nephritis
|
||||
- pomegranate
|
||||
- pumpkin
|
||||
- wisteria
|
||||
- moderatepink
|
||||
- strongcyan
|
||||
- limegreen
|
||||
- midnight
|
||||
- dark
|
||||
- relax
|
||||
- corteza
|
||||
- clearblue
|
||||
- natural
|
||||
- modern
|
||||
- moderndark
|
||||
description:
|
||||
description: |
|
||||
The description of the board
|
||||
type: string
|
||||
x-nullable: true
|
||||
subtasksDefaultBoardId:
|
||||
description: |
|
||||
The default board ID assigned to subtasks.
|
||||
type: string
|
||||
x-nullable: true
|
||||
subtasksDefaultListId:
|
||||
description: |
|
||||
The default List ID assigned to subtasks.
|
||||
type: string
|
||||
x-nullable: true
|
||||
dateSettingsDefaultBoardId:
|
||||
type: string
|
||||
x-nullable: true
|
||||
dateSettingsDefaultListId:
|
||||
type: string
|
||||
x-nullable: true
|
||||
allowsSubtasks:
|
||||
description: |
|
||||
Does the board allows subtasks?
|
||||
type: boolean
|
||||
allowsAttachments:
|
||||
description: |
|
||||
Does the board allows attachments?
|
||||
type: boolean
|
||||
allowsChecklists:
|
||||
description: |
|
||||
Does the board allows checklists?
|
||||
type: boolean
|
||||
allowsComments:
|
||||
description: |
|
||||
Does the board allows comments?
|
||||
type: boolean
|
||||
allowsDescriptionTitle:
|
||||
description: |
|
||||
Does the board allows description title?
|
||||
type: boolean
|
||||
allowsDescriptionText:
|
||||
description: |
|
||||
Does the board allows description text?
|
||||
type: boolean
|
||||
allowsActivities:
|
||||
description: |
|
||||
Does the board allows comments?
|
||||
type: boolean
|
||||
allowsLabels:
|
||||
description: |
|
||||
Does the board allows labels?
|
||||
type: boolean
|
||||
allowsAssignee:
|
||||
description: |
|
||||
Does the board allows assignee?
|
||||
type: boolean
|
||||
allowsMembers:
|
||||
description: |
|
||||
Does the board allows members?
|
||||
type: boolean
|
||||
allowsRequestedBy:
|
||||
description: |
|
||||
Does the board allows requested by?
|
||||
type: boolean
|
||||
allowsAssignedBy:
|
||||
description: |
|
||||
Does the board allows requested by?
|
||||
type: boolean
|
||||
allowsReceivedDate:
|
||||
description: |
|
||||
Does the board allows received date?
|
||||
type: boolean
|
||||
allowsStartDate:
|
||||
description: |
|
||||
Does the board allows start date?
|
||||
type: boolean
|
||||
allowsEndDate:
|
||||
description: |
|
||||
Does the board allows end date?
|
||||
type: boolean
|
||||
allowsDueDate:
|
||||
description: |
|
||||
Does the board allows due date?
|
||||
type: boolean
|
||||
presentParentTask:
|
||||
description: |
|
||||
Controls how to present the parent task:
|
||||
|
||||
- `prefix-with-full-path`: add a prefix with the full path
|
||||
- `prefix-with-parent`: add a prefisx with the parent name
|
||||
- `subtext-with-full-path`: add a subtext with the full path
|
||||
- `subtext-with-parent`: add a subtext with the parent name
|
||||
- `no-parent`: does not show the parent at all
|
||||
type: string
|
||||
enum:
|
||||
- prefix-with-full-path
|
||||
- prefix-with-parent
|
||||
- subtext-with-full-path
|
||||
- subtext-with-parent
|
||||
- no-parent
|
||||
x-nullable: true
|
||||
startAt:
|
||||
description: |
|
||||
Starting date of the board.
|
||||
type: string
|
||||
x-nullable: true
|
||||
dueAt:
|
||||
description: |
|
||||
Due date of the board.
|
||||
type: string
|
||||
x-nullable: true
|
||||
endAt:
|
||||
description: |
|
||||
End date of the board.
|
||||
type: string
|
||||
x-nullable: true
|
||||
spentTime:
|
||||
description: |
|
||||
Time spent in the board.
|
||||
type: number
|
||||
x-nullable: true
|
||||
isOvertime:
|
||||
description: |
|
||||
Is the board overtimed?
|
||||
type: boolean
|
||||
x-nullable: true
|
||||
type:
|
||||
description: |
|
||||
The type of board
|
||||
type: string
|
||||
sort:
|
||||
description: |
|
||||
Sort value
|
||||
type: number
|
||||
required:
|
||||
- title
|
||||
- slug
|
||||
- archived
|
||||
- createdAt
|
||||
- stars
|
||||
- labels
|
||||
- members
|
||||
- permission
|
||||
- color
|
||||
- allowsSubtasks
|
||||
- allowsAttachments
|
||||
- allowsChecklists
|
||||
- allowsComments
|
||||
- allowsDescriptionTitle
|
||||
- allowsDescriptionText
|
||||
- allowsActivities
|
||||
- allowsLabels
|
||||
- allowsAssignee
|
||||
- allowsMembers
|
||||
- allowsRequestedBy
|
||||
- allowsAssignedBy
|
||||
- allowsReceivedDate
|
||||
- allowsStartDate
|
||||
- allowsEndDate
|
||||
- allowsDueDate
|
||||
- type
|
||||
- sort
|
||||
BoardsLabels:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
description: |
|
||||
Unique id of a label
|
||||
type: string
|
||||
name:
|
||||
description: |
|
||||
Name of a label
|
||||
type: string
|
||||
color:
|
||||
description: |
|
||||
color of a label.
|
||||
|
||||
Can be amongst `green`, `yellow`, `orange`, `red`, `purple`,
|
||||
`blue`, `sky`, `lime`, `pink`, `black`,
|
||||
`silver`, `peachpuff`, `crimson`, `plum`, `darkgreen`,
|
||||
`slateblue`, `magenta`, `gold`, `navy`, `gray`,
|
||||
`saddlebrown`, `paleturquoise`, `mistyrose`, `indigo`
|
||||
type: string
|
||||
enum:
|
||||
- green
|
||||
- yellow
|
||||
- orange
|
||||
- red
|
||||
- purple
|
||||
- blue
|
||||
- sky
|
||||
- lime
|
||||
- pink
|
||||
- black
|
||||
- silver
|
||||
- peachpuff
|
||||
- crimson
|
||||
- plum
|
||||
- darkgreen
|
||||
- slateblue
|
||||
- magenta
|
||||
- gold
|
||||
- navy
|
||||
- gray
|
||||
- saddlebrown
|
||||
- paleturquoise
|
||||
- mistyrose
|
||||
- indigo
|
||||
required:
|
||||
- _id
|
||||
- color
|
||||
BoardsMembers:
|
||||
type: object
|
||||
properties:
|
||||
userId:
|
||||
description: |
|
||||
The uniq ID of the member
|
||||
type: string
|
||||
isAdmin:
|
||||
description: |
|
||||
Is the member an admin of the board?
|
||||
type: boolean
|
||||
isActive:
|
||||
description: |
|
||||
Is the member active?
|
||||
type: boolean
|
||||
isNoComments:
|
||||
description: |
|
||||
Is the member not allowed to make comments
|
||||
type: boolean
|
||||
isCommentOnly:
|
||||
description: |
|
||||
Is the member only allowed to comment on the board
|
||||
type: boolean
|
||||
isWorker:
|
||||
description: |
|
||||
Is the member only allowed to move card, assign himself to card and comment
|
||||
type: boolean
|
||||
required:
|
||||
- userId
|
||||
- isAdmin
|
||||
- isActive
|
||||
CardComments:
|
||||
type: object
|
||||
description: A comment on a card
|
||||
|
||||
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
|
||||
appTitle = (defaultText = "Wekan"),
|
||||
# The name of the app as it is displayed to the user.
|
||||
|
||||
appVersion = 489,
|
||||
appVersion = 491,
|
||||
# Increment this for every release.
|
||||
|
||||
appMarketingVersion = (defaultText = "4.89.0~2021-01-28"),
|
||||
appMarketingVersion = (defaultText = "4.91.0~2021-01-29"),
|
||||
# Human-readable presentation of the app version.
|
||||
|
||||
minUpgradableAppVersion = 0,
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
Meteor.publish('user-miniprofile', function(userId) {
|
||||
check(userId, String);
|
||||
Meteor.publish('user-miniprofile', function(usernames) {
|
||||
check(usernames, Array);
|
||||
|
||||
return Users.find(userId, {
|
||||
fields: {
|
||||
username: 1,
|
||||
'profile.fullname': 1,
|
||||
'profile.avatarUrl': 1,
|
||||
'profile.initials': 1,
|
||||
},
|
||||
});
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('usernames:', usernames);
|
||||
return Users.find(
|
||||
{ username: { $in: usernames } },
|
||||
{ fields: Users.safeFields },
|
||||
);
|
||||
});
|
||||
|
||||
Meteor.publish('user-admin', function() {
|
||||
|
||||
Reference in new issue
Block a user