mirror of
https://github.com/wekan/wekan.git
synced 2026-11-05 21:44:59 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f450df1af | ||
|
|
e933890730 | ||
|
|
8eafa1ac66 | ||
|
|
858bb35612 | ||
|
|
f9018fc3a8 | ||
|
|
252c4b19f9 | ||
|
|
05349a5deb | ||
|
|
d52affe658 | ||
|
|
23dcd084a4 | ||
|
|
a853189486 | ||
|
|
82d0a3df85 | ||
|
|
ef189477dd | ||
|
|
4bcc795778 | ||
|
|
01346152b5 | ||
|
|
5b7b5b3e7e | ||
|
|
2df29324e6 | ||
|
|
51f52fee23 | ||
|
|
6e088af3d1 | ||
|
|
fc9f0d8392 | ||
|
|
cfa2bbd3d4 | ||
|
|
52d633ca69 | ||
|
|
b2fee6a6c1 | ||
|
|
66d35a1528 | ||
|
|
b7105d7b57 | ||
|
|
d5fbd50b76 | ||
|
|
06515559a6 | ||
|
|
c61a126c8b | ||
|
|
b737adfcdf | ||
|
|
3b44acd87c | ||
|
|
6fad68b9b9 | ||
|
|
b05f8e5251 | ||
|
|
31c2afb072 | ||
|
|
863f0fc5db | ||
|
|
055b528532 | ||
|
|
fda392e662 | ||
|
|
e5f9d0a4dd | ||
|
|
3f16bf6054 | ||
|
|
6774b9e905 | ||
|
|
00a38b36a4 | ||
|
|
de365ad62a | ||
|
|
fe631ff75b | ||
|
|
eed649fbe6 | ||
|
|
8ddbc622db | ||
|
|
24b21d23ba | ||
|
|
64fa02cdf5 | ||
|
|
3b50b2c59f | ||
|
|
921460db40 | ||
|
|
4156073b1a | ||
|
|
af7c74b2d3 | ||
|
|
4064f3f406 | ||
|
|
94e47401cb | ||
|
|
5ef83ab236 | ||
|
|
c22eaa26cd | ||
|
|
060b9acd86 | ||
|
|
213b7b4819 | ||
|
|
7a576f9ae4 | ||
|
|
b80396f627 | ||
|
|
0735981366 | ||
|
|
5d8cca40d2 | ||
|
|
09ce3e464f | ||
|
|
4c5a2fbd1f | ||
|
|
012ca39a8d | ||
|
|
c3458855bd | ||
|
|
cfcc73724f | ||
|
|
4448488767 | ||
|
|
7dc0bbd7b2 | ||
|
|
269698ba78 | ||
|
|
0a1bfd37b3 | ||
|
|
5899b9366c | ||
|
|
4b196d5378 | ||
|
|
b34ed58289 | ||
|
|
617fdaeb74 | ||
|
|
d26bf04bfa | ||
|
|
a365899312 | ||
|
|
6ebd6defe9 | ||
|
|
93337c20f8 | ||
|
|
6cdd464f54 | ||
|
|
3e0bedd8c7 | ||
|
|
4dcdec0084 | ||
|
|
05c53ca01d |
No files matched your search
+1
-1
@@ -109,7 +109,7 @@ mobile-status-bar@1.1.0
|
||||
modern-browsers@0.1.5
|
||||
modules@0.15.0
|
||||
modules-runtime@0.12.0
|
||||
momentjs:moment@2.25.2
|
||||
momentjs:moment@2.26.0
|
||||
mongo@1.10.0
|
||||
mongo-decimal@0.1.1
|
||||
mongo-dev-server@1.1.0
|
||||
|
||||
@@ -1,3 +1,77 @@
|
||||
# v4.06 2020-05-25 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Fix Card export CSV, check for vote
|
||||
undefined](https://github.com/wekan/wekan/commit/8eafa1ac66fdcf5fb5f0a95aa6cfee454ddad67f).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.05 2020-05-25 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Import/Export Custom Fields in CSV/TSV](https://github.com/wekan/wekan/pull/3115).
|
||||
Thanks to brymut.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Update packages](https://github.com/wekan/wekan/commit/3b44acd87c35340bf9fe5d210f4402f1b1a1dfdf).
|
||||
Thanks to xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- Try to fix Snap [1](https://github.com/wekan/wekan/commit/6fad68b9b9afd8de7074037d73eeac40f6a3f7c1), [2](https://github.com/wekan/wekan/commit/b737adfcdfc9b8084a7eb84420a89c014bbec1fb). Later reverted those like other ostrio-files changes too.
|
||||
Thanks to xet7.
|
||||
- [Add default attachments store path /var/snap/wekan/common/uploads where attachments will be
|
||||
stored](https://github.com/wekan/wekan/commit/c61a126c8bcb25a1eda0203b89c990ae31de7a70).
|
||||
Thanks to xet7.
|
||||
- [Make scrollParentContainer() more robust as it's used in a timeout callback. Example exception: Exception in setTimeout callback: TypeError: Cannot read property 'parentComponent' of null. Probably there is a better fix for this](https://github.com/wekan/wekan/commit/d5fbd50b760b1d3b84b5b4e8af3a8ed7608e2918).
|
||||
Thanks to marc1006.
|
||||
- [Fix error link not available. Fixes: Exception in template helper: TypeError: Cannot read property 'link' of
|
||||
undefined](https://github.com/wekan/wekan/commit/b7105d7b5712dcdbf9dadebfddaba7691810da5c).
|
||||
Thanks to marc1006.
|
||||
- [Fix minicard cover functionality. Otherwise, if `this.coverId` is undefined then `Attachments.findOne()` would return any
|
||||
attachment](https://github.com/wekan/wekan/commit/66d35a15280795b76a81c3e59cebbd2a29e4dff8).
|
||||
Thanks to marc1006.
|
||||
- [Some fixes suggested by deepcode.ai](https://github.com/wekan/wekan/pull/3112).
|
||||
Thanks to marc1006.
|
||||
- [Sorry marc1006, I had to revert deepcode.ai arrow function fixes because Python API docs generator does not work all when code has arrow functions](https://github.com/wekan/wekan/commit/f9018fc3a87080d8d97c371e29a8f3f0a20ca932).
|
||||
Thanks to xet7.
|
||||
- [Move In Progress ostrio-files changes to separate branch, and revert ostrio-files changes, so that:
|
||||
Export to CSV/TSV with custom fields works, Attachments are not exported to disk,
|
||||
It is possible to build arm64/s390x versions
|
||||
again](https://github.com/wekan/wekan/commit/d52affe65893f17bab59bb43aa9f5afbb54993d3).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.04 2020-05-24 Wekan release
|
||||
|
||||
Please use v4.05 or newer instead, that works better.
|
||||
|
||||
This release adds the following features:
|
||||
|
||||
- [Found Time Tracking GPLv3 software "Titra" with integration to Wekan](https://github.com/wekan/wekan/wiki/Time-Tracking).
|
||||
Thanks to willhseitz.
|
||||
- [Theme: Natural](https://github.com/wekan/wekan/pull/3098).
|
||||
You can select it from Board Settings / Change color / natural.
|
||||
Thanks to compumatter and helioguardabaxo.
|
||||
- [Theme: Modern](https://github.com/wekan/wekan/pull/3106).
|
||||
Thanks to jeroenstoker com and helioguardabaxo.
|
||||
- [Export board to HTML static page .zip archive](https://github.com/wekan/wekan/pull/3043).
|
||||
Thanks to Lewiscowles1986.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Change the swimlaneid of a card only if a new target swimlaneid is selected](https://github.com/wekan/wekan/pull/3108).
|
||||
Thanks to marc1006.
|
||||
- [Set '*' as default value for swimlane and list name in card move action](https://github.com/wekan/wekan/pull/3109).
|
||||
Thanks to hickorysb and marc1006.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.03 2020-05-16 Wekan release
|
||||
|
||||
This release adds the following features:
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
|
||||
appVersion: "v4.03.0"
|
||||
appVersion: "v4.06.0"
|
||||
files:
|
||||
userUploads:
|
||||
- README.md
|
||||
|
||||
@@ -526,3 +526,185 @@ setBoardClear(color1,color2)
|
||||
|
||||
.board-color-clearblue
|
||||
setBoardClear(rgb(73, 155, 234),rgb(0, 174, 204))
|
||||
|
||||
/*
|
||||
Alternate "Natural" Styling
|
||||
*/
|
||||
.board-color-natural
|
||||
setBoardColor(#596557)
|
||||
|
||||
&#header-quick-access
|
||||
background-color: #2d392b
|
||||
|
||||
.ui-sortable
|
||||
background-color:#dedede
|
||||
|
||||
.list-header
|
||||
background-color: #c9cfc3
|
||||
border-bottom: 6px solid #c9cfc3
|
||||
|
||||
.swimlane .swimlane-header-wrap
|
||||
background-color: #c2c0ab
|
||||
|
||||
/*
|
||||
Alternate "Modern" Styling
|
||||
*/
|
||||
.board-color-modern
|
||||
setBoardColor(#2A80B8)
|
||||
|
||||
/* General */
|
||||
body
|
||||
background: #f5f5f5
|
||||
|
||||
&#header-quick-access
|
||||
padding: 10px
|
||||
font-size: 14px
|
||||
background: #333 !important
|
||||
|
||||
&#header-quick-access ul
|
||||
overflow: visible
|
||||
|
||||
&#header-quick-access ul li.current
|
||||
border: 0 !important
|
||||
font-weight: bold
|
||||
|
||||
&#header-quick-access ul li.separator
|
||||
display: none
|
||||
|
||||
&#header-quick-access ul li:nth-child(3)
|
||||
margin-right: 10px
|
||||
|
||||
&#header-quick-access ul li a
|
||||
padding: 5px 10px
|
||||
border-radius: 2px
|
||||
|
||||
&#header-quick-access ul li.current a
|
||||
border-radius: 2px
|
||||
background: rgba(255,255,255,.2)
|
||||
|
||||
&#header #header-main-bar h1
|
||||
font-family: Poppins
|
||||
font-weight: bold
|
||||
&#header-quick-access #header-user-bar
|
||||
position relative
|
||||
|
||||
&#header-quick-access #header-user-bar .header-user-bar-name
|
||||
margin: 5px 3px 0 0;
|
||||
|
||||
section#notifications-drawer
|
||||
top: 46px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,.1)
|
||||
max-width: 100%
|
||||
|
||||
section#notifications-drawer .header
|
||||
top: 46px;
|
||||
border-radius: 0 3px
|
||||
height: 21px
|
||||
background: #f7f7f7
|
||||
|
||||
/* Swimlane */
|
||||
.swimlane
|
||||
background: #f5f5f5
|
||||
|
||||
.swimlane .swimlane-header-wrap .swimlane-header
|
||||
font-family: Poppins
|
||||
|
||||
/* All board views */
|
||||
.board-list .board-list-item
|
||||
padding: 20px
|
||||
|
||||
.board-list-item-name
|
||||
font-family: Poppins
|
||||
|
||||
/* Board */
|
||||
.list
|
||||
background: transparent
|
||||
border-left: 0
|
||||
margin: 10px 0
|
||||
padding: 0px
|
||||
border-radius: 5px
|
||||
min-width: 300px
|
||||
|
||||
.list-body .open-minicard-composer:hover /*me*/
|
||||
background: none
|
||||
box-shadow: none
|
||||
|
||||
.list:first-child
|
||||
margin-left: 5px
|
||||
|
||||
.list.list-composer.js-list-composer
|
||||
transition: all .3s ease
|
||||
min-width: 80px
|
||||
|
||||
.open-list-composer.js-open-inlined-form:hover
|
||||
color: #222
|
||||
|
||||
.list-header
|
||||
background: none
|
||||
border-bottom-width: 0px
|
||||
|
||||
.list-header .list-header-name
|
||||
font-family: Poppins
|
||||
color: #000
|
||||
font-weight: 500
|
||||
|
||||
/* Card changes */
|
||||
.minicard
|
||||
background: #FFF
|
||||
padding: 15px 15px 10px
|
||||
box-shadow: 0 3px 8px rgba(0,0,0,.05)
|
||||
|
||||
.minicard-plum:hover:not(.minicard-composer), .is-selected .minicard-plum, .draggable-hover-card .minicard-plum
|
||||
background: none
|
||||
|
||||
.minicard-title
|
||||
line-height: 1.5em
|
||||
|
||||
.minicard .minicard-cover
|
||||
background-size: cover
|
||||
margin: -15px -15px 10px
|
||||
height: 100px
|
||||
|
||||
.card-label-orange
|
||||
color: #fff
|
||||
|
||||
.card-date
|
||||
font-size: 12px
|
||||
padding: 3px 5px
|
||||
|
||||
/* Pop over */
|
||||
.header-title
|
||||
font-family: Poppins
|
||||
font-size: 16px
|
||||
color: #333
|
||||
|
||||
.pop-over
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,.1)
|
||||
border: 0
|
||||
border-radius: 5px
|
||||
|
||||
.pop-over .header
|
||||
padding: 10px
|
||||
border-bottom: 0
|
||||
border-radius: 5px 5px 0 0
|
||||
|
||||
.pop-over .content-container .content
|
||||
padding: 5px 20px 20px
|
||||
width: 260px
|
||||
|
||||
.pop-over-list li > a
|
||||
border-radius: 5px
|
||||
|
||||
.pop-over-list li > a > i
|
||||
margin-right: 5px
|
||||
|
||||
.pop-over-list li>a .sub-name
|
||||
margin-bottom: 8px
|
||||
|
||||
/* Sidebar */
|
||||
.sidebar .sidebar-shadow
|
||||
box-shadow: 0 0 60px rgba(0,0,0,.2)
|
||||
|
||||
.sidebar .sidebar-content
|
||||
padding: 30px
|
||||
|
||||
@@ -74,11 +74,18 @@ BlazeComponent.extendComponent({
|
||||
|
||||
scrollParentContainer() {
|
||||
const cardPanelWidth = 510;
|
||||
const bodyBoardComponent = this.parentComponent().parentComponent();
|
||||
const parentComponent = this.parentComponent();
|
||||
// TODO sometimes parentComponent is not available, maybe because it's not
|
||||
// yet created?!
|
||||
if (!parentComponent) return;
|
||||
const bodyBoardComponent = parentComponent.parentComponent();
|
||||
//On Mobile View Parent is Board, Not Board Body. I cant see how this funciton should work then.
|
||||
if (bodyBoardComponent === null) return;
|
||||
const $cardView = this.$(this.firstNode());
|
||||
const $cardContainer = bodyBoardComponent.$('.js-swimlanes');
|
||||
// TODO sometimes cardContainer is not available, maybe because it's not yet
|
||||
// created?!
|
||||
if (!$cardContainer) return;
|
||||
const cardContainerScroll = $cardContainer.scrollLeft();
|
||||
const cardContainerWidth = $cardContainer.width();
|
||||
|
||||
|
||||
@@ -74,18 +74,16 @@ BlazeComponent.extendComponent({
|
||||
const sortIndex = calculateIndex(prevCardDom, nextCardDom, nCards);
|
||||
const listId = Blaze.getData(ui.item.parents('.list').get(0))._id;
|
||||
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
let swimlaneId = '';
|
||||
const defaultSwimlaneId = currentBoard.getDefaultSwimline()._id;
|
||||
let targetSwimlaneId = null;
|
||||
|
||||
// only set a new swimelane ID if the swimlanes view is active
|
||||
if (
|
||||
Utils.boardView() === 'board-view-swimlanes' ||
|
||||
currentBoard.isTemplatesBoard()
|
||||
)
|
||||
swimlaneId = Blaze.getData(ui.item.parents('.swimlane').get(0))._id;
|
||||
else if (
|
||||
Utils.boardView() === 'board-view-lists' ||
|
||||
Utils.boardView() === 'board-view-cal' ||
|
||||
!Utils.boardView
|
||||
)
|
||||
swimlaneId = currentBoard.getDefaultSwimline()._id;
|
||||
targetSwimlaneId = Blaze.getData(ui.item.parents('.swimlane').get(0))
|
||||
._id;
|
||||
|
||||
// Normally the jquery-ui sortable library moves the dragged DOM element
|
||||
// to its new position, which disrupts Blaze reactive updates mechanism
|
||||
@@ -98,9 +96,12 @@ BlazeComponent.extendComponent({
|
||||
|
||||
if (MultiSelection.isActive()) {
|
||||
Cards.find(MultiSelection.getMongoSelector()).forEach((card, i) => {
|
||||
const newSwimlaneId = targetSwimlaneId
|
||||
? targetSwimlaneId
|
||||
: card.swimlaneId || defaultSwimlaneId;
|
||||
card.move(
|
||||
currentBoard._id,
|
||||
swimlaneId,
|
||||
newSwimlaneId,
|
||||
listId,
|
||||
sortIndex.base + i * sortIndex.increment,
|
||||
);
|
||||
@@ -108,7 +109,10 @@ BlazeComponent.extendComponent({
|
||||
} else {
|
||||
const cardDomElement = ui.item.get(0);
|
||||
const card = Blaze.getData(cardDomElement);
|
||||
card.move(currentBoard._id, swimlaneId, listId, sortIndex.base);
|
||||
const newSwimlaneId = targetSwimlaneId
|
||||
? targetSwimlaneId
|
||||
: card.swimlaneId || defaultSwimlaneId;
|
||||
card.move(currentBoard._id, newSwimlaneId, listId, sortIndex.base);
|
||||
}
|
||||
boardComponent.setIsDragging(false);
|
||||
},
|
||||
|
||||
@@ -15,3 +15,27 @@
|
||||
local('Roboto-Bold'),
|
||||
url('/fonts/roboto-bold.woff2') format('woff2'),
|
||||
url('/fonts/roboto-bold.woff') format('woff')
|
||||
|
||||
@font-face
|
||||
font-family: 'Poppins'
|
||||
font-style: normal
|
||||
font-weight: 400
|
||||
src: local('Poppins'),
|
||||
local('Poppins-Regular'),
|
||||
url('/fonts/poppins-regular.woff') format('woff')
|
||||
|
||||
@font-face
|
||||
font-family: 'Poppins'
|
||||
font-style: normal
|
||||
font-weight: 500
|
||||
src: local('Poppins Medium'),
|
||||
local('Poppins-Medium'),
|
||||
url('/fonts/poppins-medium.woff') format('woff')
|
||||
|
||||
@font-face
|
||||
font-family: 'Poppins'
|
||||
font-style: normal
|
||||
font-weight: 700
|
||||
src: local('Poppins Bold'),
|
||||
local('Poppins-Bold'),
|
||||
url('/fonts/poppins-bold.woff') format('woff')
|
||||
@@ -32,7 +32,7 @@ a:hover,a:focus
|
||||
border-radius: unset
|
||||
|
||||
html, body, input, select, textarea, button
|
||||
font: 14px Roboto, "Helvetica Neue", Arial, Helvetica, sans-serif
|
||||
font: 14px Roboto, Poppins, "Helvetica Neue", Arial, Helvetica, sans-serif
|
||||
line-height: 18px
|
||||
color: #4d4d4d
|
||||
|
||||
|
||||
@@ -68,8 +68,8 @@ BlazeComponent.extendComponent({
|
||||
const ruleName = this.data().ruleName.get();
|
||||
const trigger = this.data().triggerVar.get();
|
||||
const actionSelected = this.find('#move-spec-action').value;
|
||||
const swimlaneName = this.find('#swimlaneName').value;
|
||||
const listName = this.find('#listName').value;
|
||||
const swimlaneName = this.find('#swimlaneName').value || '*';
|
||||
const listName = this.find('#listName').value || '*';
|
||||
const boardId = Session.get('currentBoard');
|
||||
const destBoardId = this.find('#board-id').value;
|
||||
const desc = Utils.getTriggerActionDesc(event, this);
|
||||
|
||||
@@ -164,6 +164,7 @@ BlazeComponent.extendComponent({
|
||||
const boardId = Session.get('currentBoard');
|
||||
const actionId = Actions.insert({
|
||||
actionType: 'removeMember',
|
||||
// deepcode ignore NoHardcodedCredentials: it's no credential
|
||||
username: '*',
|
||||
boardId,
|
||||
desc,
|
||||
|
||||
@@ -363,7 +363,7 @@ template(name="boardMenuPopup")
|
||||
template(name="exportBoard")
|
||||
ul.pop-over-list
|
||||
li
|
||||
a(href="{{exportUrl}}", download="{{exportJsonFilename}}")
|
||||
a.download-json-link(href="{{exportUrl}}", download="{{exportJsonFilename}}")
|
||||
i.fa.fa-share-alt
|
||||
| {{_ 'export-board-json'}}
|
||||
li
|
||||
@@ -374,6 +374,10 @@ template(name="exportBoard")
|
||||
a(href="{{exportTsvUrl}}", download="{{exportTsvFilename}}")
|
||||
i.fa.fa-share-alt
|
||||
| {{_ 'export-board-tsv'}}
|
||||
li
|
||||
a.html-export-board
|
||||
i.fa.fa-archive
|
||||
| {{_ 'export-board-html'}}
|
||||
|
||||
template(name="labelsWidget")
|
||||
.board-widget.board-widget-labels
|
||||
|
||||
@@ -463,6 +463,13 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
}).register('exportBoardPopup');
|
||||
|
||||
Template.exportBoard.events({
|
||||
'click .html-export-board': async event => {
|
||||
event.preventDefault();
|
||||
await ExportHtml(Popup)();
|
||||
},
|
||||
});
|
||||
|
||||
Template.labelsWidget.events({
|
||||
'click .js-label': Popup.open('editLabel'),
|
||||
'click .js-add-label': Popup.open('createLabel'),
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
};
|
||||
return this.each(function() {
|
||||
const element = this;
|
||||
$(element).bind('dragenter dragover dragleave', stopFn);
|
||||
return $(element).bind('drop', function(event) {
|
||||
$(element).on('dragenter dragover dragleave', stopFn);
|
||||
return $(element).on('drop', function(event) {
|
||||
stopFn(event);
|
||||
const files = event.dataTransfer.files;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
const JSZip = require('jszip');
|
||||
|
||||
window.ExportHtml = Popup => {
|
||||
const saveAs = function(blob, filename) {
|
||||
let dl = document.createElement('a');
|
||||
dl.href = window.URL.createObjectURL(blob);
|
||||
dl.onclick = event => document.body.removeChild(event.target);
|
||||
dl.style.display = 'none';
|
||||
dl.target = '_blank';
|
||||
dl.download = filename;
|
||||
document.body.appendChild(dl);
|
||||
dl.click();
|
||||
};
|
||||
|
||||
const asyncForEach = async function(array, callback) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array);
|
||||
}
|
||||
};
|
||||
|
||||
const getPageHtmlString = () => {
|
||||
return `<!doctype html>${window.document.querySelector('html').outerHTML}`;
|
||||
};
|
||||
|
||||
const removeAnchors = htmlString => {
|
||||
const replaceOpenAnchor = htmlString.replace(
|
||||
new RegExp('<a ', 'gim'),
|
||||
'<span ',
|
||||
);
|
||||
return replaceOpenAnchor.replace(new RegExp('</a', 'gim'), '</span');
|
||||
};
|
||||
|
||||
const ensureSidebarRemoved = () => {
|
||||
document.querySelector('.board-sidebar.sidebar').remove();
|
||||
};
|
||||
|
||||
const addJsonExportToZip = async (zip, boardSlug) => {
|
||||
const downloadJSONLink = document.querySelector('.download-json-link');
|
||||
const downloadJSONURL = downloadJSONLink.href;
|
||||
const response = await fetch(downloadJSONURL);
|
||||
const responseBody = await response.text();
|
||||
zip.file(`data/${boardSlug}.json`, responseBody);
|
||||
};
|
||||
|
||||
const closeSidebar = () => {
|
||||
document.querySelector('.board-header-btn.js-toggle-sidebar').click();
|
||||
};
|
||||
|
||||
const cleanBoardHtml = () => {
|
||||
Array.from(document.querySelectorAll('script')).forEach(elem =>
|
||||
elem.remove(),
|
||||
);
|
||||
Array.from(
|
||||
document.querySelectorAll('link:not([rel="stylesheet"])'),
|
||||
).forEach(elem => elem.remove());
|
||||
document.querySelector('#header-quick-access').remove();
|
||||
Array.from(
|
||||
document.querySelectorAll('#header-main-bar .board-header-btns'),
|
||||
).forEach(elem => elem.remove());
|
||||
Array.from(document.querySelectorAll('.list-composer')).forEach(elem =>
|
||||
elem.remove(),
|
||||
);
|
||||
Array.from(
|
||||
document.querySelectorAll(
|
||||
'.list-composer,.js-card-composer, .js-add-card',
|
||||
),
|
||||
).forEach(elem => elem.remove());
|
||||
Array.from(
|
||||
document.querySelectorAll('.js-perfect-scrollbar > div:nth-of-type(n+2)'),
|
||||
).forEach(elem => elem.remove());
|
||||
Array.from(document.querySelectorAll('.js-perfect-scrollbar')).forEach(
|
||||
elem => {
|
||||
elem.style = 'overflow-y: auto !important;';
|
||||
elem.classList.remove('js-perfect-scrollbar');
|
||||
},
|
||||
);
|
||||
Array.from(document.querySelectorAll('[href]:not(link)')).forEach(elem =>
|
||||
elem.attributes.removeNamedItem('href'),
|
||||
);
|
||||
Array.from(document.querySelectorAll('[href]')).forEach(elem => {
|
||||
// eslint-disable-next-line no-self-assign
|
||||
elem.href = elem.href;
|
||||
// eslint-disable-next-line no-self-assign
|
||||
elem.src = elem.src;
|
||||
});
|
||||
Array.from(document.querySelectorAll('.is-editable')).forEach(elem => {
|
||||
elem.classList.remove('is-editable');
|
||||
});
|
||||
};
|
||||
|
||||
const getBoardSlug = () => {
|
||||
return window.location.href.split('/').pop();
|
||||
};
|
||||
|
||||
const getStylesheetList = () => {
|
||||
return Array.from(
|
||||
document.querySelectorAll('link[href][rel="stylesheet"]'),
|
||||
);
|
||||
};
|
||||
|
||||
const downloadStylesheets = async (stylesheets, zip) => {
|
||||
await asyncForEach(stylesheets, async elem => {
|
||||
const response = await fetch(elem.href);
|
||||
const responseBody = await response.text();
|
||||
|
||||
const finalResponse = responseBody.replace(
|
||||
new RegExp('packages/[^/]+/upstream/', 'gim'),
|
||||
'../',
|
||||
);
|
||||
|
||||
const filename = elem.href
|
||||
.split('/')
|
||||
.pop()
|
||||
.split('?')
|
||||
.shift();
|
||||
const fileFullPath = `style/${filename}`;
|
||||
zip.file(fileFullPath, finalResponse);
|
||||
elem.href = `../${fileFullPath}`;
|
||||
});
|
||||
};
|
||||
|
||||
const getSrcAttached = () => {
|
||||
return Array.from(document.querySelectorAll('[src]'));
|
||||
};
|
||||
|
||||
const downloadSrcAttached = async (elements, zip, boardSlug) => {
|
||||
await asyncForEach(elements, async elem => {
|
||||
const response = await fetch(elem.src);
|
||||
const responseBody = await response.blob();
|
||||
const filename = elem.src
|
||||
.split('/')
|
||||
.pop()
|
||||
.split('?')
|
||||
.shift();
|
||||
const fileFullPath = `${boardSlug}/${elem.tagName.toLowerCase()}/${filename}`;
|
||||
zip.file(fileFullPath, responseBody);
|
||||
elem.src = `./${elem.tagName.toLowerCase()}/${filename}`;
|
||||
});
|
||||
};
|
||||
|
||||
const removeCssUrlSurround = url => {
|
||||
const working = url || '';
|
||||
return working
|
||||
.split('url(')
|
||||
.join('')
|
||||
.split('")')
|
||||
.join('')
|
||||
.split('"')
|
||||
.join('')
|
||||
.split("')")
|
||||
.join('')
|
||||
.split("'")
|
||||
.join('')
|
||||
.split(')')
|
||||
.join('');
|
||||
};
|
||||
|
||||
const getCardCovers = () => {
|
||||
return Array.from(document.querySelectorAll('.minicard-cover')).filter(
|
||||
elem => elem.style['background-image'],
|
||||
);
|
||||
};
|
||||
|
||||
const downloadCardCovers = async (elements, zip, boardSlug) => {
|
||||
await asyncForEach(elements, async elem => {
|
||||
const response = await fetch(
|
||||
removeCssUrlSurround(elem.style['background-image']),
|
||||
);
|
||||
const responseBody = await response.blob();
|
||||
const filename = removeCssUrlSurround(elem.style['background-image'])
|
||||
.split('/')
|
||||
.pop()
|
||||
.split('?')
|
||||
.shift()
|
||||
.split('#')
|
||||
.shift();
|
||||
const fileFullPath = `${boardSlug}/covers/${filename}`;
|
||||
zip.file(fileFullPath, responseBody);
|
||||
elem.style = "background-image: url('" + `covers/${filename}` + "')";
|
||||
});
|
||||
};
|
||||
|
||||
const addBoardHTMLToZip = (boardSlug, zip) => {
|
||||
ensureSidebarRemoved();
|
||||
const htmlOutputPath = `${boardSlug}/index.html`;
|
||||
zip.file(
|
||||
htmlOutputPath,
|
||||
new Blob([removeAnchors(getPageHtmlString())], {
|
||||
type: 'application/html',
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
return async () => {
|
||||
const zip = new JSZip();
|
||||
const boardSlug = getBoardSlug();
|
||||
|
||||
await addJsonExportToZip(zip, boardSlug);
|
||||
Popup.close();
|
||||
closeSidebar();
|
||||
cleanBoardHtml();
|
||||
|
||||
await downloadStylesheets(getStylesheetList(), zip);
|
||||
await downloadSrcAttached(getSrcAttached(), zip, boardSlug);
|
||||
await downloadCardCovers(getCardCovers(), zip, boardSlug);
|
||||
|
||||
addBoardHTMLToZip(boardSlug, zip);
|
||||
|
||||
const content = await zip.generateAsync({ type: 'blob' });
|
||||
saveAs(content, `${boardSlug}.zip`);
|
||||
window.location.reload();
|
||||
};
|
||||
};
|
||||
@@ -35,7 +35,7 @@
|
||||
options = $.extend({}, defaults, options);
|
||||
return this.each(function() {
|
||||
const element = this;
|
||||
return $(element).bind('paste', function(event) {
|
||||
return $(element).on('paste', function(event) {
|
||||
const types = event.clipboardData.types;
|
||||
const items = event.clipboardData.items;
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ window.Popup = new (class {
|
||||
// has one. This allows us to position a sub-popup exactly at the same
|
||||
// position than its parent.
|
||||
let openerElement;
|
||||
if (clickFromPopup(evt)) {
|
||||
if (clickFromPopup(evt) && self._getTopStack()) {
|
||||
openerElement = self._getTopStack().openerElement;
|
||||
} else {
|
||||
self._stack = [];
|
||||
|
||||
+9
-9
@@ -164,15 +164,15 @@
|
||||
"cardStartVotingPopup-title": "Abstimmung starten",
|
||||
"positiveVoteMembersPopup-title": "Befürworter",
|
||||
"negativeVoteMembersPopup-title": "Gegner",
|
||||
"card-edit-voting": "Edit voting",
|
||||
"editVoteEndDatePopup-title": "Change vote end date",
|
||||
"allowNonBoardMembers": "Allow all logged in users",
|
||||
"card-edit-voting": "Abstimmung editieren",
|
||||
"editVoteEndDatePopup-title": "Enddatum der Abstimmung ändern",
|
||||
"allowNonBoardMembers": "Alle eingeloggte Nutzer erlauben",
|
||||
"vote-question": "Abstimmen über",
|
||||
"vote-public": "Zeigen, wer was gewählt hat",
|
||||
"vote-for-it": "Dafür",
|
||||
"vote-against": "Dagegen",
|
||||
"deleteVotePopup-title": "Delete vote?",
|
||||
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
|
||||
"deleteVotePopup-title": "Wahl löschen?",
|
||||
"vote-delete-pop": "Löschen ist unwiderruflich. Alle Aktionen die dieser Karte zugeordnet sind werden ebenfalls gelöscht.",
|
||||
"cardDeletePopup-title": "Karte löschen?",
|
||||
"cardDetailsActionsPopup-title": "Kartenaktionen",
|
||||
"cardLabelsPopup-title": "Labels",
|
||||
@@ -309,7 +309,7 @@
|
||||
"error-board-notAMember": "Um das zu tun, müssen Sie Mitglied dieses Boards sein",
|
||||
"error-json-malformed": "Ihre Eingabe ist kein gültiges JSON",
|
||||
"error-json-schema": "Ihre JSON-Daten enthalten nicht die gewünschten Informationen im richtigen Format",
|
||||
"error-csv-schema": "Your CSV(Comma Separated Values)/TSV (Tab Separated Values) does not include the proper information in the correct format",
|
||||
"error-csv-schema": "hre CSV (Comma Separated Values)/TSV (Tab Separated Values) enthalten nicht die gewünschten Informationen im richtigen Format",
|
||||
"error-list-doesNotExist": "Diese Liste existiert nicht",
|
||||
"error-user-doesNotExist": "Dieser Nutzer existiert nicht",
|
||||
"error-user-notAllowSelf": "Sie können sich nicht selbst einladen.",
|
||||
@@ -639,7 +639,7 @@
|
||||
"r-when-a-card": "Wenn Karte",
|
||||
"r-is": "wird",
|
||||
"r-is-moved": "verschoben wird",
|
||||
"r-added-to": "Added to",
|
||||
"r-added-to": "Hinzugefügt zu",
|
||||
"r-removed-from": "entfernt von",
|
||||
"r-the-board": "das Board",
|
||||
"r-list": "Liste",
|
||||
@@ -802,8 +802,8 @@
|
||||
"swimlane": "Swimlane",
|
||||
"owner": "Eigentümer",
|
||||
"last-modified-at": "Zuletzt geändert um",
|
||||
"last-activity": "Last activity",
|
||||
"voting": "Voting",
|
||||
"last-activity": "Letzte Aktivität",
|
||||
"voting": "Abstimunng",
|
||||
"archived": "Archiviert",
|
||||
"delete-linked-card-before-this-card": "You can not delete this card before first deleting linked card that has",
|
||||
"delete-linked-cards-before-this-list": "You can not delete this list before first deleting linked cards that are pointing to cards in this list"
|
||||
|
||||
+5
-5
@@ -43,7 +43,7 @@
|
||||
"act-withBoardTitle": "__board__",
|
||||
"act-withCardTitle": "[__board__] __card__",
|
||||
"actions": "Ενέργειες",
|
||||
"activities": "Activities",
|
||||
"activities": "Δραστηριότητες",
|
||||
"activity": "Δραστηριότητα",
|
||||
"activity-added": "added %s to %s",
|
||||
"activity-archived": "%s μετακινήθηκε στο Αρχείο",
|
||||
@@ -55,7 +55,7 @@
|
||||
"activity-imported-board": "imported %s from %s",
|
||||
"activity-joined": "joined %s",
|
||||
"activity-moved": "moved %s from %s to %s",
|
||||
"activity-on": "on %s",
|
||||
"activity-on": "στό %s",
|
||||
"activity-removed": "removed %s from %s",
|
||||
"activity-sent": "sent %s to %s",
|
||||
"activity-unjoined": "unjoined %s",
|
||||
@@ -76,18 +76,18 @@
|
||||
"activity-editComment": "edited comment %s",
|
||||
"activity-deleteComment": "deleted comment %s",
|
||||
"add-attachment": "Add Attachment",
|
||||
"add-board": "Add Board",
|
||||
"add-board": "Προσθήκη Πίνακα",
|
||||
"add-card": "Προσθήκη Κάρτας",
|
||||
"add-swimlane": "Add Swimlane",
|
||||
"add-subtask": "Add Subtask",
|
||||
"add-checklist": "Add Checklist",
|
||||
"add-checklist": "Προσθήκη Λίστας ελέγχου",
|
||||
"add-checklist-item": "Add an item to checklist",
|
||||
"add-cover": "Add Cover",
|
||||
"add-label": "Προσθήκη Ετικέτας",
|
||||
"add-list": "Προσθήκη Λίστας",
|
||||
"add-members": "Προσθήκη Μελών",
|
||||
"added": "Προστέθηκε",
|
||||
"addMemberPopup-title": "Μέλοι",
|
||||
"addMemberPopup-title": "Μέλη",
|
||||
"admin": "Διαχειριστής",
|
||||
"admin-desc": "Can view and edit cards, remove members, and change settings for the board.",
|
||||
"admin-announcement": "Announcement",
|
||||
|
||||
+7
-7
@@ -687,7 +687,7 @@
|
||||
"r-of-checklist": "de la lista de verificación",
|
||||
"r-send-email": "Enviar un email",
|
||||
"r-to": "a",
|
||||
"r-of": "of",
|
||||
"r-of": "de",
|
||||
"r-subject": "asunto",
|
||||
"r-rule-details": "Detalle de la regla",
|
||||
"r-d-move-to-top-gen": "Mover la tarjeta al inicio de su lista",
|
||||
@@ -790,7 +790,7 @@
|
||||
"remove-all-read": "Eliminar todos los leídos",
|
||||
"allow-rename": "Permitir renombrar",
|
||||
"allowRenamePopup-title": "Permitir renombrar",
|
||||
"start-day-of-week": "Set day of the week start",
|
||||
"start-day-of-week": "Establecer el dia de comienzo de la semana",
|
||||
"monday": "Lunes",
|
||||
"tuesday": "Martes",
|
||||
"wednesday": "Miércoles",
|
||||
@@ -801,10 +801,10 @@
|
||||
"status": "Estado",
|
||||
"swimlane": "Carril",
|
||||
"owner": "Propietario",
|
||||
"last-modified-at": "Last modified at",
|
||||
"last-modified-at": "Última modificación ",
|
||||
"last-activity": "Última actividad",
|
||||
"voting": "Voting",
|
||||
"archived": "Archived",
|
||||
"delete-linked-card-before-this-card": "You can not delete this card before first deleting linked card that has",
|
||||
"delete-linked-cards-before-this-list": "You can not delete this list before first deleting linked cards that are pointing to cards in this list"
|
||||
"voting": "Votar",
|
||||
"archived": "Archivado",
|
||||
"delete-linked-card-before-this-card": "No puede borrar esta tarjeta antes de borrar la tarjeta enlazada que tiene",
|
||||
"delete-linked-cards-before-this-list": "No puede borrar esta lista antes de borrar las tarjetas enlazadas que apuntan a tarjetas en esta lista"
|
||||
}
|
||||
+1
-1
@@ -805,6 +805,6 @@
|
||||
"last-activity": "פעילות אחרונה",
|
||||
"voting": "הצבעה",
|
||||
"archived": "בארכיון",
|
||||
"delete-linked-card-before-this-card": "You can not delete this card before first deleting linked card that has",
|
||||
"delete-linked-card-before-this-card": "לא ניתן למחוק את הכרטיס הזה לפני שמוחקים את הכרטיס המקושר שיש לו",
|
||||
"delete-linked-cards-before-this-list": "לא ניתן למחוק את הרשימה הזו לפני שמוחקים את הכרטיסים שמצביעים לכרטיסים ברשימה הזו"
|
||||
}
|
||||
+24
-24
@@ -164,15 +164,15 @@
|
||||
"cardStartVotingPopup-title": "Zacznij głosowanie",
|
||||
"positiveVoteMembersPopup-title": "Zwolennicy",
|
||||
"negativeVoteMembersPopup-title": "Przeciwnicy",
|
||||
"card-edit-voting": "Edit voting",
|
||||
"editVoteEndDatePopup-title": "Change vote end date",
|
||||
"allowNonBoardMembers": "Allow all logged in users",
|
||||
"card-edit-voting": "Edytuj głosowanie",
|
||||
"editVoteEndDatePopup-title": "Zmień głos oraz datę",
|
||||
"allowNonBoardMembers": "Pozwól wszystkim zalogowanym użytkownikom",
|
||||
"vote-question": "Pytanie do głosowania",
|
||||
"vote-public": "Pokaż, kto głosował na wybrane opcje",
|
||||
"vote-for-it": "za",
|
||||
"vote-against": "przeciwko",
|
||||
"deleteVotePopup-title": "Delete vote?",
|
||||
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
|
||||
"deleteVotePopup-title": "Usunąć głos?",
|
||||
"vote-delete-pop": "Usuwanie jest nieodwracalne. Stracisz wszystkie czynności związane z tym głosem.",
|
||||
"cardDeletePopup-title": "Usunąć kartę?",
|
||||
"cardDetailsActionsPopup-title": "Czynności kart",
|
||||
"cardLabelsPopup-title": "Etykiety",
|
||||
@@ -309,7 +309,7 @@
|
||||
"error-board-notAMember": "Musisz być członkiem tej tablicy, żeby wykonać tę czynność",
|
||||
"error-json-malformed": "Twoja fraza nie jest w formacie JSON",
|
||||
"error-json-schema": "Twoje dane JSON nie zawierają prawidłowych informacji w poprawnym formacie",
|
||||
"error-csv-schema": "Your CSV(Comma Separated Values)/TSV (Tab Separated Values) does not include the proper information in the correct format",
|
||||
"error-csv-schema": "Twój plik CSV(plik oddzielony przecinkami)/TSV (plik oddzielony tabulatorami) nie zawiera danych w poprawnym formacie",
|
||||
"error-list-doesNotExist": "Ta lista nie isnieje",
|
||||
"error-user-doesNotExist": "Ten użytkownik nie istnieje",
|
||||
"error-user-notAllowSelf": "Nie możesz zaprosić samego siebie",
|
||||
@@ -317,10 +317,10 @@
|
||||
"error-username-taken": "Ta nazwa jest już zajęta",
|
||||
"error-email-taken": "Adres email jest już zarezerwowany",
|
||||
"export-board": "Eksportuj tablicę",
|
||||
"export-board-json": "Export board to JSON",
|
||||
"export-board-csv": "Export board to CSV",
|
||||
"export-board-tsv": "Export board to TSV",
|
||||
"export-board-html": "Export board to HTML",
|
||||
"export-board-json": "Eksportuj tablicę do JSON",
|
||||
"export-board-csv": "Eksportuj tablicę do CSV",
|
||||
"export-board-tsv": "Eksportuj tablicę do TSV",
|
||||
"export-board-html": "Eksportuj tablicę do HTML",
|
||||
"exportBoardPopup-title": "Eksportuj tablicę",
|
||||
"sort": "Sortuj",
|
||||
"sort-desc": "Kliknij by sortować listę",
|
||||
@@ -357,16 +357,16 @@
|
||||
"import-board-c": "Import tablicy",
|
||||
"import-board-title-trello": "Importuj tablicę z Trello",
|
||||
"import-board-title-wekan": "Importuj tablicę z poprzedniego eksportu",
|
||||
"import-board-title-csv": "Import board from CSV/TSV",
|
||||
"import-board-title-csv": "Importuj tablicę z CSV/TSV",
|
||||
"from-trello": "Z Trello",
|
||||
"from-wekan": "Z poprzedniego eksportu",
|
||||
"from-csv": "From CSV/TSV",
|
||||
"from-csv": "Z CSV/TSV",
|
||||
"import-board-instruction-trello": "W twojej tablicy na Trello przejdź do 'Menu', następnie 'Więcej', 'Drukuj i eksportuj', 'Eksportuj jako JSON' i skopiuj wynik",
|
||||
"import-board-instruction-csv": "Paste in your Comma Separated Values(CSV)/ Tab Separated Values (TSV) .",
|
||||
"import-board-instruction-csv": "Wklej swoje dane w postaci wartości oddzielanych przecinkiem (CSV) lub tabulatorem (TSV)",
|
||||
"import-board-instruction-wekan": "Na Twojej tablicy przejdź do 'Menu', a następnie wybierz 'Eksportuj tablicę' i skopiuj tekst w pobranym pliku.",
|
||||
"import-board-instruction-about-errors": "W przypadku, gdy otrzymujesz błędy importowania tablicy, czasami importowanie pomimo wszystko działa poprawnie i tablica znajduje się w oknie Wszystkie tablice.",
|
||||
"import-json-placeholder": "Wklej Twoje dane JSON tutaj",
|
||||
"import-csv-placeholder": "Paste your valid CSV/TSV data here",
|
||||
"import-csv-placeholder": "Wklej swoje dane z pliku CSV/TSV tutaj",
|
||||
"import-map-members": "Przypisz członków",
|
||||
"import-members-map": "Twoje zaimportowane tablice mają kilku członków. Proszę wybierz członków których chcesz zaimportować dla Twoich użytkowników",
|
||||
"import-show-user-mapping": "Przejrzyj wybranych członków",
|
||||
@@ -399,7 +399,7 @@
|
||||
"swimlaneActionPopup-title": "Opcje diagramu czynności",
|
||||
"swimlaneAddPopup-title": "Dodaj diagram czynności poniżej",
|
||||
"listImportCardPopup-title": "Zaimportuj kartę z Trello",
|
||||
"listImportCardsTsvPopup-title": "Import Excel CSV/TSV",
|
||||
"listImportCardsTsvPopup-title": "Importuj CSV/TSV z Excela",
|
||||
"listMorePopup-title": "Więcej",
|
||||
"link-list": "Podepnij do tej listy",
|
||||
"list-delete-pop": "Wszystkie czynności zostaną usunięte z Aktywności i nie będziesz w stanie przywrócić listy. Nie ma możliwości cofnięcia tej operacji.",
|
||||
@@ -639,7 +639,7 @@
|
||||
"r-when-a-card": "Gdy karta",
|
||||
"r-is": "jest",
|
||||
"r-is-moved": "jest przenoszona",
|
||||
"r-added-to": "Added to",
|
||||
"r-added-to": "Dodany do",
|
||||
"r-removed-from": "usunął z",
|
||||
"r-the-board": "tablicy",
|
||||
"r-list": "lista",
|
||||
@@ -799,12 +799,12 @@
|
||||
"saturday": "Sobota",
|
||||
"sunday": "Niedziela",
|
||||
"status": "Status",
|
||||
"swimlane": "Swimlane",
|
||||
"owner": "Owner",
|
||||
"last-modified-at": "Last modified at",
|
||||
"last-activity": "Last activity",
|
||||
"voting": "Voting",
|
||||
"archived": "Archived",
|
||||
"delete-linked-card-before-this-card": "You can not delete this card before first deleting linked card that has",
|
||||
"delete-linked-cards-before-this-list": "You can not delete this list before first deleting linked cards that are pointing to cards in this list"
|
||||
"swimlane": "Diagram czynności",
|
||||
"owner": "Właściciel",
|
||||
"last-modified-at": "Ostatnio zmodyfikowano",
|
||||
"last-activity": "Ostatnia aktywność",
|
||||
"voting": "Głosowanie",
|
||||
"archived": "Zarchiwizowany",
|
||||
"delete-linked-card-before-this-card": "Nie możesz usunąć tej karty, dopóki nie usuniesz podpiętej karty, w której są",
|
||||
"delete-linked-cards-before-this-list": "Nie możesz usunąć tej karty, dopóki nie usuniesz podpiętych kart, które wskazują na karty w tej liście"
|
||||
}
|
||||
+2
-2
@@ -805,6 +805,6 @@
|
||||
"last-activity": "Последние действия",
|
||||
"voting": "Голосование",
|
||||
"archived": "Архивировано",
|
||||
"delete-linked-card-before-this-card": "You can not delete this card before first deleting linked card that has",
|
||||
"delete-linked-cards-before-this-list": "You can not delete this list before first deleting linked cards that are pointing to cards in this list"
|
||||
"delete-linked-card-before-this-card": "Вы не можете удалить карточку, не удалив связанную c ней карточку, которая имеет ",
|
||||
"delete-linked-cards-before-this-list": "Вы не можете удалить этот список, не удалив карточки, которые указывают на карточки в этом списке"
|
||||
}
|
||||
+25
-25
@@ -164,15 +164,15 @@
|
||||
"cardStartVotingPopup-title": "建立投票",
|
||||
"positiveVoteMembersPopup-title": "支持",
|
||||
"negativeVoteMembersPopup-title": "反对",
|
||||
"card-edit-voting": "Edit voting",
|
||||
"editVoteEndDatePopup-title": "Change vote end date",
|
||||
"allowNonBoardMembers": "Allow all logged in users",
|
||||
"card-edit-voting": "编辑投票",
|
||||
"editVoteEndDatePopup-title": "修改投票截止日期",
|
||||
"allowNonBoardMembers": "允许所有已登入账户",
|
||||
"vote-question": "投票题目",
|
||||
"vote-public": "查看投票结果",
|
||||
"vote-for-it": "同意",
|
||||
"vote-against": "反对",
|
||||
"deleteVotePopup-title": "Delete vote?",
|
||||
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
|
||||
"deleteVotePopup-title": "删除投票?",
|
||||
"vote-delete-pop": "永久删除。此操作会将所有数据删除掉。",
|
||||
"cardDeletePopup-title": "彻底删除卡片?",
|
||||
"cardDetailsActionsPopup-title": "卡片操作",
|
||||
"cardLabelsPopup-title": "标签",
|
||||
@@ -309,7 +309,7 @@
|
||||
"error-board-notAMember": "需要成为看板成员才能执行此操作",
|
||||
"error-json-malformed": "文本不是合法的 JSON",
|
||||
"error-json-schema": "JSON 数据没有用正确的格式包含合适的信息",
|
||||
"error-csv-schema": "Your CSV(Comma Separated Values)/TSV (Tab Separated Values) does not include the proper information in the correct format",
|
||||
"error-csv-schema": "CSV(逗号分隔值)/TSV(制表符分隔值)数据格式的不正确",
|
||||
"error-list-doesNotExist": "不存在此列表",
|
||||
"error-user-doesNotExist": "该用户不存在",
|
||||
"error-user-notAllowSelf": "无法邀请自己",
|
||||
@@ -317,10 +317,10 @@
|
||||
"error-username-taken": "此用户名已存在",
|
||||
"error-email-taken": "此EMail已存在",
|
||||
"export-board": "导出看板",
|
||||
"export-board-json": "Export board to JSON",
|
||||
"export-board-csv": "Export board to CSV",
|
||||
"export-board-tsv": "Export board to TSV",
|
||||
"export-board-html": "Export board to HTML",
|
||||
"export-board-json": "看板导出为JSON",
|
||||
"export-board-csv": "看板导出为CSV",
|
||||
"export-board-tsv": "看板导出为TSV",
|
||||
"export-board-html": "看板导出为HTML",
|
||||
"exportBoardPopup-title": "导出看板",
|
||||
"sort": "排序",
|
||||
"sort-desc": "点此来将列表排序",
|
||||
@@ -357,16 +357,16 @@
|
||||
"import-board-c": "导入看板",
|
||||
"import-board-title-trello": "从Trello导入看板",
|
||||
"import-board-title-wekan": "从以前的导出数据导入看板",
|
||||
"import-board-title-csv": "Import board from CSV/TSV",
|
||||
"import-board-title-csv": "导入CSV/TSV看板",
|
||||
"from-trello": "自 Trello",
|
||||
"from-wekan": "自以前的导出",
|
||||
"from-csv": "From CSV/TSV",
|
||||
"from-csv": "从CSV/TSV",
|
||||
"import-board-instruction-trello": "在你的Trello看板中,点击“菜单”,然后选择“更多”,“打印与导出”,“导出为 JSON” 并拷贝结果文本",
|
||||
"import-board-instruction-csv": "Paste in your Comma Separated Values(CSV)/ Tab Separated Values (TSV) .",
|
||||
"import-board-instruction-csv": "粘贴逗号分隔值(CSV)/制表符分隔值(TSV)。",
|
||||
"import-board-instruction-wekan": "在您的看板,点击“菜单”,然后“导出看板”,复制下载文件中的文本。",
|
||||
"import-board-instruction-about-errors": "如果在导入看板时出现错误,导入工作可能仍然在进行中,并且看板已经出现在全部看板页。",
|
||||
"import-json-placeholder": "粘贴您有效的 JSON 数据至此",
|
||||
"import-csv-placeholder": "Paste your valid CSV/TSV data here",
|
||||
"import-csv-placeholder": "在此处粘贴有效的CSV/TSV数据",
|
||||
"import-map-members": "映射成员",
|
||||
"import-members-map": "您导入的看板有一些成员,请映射这些成员到您导入的用户。",
|
||||
"import-show-user-mapping": "核对成员映射",
|
||||
@@ -399,7 +399,7 @@
|
||||
"swimlaneActionPopup-title": "泳道图操作",
|
||||
"swimlaneAddPopup-title": "在下面添加一个泳道",
|
||||
"listImportCardPopup-title": "导入 Trello 卡片",
|
||||
"listImportCardsTsvPopup-title": "Import Excel CSV/TSV",
|
||||
"listImportCardsTsvPopup-title": "导入Excel CSV/TSV",
|
||||
"listMorePopup-title": "更多",
|
||||
"link-list": "关联到这个列表",
|
||||
"list-delete-pop": "所有活动将被从活动动态中删除并且你无法恢复他们,此操作无法撤销。",
|
||||
@@ -639,7 +639,7 @@
|
||||
"r-when-a-card": "当一张卡片",
|
||||
"r-is": "是",
|
||||
"r-is-moved": "已经移动",
|
||||
"r-added-to": "Added to",
|
||||
"r-added-to": "添加到",
|
||||
"r-removed-from": "已移除",
|
||||
"r-the-board": "该看板",
|
||||
"r-list": "列表",
|
||||
@@ -798,13 +798,13 @@
|
||||
"friday": "周五",
|
||||
"saturday": "周六",
|
||||
"sunday": "周日",
|
||||
"status": "Status",
|
||||
"swimlane": "Swimlane",
|
||||
"owner": "Owner",
|
||||
"last-modified-at": "Last modified at",
|
||||
"last-activity": "Last activity",
|
||||
"voting": "Voting",
|
||||
"archived": "Archived",
|
||||
"delete-linked-card-before-this-card": "You can not delete this card before first deleting linked card that has",
|
||||
"delete-linked-cards-before-this-list": "You can not delete this list before first deleting linked cards that are pointing to cards in this list"
|
||||
"status": "状态",
|
||||
"swimlane": "泳道",
|
||||
"owner": "所有者",
|
||||
"last-modified-at": "上次修改时间",
|
||||
"last-activity": "上次活动",
|
||||
"voting": "投票",
|
||||
"archived": "存档",
|
||||
"delete-linked-card-before-this-card": "在你首次删除卡片前你无法删除此选项卡片",
|
||||
"delete-linked-cards-before-this-list": "在首先删除指向此列表中的卡的链接卡之前,不能删除此列表"
|
||||
}
|
||||
@@ -747,7 +747,7 @@
|
||||
"error-ldap-login": "嘗試登入時出現錯誤",
|
||||
"display-authentication-method": "顯示認證方式",
|
||||
"default-authentication-method": "預設認證方式",
|
||||
"duplicate-board": "重複的看板",
|
||||
"duplicate-board": "複製看板",
|
||||
"people-number": "人數是:",
|
||||
"swimlaneDeletePopup-title": "是否刪除泳道?",
|
||||
"swimlane-delete-pop": "所有動作將從活動來源中刪除,您將無法恢復泳道。此操作無法還原。",
|
||||
|
||||
+3
-1
@@ -255,7 +255,9 @@ Boards.attachSchema(
|
||||
'dark',
|
||||
'relax',
|
||||
'corteza',
|
||||
'clearblue'
|
||||
'clearblue',
|
||||
'natural',
|
||||
'modern',
|
||||
],
|
||||
// eslint-disable-next-line consistent-return
|
||||
autoValue() {
|
||||
|
||||
@@ -530,6 +530,7 @@ Cards.helpers({
|
||||
},
|
||||
|
||||
cover() {
|
||||
if (!this.coverId) return false;
|
||||
const cover = Attachments.findOne(this.coverId);
|
||||
// if we return a cover before it is fully stored, we will get errors when we try to display it
|
||||
// todo XXX we could return a default "upload pending" image in the meantime?
|
||||
|
||||
@@ -70,7 +70,9 @@ Checklists.helpers({
|
||||
this._id = null;
|
||||
this.cardId = newCardId;
|
||||
const newChecklistId = Checklists.insert(this);
|
||||
ChecklistItems.find({ checklistId: oldChecklistId }).forEach(item => {
|
||||
ChecklistItems.find({ checklistId: oldChecklistId }).forEach(function(
|
||||
item,
|
||||
) {
|
||||
item._id = null;
|
||||
item.checklistId = newChecklistId;
|
||||
item.cardId = newCardId;
|
||||
|
||||
+86
-16
@@ -50,6 +50,7 @@ export class CsvCreator {
|
||||
*/
|
||||
mapHeadertoCardFieldIndex(headerRow) {
|
||||
const index = {};
|
||||
index.customFields = [];
|
||||
for (let i = 0; i < headerRow.length; i++) {
|
||||
switch (headerRow[i].trim().toLowerCase()) {
|
||||
case 'title':
|
||||
@@ -98,9 +99,50 @@ export class CsvCreator {
|
||||
index.modifiedAt = i;
|
||||
break;
|
||||
}
|
||||
if (headerRow[i].toLowerCase().startsWith('customfield')) {
|
||||
if (headerRow[i].split('-')[2] === 'dropdown') {
|
||||
index.customFields.push({
|
||||
name: headerRow[i].split('-')[1],
|
||||
type: headerRow[i].split('-')[2],
|
||||
options: headerRow[i].split('-')[3].split('/'),
|
||||
position: i,
|
||||
});
|
||||
} else {
|
||||
index.customFields.push({
|
||||
name: headerRow[i].split('-')[1],
|
||||
type: headerRow[i].split('-')[2],
|
||||
position: i,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
this.fieldIndex = index;
|
||||
}
|
||||
createCustomFields(boardId) {
|
||||
this.fieldIndex.customFields.forEach(customField => {
|
||||
let settings = {};
|
||||
if (customField.type === 'dropdown') {
|
||||
settings = {
|
||||
dropdownItems: customField.options.map(option => {
|
||||
return { _id: Random.id(6), name: option };
|
||||
}),
|
||||
};
|
||||
} else {
|
||||
settings = {};
|
||||
}
|
||||
const id = CustomFields.direct.insert({
|
||||
name: customField.name,
|
||||
type: customField.type,
|
||||
settings,
|
||||
showOnCard: false,
|
||||
automaticallyOnCard: false,
|
||||
showLabelOnMiniCard: false,
|
||||
boardIds: [boardId],
|
||||
});
|
||||
customField.id = id;
|
||||
customField.settings = settings;
|
||||
});
|
||||
}
|
||||
|
||||
createBoard(csvData) {
|
||||
const boardToCreate = {
|
||||
@@ -228,9 +270,10 @@ export class CsvCreator {
|
||||
const cardToCreate = {
|
||||
archived: false,
|
||||
boardId,
|
||||
createdAt: csvData[i][this.fieldIndex.createdAt]
|
||||
? this._now(new Date(csvData[i][this.fieldIndex.createdAt]))
|
||||
: null,
|
||||
createdAt:
|
||||
csvData[i][this.fieldIndex.createdAt] !== ' ' || ''
|
||||
? this._now(new Date(csvData[i][this.fieldIndex.createdAt]))
|
||||
: null,
|
||||
dateLastActivity: this._now(),
|
||||
description: csvData[i][this.fieldIndex.description],
|
||||
listId: this.lists[csvData[i][this.fieldIndex.stage]],
|
||||
@@ -238,20 +281,24 @@ export class CsvCreator {
|
||||
sort: -1,
|
||||
title: csvData[i][this.fieldIndex.title],
|
||||
userId: this._user(),
|
||||
startAt: csvData[i][this.fieldIndex.startAt]
|
||||
? this._now(new Date(csvData[i][this.fieldIndex.startAt]))
|
||||
: null,
|
||||
dueAt: csvData[i][this.fieldIndex.dueAt]
|
||||
? this._now(new Date(csvData[i][this.fieldIndex.dueAt]))
|
||||
: null,
|
||||
endAt: csvData[i][this.fieldIndex.endAt]
|
||||
? this._now(new Date(csvData[i][this.fieldIndex.endAt]))
|
||||
: null,
|
||||
startAt:
|
||||
csvData[i][this.fieldIndex.startAt] !== ' ' || ''
|
||||
? this._now(new Date(csvData[i][this.fieldIndex.startAt]))
|
||||
: null,
|
||||
dueAt:
|
||||
csvData[i][this.fieldIndex.dueAt] !== ' ' || ''
|
||||
? this._now(new Date(csvData[i][this.fieldIndex.dueAt]))
|
||||
: null,
|
||||
endAt:
|
||||
csvData[i][this.fieldIndex.endAt] !== ' ' || ''
|
||||
? this._now(new Date(csvData[i][this.fieldIndex.endAt]))
|
||||
: null,
|
||||
spentTime: null,
|
||||
labelIds: [],
|
||||
modifiedAt: csvData[i][this.fieldIndex.modifiedAt]
|
||||
? this._now(new Date(csvData[i][this.fieldIndex.modifiedAt]))
|
||||
: null,
|
||||
modifiedAt:
|
||||
csvData[i][this.fieldIndex.modifiedAt] !== ' ' || ''
|
||||
? this._now(new Date(csvData[i][this.fieldIndex.modifiedAt]))
|
||||
: null,
|
||||
};
|
||||
// add the labels
|
||||
if (csvData[i][this.fieldIndex.labels]) {
|
||||
@@ -290,7 +337,29 @@ export class CsvCreator {
|
||||
cardToCreate.members = wekanMembers;
|
||||
}
|
||||
}
|
||||
Cards.direct.insert(cardToCreate);
|
||||
// add the custom fields
|
||||
if (this.fieldIndex.customFields.length > 0) {
|
||||
const customFields = [];
|
||||
this.fieldIndex.customFields.forEach(customField => {
|
||||
if (csvData[i][customField.position] !== ' ') {
|
||||
if (customField.type === 'dropdown') {
|
||||
customFields.push({
|
||||
_id: customField.id,
|
||||
value: customField.settings.dropdownItems.find(
|
||||
({ name }) => name === csvData[i][customField.position],
|
||||
)._id,
|
||||
});
|
||||
} else {
|
||||
customFields.push({
|
||||
_id: customField.id,
|
||||
value: csvData[i][customField.position],
|
||||
});
|
||||
}
|
||||
}
|
||||
cardToCreate.customFields = customFields;
|
||||
});
|
||||
Cards.direct.insert(cardToCreate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,6 +376,7 @@ export class CsvCreator {
|
||||
const boardId = this.createBoard(board);
|
||||
this.createLists(board, boardId);
|
||||
this.createSwimlanes(boardId);
|
||||
this.createCustomFields(boardId);
|
||||
this.createCards(board, boardId);
|
||||
return boardId;
|
||||
}
|
||||
|
||||
+65
-16
@@ -37,8 +37,8 @@ export class Exporter {
|
||||
result.cards = Cards.find(byBoardNoLinked, noBoardId).fetch();
|
||||
result.swimlanes = Swimlanes.find(byBoard, noBoardId).fetch();
|
||||
result.customFields = CustomFields.find(
|
||||
{ boardIds: { $in: [this.boardId] } },
|
||||
{ fields: { boardId: 0 } },
|
||||
{ boardIds: this.boardId },
|
||||
{ fields: { boardIds: 0 } },
|
||||
).fetch();
|
||||
result.comments = CardComments.find(byBoard, noBoardId).fetch();
|
||||
result.activities = Activities.find(byBoard, noBoardId).fetch();
|
||||
@@ -214,7 +214,29 @@ export class Exporter {
|
||||
'Vote',
|
||||
'Archived',
|
||||
);
|
||||
|
||||
const customFieldMap = {};
|
||||
let i = 0;
|
||||
result.customFields.forEach(customField => {
|
||||
customFieldMap[customField._id] = i;
|
||||
customFieldMap[customField._id] = {
|
||||
position: i,
|
||||
type: customField.type,
|
||||
};
|
||||
if (customField.type === 'dropdown') {
|
||||
let options = '';
|
||||
customField.settings.dropdownItems.forEach(item => {
|
||||
options = options === '' ? item.name : `/${options + item.name}`;
|
||||
});
|
||||
columnHeaders.push(
|
||||
`CustomField-${customField.name}-${customField.type}-${options}`,
|
||||
);
|
||||
} else {
|
||||
columnHeaders.push(
|
||||
`CustomField-${customField.name}-${customField.type}`,
|
||||
);
|
||||
}
|
||||
i++;
|
||||
});
|
||||
/* TODO: Try to get translations working.
|
||||
These currently only bring English translations.
|
||||
TAPi18n.__('title'),
|
||||
@@ -290,23 +312,17 @@ export class Exporter {
|
||||
labels = `${labels + label.name}-${label.color} `;
|
||||
});
|
||||
currentRow.push(labels.trim());
|
||||
currentRow.push(card.startAt ? moment(card.startAt).format('LLLL') : ' ');
|
||||
currentRow.push(card.dueAt ? moment(card.dueAt).format('LLLL') : ' ');
|
||||
currentRow.push(card.endAt ? moment(card.endAt).format('LLLL') : ' ');
|
||||
currentRow.push(card.startAt ? moment(card.startAt).format() : ' ');
|
||||
currentRow.push(card.dueAt ? moment(card.dueAt).format() : ' ');
|
||||
currentRow.push(card.endAt ? moment(card.endAt).format() : ' ');
|
||||
currentRow.push(card.isOvertime ? 'true' : 'false');
|
||||
currentRow.push(card.spentTime);
|
||||
currentRow.push(card.createdAt ? moment(card.createdAt).format() : ' ');
|
||||
currentRow.push(card.modifiedAt ? moment(card.modifiedAt).format() : ' ');
|
||||
currentRow.push(
|
||||
card.createdAt ? moment(card.createdAt).format('LLLL') : ' ',
|
||||
card.dateLastActivity ? moment(card.dateLastActivity).format() : ' ',
|
||||
);
|
||||
currentRow.push(
|
||||
card.modifiedAt ? moment(card.modifiedAt).format('LLLL') : ' ',
|
||||
);
|
||||
currentRow.push(
|
||||
card.dateLastActivity
|
||||
? moment(card.dateLastActivity).format('LLLL')
|
||||
: ' ',
|
||||
);
|
||||
if (card.vote.question) {
|
||||
if (card.vote.question !== undefined) {
|
||||
let positiveVoters = '';
|
||||
let negativeVoters = '';
|
||||
card.vote.positive.forEach(userId => {
|
||||
@@ -331,6 +347,39 @@ export class Exporter {
|
||||
currentRow.push(' ');
|
||||
}
|
||||
currentRow.push(card.archived ? 'true' : 'false');
|
||||
//Custom fields
|
||||
const customFieldValuesToPush = new Array(result.customFields.length);
|
||||
card.customFields.forEach(field => {
|
||||
if (customFieldMap[field._id].type === 'date') {
|
||||
customFieldValuesToPush[customFieldMap[field._id].position] = moment(
|
||||
field.value,
|
||||
).format();
|
||||
} else if (customFieldMap[field._id].type === 'dropdown') {
|
||||
const dropdownOptions = result.customFields.find(
|
||||
({ _id }) => _id === field._id,
|
||||
).settings.dropdownItems;
|
||||
const fieldValue = dropdownOptions.find(
|
||||
({ _id }) => _id === field.value,
|
||||
).name;
|
||||
customFieldValuesToPush[
|
||||
customFieldMap[field._id].position
|
||||
] = fieldValue;
|
||||
} else {
|
||||
customFieldValuesToPush[customFieldMap[field._id].position] =
|
||||
field.value;
|
||||
}
|
||||
});
|
||||
for (
|
||||
let valueIndex = 0;
|
||||
valueIndex < customFieldValuesToPush.length;
|
||||
valueIndex++
|
||||
) {
|
||||
if (!(valueIndex in customFieldValuesToPush)) {
|
||||
currentRow.push(' ');
|
||||
} else {
|
||||
currentRow.push(customFieldValuesToPush[valueIndex]);
|
||||
}
|
||||
}
|
||||
stringifier.write(currentRow);
|
||||
});
|
||||
stringifier.end();
|
||||
|
||||
+1
-1
@@ -259,7 +259,7 @@ if (Meteor.isServer) {
|
||||
throw new Meteor.Error('invalid-user');
|
||||
}
|
||||
const user = Meteor.user();
|
||||
if (!user.emails && !user.emails[0] && user.emails[0].address) {
|
||||
if (!user.emails || !user.emails[0] || user.emails[0].address) {
|
||||
throw new Meteor.Error('email-invalid');
|
||||
}
|
||||
this.unblock();
|
||||
|
||||
Generated
+41
-7
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v4.03.0",
|
||||
"version": "v4.06.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -2039,6 +2039,11 @@
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"immediate": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
|
||||
@@ -2460,6 +2465,17 @@
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"jszip": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.4.0.tgz",
|
||||
"integrity": "sha512-gZAOYuPl4EhPTXT0GjhI3o+ZAz3su6EhLrKUoAivcKqyqC7laS5JEv4XWZND9BgcDcF83vI85yGbDmDR6UhrIg==",
|
||||
"requires": {
|
||||
"lie": "~3.3.0",
|
||||
"pako": "~1.0.2",
|
||||
"readable-stream": "~2.3.6",
|
||||
"set-immediate-shim": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
@@ -2514,6 +2530,14 @@
|
||||
"type-check": "~0.3.2"
|
||||
}
|
||||
},
|
||||
"lie": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
|
||||
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
|
||||
"requires": {
|
||||
"immediate": "~3.0.5"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-7.3.0.tgz",
|
||||
@@ -3869,6 +3893,11 @@
|
||||
"path-to-regexp": "~1.2.1"
|
||||
}
|
||||
},
|
||||
"pako": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
||||
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
|
||||
},
|
||||
"papaparse": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.2.0.tgz",
|
||||
@@ -4031,9 +4060,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"prettier-eslint": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-9.0.1.tgz",
|
||||
"integrity": "sha512-KZT65QTosSAqBBqmrC+RpXbsMRe7Os2YSR9cAfFbDlyPAopzA/S5bioiZ3rpziNQNSJaOxmtXSx07EQ+o2Dlug==",
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-9.0.2.tgz",
|
||||
"integrity": "sha512-u6EQqxUhaGfra9gy9shcR7MT7r/2twwEfRGy1tfzyaJvLQwSg34M9IU5HuF7FsLW2QUgr5VIUc56EPWibw1pdw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/parser": "^1.10.2",
|
||||
@@ -4330,6 +4359,11 @@
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
|
||||
},
|
||||
"set-immediate-shim": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
|
||||
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
|
||||
},
|
||||
"set-value": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
|
||||
@@ -4937,9 +4971,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.8.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
|
||||
"integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
|
||||
"version": "3.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.3.tgz",
|
||||
"integrity": "sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==",
|
||||
"dev": true
|
||||
},
|
||||
"union-value": {
|
||||
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v4.03.0",
|
||||
"version": "v4.06.0",
|
||||
"description": "Open-Source kanban",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -51,7 +51,7 @@
|
||||
"lint-staged": "^7.3.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
"prettier": "^1.19.1",
|
||||
"prettier-eslint": "^9.0.1"
|
||||
"prettier-eslint": "^9.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.9.6",
|
||||
@@ -66,6 +66,7 @@
|
||||
"es6-promise": "^4.2.4",
|
||||
"flatted": "^2.0.1",
|
||||
"gridfs-stream": "^0.5.3",
|
||||
"jszip": "^3.4.0",
|
||||
"ldapjs": "^1.0.2",
|
||||
"meteor-node-stubs": "^0.4.1",
|
||||
"mongodb": "^3.5.7",
|
||||
|
||||
+10
-2
@@ -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.03">Wekan REST API v4.03</a>
|
||||
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v4.06">Wekan REST API v4.06</a>
|
||||
|
||||
</li>
|
||||
|
||||
@@ -2022,7 +2022,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.03</h1>
|
||||
<h1 id="wekan-rest-api">Wekan REST API v4.06</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>
|
||||
@@ -14048,6 +14048,14 @@ UserSecurity
|
||||
<td>clearblue</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>color</td>
|
||||
<td>natural</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>color</td>
|
||||
<td>modern</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>presentParentTask</td>
|
||||
<td>prefix-with-full-path</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
swagger: '2.0'
|
||||
info:
|
||||
title: Wekan REST API
|
||||
version: v4.03
|
||||
version: v4.06
|
||||
description: |
|
||||
The REST API allows you to control and extend Wekan with ease.
|
||||
|
||||
@@ -2079,6 +2079,8 @@ definitions:
|
||||
- relax
|
||||
- corteza
|
||||
- clearblue
|
||||
- natural
|
||||
- modern
|
||||
description:
|
||||
description: |
|
||||
The description of the board
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+64
-64
@@ -1,64 +1,64 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM NOTE: You can try this to install Meteor on Windows, it works:
|
||||
REM https://github.com/zodern/windows-meteor-installer/
|
||||
|
||||
REM Installing Meteor with Chocolatey does not currently work.
|
||||
|
||||
REM NOTE: THIS .BAT DOES NOT WORK !!
|
||||
REM Use instead this webpage instructions to build on Windows:
|
||||
REM https://github.com/wekan/wekan/wiki/Install-Wekan-from-source-on-Windows
|
||||
REM Please add fix PRs, like config of MongoDB etc.
|
||||
|
||||
md C:\repos
|
||||
cd C:\repos
|
||||
|
||||
REM Install chocolatey
|
||||
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
|
||||
|
||||
choco install -y git curl python2 dotnet4.5.2 nano mongodb-3 mongoclient meteor
|
||||
|
||||
curl -O https://nodejs.org/dist/v12.16.3/node-v12.16.2-x64.msi
|
||||
call node-v12.16.3-x64.msi
|
||||
|
||||
call npm config -g set msvs_version 2015
|
||||
call meteor npm config -g set msvs_version 2015
|
||||
|
||||
call npm -g install npm
|
||||
call npm -g install node-gyp
|
||||
call npm -g install fibers
|
||||
cd C:\repos
|
||||
git clone https://github.com/wekan/wekan.git
|
||||
cd wekan
|
||||
git checkout edge
|
||||
echo "Building Wekan."
|
||||
REM del /S /F /Q packages
|
||||
REM ## REPOS BELOW ARE INCLUDED TO WEKAN
|
||||
REM md packages
|
||||
REM cd packages
|
||||
REM git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router
|
||||
REM git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core
|
||||
REM git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-cas.git
|
||||
REM git clone --depth 1 -b master https://github.com/wekan/wekan-ldap.git
|
||||
REM git clone --depth 1 -b master https://github.com/wekan/wekan-scrollbar.git
|
||||
REM git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-oidc.git
|
||||
REM git clone --depth 1 -b master --recurse-submodules https://github.com/wekan/markdown.git
|
||||
REM move meteor-accounts-oidc/packages/switch_accounts-oidc wekan_accounts-oidc
|
||||
REM move meteor-accounts-oidc/packages/switch_oidc wekan_oidc
|
||||
REM del /S /F /Q meteor-accounts-oidc
|
||||
REM sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' ~/repos/wekan/packages/meteor-useraccounts-core/package.js
|
||||
cd ..
|
||||
REM del /S /F /Q node_modules
|
||||
call meteor npm install
|
||||
REM del /S /F /Q .build
|
||||
call meteor build .build --directory
|
||||
copy fix-download-unicode\cfs_access-point.txt .build\bundle\programs\server\packages\cfs_access-point.js
|
||||
REM ## Remove legacy webbroser bundle, so that Wekan works also at Android Firefox, iOS Safari, etc.
|
||||
del /S /F /Q rm .build/bundle/programs/web.browser.legacy
|
||||
REM ## Install some NPM packages
|
||||
cd .build\bundle\programs\server
|
||||
call meteor npm install
|
||||
REM cd C:\repos\wekan\.meteor\local\build\programs\server
|
||||
REM del node_modules
|
||||
cd C:\repos\wekan
|
||||
call start-wekan.bat
|
||||
@ECHO OFF
|
||||
|
||||
REM NOTE: You can try this to install Meteor on Windows, it works:
|
||||
REM https://github.com/zodern/windows-meteor-installer/
|
||||
|
||||
REM Installing Meteor with Chocolatey does not currently work.
|
||||
|
||||
REM NOTE: THIS .BAT DOES NOT WORK !!
|
||||
REM Use instead this webpage instructions to build on Windows:
|
||||
REM https://github.com/wekan/wekan/wiki/Install-Wekan-from-source-on-Windows
|
||||
REM Please add fix PRs, like config of MongoDB etc.
|
||||
|
||||
md C:\repos
|
||||
cd C:\repos
|
||||
|
||||
REM Install chocolatey
|
||||
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
|
||||
|
||||
choco install -y git curl python2 dotnet4.5.2 nano mongodb-3 mongoclient meteor
|
||||
|
||||
curl -O https://nodejs.org/dist/v12.16.3/node-v12.16.2-x64.msi
|
||||
call node-v12.16.3-x64.msi
|
||||
|
||||
call npm config -g set msvs_version 2015
|
||||
call meteor npm config -g set msvs_version 2015
|
||||
|
||||
call npm -g install npm
|
||||
call npm -g install node-gyp
|
||||
call npm -g install fibers
|
||||
cd C:\repos
|
||||
git clone https://github.com/wekan/wekan.git
|
||||
cd wekan
|
||||
git checkout edge
|
||||
echo "Building Wekan."
|
||||
REM del /S /F /Q packages
|
||||
REM ## REPOS BELOW ARE INCLUDED TO WEKAN
|
||||
REM md packages
|
||||
REM cd packages
|
||||
REM git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router
|
||||
REM git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core
|
||||
REM git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-cas.git
|
||||
REM git clone --depth 1 -b master https://github.com/wekan/wekan-ldap.git
|
||||
REM git clone --depth 1 -b master https://github.com/wekan/wekan-scrollbar.git
|
||||
REM git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-oidc.git
|
||||
REM git clone --depth 1 -b master --recurse-submodules https://github.com/wekan/markdown.git
|
||||
REM move meteor-accounts-oidc/packages/switch_accounts-oidc wekan_accounts-oidc
|
||||
REM move meteor-accounts-oidc/packages/switch_oidc wekan_oidc
|
||||
REM del /S /F /Q meteor-accounts-oidc
|
||||
REM sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' ~/repos/wekan/packages/meteor-useraccounts-core/package.js
|
||||
cd ..
|
||||
REM del /S /F /Q node_modules
|
||||
call meteor npm install
|
||||
REM del /S /F /Q .build
|
||||
call meteor build .build --directory
|
||||
copy fix-download-unicode\cfs_access-point.txt .build\bundle\programs\server\packages\cfs_access-point.js
|
||||
REM ## Remove legacy webbroser bundle, so that Wekan works also at Android Firefox, iOS Safari, etc.
|
||||
del /S /F /Q rm .build/bundle/programs/web.browser.legacy
|
||||
REM ## Install some NPM packages
|
||||
cd .build\bundle\programs\server
|
||||
call meteor npm install
|
||||
REM cd C:\repos\wekan\.meteor\local\build\programs\server
|
||||
REM del node_modules
|
||||
cd C:\repos\wekan
|
||||
call start-wekan.bat
|
||||
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
|
||||
appTitle = (defaultText = "Wekan"),
|
||||
# The name of the app as it is displayed to the user.
|
||||
|
||||
appVersion = 403,
|
||||
appVersion = 406,
|
||||
# Increment this for every release.
|
||||
|
||||
appMarketingVersion = (defaultText = "4.03.0~2020-05-16"),
|
||||
appMarketingVersion = (defaultText = "4.06.0~2020-05-25"),
|
||||
# Human-readable presentation of the app version.
|
||||
|
||||
minUpgradableAppVersion = 0,
|
||||
|
||||
@@ -119,7 +119,9 @@ Migrations.add('use-css-class-for-boards-colors', () => {
|
||||
'#2C3E51': 'dark',
|
||||
'#27AE61': 'relax',
|
||||
'#568BA2': 'corteza',
|
||||
'#499BEA': 'clearblue'
|
||||
'#499BEA': 'clearblue',
|
||||
'#596557': 'natural',
|
||||
'#2A80B8': 'modern',
|
||||
};
|
||||
Boards.find().forEach(board => {
|
||||
const oldBoardColor = board.background.color;
|
||||
|
||||
@@ -96,6 +96,8 @@ DESCRIPTION_ATTACHMENTS_STORE_PATH="Allow wekan ower to specify where uploaded f
|
||||
DEFAULT_ATTACHMENTS_STORE_PATH=""
|
||||
KEY_ATTACHMENTS_STORE_PATH="attachments-store-path"
|
||||
|
||||
# Example, not in use: /var/snap/wekan/common/uploads/
|
||||
|
||||
DESCRIPTION_MAX_IMAGE_PIXEL="Max image pixel: Allow to shrink attached/pasted image https://github.com/wekan/wekan/pull/2544"
|
||||
DEFAULT_MAX_IMAGE_PIXEL=""
|
||||
KEY_MAX_IMAGE_PIXEL="max-image-pixel"
|
||||
|
||||
@@ -24,6 +24,12 @@ if test -f "$SNAP_COMMON/mongodb.log"; then
|
||||
rm -f "$SNAP_COMMON/mongodb.log"
|
||||
fi
|
||||
|
||||
# Not in use. If uploads directory does not exist, create it.
|
||||
# Wekan will store attachments there.
|
||||
#if [ ! -d "$SNAP_COMMON/uploads" ]; then
|
||||
# mkdir "$SNAP_COMMON/uploads"
|
||||
#fi
|
||||
|
||||
# Alternative: When starting MongoDB, and using logfile, truncate log to last 1000 lines of text.
|
||||
# 1) If file exists:
|
||||
#if test -f "$SNAP_COMMON/mongodb.log"; then
|
||||
|
||||
@@ -234,6 +234,8 @@ parts:
|
||||
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-gyp/node_modules/tar/lib/.mkdir.js.swp
|
||||
# Meteor 1.8.x additional .swp remove
|
||||
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
|
||||
# ostrio tmp remove
|
||||
rm -rf $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/meteor/ostrio_files/node_modules/request-libcurl/.node_modules-garbage*
|
||||
|
||||
organize:
|
||||
README: README.wekan
|
||||
|
||||
Reference in new issue
Block a user