mirror of
https://github.com/wekan/wekan.git
synced 2026-11-08 03:22:32 -05:00
(Arabic and its variants, Persian/Farsi, Hebrew, Uyghur, Uzbek-Arabic and Yiddish — the languages flagged `rtl: true` in `imports/i18n/languages.js`). Previously only some pages flipped. The root `<html>` element now gets a reactive `dir="rtl"`/`dir="ltr"` attribute that follows the chosen language, so the whole UI mirrors at once. To make this work on every page rather than a handful, all directional component CSS was converted to CSS logical properties (`margin-left`→`margin-inline-start`, `left:`→`inset-inline-start:`, `text-align: left`→`text-align: start`, `float: left`→`float: inline-start`, and the mirror-image right/end variants) across 48 stylesheets, which flip automatically with `dir`. Horizontal-centering rules using `left: 50%` + `transform: translate(-50%, …)` were intentionally kept physical, since those already center correctly in both directions. The calendar view also renders RTL. Thanks to xet7 and Claude. - Tests for the RTL UI. A fast, server-less `tests/rtl.test.js` (run with `node tests/rtl.test.js`) checks that exactly the expected languages are flagged `rtl: true`, that the direction helper maps each language to the right `dir` value, that the root `<html>` and the client keep `dir` in sync, and — as a regression guard — that component CSS keeps using logical properties (no physical `margin-left`/`float: left`/bare `left:` offsets sneak back in). A Playwright browser spec `tests/playwright/specs/18-rtl-layout.e2e.js` drives the app in both English (LTR) and Arabic (RTL) and asserts, on the boards list, board view, card details, my-cards / due-cards / global-search, the admin settings page and the login page, that the direction is correct, the translated text is visible, and leading-edge content (the boards menu, the first board list) sits on the correct side. Thanks to xet7 and Claude. - Fixed the "Meteor unit tests" CI job hanging until its 45-minute timeout. The workflow set `TEST_WATCH: '0'`, but meteortesting:mocha computes `testWatch: TEST_WATCH || …` and the string `'0'` is truthy in JavaScript, so it turned on watch mode and the process never exited. Removing the env var lets `meteor test --once` finish and exit with the correct status. Thanks to xet7 and Claude ! Fixes #6136, fixes #3376, fixes #884
185 lines
2.9 KiB
CSS
185 lines
2.9 KiB
CSS
/* Board Conversion Progress Styles */
|
|
.board-conversion-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
inset-inline-start: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.7);
|
|
z-index: 9999;
|
|
display: none;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.board-conversion-overlay.active {
|
|
display: flex;
|
|
}
|
|
|
|
.board-conversion-modal {
|
|
background: white;
|
|
border-radius: 8px;
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
|
|
max-width: 500px;
|
|
width: 90%;
|
|
max-height: 80vh;
|
|
overflow: hidden;
|
|
animation: slideIn 0.3s ease-out;
|
|
}
|
|
|
|
@keyframes slideIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.board-conversion-header {
|
|
padding: 20px 24px 16px;
|
|
border-bottom: 1px solid #e0e0e0;
|
|
text-align: center;
|
|
}
|
|
|
|
.board-conversion-header h3 {
|
|
margin: 0 0 8px 0;
|
|
color: #333;
|
|
font-size: 20px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.board-conversion-header h3 i {
|
|
margin-inline-end: 8px;
|
|
color: #2196F3;
|
|
}
|
|
|
|
.board-conversion-header p {
|
|
margin: 0;
|
|
color: #666;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.board-conversion-content {
|
|
padding: 24px;
|
|
}
|
|
|
|
.conversion-progress {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.progress-bar {
|
|
width: 100%;
|
|
height: 8px;
|
|
background-color: #e0e0e0;
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.progress-fill {
|
|
height: 100%;
|
|
background: linear-gradient(90deg, #2196F3, #21CBF3);
|
|
border-radius: 4px;
|
|
transition: width 0.3s ease;
|
|
position: relative;
|
|
}
|
|
|
|
.progress-fill::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
inset-inline-start: 0;
|
|
inset-inline-end: 0;
|
|
bottom: 0;
|
|
background: linear-gradient(
|
|
90deg,
|
|
transparent,
|
|
rgba(255, 255, 255, 0.3),
|
|
transparent
|
|
);
|
|
animation: shimmer 2s infinite;
|
|
}
|
|
|
|
@keyframes shimmer {
|
|
0% {
|
|
transform: translateX(-100%);
|
|
}
|
|
100% {
|
|
transform: translateX(100%);
|
|
}
|
|
}
|
|
|
|
.progress-text {
|
|
text-align: center;
|
|
font-weight: 600;
|
|
color: #2196F3;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.conversion-status {
|
|
text-align: center;
|
|
margin-bottom: 16px;
|
|
color: #333;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.conversion-status i {
|
|
margin-inline-end: 8px;
|
|
color: #2196F3;
|
|
}
|
|
|
|
.conversion-time {
|
|
text-align: center;
|
|
color: #666;
|
|
font-size: 14px;
|
|
background-color: #f5f5f5;
|
|
padding: 8px 12px;
|
|
border-radius: 4px;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.conversion-time i {
|
|
margin-inline-end: 6px;
|
|
color: #FF9800;
|
|
}
|
|
|
|
.board-conversion-footer {
|
|
padding: 16px 24px 20px;
|
|
border-top: 1px solid #e0e0e0;
|
|
background-color: #f9f9f9;
|
|
}
|
|
|
|
.conversion-info {
|
|
text-align: center;
|
|
color: #666;
|
|
font-size: 13px;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.conversion-info i {
|
|
margin-inline-end: 6px;
|
|
color: #2196F3;
|
|
}
|
|
|
|
/* Responsive design */
|
|
@media (max-width: 600px) {
|
|
.board-conversion-modal {
|
|
width: 95%;
|
|
margin: 20px;
|
|
}
|
|
|
|
.board-conversion-header,
|
|
.board-conversion-content,
|
|
.board-conversion-footer {
|
|
padding-inline-start: 16px;
|
|
padding-inline-end: 16px;
|
|
}
|
|
|
|
.board-conversion-header h3 {
|
|
font-size: 18px;
|
|
}
|
|
}
|