Reverted New UI Design of WeKan v8.29 and added more fixes and performance improvements.

Thanks to xet7 !
This commit is contained in:
Lauri Ojansivu 2026-02-08 00:48:39 +02:00
parent d152d8fc1b
commit 1b8b8d2eef
196 changed files with 17659 additions and 10028 deletions

View file

@ -4,17 +4,17 @@ Template.passwordInput.onRendered(function() {
const template = this;
const input = template.find('input.password-field');
const label = template.find('label');
// Set the dynamic id and name based on the field _id
if (template.data && template.data._id) {
const fieldId = `at-field-${template.data._id}`;
input.id = fieldId;
input.name = fieldId;
label.setAttribute('for', fieldId);
// Ensure the input starts as password type for password fields
input.type = 'password';
// Initially show eye icon (password is hidden) and hide eye-slash icon
const eyeIcon = template.find('.eye-icon');
const eyeSlashIcon = template.find('.eye-slash-icon');
@ -33,7 +33,7 @@ Template.passwordInput.events({
const input = template.find('input.password-field');
const eyeIcon = template.find('.eye-icon');
const eyeSlashIcon = template.find('.eye-slash-icon');
if (input.type === 'password') {
input.type = 'text';
// Show eye-slash icon when password is visible

View file

@ -1,40 +1,47 @@
.member {
display: flex;
background-color: #dbdbdb;
aspect-ratio: 1 / 1;
border-radius: 3px;
display: block;
position: relative;
float: left;
height: clamp(24px, 3.5vw, 36px);
width: clamp(24px, 3.5vw, 36px);
margin: .3vh;
cursor: pointer;
user-select: none;
z-index: 1;
text-decoration: none;
border-radius: 50%;
padding: 0.2em;
font-size: 0.9em;
height: var(--label-height);
align-items: center;
justify-content: center;
align-self: flex-start;
color: #111;
margin: 0 0.2ch;
}
.js-select-initials {
justify-content: start;
p {
margin: 0;
}
.member .avatar {
overflow: hidden;
border-radius: 50%;
}
.member .avatar.avatar-initials {
height: 70%;
width: 70%;
padding: 15%;
background-color: #dbdbdb;
color: #444;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
}
.member .avatar.avatar-image {
object-fit: cover;
object-position: center;
height: 100%;
width: 100%;
}
.member .member-presence-status {
background-color: #b3b3b3;
border: 1px solid #fff;
border-radius: 50%;
height: 1.2ch;
width: 1.2ch;
height: 7px;
width: 7px;
position: absolute;
transform: translate(1.6ch, 1.6ch);
right: -1px;
bottom: -1px;
border: 1px solid #fff;
z-index: 15;
}
@ -54,6 +61,18 @@
background: #e44242;
border-color: #f1dada;
}
.member .edit-avatar {
position: absolute;
top: 0;
height: 100%;
width: 100%;
border-radius: 50%;
background: #000;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
}
.member .edit-avatar:hover {
opacity: 0.6;
}
@ -93,4 +112,9 @@
}
.mini-profile-info .info p {
padding-top: 0;
}
}
.mini-profile-info .member {
width: clamp(40px, 5vw, 60px);
height: clamp(40px, 5vw, 60px);
margin-right: 10px;
}

View file

@ -19,8 +19,8 @@ template(name="userAvatar")
i.fa.fa-pencil-square-o
template(name="userAvatarInitials")
.avatar-initials
= initials
svg.avatar.avatar-initials(viewBox="0 0 {{viewPortWidth}} 15")
text(x="50%" y="11" text-anchor="middle" dominant-baseline="middle" font-size="16")= initials
template(name="orgAvatar")
a.member.orgOrTeamMember(class="js-member" title="{{orgData.orgDisplayName}}")

View file

@ -34,10 +34,10 @@ Template.userAvatar.helpers({
memberType() {
const user = ReactiveCache.getUser(this.userId);
if (!user) return '';
const board = Utils.getCurrentBoard();
if (!board) return '';
// Return role in priority order: Admin, Normal, NormalAssignedOnly, NoComments, CommentOnly, CommentAssignedOnly, Worker, ReadOnly, ReadAssignedOnly
if (user.isBoardAdmin()) return 'admin';
if (board.hasReadAssignedOnly(user._id)) return 'read-assigned-only';

View file

@ -1,106 +1,109 @@
.auth-container {
display: grid;
align-content: stretch;
align-items: stretch;
justify-items: stretch;
justify-content: center;
padding: 2lh 0;
/* i.e. center horizontally */
margin-inline: auto;;
/* parent container has relative positionning */
grid-template-columns: 100%;
grid-template-rows: minmax(20vh, 300px) min-content 1fr;
position: relative;
.auth-layout .at-form-landing-logo {
width: min(249px, 32vw);
margin: auto;
margin-top: 6vh;
margin-bottom: 2.5vh;
}
body.mobile-mode:has(.auth-container) {
.auth-container {
grid-template-columns: 90vw;
min-height: 100%;
}
}
.auth-logo {
&, &>a:not(img), > img {
display: flex;
flex: 1;
justify-content: center;
}
}
.auth-container {
flex: 1;
max-width: max(30vw, 600px);
gap: 1lh;
margin-bottom: 1lh;
max-height: 80vh;
position: relative;
}
.auth-layout .auth-dialog {
width: min(275px, 36vw);
padding: 3vh 3vw;
margin: auto;
margin-bottom: 2.5vh;
background: #fff;
font-size: 1.1em;
border-radius: 0.4vw;
border: 1px solid #dbdbdb;
border-bottom-color: #c2c2c2;
box-shadow: 0 0.2vh 0.8vh rgba(0,0,0,0.3);
padding: 0 2ch 0.5lh 2ch;
white-space: wrap;
/* try to override properties of non-flex forms
without referring too much to classes and ids, as forms
are dynamic */
&, div:not(#legalNoticeDiv, .lds-roller, .password-input-container, :empty), form {
display: flex;
flex-direction: column;
gap: 1lh;
>:not(.at-input) {
gap: 0.4lh;
}
.at-input {
gap: 0;
}
}
*:not(div) {
width: 100%;
margin: 0;
}
}
.auth-layout .auth-dialog .at-form .at-link {
color: #17683a;
}
.password-input-container {
display: grid;
align-self: stretch;
grid-template-columns: 1fr 6ch;
.auth-layout .auth-dialog .at-form label {
margin-bottom: 0.4vh;
}
body.mobile-mode {
.auth-layout {
max-height: unset;
}
.password-input-container {
grid-auto-flow: row;
}
.auth-layout .auth-dialog .at-form input {
width: 100%;
}
.password-input-container {
position: relative;
display: flex;
align-items: center;
}
.password-input-container input {
flex: 1;
padding-right: 55px; /* More room for the bigger button */
box-sizing: border-box;
}
.password-toggle-btn {
position: absolute;
right: 5px; /* Adjusted for larger button */
top: calc(50% - 26px); /* Moved up by 20px + 6px = 26px total */
transform: translateY(-50%);
background: #f8f8f8 !important;
border: 1px solid #ddd !important;
border-radius: 3px !important;
color: #000 !important; /* Black color for the icon */
cursor: pointer;
padding: 8px 6px 8px 12px; /* 2x bigger padding, 6px less on right */
font-size: 16px; /* 2x bigger font size */
width: auto !important;
height: auto !important;
line-height: 1;
display: flex !important;
align-items: center;
justify-content: center;
z-index: 10;
min-width: 40px; /* 2x bigger minimum width */
min-height: 32px; /* 2x bigger minimum height */
}
/* Adjust position for login and register pages */
.auth-layout .password-toggle-btn {
top: calc(50% - 11px); /* Move 15px down for login/register */
}
.password-toggle-btn .eye-text {
color: #000 !important;
font-size: 16px !important;
line-height: 1;
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
opacity: 0.8;
}
.eye-slash-line {
position: absolute;
top: 10px;
left: 10px;
width: 20px;
height: 20px;
pointer-events: none;
stroke: #000;
stroke-width: 2;
fill: none;
}
.password-toggle-btn:hover .eye-text {
color: #000 !important;
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
opacity: 0.8;
}
.auth-layout .auth-dialog .at-form button {
width: 100%;
background: #216694;
color: #fff;
min-height: 2lh;
}
.auth-layout .auth-dialog .at-form .at-title {
background: #f7f7f7;
margin: -3vh -3vw;
padding: 2vh 3vw 0.7vh;
margin-bottom: 2.5vh;
border-bottom: 1px solid #dcdcdc;
color: #4d4d4d;
font-weight: bold;
text-align: center;
}
.auth-layout .auth-dialog .at-form .at-signup-link,
.auth-layout .auth-dialog .at-form .at-signin-link,
.auth-layout .auth-dialog .at-form .at-forgotPwd {
font-size: 0.9em;
margin-top: 2vh;
color: #4d4d4d;
}
.auth-layout .auth-dialog .at-form .at-signup-link .at-signUp,
@ -110,4 +113,43 @@ body.mobile-mode {
.auth-layout .auth-dialog .at-form .at-signin-link .at-signIn,
.auth-layout .auth-dialog .at-form .at-forgotPwd .at-signIn {
font-weight: bold;
}
}
.auth-layout .auth-dialog .at-form-lang {
margin-top: 0px;
}
.auth-layout .auth-dialog .at-form-lang .select-lang {
width: 100%;
margin-top: 10px;
}
@media screen and (max-width: 800px) {
.auth-layout {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
.auth-layout .at-form-landing-logo {
width: 125px;
position: absolute;
top: 0px;
right: 20px;
margin-top: 5px;
margin-bottom: 5px;
}
.auth-layout .at-form-landing-logo img {
width: 125px;
}
.auth-layout .auth-dialog {
width: calc(100% - 50px);
height: calc(100% - 50px);
padding: 25px;
min-height: 380px;
margin: 0px;
margin-bottom: 0px;
border: 0px;
}
.auth-layout .auth-dialog .at-form .at-title h3 {
width: calc(100% - 125px);
overflow-x: hidden;
}
}

View file

@ -5,126 +5,106 @@ template(name="headerUserBar")
+userAvatar(userId=currentUser._id)
unless isMiniScreen
unless isSandstorm
.avatar-user-fullname
if currentUser.profile.fullname
= currentUser.profile.fullname
else
= currentUser.username
if currentUser.profile.fullname
= currentUser.profile.fullname
else
= currentUser.username
template(name="memberMenuPopup")
ul.pop-over-list
with currentUser
li
a.js-toggle-grey-icons(href="#")
span
i.fa.fa-paint-brush
| {{_ 'grey-icons'}}
i.fa.fa-paint-brush
| {{_ 'grey-icons'}}
if currentUser.profile
if currentUser.profile.GreyIcons
i.fa.fa-check
li
a.js-my-cards(href="{{pathFor 'my-cards'}}")
span
i.fa.fa-list
| {{_ 'my-cards'}}
i.fa.fa-list
| {{_ 'my-cards'}}
li
a.js-due-cards(href="{{pathFor 'due-cards'}}")
span
i.fa.fa-calendar
| {{_ 'dueCards-title'}}
i.fa.fa-calendar
| {{_ 'dueCards-title'}}
li
a.js-global-search(href="{{pathFor 'global-search'}}")
span
i.fa.fa-search
| {{_ 'globalSearch-title'}}
i.fa.fa-search
| {{_ 'globalSearch-title'}}
li
a(href="{{pathFor 'home'}}")
span
i.fa.fa-home
| {{_ 'all-boards'}}
i.fa.fa-home
| {{_ 'all-boards'}}
li
a(href="{{pathFor 'public'}}")
span
i.fa.fa-globe
| {{_ 'public'}}
i.fa.fa-globe
| {{_ 'public'}}
li
a.js-open-archived-board
span
i.fa.fa-archive
| {{_ 'archives'}}
a.board-header-btn.js-open-archived-board
i.fa.fa-archive
span {{_ 'archives'}}
li
a.js-notifications-drawer-toggle
span
i.fa.fa-bell
| {{_ 'notifications'}}
i.fa.fa-bell
| {{_ 'notifications'}}
if currentSetting.customHelpLinkUrl
li
a(href="{{currentSetting.customHelpLinkUrl}}", title="{{_ 'help'}}", target="_blank", rel="noopener noreferrer")
span
i.fa.fa-question-circle
| {{_ 'help'}}
i.fa.fa-question-circle
| {{_ 'help'}}
unless currentUser.isWorker
ul.pop-over-list
li
a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}")
span
i.fa.fa-list
| {{_ 'templates'}}
i.fa.fa-list
| {{_ 'templates'}}
if currentUser.isAdmin
li
a.js-go-setting(href="{{pathFor 'setting'}}")
span
i.fa.fa-lock
| {{_ 'admin-panel'}}
i.fa.fa-lock
| {{_ 'admin-panel'}}
hr
if isSameDomainNameSettingValue
li
a.js-invite-people
span
i.fa.fa-envelope
| {{_ 'invite-people'}}
i.fa.fa-envelope
| {{_ 'invite-people'}}
if isNotOAuth2AuthenticationMethod
li
a.js-edit-profile
span
i.fa.fa-user
| {{_ 'edit-profile'}}
i.fa.fa-user
| {{_ 'edit-profile'}}
li
a.js-change-settings
span
i.fa.fa-cog
| {{_ 'change-settings'}}
i.fa.fa-cog
| {{_ 'change-settings'}}
li
a.js-change-avatar
span
i.fa.fa-picture-o
| {{_ 'edit-avatar'}}
i.fa.fa-picture-o
| {{_ 'edit-avatar'}}
unless isSandstorm
if isNotOAuth2AuthenticationMethod
li
a.js-change-password
span
i.fa.fa-key
| {{_ 'changePasswordPopup-title'}}
i.fa.fa-key
| {{_ 'changePasswordPopup-title'}}
li
a.js-change-language
span
i.fa.fa-flag
| {{_ 'changeLanguagePopup-title'}}
i.fa.fa-flag
| {{_ 'changeLanguagePopup-title'}}
if isSupportPageEnabled
li
a(href="{{pathFor 'support'}}")
span
i.fa.fa-question-circle
| {{_ 'support'}}
i.fa.fa-question-circle
| {{_ 'support'}}
unless isSandstorm
hr
ul.pop-over-list
hr
li
a.js-logout
span
i.fa.fa-sign-out
| {{_ 'log-out'}}
i.fa.fa-sign-out
| {{_ 'log-out'}}
template(name="invitePeoplePopup")
ul#registration-setting.setting-detail
@ -154,7 +134,7 @@ template(name="editProfilePopup")
form
label
| {{_ 'fullname'}}
input.js-profile-fullname(type="text" value=profile.fullname )
input.js-profile-fullname(type="text" value=profile.fullname autofocus)
label
| {{_ 'username'}}
span.error.hide.username-taken

View file

@ -168,33 +168,22 @@ Template.invitePeoplePopup.events({
},
});
Template.editProfilePopup.onCreated(function() {
this.subscribe('accountSettings');
});
Template.editProfilePopup.helpers({
allowEmailChange() {
Meteor.call('AccountSettings.allowEmailChange', (_, result) => {
if (result) {
return true;
} else {
return false;
}
});
const setting = AccountSettings.findOne('accounts-allowEmailChange');
return setting && setting.booleanValue;
},
allowUserNameChange() {
Meteor.call('AccountSettings.allowUserNameChange', (_, result) => {
if (result) {
return true;
} else {
return false;
}
});
const setting = AccountSettings.findOne('accounts-allowUserNameChange');
return setting && setting.booleanValue;
},
allowUserDelete() {
Meteor.call('AccountSettings.allowUserDelete', (_, result) => {
if (result) {
return true;
} else {
return false;
}
});
const setting = AccountSettings.findOne('accounts-allowUserDelete');
return setting && setting.booleanValue;
},
});
@ -342,7 +331,6 @@ Template.changeLanguagePopup.events({
},
});
TAPi18n.setLanguage(this.tag);
Popup.close();
event.preventDefault();
},
});