diff --git a/webapp/src/components/backup-center/BackupOperationsSidebar.tsx b/webapp/src/components/backup-center/BackupOperationsSidebar.tsx index 61390e2..1b9720c 100644 --- a/webapp/src/components/backup-center/BackupOperationsSidebar.tsx +++ b/webapp/src/components/backup-center/BackupOperationsSidebar.tsx @@ -41,42 +41,47 @@ export function BackupOperationsSidebar(props: BackupOperationsSidebarProps) { -
+
+ + + {t('txt_backup_recommend_title')} + {t('txt_backup_recommend_group_webdav')} · {t('txt_backup_recommend_group_s3')} + + -
-

{t('txt_backup_recommend_title')}

-
-
-

{t('txt_backup_recommend_group_webdav')}

-
- {props.recommendedWebDavProviders.map((provider) => ( - - ))} -
-
-
-

{t('txt_backup_recommend_group_s3')}

- {props.recommendedS3Providers.length ? ( + ) : null} + + ))} +
+
+
+

{t('txt_backup_recommend_group_s3')}

+ {props.recommendedS3Providers.length ? (
{props.recommendedS3Providers.map((provider) => (
- ) : ( -
{t('txt_backup_recommend_empty')}
- )} -
+ ) : ( +
{t('txt_backup_recommend_empty')}
+ )} + + + ); } diff --git a/webapp/src/components/vault/VaultEditor.tsx b/webapp/src/components/vault/VaultEditor.tsx index 2648525..42a849e 100644 --- a/webapp/src/components/vault/VaultEditor.tsx +++ b/webapp/src/components/vault/VaultEditor.tsx @@ -109,7 +109,13 @@ function WebsiteRow(props: WebsiteRowProps) { ))} {props.canRemove && ( - diff --git a/webapp/src/lib/i18n/locales/en.ts b/webapp/src/lib/i18n/locales/en.ts index ebb60be..3862ce4 100644 --- a/webapp/src/lib/i18n/locales/en.ts +++ b/webapp/src/lib/i18n/locales/en.ts @@ -766,13 +766,13 @@ const en: Record = { "txt_user_deleted": "User deleted", "txt_user_status_updated": "User status updated", "txt_username": "Username", - "txt_uri_match_default_base_domain": "Default (Base Domain)", + "txt_uri_match_default_base_domain": "Default", "txt_uri_match_base_domain": "Base Domain", "txt_uri_match_host": "Host", "txt_uri_match_exact": "Exact", "txt_uri_match_never": "Never", "txt_uri_match_starts_with": "Starts With", - "txt_uri_match_regular_expression": "Regular Expression", + "txt_uri_match_regular_expression": "Regex", "txt_users": "Users", "txt_vault_synced": "Vault synced", "txt_verification_code": "Verification Code", diff --git a/webapp/src/lib/i18n/locales/es.ts b/webapp/src/lib/i18n/locales/es.ts index b6d968e..5192f4b 100644 --- a/webapp/src/lib/i18n/locales/es.ts +++ b/webapp/src/lib/i18n/locales/es.ts @@ -766,13 +766,13 @@ const es: Record = { "txt_user_deleted": "Usuario eliminado", "txt_user_status_updated": "Estado del usuario actualizado", "txt_username": "Nombre de usuario", - "txt_uri_match_default_base_domain": "Predeterminado (dominio base)", + "txt_uri_match_default_base_domain": "Predet.", "txt_uri_match_base_domain": "Dominio base", "txt_uri_match_host": "Host", "txt_uri_match_exact": "Exacto", "txt_uri_match_never": "Nunca", "txt_uri_match_starts_with": "Empieza con", - "txt_uri_match_regular_expression": "Expresión regular", + "txt_uri_match_regular_expression": "Regex", "txt_users": "Usuarios", "txt_vault_synced": "Bóveda sincronizada", "txt_verification_code": "Código de verificación", diff --git a/webapp/src/lib/i18n/locales/ru.ts b/webapp/src/lib/i18n/locales/ru.ts index ed1fdf7..68b7cde 100644 --- a/webapp/src/lib/i18n/locales/ru.ts +++ b/webapp/src/lib/i18n/locales/ru.ts @@ -766,13 +766,13 @@ const ru: Record = { "txt_user_deleted": "Пользователь удален", "txt_user_status_updated": "Статус пользователя обновлен", "txt_username": "Имя пользователя", - "txt_uri_match_default_base_domain": "По умолчанию (базовый домен)", + "txt_uri_match_default_base_domain": "По умолч.", "txt_uri_match_base_domain": "Базовый домен", "txt_uri_match_host": "Хост", "txt_uri_match_exact": "Точный", "txt_uri_match_never": "Никогда", "txt_uri_match_starts_with": "Начинается с", - "txt_uri_match_regular_expression": "Регулярное выражение", + "txt_uri_match_regular_expression": "Regex", "txt_users": "Пользователи", "txt_vault_synced": "Сейф синхронизирован", "txt_verification_code": "Код подтверждения", diff --git a/webapp/src/lib/i18n/locales/zh-CN.ts b/webapp/src/lib/i18n/locales/zh-CN.ts index cdf373f..d9e2ace 100644 --- a/webapp/src/lib/i18n/locales/zh-CN.ts +++ b/webapp/src/lib/i18n/locales/zh-CN.ts @@ -766,13 +766,13 @@ const zhCN: Record = { "txt_user_deleted": "用户已删除", "txt_user_status_updated": "用户状态已更新", "txt_username": "用户名", - "txt_uri_match_default_base_domain": "默认(基础域名)", + "txt_uri_match_default_base_domain": "默认", "txt_uri_match_base_domain": "基础域名", "txt_uri_match_host": "主机", "txt_uri_match_exact": "精确", "txt_uri_match_never": "从不", "txt_uri_match_starts_with": "开始于", - "txt_uri_match_regular_expression": "正则表达式", + "txt_uri_match_regular_expression": "正则表达", "txt_users": "用户", "txt_vault_synced": "密码库已同步", "txt_verification_code": "验证码", diff --git a/webapp/src/lib/i18n/locales/zh-TW.ts b/webapp/src/lib/i18n/locales/zh-TW.ts index 7d6a240..94092f3 100644 --- a/webapp/src/lib/i18n/locales/zh-TW.ts +++ b/webapp/src/lib/i18n/locales/zh-TW.ts @@ -766,13 +766,13 @@ const zhTW: Record = { "txt_user_deleted": "用戶已刪除", "txt_user_status_updated": "用戶狀態已更新", "txt_username": "用戶名", - "txt_uri_match_default_base_domain": "默認(基礎域名)", + "txt_uri_match_default_base_domain": "默認", "txt_uri_match_base_domain": "基礎域名", "txt_uri_match_host": "主機", "txt_uri_match_exact": "精確", "txt_uri_match_never": "從不", "txt_uri_match_starts_with": "開始於", - "txt_uri_match_regular_expression": "正則表達式", + "txt_uri_match_regular_expression": "正則表達", "txt_users": "用戶", "txt_vault_synced": "密碼庫已同步", "txt_verification_code": "驗證碼", diff --git a/webapp/src/styles/dark.css b/webapp/src/styles/dark.css index b68ac1e..33c63ce 100644 --- a/webapp/src/styles/dark.css +++ b/webapp/src/styles/dark.css @@ -208,6 +208,7 @@ :root[data-theme='dark'] .backup-help-bubble, :root[data-theme='dark'] .backup-recommendation-card, :root[data-theme='dark'] .backup-recommendation-dav-item, +:root[data-theme='dark'] .backup-recommendations-summary, :root[data-theme='dark'] .backup-browser-path, :root[data-theme='dark'] .backup-browser-list, :root[data-theme='dark'] .restore-progress-card, diff --git a/webapp/src/styles/management.css b/webapp/src/styles/management.css index f22ace6..86e5946 100644 --- a/webapp/src/styles/management.css +++ b/webapp/src/styles/management.css @@ -34,6 +34,50 @@ @apply grid gap-2.5; } +.backup-recommendations-disclosure { + @apply mt-3; +} + +.backup-recommendations-summary { + @apply flex cursor-pointer list-none items-center justify-between gap-3 rounded-xl border px-3 py-2.5; + border-color: var(--line); + background: #f8fafc; + color: #0f172a; +} + +.backup-recommendations-summary::-webkit-details-marker { + display: none; +} + +.backup-recommendations-summary > span:first-child { + @apply grid min-w-0 gap-0.5; +} + +.backup-recommendations-summary strong { + @apply text-sm; +} + +.backup-recommendations-summary small { + @apply text-xs font-semibold; + color: #64748b; +} + +.backup-recommendations-summary-icon { + @apply h-2.5 w-2.5 shrink-0; + border-right: 2px solid #365fa8; + border-bottom: 2px solid #365fa8; + transform: rotate(45deg) translateY(-2px); + transition: transform var(--dur-fast) var(--ease-out-soft); +} + +.backup-recommendations-disclosure[open] .backup-recommendations-summary-icon { + transform: rotate(225deg) translate(-1px, -1px); +} + +.backup-recommendations-body { + @apply pt-2.5; +} + .backup-option-field { @apply inline-flex items-center gap-2; } @@ -576,7 +620,7 @@ .website-row { @apply mb-2 grid items-center gap-2 rounded-[18px] border p-1.5; - grid-template-columns: auto minmax(0, 1fr) minmax(130px, 160px) auto; + grid-template-columns: auto minmax(0, 1fr) minmax(96px, 120px) auto; border-color: transparent; background: color-mix(in srgb, var(--panel) 84%, transparent); transition: @@ -605,7 +649,7 @@ } .website-match-select { - @apply h-12 py-2.5 pr-[38px] text-[13px] leading-[1.2]; + @apply h-12 py-2.5 pr-[30px] text-[13px] leading-[1.2]; } .website-match-select option { @@ -618,30 +662,22 @@ @media (max-width: 760px) { .website-row { - grid-template-columns: auto minmax(0, 1fr) auto; - @apply items-start; + grid-template-columns: auto minmax(88px, 1fr) minmax(72px, 84px) auto; + @apply items-center; } - .website-row > :nth-child(1) { - grid-column: 1; - grid-row: 1; - align-self: center; + .website-row .website-remove-btn { + width: 30px; + min-width: 30px; + height: 30px; + padding: 0; + gap: 0; + border-radius: 999px; + font-size: 0; } - .website-row > :nth-child(2) { - grid-column: 2 / span 2; - grid-row: 1; - } - - .website-row > :nth-child(3) { - grid-column: 1 / span 2; - grid-row: 2; - } - - .website-row > :nth-child(4) { - grid-column: 3; - grid-row: 2; - justify-self: start; + .website-row .website-remove-btn .btn-icon { + margin: 0; } } diff --git a/webapp/src/styles/responsive.css b/webapp/src/styles/responsive.css index 7d29ce2..b5225b5 100644 --- a/webapp/src/styles/responsive.css +++ b/webapp/src/styles/responsive.css @@ -360,7 +360,7 @@ } .list-item { - @apply rounded-[14px] p-3; + @apply rounded-[14px] py-2 px-3; } .row-check { @@ -432,6 +432,163 @@ @apply p-3.5; } + .mobile-detail-sheet { + padding-bottom: 10px; + } + + .mobile-panel-head { + margin: 6px 8px 8px; + } + + .mobile-panel-back { + min-height: 36px; + } + + .mobile-detail-sheet > .detail-switch-stage, + .mobile-detail-sheet > .card, + .mobile-detail-sheet > .empty { + margin-left: 8px; + margin-right: 8px; + } + + .mobile-detail-sheet .card { + margin-bottom: 8px; + padding: 10px 12px; + border-radius: 14px; + } + + .mobile-detail-sheet .card h4 { + margin: 0 0 8px; + font-size: 15px; + line-height: 1.25; + } + + .mobile-detail-sheet .detail-title { + font-size: 15px; + line-height: 1.25; + } + + .mobile-detail-sheet .section-head { + flex-direction: row; + align-items: center; + justify-content: space-between; + gap: 8px; + margin-bottom: 8px; + min-width: 0; + } + + .mobile-detail-sheet .section-head h3, + .mobile-detail-sheet .section-head h4 { + margin: 0; + min-width: 0; + } + + .mobile-detail-sheet .section-head > .btn.small { + flex: 0 0 auto; + height: 32px; + padding: 0 10px; + font-size: 13px; + } + + .mobile-detail-sheet .field { + margin-bottom: 8px; + } + + .mobile-detail-sheet .field > span { + margin: 0 0 4px; + font-size: 13px; + line-height: 1.2; + } + + .mobile-detail-sheet .field-grid { + gap: 0px; + } + + .mobile-detail-sheet .input { + height: 42px; + border-radius: 12px; + padding: 8px 11px; + font-size: 15px; + } + + .mobile-detail-sheet select.input { + padding-right: 30px; + background-position: + calc(100% - 15px) calc(50% - 3px), + calc(100% - 9px) calc(50% - 3px); + } + + .mobile-detail-sheet .textarea { + min-height: 82px; + } + + .mobile-detail-sheet .input-action-wrap .input { + padding-right: 42px; + } + + .mobile-detail-sheet .input-icon-btn { + right: 6px; + width: 30px; + height: 30px; + } + + .mobile-detail-sheet .website-row { + grid-template-columns: auto minmax(88px, 1fr) minmax(72px, 84px) auto; + gap: 5px; + align-items: center; + margin-bottom: 6px; + padding: 4px; + border-radius: 12px; + } + + .mobile-detail-sheet .website-row > * { + grid-column: auto !important; + grid-row: auto !important; + } + + .mobile-detail-sheet .website-order-actions { + gap: 2px; + } + + .mobile-detail-sheet .website-order-btn { + width: 24px; + min-width: 24px; + height: 19px; + border-radius: 7px; + } + + .mobile-detail-sheet .website-match-select { + height: 40px; + min-width: 0; + padding-left: 8px; + padding-right: 24px; + font-size: 12px; + background-position: + calc(100% - 12px) calc(50% - 3px), + calc(100% - 7px) calc(50% - 3px); + background-size: 5px 5px, 5px 5px; + } + + .mobile-detail-sheet .website-remove-btn { + width: 30px; + min-width: 30px; + height: 30px; + padding: 0; + gap: 0; + border-radius: 999px; + font-size: 0; + } + + .mobile-detail-sheet .website-remove-btn .btn-icon { + margin: 0; + } + + .mobile-detail-sheet .attachment-row, + .mobile-detail-sheet .custom-field-card { + padding-top: 7px; + padding-bottom: 7px; + } + .section-head { @apply flex-col items-start gap-2.5; } @@ -666,34 +823,71 @@ @media (max-width: 1180px) { .backup-grid { grid-template-columns: 1fr; + gap: 8px; } .backup-operations-sidebar, - .backup-destination-sidebar { + .backup-destination-sidebar, + .backup-detail-panel { position: static; + padding: 12px; + border-radius: 14px; } } @media (max-width: 640px) { + .settings-modules-grid { + gap: 8px; + } + + .settings-module { + padding: 10px 12px; + border-radius: 14px; + } + .settings-module h3 { - margin-bottom: 12px; + margin-bottom: 8px; + font-size: 15px; + line-height: 1.25; } .settings-module .field, .auth-card .field { - margin-bottom: 12px; + margin-bottom: 8px; } .settings-module .field > span, .auth-card .field > span { margin-top: 0; - margin-bottom: 6px; + margin-bottom: 4px; + font-size: 13px; + line-height: 1.2; } .settings-module .field-grid, .auth-card .field-grid, .session-timeout-fields { - gap: 12px; + gap: 8px; + } + + .settings-module .input { + height: 42px; + border-radius: 12px; + padding: 8px 11px; + font-size: 15px; + } + + .settings-module select.input { + padding-right: 30px; + background-position: + calc(100% - 15px) calc(50% - 3px), + calc(100% - 9px) calc(50% - 3px); + } + + .settings-module .field-help { + margin-top: 5px; + font-size: 12px; + line-height: 1.35; } .settings-module .btn, @@ -701,6 +895,46 @@ margin-top: 2px; } + .settings-module .actions { + gap: 7px; + } + + .settings-module .totp-grid { + gap: 8px; + margin-bottom: 8px; + } + + .settings-module .totp-qr { + min-height: 132px; + padding: 8px; + } + + .settings-module .totp-qr svg, + .settings-module .totp-qr img { + width: 118px; + height: 118px; + } + + .settings-module .sensitive-actions-grid { + gap: 8px; + } + + .settings-module .sensitive-action { + padding: 10px; + border-radius: 12px; + } + + .settings-module .sensitive-action h4 { + margin-bottom: 4px; + font-size: 14px; + } + + .settings-field-note { + margin-bottom: 7px; + font-size: 12px; + line-height: 1.35; + } + .dialog-mask.totp-scan-mask { display: block; padding: 0; @@ -720,6 +954,7 @@ .backup-interval-row { grid-template-columns: 1fr; + gap: 7px; } .backup-browser-row, @@ -727,9 +962,149 @@ grid-template-columns: 1fr; } - .backup-destination-top { - align-items: flex-start; + .backup-grid { + gap: 8px; + padding: 0; + } + + .backup-operations-sidebar, + .backup-destination-sidebar, + .backup-detail-panel { + padding: 10px 12px; + border-radius: 14px; + } + + .backup-operations-sidebar .section-head, + .backup-destination-sidebar .section-head, + .backup-detail-panel .section-head { + flex-direction: row; + align-items: center; + gap: 8px; + margin-bottom: 8px; + } + + .backup-detail-panel > .section-head { flex-direction: column; + align-items: stretch; + } + + .backup-detail-panel > .section-head .actions { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 6px; + width: 100%; + } + + .backup-detail-panel > .section-head .actions .btn { + height: 36px; + min-width: 0; + padding: 0 8px; + font-size: 12px; + } + + .backup-operations-sidebar .section-head h3, + .backup-destination-sidebar .section-head h3, + .backup-detail-panel .section-head h3 { + margin: 0; + font-size: 15px; + line-height: 1.25; + } + + .backup-actions-stack, + .backup-destination-list, + .backup-recommendation-list { + gap: 7px; + } + + .backup-actions-stack .btn, + .backup-destination-addbar .btn { + height: 38px; + } + + .backup-recommendations-disclosure { + margin-top: 8px; + } + + .backup-recommendations-summary { + padding: 8px 10px; + border-radius: 12px; + } + + .backup-recommendations-body { + padding-top: 8px; + } + + .backup-recommendation-group + .backup-recommendation-group { + margin-top: 8px; + } + + .backup-recommendation-group-title { + margin-bottom: 6px; + font-size: 13px; + } + + .backup-destination-item { + padding: 9px 10px; + border-radius: 12px; + gap: 4px; + } + + .backup-destination-meta { + font-size: 12px; + } + + .backup-name-row, + .backup-detail-schedule-grid { + gap: 8px; + margin-bottom: 8px; + } + + .backup-detail-panel .field { + margin-bottom: 8px; + } + + .backup-detail-panel .field > span { + margin: 0 0 4px; + font-size: 13px; + line-height: 1.2; + } + + .backup-detail-panel .input { + height: 42px; + border-radius: 12px; + padding: 8px 11px; + font-size: 15px; + } + + .backup-detail-panel select.input { + padding-right: 30px; + background-position: + calc(100% - 15px) calc(50% - 3px), + calc(100% - 9px) calc(50% - 3px); + } + + .backup-schedule-attachments-row { + margin-bottom: 8px; + } + + .backup-option-label { + font-size: 14px; + } + + .backup-option-label input[type='checkbox'] { + width: 19px; + height: 19px; + } + + .backup-browser-path, + .backup-browser-empty { + padding: 9px 10px; + border-radius: 12px; + } + + .backup-destination-top { + align-items: center; + flex-direction: row; } .backup-add-chooser {