This commit is contained in:
John R. Supplee 2020-12-31 19:15:59 +02:00
commit 223fb78bd8
75 changed files with 34838 additions and 33655 deletions

View file

@ -1,3 +1,64 @@
# Upcoming Wekan release
This release fixes the following bugs:
- [New Checklistitems are now autoresized too](https://github.com/wekan/wekan/pull/3411).
Thanks to mfilser.
- [Swimlane + and = Icons resized for better handling at mobile view](https://github.com/wekan/wekan/pull/3412).
Thanks to mfilser.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.68 2020-12-29 Wekan release
This release fixes the following bugs:
- [Checklist-Items, Drag-Drop Handle now at the left side](https://github.com/wekan/wekan/pull/3407).
Thanks to mfilser.
- [Checklist-Items, Autoresize the textarea vertically to fit the user-input](https://github.com/wekan/wekan/pull/3408).
Thanks to mfilser.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.67 2020-12-29 Wekan release
This release adds the following new features:
- Teams/Organizations to Admin Panel. In Progress.
[Part 1](https://github.com/wekan/wekan/commit/9e2093d6aed38e66fc4d63823315c9382e013a32).
Thanks to xet7.
and fixes the following bugs:
- [Checklist Mini-Screen, appendTo: 'parent' not necessary anymore](https://github.com/wekan/wekan/pull/3405).
Thanks to mfilser.
- [Allow to edit email verified and initials at Admin Panel/People/People](https://github.com/wekan/wekan/commit/d03e2170dd10741bd78722cc35b52cffa220a2e7).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.66 2020-12-27 Wekan release
This release fixes the following bugs:
- [Fix Mobile miniscreen: Drag handle not visible in long checklist item
text](https://github.com/wekan/wekan/commit/a8453657c95a4bde2ae86b4c77e55bb2174adf26).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.65 2020-12-26 Wekan release
This release fixes the following bugs:
- [Fixed Drag and drop between checklists closes the card sometimes on
Firefox](https://github.com/wekan/wekan/commit/c7808c5c03f98eae709e5ef89e8e17af4689cb2e).
xet7 thanks mfilser about [similar fix of appendTo parent](https://github.com/wekan/wekan/pull/3342)
that did work here too to fix this.
Thanks to mfilser and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.64 2020-12-24 Wekan release # v4.64 2020-12-24 Wekan release
This release fixes the following bugs: This release fixes the following bugs:

View file

@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928 appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v4.64.0" appVersion: "v4.68.0"
files: files:
userUploads: userUploads:
- README.md - README.md

View file

@ -102,9 +102,9 @@ template(name='checklistItemDetail')
if canModifyCard if canModifyCard
.check-box-container .check-box-container
.check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}") .check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
if isMiniScreenOrShowDesktopDragHandles
span.fa.checklistitem-handle(class="fa-arrows" title="{{_ 'dragChecklistItem'}}")
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}") .item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
if isMiniScreenOrShowDesktopDragHandles
span.fa.checklistitem-handle(class="fa-arrows" title="{{_ 'dragChecklistItem'}}")
+viewer +viewer
= item.title = item.title
else else

View file

@ -6,7 +6,7 @@ function initSorting(items) {
helper: 'clone', helper: 'clone',
items: '.js-checklist-item:not(.placeholder)', items: '.js-checklist-item:not(.placeholder)',
connectWith: '.js-checklist-items', connectWith: '.js-checklist-items',
appendTo: '.board-canvas', appendTo: 'parent',
distance: 7, distance: 7,
placeholder: 'checklist-item placeholder', placeholder: 'checklist-item placeholder',
scroll: false, scroll: false,
@ -59,7 +59,6 @@ BlazeComponent.extendComponent({
if (Utils.isMiniScreenOrShowDesktopDragHandles()) { if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
$(self.itemsDom).sortable({ $(self.itemsDom).sortable({
handle: 'span.fa.checklistitem-handle', handle: 'span.fa.checklistitem-handle',
appendTo: 'parent',
}); });
} }
} }
@ -224,6 +223,14 @@ Template.checklists.helpers({
}, },
}); });
Template.addChecklistItemForm.onRendered(() => {
autosize($('textarea.js-add-checklist-item'))
});
Template.editChecklistItemForm.onRendered(() => {
autosize($('textarea.js-edit-checklist-item'))
});
Template.checklistDeleteDialog.onCreated(() => { Template.checklistDeleteDialog.onCreated(() => {
const $cardDetails = this.$('.card-details'); const $cardDetails = this.$('.card-details');
this.scrollState = { this.scrollState = {

View file

@ -134,7 +134,7 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
background-color: darken(white, 8%) background-color: darken(white, 8%)
.check-box-container .check-box-container
padding-right: 1px; padding-right: 10px;
.check-box .check-box
margin: 0.1em 0 0 0; margin: 0.1em 0 0 0;
@ -144,7 +144,6 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
.item-title .item-title
flex: 1 flex: 1
margin-left: 10px;
&.is-checked &.is-checked
color: #8c8c8c color: #8c8c8c
font-style: italic font-style: italic
@ -157,7 +156,8 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
max-width: 420px max-width: 420px
span.fa.checklistitem-handle span.fa.checklistitem-handle
float: right padding-top: 2px
padding-right: 10px;
.js-delete-checklist-item .js-delete-checklist-item
margin: 0 0 0.5em 1.33em margin: 0 0 0.5em 1.33em

View file

@ -5,34 +5,102 @@ template(name="people")
else else
.content-title.ext-box .content-title.ext-box
.ext-box-left .ext-box-left
span if loading.get
i.fa.fa-users +spinner
| {{_ 'people'}} else if orgSetting.get
input#searchInput(placeholder="{{_ 'search'}}") span
button#searchButton i.fa.fa-sitemap
i.fa.fa-search | {{_ 'organizations'}}
| {{_ 'search'}} input#searchOrgInput(placeholder="{{_ 'search'}}")
.ext-box-right button#searchOrgButton
span {{_ 'people-number'}} #{peopleNumber} i.fa.fa-search
| {{_ 'search'}}
.ext-box-right
span {{_ 'org-number'}} #{orgNumber}
else if teamSetting.get
span
i.fa.fa-users
| {{_ 'teams'}}
input#searchTeamInput(placeholder="{{_ 'search'}}")
button#searchTeamButton
i.fa.fa-search
| {{_ 'search'}}
.ext-box-right
span {{_ 'team-number'}} #{teamNumber}
else if peopleSetting.get
span
i.fa.fa-user
| {{_ 'people'}}
input#searchInput(placeholder="{{_ 'search'}}")
button#searchButton
i.fa.fa-search
| {{_ 'search'}}
.ext-box-right
span {{_ 'people-number'}} #{peopleNumber}
.content-body .content-body
.side-menu .side-menu
ul ul
li.active li.active
a.js-setting-menu(data-id="people-setting") a.js-org-menu(data-id="org-setting")
i.fa.fa-sitemap
| {{_ 'organizations'}}
li
a.js-team-menu(data-id="team-setting")
i.fa.fa-users i.fa.fa-users
| {{_ 'teams'}}
li
a.js-people-menu(data-id="people-setting")
i.fa.fa-user
| {{_ 'people'}} | {{_ 'people'}}
.main-body .main-body
if loading.get if loading.get
+spinner +spinner
else if people.get else if orgSetting.get
+orgGeneral
else if teamSetting.get
+teamGeneral
else if peopleSetting.get
+peopleGeneral +peopleGeneral
template(name="orgGeneral")
table
tbody
tr
th {{_ 'displayName'}}
th {{_ 'description'}}
th {{_ 'shortName'}}
th {{_ 'website'}}
th {{_ 'teams'}}
th {{_ 'createdAt'}}
th {{_ 'active'}}
th
+newOrgRow
each org in orgList
+orgRow(orgId=org._id)
template(name="teamGeneral")
table
tbody
tr
th {{_ 'displayName'}}
th {{_ 'description'}}
th {{_ 'shortName'}}
th {{_ 'website'}}
th {{_ 'createdAt'}}
th {{_ 'active'}}
th
+newTeamRow
each team in teamList
+teamRow(teamId=team._id)
template(name="peopleGeneral") template(name="peopleGeneral")
table table
tbody tbody
tr tr
th {{_ 'username'}} th {{_ 'username'}}
th {{_ 'fullname'}} th {{_ 'fullname'}}
th {{_ 'initials'}}
th {{_ 'admin'}} th {{_ 'admin'}}
th {{_ 'email'}} th {{_ 'email'}}
th {{_ 'verified'}} th {{_ 'verified'}}
@ -44,11 +112,93 @@ template(name="peopleGeneral")
each user in peopleList each user in peopleList
+peopleRow(userId=user._id) +peopleRow(userId=user._id)
template(name="newOrgRow")
a.new-org
i.fa.fa-edit
| {{_ 'new'}}
template(name="newTeamRow")
a.new-team
i.fa.fa-edit
| {{_ 'new'}}
template(name="newUserRow") template(name="newUserRow")
a.new-user a.new-user
i.fa.fa-edit i.fa.fa-edit
| {{_ 'new'}} | {{_ 'new'}}
template(name="orgRow")
tr
if orgData.loginDisabled
td <s>{{ orgData.displayName }}</s>
else
td {{ orgData.displayName }}
if orgData.loginDisabled
td <s>{{ orgData.orgDesc }}</s>
else
td {{ orgData.desc }}
if orgData.loginDisabled
td <s>{{ orgData.name }}</s>
else
td {{ orgData.name }}
if orgData.loginDisabled
td <s>{{ orgData.website }}</s>
else
td {{ orgData.website }}
if orgData.loginDisabled
td <s>{{ orgData.teams }}</s>
else
td {{ orgData.teams }}
if orgData.loginDisabled
td <s>{{ moment orgData.createdAt 'LLL' }}</s>
else
td {{ moment orgData.createdAt 'LLL' }}
td
if orgData.loginDisabled
| {{_ 'no'}}
else
| {{_ 'yes'}}
td
a.edit-org
i.fa.fa-edit
| {{_ 'edit'}}
a.more-settings-org
i.fa.fa-ellipsis-h
template(name="teamRow")
tr
if teamData.loginDisabled
td <s>{{ teamData.displayName }}</s>
else
td {{ teamData.displayName }}
if teamData.loginDisabled
td <s>{{ teamData.desc }}</s>
else
td {{ teamData.desc }}
if teamData.loginDisabled
td <s>{{ teamData.dame }}</s>
else
td {{ teamData.name }}
if teamData.loginDisabled
td <s>{{ teamData.website }}</s>
else
td {{ teamData.website }}
if orgData.loginDisabled
td <s>{{ moment teamData.createdAt 'LLL' }}</s>
else
td {{ moment teamData.createdAt 'LLL' }}
td
if teamData.loginDisabled
| {{_ 'no'}}
else
| {{_ 'yes'}}
td
a.edit-team
i.fa.fa-edit
| {{_ 'edit'}}
a.more-settings-team
i.fa.fa-ellipsis-h
template(name="peopleRow") template(name="peopleRow")
tr tr
if userData.loginDisabled if userData.loginDisabled
@ -59,6 +209,10 @@ template(name="peopleRow")
td <s>{{ userData.profile.fullname }}</s> td <s>{{ userData.profile.fullname }}</s>
else else
td {{ userData.profile.fullname }} td {{ userData.profile.fullname }}
if userData.loginDisabled
td <s>{{ userData.profile.initials }}</s>
else
td {{ userData.profile.initials }}
if userData.loginDisabled if userData.loginDisabled
td td
if userData.isAdmin if userData.isAdmin
@ -107,12 +261,61 @@ template(name="peopleRow")
a.more-settings-user a.more-settings-user
i.fa.fa-ellipsis-h i.fa.fa-ellipsis-h
template(name="editOrgPopup")
form
label.hide.orgId(type="text" value=org._id)
label
| {{_ 'orgDisplayName'}}
input.js-orgDisplayName(type="text" value=org.displayName required)
span.error.hide.orgname-taken
| {{_ 'error-orgname-taken'}}
label
| {{_ 'orgDesc'}}
input.js-orgDesc(type="text" value=org.desc required)
label
| {{_ 'orgName'}}
input.js-orgName(type="text" value=org.name required)
label
| {{_ 'orgWebsite'}}
input.js-orgWebsite(type="text" value=org.website required)
label
| {{_ 'active'}}
select.select-active.js-org-isactive
option(value="false") {{_ 'yes'}}
option(value="true" selected="{{org.loginDisabled}}") {{_ 'no'}}
hr
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="editTeamPopup")
form
label.hide.teamId(type="text" value=team._id)
label
| {{_ 'displayName'}}
input.js-teamDisplayName(type="text" value=team.displayName required)
span.error.hide.teamname-taken
| {{_ 'error-teamname-taken'}}
label
| {{_ 'desc'}}
input.js-orgDesc(type="text" value=org.desc required)
label
| {{_ 'name'}}
input.js-orgName(type="text" value=org.name required)
label
| {{_ 'website'}}
input.js-orgWebsite(type="text" value=org.website required)
label
| {{_ 'active'}}
select.select-active.js-team-isactive
option(value="false") {{_ 'yes'}}
option(value="true" selected="{{team.loginDisabled}}") {{_ 'no'}}
hr
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="editUserPopup") template(name="editUserPopup")
form form
label.hide.userId(type="text" value=user._id) label.hide.userId(type="text" value=user._id)
label
| {{_ 'fullname'}}
input.js-profile-fullname(type="text" value=user.profile.fullname required)
label label
| {{_ 'username'}} | {{_ 'username'}}
span.error.hide.username-taken span.error.hide.username-taken
@ -121,6 +324,17 @@ template(name="editUserPopup")
input.js-profile-username(type="text" value=user.username readonly) input.js-profile-username(type="text" value=user.username readonly)
else else
input.js-profile-username(type="text" value=user.username required) input.js-profile-username(type="text" value=user.username required)
label
| {{_ 'fullname'}}
input.js-profile-fullname(type="text" value=user.profile.fullname required)
label
| {{_ 'initials'}}
input.js-profile-initials(type="text" value=user.profile.initials)
label
| {{_ 'admin'}}
select.select-role.js-profile-isadmin
option(value="false") {{_ 'no'}}
option(value="true" selected="{{user.isAdmin}}") {{_ 'yes'}}
label label
| {{_ 'email'}} | {{_ 'email'}}
span.error.hide.email-taken span.error.hide.email-taken
@ -130,10 +344,10 @@ template(name="editUserPopup")
else else
input.js-profile-email(type="email" value="{{user.emails.[0].address}}" required) input.js-profile-email(type="email" value="{{user.emails.[0].address}}" required)
label label
| {{_ 'admin'}} | {{_ 'verified'}}
select.select-role.js-profile-isadmin select.select-verified.js-profile-email-verified
option(value="false") {{_ 'no'}} option(value="false") {{_ 'no'}}
option(value="true" selected="{{user.isAdmin}}") {{_ 'yes'}} option(value="true" selected="{{userData.emails.[0].verified}}") {{_ 'yes'}}
label label
| {{_ 'active'}} | {{_ 'active'}}
select.select-active.js-profile-isactive select.select-active.js-profile-isactive
@ -154,6 +368,54 @@ template(name="editUserPopup")
div.buttonsContainer div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}") input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="newOrgPopup")
form
//label.hide.userId(type="text" value=user._id)
label
| {{_ 'orgDisplayName'}}
input.js-orgDisplayName(type="text" value="" required)
label
| {{_ 'orgDesc'}}
input.js-orgDesc(type="text" value="" required)
label
| {{_ 'orgName'}}
input.js-orgName(type="text" value="")
label
| {{_ 'orgWebsite'}}
input.js-orgWebsite(type="text" value="")
label
| {{_ 'active'}}
select.select-active.js-profile-isactive
option(value="false" selected="selected") {{_ 'yes'}}
option(value="true") {{_ 'no'}}
hr
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="newTeamPopup")
form
//label.hide.teamId(type="text" value=team._id)
label
| {{_ 'displayName'}}
input.js-teamDisplayName(type="text" value="" required)
label
| {{_ 'desc'}}
input.js-teamDesc(type="text" value="" required)
label
| {{_ 'shortName'}}
input.js-teamName(type="text" value="")
label
| {{_ 'website'}}
input.js-teamWebsite(type="text" value="")
label
| {{_ 'active'}}
select.select-active.js-profile-isactive
option(value="false" selected="selected") {{_ 'yes'}}
option(value="true") {{_ 'no'}}
hr
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="newUserPopup") template(name="newUserPopup")
form form
//label.hide.userId(type="text" value=user._id) //label.hide.userId(type="text" value=user._id)
@ -201,6 +463,31 @@ template(name="newUserPopup")
div.buttonsContainer div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}") input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="settingsOrgPopup")
ul.pop-over-list
li
a.impersonate-org
i.fa.fa-user
| {{_ 'impersonate-org'}}
// Delete is not enabled yet, because it does leave empty user avatars
// to boards: boards members, card members and assignees have
// empty users. See:
// - wekan/client/components/settings/peopleBody.jade deleteButton
// - wekan/client/components/settings/peopleBody.js deleteButton
// - wekan/client/components/sidebar/sidebar.js Popup.afterConfirm('removeMember'
// that does now remove member from board, card members and assignees correctly,
// but that should be used to remove user from all boards similarly
// - wekan/models/users.js Delete is not enabled
//li
// br
// br
// hr
//li
// form
// label.hide.userId(type="text" value=user._id)
// div.buttonsContainer
// input#deleteButton.card-details-red.right.wide(type="button" value="{{_ 'delete'}}")
template(name="settingsUserPopup") template(name="settingsUserPopup")
ul.pop-over-list ul.pop-over-list
li li

View file

@ -1,3 +1,5 @@
const orgsPerPage = 25;
const teamsPerPage = 25;
const usersPerPage = 25; const usersPerPage = 25;
BlazeComponent.extendComponent({ BlazeComponent.extendComponent({
@ -7,17 +9,45 @@ BlazeComponent.extendComponent({
onCreated() { onCreated() {
this.error = new ReactiveVar(''); this.error = new ReactiveVar('');
this.loading = new ReactiveVar(false); this.loading = new ReactiveVar(false);
this.people = new ReactiveVar(true); this.orgSetting = new ReactiveVar(true);
this.teamSetting = new ReactiveVar(true);
this.peopleSetting = new ReactiveVar(true);
this.findOrgsOptions = new ReactiveVar({});
this.findTeamsOptions = new ReactiveVar({});
this.findUsersOptions = new ReactiveVar({}); this.findUsersOptions = new ReactiveVar({});
this.number = new ReactiveVar(0); this.numberOrgs = new ReactiveVar(0);
this.numberTeams = new ReactiveVar(0);
this.numberPeople = new ReactiveVar(0);
this.page = new ReactiveVar(1); this.page = new ReactiveVar(1);
this.loadNextPageLocked = false; this.loadNextPageLocked = false;
this.callFirstWith(null, 'resetNextPeak'); this.callFirstWith(null, 'resetNextPeak');
this.autorun(() => { this.autorun(() => {
const limit = this.page.get() * usersPerPage; const limitOrgs = this.page.get() * orgsPerPage;
const limitTeams = this.page.get() * teamsPerPage;
const limitUsers = this.page.get() * usersPerPage;
this.subscribe('people', this.findUsersOptions.get(), limit, () => { this.subscribe('org', this.findOrgsOptions.get(), limitOrgs, () => {
this.loadNextPageLocked = false;
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
this.calculateNextPeak();
const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
if (nextPeakBefore === nextPeakAfter) {
this.callFirstWith(null, 'resetNextPeak');
}
});
this.subscribe('team', this.findTeamsOptions.get(), limitTeams, () => {
this.loadNextPageLocked = false;
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
this.calculateNextPeak();
const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
if (nextPeakBefore === nextPeakAfter) {
this.callFirstWith(null, 'resetNextPeak');
}
});
this.subscribe('people', this.findUsersOptions.get(), limitUsers, () => {
this.loadNextPageLocked = false; this.loadNextPageLocked = false;
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak'); const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
this.calculateNextPeak(); this.calculateNextPeak();
@ -31,6 +61,22 @@ BlazeComponent.extendComponent({
events() { events() {
return [ return [
{ {
'click #searchOrgButton'() {
this.filterOrg();
},
'keydown #searchOrgInput'(event) {
if (event.keyCode === 13 && !event.shiftKey) {
this.filterOrg();
}
},
'click #searchTeamButton'() {
this.filterTeam();
},
'keydown #searchTeamInput'(event) {
if (event.keyCode === 13 && !event.shiftKey) {
this.filterTeam();
}
},
'click #searchButton'() { 'click #searchButton'() {
this.filterPeople(); this.filterPeople();
}, },
@ -39,9 +85,18 @@ BlazeComponent.extendComponent({
this.filterPeople(); this.filterPeople();
} }
}, },
'click #newOrgButton'() {
Popup.open('newOrg');
},
'click #newTeamButton'() {
Popup.open('newTeam');
},
'click #newUserButton'() { 'click #newUserButton'() {
Popup.open('newUser'); Popup.open('newUser');
}, },
'click a.js-org-menu': this.switchMenu,
'click a.js-team-menu': this.switchMenu,
'click a.js-people-menu': this.switchMenu,
}, },
]; ];
}, },
@ -84,18 +139,63 @@ BlazeComponent.extendComponent({
setLoading(w) { setLoading(w) {
this.loading.set(w); this.loading.set(w);
}, },
orgList() {
const orgs = Org.find(this.findOrgsOptions.get(), {
fields: { _id: true },
});
this.numberOrgs.set(org.count(false));
return orgs;
},
teamList() {
const teams = Team.find(this.findTeamsOptions.get(), {
fields: { _id: true },
});
this.numberTeams.set(team.count(false));
return teams;
},
peopleList() { peopleList() {
const users = Users.find(this.findUsersOptions.get(), { const users = Users.find(this.findUsersOptions.get(), {
fields: { _id: true }, fields: { _id: true },
}); });
this.number.set(users.count(false)); this.numberPeople.set(users.count(false));
return users; return users;
}, },
orgNumber() {
return this.numberOrgs.get();
},
teamNumber() {
return this.numberTeams.get();
},
peopleNumber() { peopleNumber() {
return this.number.get(); return this.numberPeople.get();
},
switchMenu(event) {
const target = $(event.target);
if (!target.hasClass('active')) {
$('.side-menu li.active').removeClass('active');
target.parent().addClass('active');
const targetID = target.data('id');
this.orgSetting.set('org-setting' === targetID);
this.teamSetting.set('team-setting' === targetID);
this.peopleSetting.set('people-setting' === targetID);
}
}, },
}).register('people'); }).register('people');
Template.orgRow.helpers({
orgData() {
const orgCollection = this.esSearch ? ESSearchResults : Org;
return orgCollection.findOne(this.orgId);
},
});
Template.teamRow.helpers({
teamData() {
const teamCollection = this.esSearch ? ESSearchResults : Team;
return teamCollection.findOne(this.teamId);
},
});
Template.peopleRow.helpers({ Template.peopleRow.helpers({
userData() { userData() {
const userCollection = this.esSearch ? ESSearchResults : Users; const userCollection = this.esSearch ? ESSearchResults : Users;
@ -122,6 +222,51 @@ Template.editUserPopup.onCreated(function() {
}); });
}); });
Template.editOrgPopup.helpers({
org() {
return Org.findOne(this.orgId);
},
/*
isSelected(match) {
const orgId = Template.instance().data.orgId;
const selected = Org.findOne(orgId).authenticationMethod;
return selected === match;
},
isLdap() {
const userId = Template.instance().data.userId;
const selected = Users.findOne(userId).authenticationMethod;
return selected === 'ldap';
},
*/
errorMessage() {
return Template.instance().errorMessage.get();
},
});
Template.editTeamPopup.helpers({
team() {
return Team.findOne(this.teamId);
},
/*
authentications() {
return Template.instance().authenticationMethods.get();
},
isSelected(match) {
const userId = Template.instance().data.userId;
const selected = Users.findOne(userId).authenticationMethod;
return selected === match;
},
isLdap() {
const userId = Template.instance().data.userId;
const selected = Users.findOne(userId).authenticationMethod;
return selected === 'ldap';
},
*/
errorMessage() {
return Template.instance().errorMessage.get();
},
});
Template.editUserPopup.helpers({ Template.editUserPopup.helpers({
user() { user() {
return Users.findOne(this.userId); return Users.findOne(this.userId);
@ -144,6 +289,46 @@ Template.editUserPopup.helpers({
}, },
}); });
Template.newOrgPopup.onCreated(function() {
//this.authenticationMethods = new ReactiveVar([]);
this.errorMessage = new ReactiveVar('');
/*
Meteor.call('getAuthenticationsEnabled', (_, result) => {
if (result) {
// TODO : add a management of different languages
// (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
this.authenticationMethods.set([
{ value: 'password' },
// Gets only the authentication methods availables
...Object.entries(result)
.filter(e => e[1])
.map(e => ({ value: e[0] })),
]);
}
});
*/
});
Template.newTeamPopup.onCreated(function() {
//this.authenticationMethods = new ReactiveVar([]);
this.errorMessage = new ReactiveVar('');
/*
Meteor.call('getAuthenticationsEnabled', (_, result) => {
if (result) {
// TODO : add a management of different languages
// (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
this.authenticationMethods.set([
{ value: 'password' },
// Gets only the authentication methods availables
...Object.entries(result)
.filter(e => e[1])
.map(e => ({ value: e[0] })),
]);
}
});
*/
});
Template.newUserPopup.onCreated(function() { Template.newUserPopup.onCreated(function() {
this.authenticationMethods = new ReactiveVar([]); this.authenticationMethods = new ReactiveVar([]);
this.errorMessage = new ReactiveVar(''); this.errorMessage = new ReactiveVar('');
@ -214,18 +399,24 @@ Template.editUserPopup.events({
submit(event, templateInstance) { submit(event, templateInstance) {
event.preventDefault(); event.preventDefault();
const user = Users.findOne(this.userId); const user = Users.findOne(this.userId);
const fullname = templateInstance.find('.js-profile-fullname').value.trim();
const username = templateInstance.find('.js-profile-username').value.trim(); const username = templateInstance.find('.js-profile-username').value.trim();
const fullname = templateInstance.find('.js-profile-fullname').value.trim();
const initials = templateInstance.find('.js-profile-initials').value.trim();
const password = templateInstance.find('.js-profile-password').value; const password = templateInstance.find('.js-profile-password').value;
const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim(); const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
const isActive = templateInstance.find('.js-profile-isactive').value.trim(); const isActive = templateInstance.find('.js-profile-isactive').value.trim();
const email = templateInstance.find('.js-profile-email').value.trim(); const email = templateInstance.find('.js-profile-email').value.trim();
const verified = templateInstance
.find('.js-profile-email-verified')
.value.trim();
const authentication = templateInstance const authentication = templateInstance
.find('.js-authenticationMethod') .find('.js-authenticationMethod')
.value.trim(); .value.trim();
const isChangePassword = password.length > 0; const isChangePassword = password.length > 0;
const isChangeUserName = username !== user.username; const isChangeUserName = username !== user.username;
const isChangeInitials = initials.length > 0;
const isChangeEmailVerified = verified !== user.emails[0].verified;
// If previously email address has not been set, it is undefined, // If previously email address has not been set, it is undefined,
// check for undefined, and allow adding email address. // check for undefined, and allow adding email address.
@ -248,6 +439,14 @@ Template.editUserPopup.events({
Meteor.call('setPassword', password, this.userId); Meteor.call('setPassword', password, this.userId);
} }
if (isChangeEmailVerified) {
Meteor.call('setEmailVerified', email, verified === 'true', this.userId);
}
if (isChangeInitials) {
Meteor.call('setInitials', initials, this.userId);
}
if (isChangeUserName && isChangeEmail) { if (isChangeUserName && isChangeEmail) {
Meteor.call( Meteor.call(
'setUsernameAndEmail', 'setUsernameAndEmail',

View file

@ -21,7 +21,7 @@ table
.ext-box-left .ext-box-left
display: flex; display: flex;
width: 40% width: 100%
span span
vertical-align: center; vertical-align: center;
@ -47,5 +47,5 @@ table
div div
margin: auto margin: auto
.more-settings-user .more-settings-user,.more-settings-team,.more-settings-org
margin-left: 10px; margin-left: 10px;

View file

@ -17,12 +17,11 @@ template(name="swimlaneFixedHeader")
unless currentUser.isCommentOnly unless currentUser.isCommentOnly
if currentUser.isBoardAdmin if currentUser.isBoardAdmin
a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon
a.fa.fa-navicon.js-open-swimlane-menu a.fa.fa-navicon.js-open-swimlane-menu.swimlane-header-menu-icon
unless isMiniScreen if isMiniScreenOrShowDesktopDragHandles
if showDesktopDragHandles
a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle
if isMiniScreen
a.swimlane-header-miniscreen-handle.handle.fa.fa-arrows.js-swimlane-header-handle a.swimlane-header-miniscreen-handle.handle.fa.fa-arrows.js-swimlane-header-handle
else
a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle
template(name="editSwimlaneTitleForm") template(name="editSwimlaneTitleForm")
.list-composer .list-composer

View file

@ -88,7 +88,12 @@
.swimlane-header-plus-icon .swimlane-header-plus-icon
margin-left: 5px margin-left: 5px
margin-right: 10px padding-right: 20px
font-size: 22px
.swimlane-header-menu-icon
padding-right: 20px
font-size: 22px
.swimlane-header-handle .swimlane-header-handle
position: absolute position: absolute

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Zobraz způsob ověřování", "display-authentication-method": "Zobraz způsob ověřování",
"default-authentication-method": "Zobraz způsob ověřování", "default-authentication-method": "Zobraz způsob ověřování",
"duplicate-board": "Duplikovat tablo", "duplicate-board": "Duplikovat tablo",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"people-number": "The number of people is:", "people-number": "The number of people is:",
"swimlaneDeletePopup-title": "Smazat Swimlane ?", "swimlaneDeletePopup-title": "Smazat Swimlane ?",
"swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.", "swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
@ -836,5 +838,11 @@
"hide-checked-items": "Skrýt zvolené položky", "hide-checked-items": "Skrýt zvolené položky",
"task": "Úkol", "task": "Úkol",
"create-task": "Vytvořit úkol", "create-task": "Vytvořit úkol",
"ok": "OK" "ok": "OK",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Display Authentication Method", "display-authentication-method": "Display Authentication Method",
"default-authentication-method": "Default Authentication Method", "default-authentication-method": "Default Authentication Method",
"duplicate-board": "Duplicate Board", "duplicate-board": "Duplicate Board",
"org-number": "The number of organizations is: ",
"team-number": "The number of teams is: ",
"people-number": "The number of people is: ", "people-number": "The number of people is: ",
"swimlaneDeletePopup-title": "Delete Swimlane ?", "swimlaneDeletePopup-title": "Delete Swimlane ?",
"swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.", "swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
@ -836,5 +838,11 @@
"hide-checked-items": "Hide checked items", "hide-checked-items": "Hide checked items",
"task": "Task", "task": "Task",
"create-task": "Create Task", "create-task": "Create Task",
"ok": "OK" "ok": "OK",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Mostrar el método de autenticación", "display-authentication-method": "Mostrar el método de autenticación",
"default-authentication-method": "Método de autenticación por defecto", "default-authentication-method": "Método de autenticación por defecto",
"duplicate-board": "Duplicar tablero", "duplicate-board": "Duplicar tablero",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"people-number": "El número de personas es:", "people-number": "El número de personas es:",
"swimlaneDeletePopup-title": "¿Eliminar el carril «swimlane»?", "swimlaneDeletePopup-title": "¿Eliminar el carril «swimlane»?",
"swimlane-delete-pop": "Todas las acciones serán eliminadas de la fuente de actividades y no se podrá recuperar el carril «swimlane». Esta acción no puede deshacerse.", "swimlane-delete-pop": "Todas las acciones serán eliminadas de la fuente de actividades y no se podrá recuperar el carril «swimlane». Esta acción no puede deshacerse.",
@ -836,5 +838,11 @@
"hide-checked-items": "Ocultar elementos marcados", "hide-checked-items": "Ocultar elementos marcados",
"task": "Tarea", "task": "Tarea",
"create-task": "Crear tarea", "create-task": "Crear tarea",
"ok": "OK" "ok": "OK",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Afficher la méthode d'authentification", "display-authentication-method": "Afficher la méthode d'authentification",
"default-authentication-method": "Méthode d'authentification par défaut", "default-authentication-method": "Méthode d'authentification par défaut",
"duplicate-board": "Dupliquer le tableau", "duplicate-board": "Dupliquer le tableau",
"org-number": "Le nombre d'organisations est de :",
"team-number": "Le nombre d'équipes est de :",
"people-number": "Le nombre d'utilisateurs est de :", "people-number": "Le nombre d'utilisateurs est de :",
"swimlaneDeletePopup-title": "Supprimer le couloir ?", "swimlaneDeletePopup-title": "Supprimer le couloir ?",
"swimlane-delete-pop": "Toutes les actions vont être supprimées du suivi d'activités et vous ne pourrez plus utiliser ce couloir. Cette action est irréversible.", "swimlane-delete-pop": "Toutes les actions vont être supprimées du suivi d'activités et vous ne pourrez plus utiliser ce couloir. Cette action est irréversible.",
@ -836,5 +838,11 @@
"hide-checked-items": "Cacher les éléments cochés", "hide-checked-items": "Cacher les éléments cochés",
"task": "Tâche", "task": "Tâche",
"create-task": "Créer une tâche", "create-task": "Créer une tâche",
"ok": "OK" "ok": "OK",
"organizations": "Organisations",
"teams": "Équipes",
"displayName": "Nom d'Affichage",
"shortName": "Nom Court",
"website": "Site Web",
"person": "Personne"
} }

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "הצגת שיטת אימות", "display-authentication-method": "הצגת שיטת אימות",
"default-authentication-method": "שיטת אימות כבררת מחדל", "default-authentication-method": "שיטת אימות כבררת מחדל",
"duplicate-board": "שכפול לוח", "duplicate-board": "שכפול לוח",
"org-number": "מספר הארגונים הוא:",
"team-number": "מספר הצוותים הוא:",
"people-number": "מספר האנשים הוא:", "people-number": "מספר האנשים הוא:",
"swimlaneDeletePopup-title": "למחוק מסלול?", "swimlaneDeletePopup-title": "למחוק מסלול?",
"swimlane-delete-pop": "כל הפעולות יוסרו מהזנת הפעילות ולא תהיה לך אפשרות לשחזר את המסלול. אי אפשר לחזור אחורה.", "swimlane-delete-pop": "כל הפעולות יוסרו מהזנת הפעילות ולא תהיה לך אפשרות לשחזר את המסלול. אי אפשר לחזור אחורה.",
@ -836,5 +838,11 @@
"hide-checked-items": "הסתרת הפריטים שסומנו", "hide-checked-items": "הסתרת הפריטים שסומנו",
"task": "משימה", "task": "משימה",
"create-task": "צירת משימה", "create-task": "צירת משימה",
"ok": "אישור" "ok": "אישור",
"organizations": "ארגונים",
"teams": "צוותים",
"displayName": "שם התצוגה",
"shortName": "שם קצר",
"website": "אתר",
"person": "איש/ה"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -492,7 +492,7 @@
"shortcut-filter-my-cards": "カードをフィルター", "shortcut-filter-my-cards": "カードをフィルター",
"shortcut-show-shortcuts": "このショートカットリストを表示する", "shortcut-show-shortcuts": "このショートカットリストを表示する",
"shortcut-toggle-filterbar": "フィルターサイドバーの切り替え", "shortcut-toggle-filterbar": "フィルターサイドバーの切り替え",
"shortcut-toggle-searchbar": "Toggle Search Sidebar", "shortcut-toggle-searchbar": "検索サイドバーの切り替え",
"shortcut-toggle-sidebar": "ボードサイドバーの切り替え", "shortcut-toggle-sidebar": "ボードサイドバーの切り替え",
"show-cards-minimum-count": "以下より多い場合、リストにカード数を表示", "show-cards-minimum-count": "以下より多い場合、リストにカード数を表示",
"sidebar-open": "サイドバーを開く", "sidebar-open": "サイドバーを開く",
@ -774,6 +774,8 @@
"display-authentication-method": "認証方式を表示", "display-authentication-method": "認証方式を表示",
"default-authentication-method": "デフォルトの認証方式", "default-authentication-method": "デフォルトの認証方式",
"duplicate-board": "ボードの複製", "duplicate-board": "ボードの複製",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"people-number": "メンバー数:", "people-number": "メンバー数:",
"swimlaneDeletePopup-title": "スイムレーンを削除しますか?", "swimlaneDeletePopup-title": "スイムレーンを削除しますか?",
"swimlane-delete-pop": "すべての内容がアクティビティから削除されます。この削除は元に戻すことができません。", "swimlane-delete-pop": "すべての内容がアクティビティから削除されます。この削除は元に戻すことができません。",
@ -836,5 +838,11 @@
"hide-checked-items": "チェックした項目を隠す", "hide-checked-items": "チェックした項目を隠す",
"task": "Task", "task": "Task",
"create-task": "Create Task", "create-task": "Create Task",
"ok": "OK" "ok": "OK",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person"
} }

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Display Authentication Method", "display-authentication-method": "Display Authentication Method",
"default-authentication-method": "Default Authentication Method", "default-authentication-method": "Default Authentication Method",
"duplicate-board": "Duplicate Board", "duplicate-board": "Duplicate Board",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"people-number": "The number of people is:", "people-number": "The number of people is:",
"swimlaneDeletePopup-title": "Delete Swimlane ?", "swimlaneDeletePopup-title": "Delete Swimlane ?",
"swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.", "swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
@ -836,5 +838,11 @@
"hide-checked-items": "Hide checked items", "hide-checked-items": "Hide checked items",
"task": "Task", "task": "Task",
"create-task": "Create Task", "create-task": "Create Task",
"ok": "OK" "ok": "OK",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person"
} }

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Display Authentication Method", "display-authentication-method": "Display Authentication Method",
"default-authentication-method": "Default Authentication Method", "default-authentication-method": "Default Authentication Method",
"duplicate-board": "보드 복사", "duplicate-board": "보드 복사",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"people-number": "The number of people is:", "people-number": "The number of people is:",
"swimlaneDeletePopup-title": "Delete Swimlane ?", "swimlaneDeletePopup-title": "Delete Swimlane ?",
"swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.", "swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
@ -836,5 +838,11 @@
"hide-checked-items": "선택된 항목 숨기기", "hide-checked-items": "선택된 항목 숨기기",
"task": "과제", "task": "과제",
"create-task": "과제 생성", "create-task": "과제 생성",
"ok": "확인" "ok": "확인",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Toon Authenticatiemethode", "display-authentication-method": "Toon Authenticatiemethode",
"default-authentication-method": "Standaard Authenticatiemethode", "default-authentication-method": "Standaard Authenticatiemethode",
"duplicate-board": "Dupliceer Bord", "duplicate-board": "Dupliceer Bord",
"org-number": "Het aantal organisaties is:",
"team-number": "Het aantal teams is:",
"people-number": "Het aantal gebruikers is:", "people-number": "Het aantal gebruikers is:",
"swimlaneDeletePopup-title": "Swimlane verwijderen?", "swimlaneDeletePopup-title": "Swimlane verwijderen?",
"swimlane-delete-pop": "Alle acties zullen verwijderd worden van de activiteiten feed en je kunt de swimlane niet terughalen. Er is geen herstelmogelijkheid.", "swimlane-delete-pop": "Alle acties zullen verwijderd worden van de activiteiten feed en je kunt de swimlane niet terughalen. Er is geen herstelmogelijkheid.",
@ -836,5 +838,11 @@
"hide-checked-items": "Verberg aangevinkte items", "hide-checked-items": "Verberg aangevinkte items",
"task": "Taak", "task": "Taak",
"create-task": "Taak aanmaken", "create-task": "Taak aanmaken",
"ok": "OK" "ok": "OK",
"organizations": "Organisaties",
"teams": "Teams",
"displayName": "Schermnaam",
"shortName": "Korte naam",
"website": "Website",
"person": "Persoon"
} }

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Wyświetl metodę logowania", "display-authentication-method": "Wyświetl metodę logowania",
"default-authentication-method": "Domyślna metoda logowania", "default-authentication-method": "Domyślna metoda logowania",
"duplicate-board": "Duplikuj tablicę", "duplicate-board": "Duplikuj tablicę",
"org-number": "Liczba organizacji:",
"team-number": "Liczba zespołów:",
"people-number": "Liczba użytkowników to:", "people-number": "Liczba użytkowników to:",
"swimlaneDeletePopup-title": "Usunąć ścieżkę?", "swimlaneDeletePopup-title": "Usunąć ścieżkę?",
"swimlane-delete-pop": "Wszystkie zdarzenia dotyczące tej ścieżki zostaną usunięte z historii aktywności. Tej operacji nie można cofnąć. Usunięcie jest nieodwracalne.", "swimlane-delete-pop": "Wszystkie zdarzenia dotyczące tej ścieżki zostaną usunięte z historii aktywności. Tej operacji nie można cofnąć. Usunięcie jest nieodwracalne.",
@ -836,5 +838,11 @@
"hide-checked-items": "Ukryj ukończone", "hide-checked-items": "Ukryj ukończone",
"task": "Zadanie", "task": "Zadanie",
"create-task": "Utwórz zadanie", "create-task": "Utwórz zadanie",
"ok": "OK" "ok": "OK",
"organizations": "Organizacje",
"teams": "Zespoły",
"displayName": "Nazwa wyświetlana",
"shortName": "Nazwa skrócona",
"website": "Strona internetowa",
"person": "Osoba"
} }

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Mostrar Método de Autenticação", "display-authentication-method": "Mostrar Método de Autenticação",
"default-authentication-method": "Método de Autenticação Padrão", "default-authentication-method": "Método de Autenticação Padrão",
"duplicate-board": "Duplicar Quadro", "duplicate-board": "Duplicar Quadro",
"org-number": "O número de organizações é:",
"team-number": "O número de times é:",
"people-number": "O número de pessoas é:", "people-number": "O número de pessoas é:",
"swimlaneDeletePopup-title": "Excluir Raia?", "swimlaneDeletePopup-title": "Excluir Raia?",
"swimlane-delete-pop": "Todas as ações serão excluídas da lista de atividades e você não poderá recuperar a raia. Não há como desfazer.", "swimlane-delete-pop": "Todas as ações serão excluídas da lista de atividades e você não poderá recuperar a raia. Não há como desfazer.",
@ -836,5 +838,11 @@
"hide-checked-items": "Esconder itens marcados", "hide-checked-items": "Esconder itens marcados",
"task": "Tarefa", "task": "Tarefa",
"create-task": "Criar Tarefa", "create-task": "Criar Tarefa",
"ok": "OK" "ok": "OK",
"organizations": "Organizações",
"teams": "Times",
"displayName": "Nome em exibição",
"shortName": "Nome curto",
"website": "Website",
"person": "Pessoa"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Показывать способ авторизации", "display-authentication-method": "Показывать способ авторизации",
"default-authentication-method": "Способ авторизации по умолчанию", "default-authentication-method": "Способ авторизации по умолчанию",
"duplicate-board": "Клонировать доску", "duplicate-board": "Клонировать доску",
"org-number": "Количество организаций:",
"team-number": "Количество команд:",
"people-number": "Количество человек:", "people-number": "Количество человек:",
"swimlaneDeletePopup-title": "Удалить дорожку?", "swimlaneDeletePopup-title": "Удалить дорожку?",
"swimlane-delete-pop": "Все действия будут удалены из ленты активности участников, и вы не сможете восстановить дорожку. Данное действие необратимо.", "swimlane-delete-pop": "Все действия будут удалены из ленты активности участников, и вы не сможете восстановить дорожку. Данное действие необратимо.",
@ -836,5 +838,11 @@
"hide-checked-items": "Спрятать отмеченные", "hide-checked-items": "Спрятать отмеченные",
"task": "Задача", "task": "Задача",
"create-task": "Создать задачу", "create-task": "Создать задачу",
"ok": "Ok" "ok": "Ok",
"organizations": "Организации",
"teams": "Команды",
"displayName": "Отображаемое название",
"shortName": "Короткое название",
"website": "Вебсайт",
"person": "Представитель"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "Display Authentication Method", "display-authentication-method": "Display Authentication Method",
"default-authentication-method": "Default Authentication Method", "default-authentication-method": "Default Authentication Method",
"duplicate-board": "Duplicate Board", "duplicate-board": "Duplicate Board",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"people-number": "The number of people is:", "people-number": "The number of people is:",
"swimlaneDeletePopup-title": "Delete Swimlane ?", "swimlaneDeletePopup-title": "Delete Swimlane ?",
"swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.", "swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
@ -836,5 +838,11 @@
"hide-checked-items": "Сховати обрані елементи", "hide-checked-items": "Сховати обрані елементи",
"task": "Task", "task": "Task",
"create-task": "Create Task", "create-task": "Create Task",
"ok": "OK" "ok": "OK",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -774,6 +774,8 @@
"display-authentication-method": "顯示認證方式", "display-authentication-method": "顯示認證方式",
"default-authentication-method": "預設認證方式", "default-authentication-method": "預設認證方式",
"duplicate-board": "複製看板", "duplicate-board": "複製看板",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"people-number": "人數是:", "people-number": "人數是:",
"swimlaneDeletePopup-title": "是否刪除泳道?", "swimlaneDeletePopup-title": "是否刪除泳道?",
"swimlane-delete-pop": "所有動作將從活動來源中刪除,您將無法恢復泳道。此操作無法還原。", "swimlane-delete-pop": "所有動作將從活動來源中刪除,您將無法恢復泳道。此操作無法還原。",
@ -836,5 +838,11 @@
"hide-checked-items": "隱藏已勾選項目", "hide-checked-items": "隱藏已勾選項目",
"task": "任務", "task": "任務",
"create-task": "建立任務", "create-task": "建立任務",
"ok": "OK" "ok": "OK",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person"
} }

View file

@ -1,7 +1,7 @@
Org = new Mongo.Collection('org'); Org = new Mongo.Collection('org');
/** /**
* A Organization in wekan * A Organization in Wekan. A Enterprise in Trello.
*/ */
Org.attachSchema( Org.attachSchema(
new SimpleSchema({ new SimpleSchema({
@ -18,76 +18,96 @@ Org.attachSchema(
} }
}, },
}, },
version: { displayName: {
/** /**
* the version of the organization * the name to display for the organization
*/ */
type: Number, type: String,
optional: true, optional: true,
}, },
name: { desc: {
/** /**
* name of the organization * the description the organization
*/ */
type: String, type: String,
optional: true, optional: true,
max: 190, max: 190,
}, },
address1: { name: {
/** /**
* address1 of the organization * short name of the organization
*/ */
type: String, type: String,
optional: true, optional: true,
max: 255, max: 255,
}, },
address2: { website: {
/** /**
* address2 of the organization * website of the organization
*/ */
type: String, type: String,
optional: true, optional: true,
max: 255, max: 255,
}, },
city: { teams: {
/** /**
* city of the organization * List of teams of a organization
*/ */
type: String, type: [Object],
optional: true, // eslint-disable-next-line consistent-return
max: 255, autoValue() {
if (this.isInsert && !this.isSet) {
return [
{
teamId: this.teamId,
isAdmin: true,
isActive: true,
isNoComments: false,
isCommentOnly: false,
isWorker: false,
},
];
}
},
}, },
state: { 'teams.$.teamId': {
/** /**
* state of the organization * The uniq ID of the team
*/ */
type: String, type: String,
optional: true,
max: 255,
}, },
zipCode: { 'teams.$.isAdmin': {
/** /**
* zipCode of the organization * Is the team an admin of the board?
*/ */
type: String, type: Boolean,
optional: true,
max: 50,
}, },
country: { 'teams.$.isActive': {
/** /**
* country of the organization * Is the team active?
*/ */
type: String, type: Boolean,
optional: true,
max: 255,
}, },
billingEmail: { 'teams.$.isNoComments': {
/** /**
* billingEmail of the organization * Is the team not allowed to make comments
*/ */
type: String, type: Boolean,
optional: true,
},
'teams.$.isCommentOnly': {
/**
* Is the team only allowed to comment on the board
*/
type: Boolean,
optional: true,
},
'teams.$.isWorker': {
/**
* Is the team only allowed to move card, assign himself to card and comment
*/
type: Boolean,
optional: true, optional: true,
max: 255,
}, },
createdAt: { createdAt: {
/** /**

90
models/team.js Normal file
View file

@ -0,0 +1,90 @@
Team = new Mongo.Collection('team');
/**
* A Team in Wekan. Organization in Trello.
*/
Team.attachSchema(
new SimpleSchema({
_id: {
/**
* the organization id
*/
type: Number,
optional: true,
// eslint-disable-next-line consistent-return
autoValue() {
if (this.isInsert && !this.isSet) {
return incrementCounter('counters', 'orgId', 1);
}
},
},
displayName: {
/**
* the name to display for the team
*/
type: String,
optional: true,
},
desc: {
/**
* the description the team
*/
type: String,
optional: true,
max: 190,
},
name: {
/**
* short name of the team
*/
type: String,
optional: true,
max: 255,
},
website: {
/**
* website of the team
*/
type: String,
optional: true,
max: 255,
},
createdAt: {
/**
* creation date of the team
*/
type: Date,
// eslint-disable-next-line consistent-return
autoValue() {
if (this.isInsert) {
return new Date();
} else if (this.isUpsert) {
return { $setOnInsert: new Date() };
} else {
this.unset();
}
},
},
modifiedAt: {
type: Date,
denyUpdate: false,
// eslint-disable-next-line consistent-return
autoValue() {
if (this.isInsert || this.isUpsert || this.isUpdate) {
return new Date();
} else {
this.unset();
}
},
},
}),
);
if (Meteor.isServer) {
// Index for Team name.
Meteor.startup(() => {
Team._collection._ensureIndex({ name: -1 });
});
}
export default Team;

View file

@ -836,6 +836,34 @@ if (Meteor.isServer) {
} }
} }
}, },
setEmailVerified(email, verified, userId) {
if (Meteor.user() && Meteor.user().isAdmin) {
check(email, String);
check(verified, Boolean);
check(userId, String);
Users.update(userId, {
$set: {
emails: [
{
address: email,
verified,
},
],
},
});
}
},
setInitials(initials, userId) {
if (Meteor.user() && Meteor.user().isAdmin) {
check(initials, String);
check(userId, String);
Users.update(userId, {
$set: {
'profile.initials': initials,
},
});
}
},
// we accept userId, username, email // we accept userId, username, email
inviteUserToBoard(username, boardId) { inviteUserToBoard(username, boardId) {
check(username, String); check(username, String);

2
package-lock.json generated
View file

@ -1,6 +1,6 @@
{ {
"name": "wekan", "name": "wekan",
"version": "v4.64.0", "version": "v4.68.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View file

@ -1,6 +1,6 @@
{ {
"name": "wekan", "name": "wekan",
"version": "v4.64.0", "version": "v4.68.0",
"description": "Open-Source kanban", "description": "Open-Source kanban",
"private": true, "private": true,
"scripts": { "scripts": {

View file

@ -1524,7 +1524,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<ul class="toc-list-h1"> <ul class="toc-list-h1">
<li> <li>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v4.64">Wekan REST API v4.64</a> <a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v4.68">Wekan REST API v4.68</a>
</li> </li>
@ -2032,7 +2032,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<div class="page-wrapper"> <div class="page-wrapper">
<div class="dark-box"></div> <div class="dark-box"></div>
<div class="content"> <div class="content">
<h1 id="wekan-rest-api">Wekan REST API v4.64</h1> <h1 id="wekan-rest-api">Wekan REST API v4.68</h1>
<blockquote> <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> <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> </blockquote>

View file

@ -1,7 +1,7 @@
swagger: '2.0' swagger: '2.0'
info: info:
title: Wekan REST API title: Wekan REST API
version: v4.64 version: v4.68
description: | description: |
The REST API allows you to control and extend Wekan with ease. The REST API allows you to control and extend Wekan with ease.

View file

@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
appTitle = (defaultText = "Wekan"), appTitle = (defaultText = "Wekan"),
# The name of the app as it is displayed to the user. # The name of the app as it is displayed to the user.
appVersion = 464, appVersion = 468,
# Increment this for every release. # Increment this for every release.
appMarketingVersion = (defaultText = "4.64.0~2020-12-24"), appMarketingVersion = (defaultText = "4.68.0~2020-12-29"),
# Human-readable presentation of the app version. # Human-readable presentation of the app version.
minUpgradableAppVersion = 0, minUpgradableAppVersion = 0,

View file

@ -0,0 +1,27 @@
Meteor.publish('org', function(query, limit) {
check(query, Match.OneOf(Object, null));
check(limit, Number);
if (!Match.test(this.userId, String)) {
return [];
}
const user = Users.findOne(this.userId);
if (user && user.isAdmin) {
return Org.find(query, {
limit,
sort: { createdAt: -1 },
fields: {
displayName: 1,
desc: 1,
name: 1,
website: 1,
teams: 1,
createdAt: 1,
loginDisabled: 1,
},
});
}
return [];
});

View file

@ -14,6 +14,7 @@ Meteor.publish('people', function(query, limit) {
fields: { fields: {
username: 1, username: 1,
'profile.fullname': 1, 'profile.fullname': 1,
'profile.initials': 1,
isAdmin: 1, isAdmin: 1,
emails: 1, emails: 1,
createdAt: 1, createdAt: 1,

View file

@ -0,0 +1,27 @@
Meteor.publish('team', function(query, limit) {
check(query, Match.OneOf(Object, null));
check(limit, Number);
if (!Match.test(this.userId, String)) {
return [];
}
const user = Users.findOne(this.userId);
if (user && user.isAdmin) {
return Team.find(query, {
limit,
sort: { createdAt: -1 },
fields: {
displayName: 1,
desc: 1,
name: 1,
website: 1,
teams: 1,
createdAt: 1,
loginDisabled: 1,
},
});
}
return [];
});