feat: add admin/profile UI, i18n (fr/de/pt), fix CI pipelines

- Add admin panel link and profile modal in user menu dropdown
- Add French, German and Portuguese locale support (full translations)
- Register new locales across JS frontend and Rust backend
- Create CI pipeline (fmt, clippy, test, audit, build)
- Fix docker-build.yml (cache, real tests, reduced timeout)
- Fix docker-publish.yml (multi-arch via QEMU, latest tag, pre-publish tests)
- Add dependabot.yml for automated dependency updates
This commit is contained in:
Dionisio
2026-02-11 12:26:29 +01:00
parent 6b55cdf3c4
commit 3050955f9c
21 changed files with 1422 additions and 408 deletions
+40
View File
@@ -0,0 +1,40 @@
version: 2
updates:
# Rust (Cargo) dependencies
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 10
labels:
- "dependencies"
- "rust"
commit-message:
prefix: "deps(rust):"
# GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
labels:
- "dependencies"
- "ci"
commit-message:
prefix: "deps(ci):"
# Docker
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 3
labels:
- "dependencies"
- "docker"
commit-message:
prefix: "deps(docker):"
+85
View File
@@ -0,0 +1,85 @@
name: CI
on:
push:
branches: [ "main", "dev" ]
pull_request:
branches: [ "main", "dev" ]
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: "-Dwarnings"
DATABASE_URL: "postgres://postgres:postgres@localhost/oxicloud_test"
jobs:
fmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --all --check
clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-targets --all-features -- -D warnings
test:
name: Tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: oxicloud_test
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Initialize test database
run: psql -h localhost -U postgres -d oxicloud_test -f db/schema.sql
env:
PGPASSWORD: postgres
- name: Run tests
run: cargo test --all-features --workspace
env:
DATABASE_URL: "postgres://postgres:postgres@localhost/oxicloud_test"
audit:
name: Security Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: rustsec/audit-check@v2.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
build:
name: Build Check
runs-on: ubuntu-latest
needs: [fmt, clippy, test]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo build --release
+34 -14
View File
@@ -1,6 +1,5 @@
name: Docker Build and Test name: Docker Build and Test
# Trigger on push to main branch or on pull requests
on: on:
push: push:
branches: [ "main", "dev" ] branches: [ "main", "dev" ]
@@ -8,21 +7,18 @@ on:
branches: [ "main", "dev" ] branches: [ "main", "dev" ]
jobs: jobs:
# Build and test Docker image but don't push
build-and-test: build-and-test:
name: Build and Test Docker Image name: Build and Test Docker Image
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 120 # Aumentado a 2 horas para dar más tiempo a la compilación timeout-minutes: 45
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
# Set up Docker Buildx
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
# Extract metadata (tags, labels) for Docker
- name: Extract metadata (tags, labels) for Docker - name: Extract metadata (tags, labels) for Docker
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
@@ -33,7 +29,6 @@ jobs:
type=ref,event=pr type=ref,event=pr
type=sha type=sha
# Build Docker image but don't push
- name: Build Docker image - name: Build Docker image
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
@@ -41,16 +36,41 @@ jobs:
push: false push: false
load: true load: true
tags: test/oxicloud:test tags: test/oxicloud:test
# Caché eliminado para evitar problemas de expiración de token cache-from: type=gha
cache-to: type=gha,mode=max
# Run some basic tests against the built image - name: Verify image starts correctly
- name: Test Docker image
run: | run: |
docker run --rm test/oxicloud:test --version || true # Start the container in background
docker run --rm test/oxicloud:test --help || true docker run -d --name oxicloud-test \
-e DATABASE_URL="postgres://test:test@localhost/test" \
-p 8080:8080 \
test/oxicloud:test || true
# Verify the image structure # Give it a moment to start (or fail)
echo "✅ Checking Docker image layers and size" sleep 3
docker image inspect test/oxicloud:test
# Check that the container exists and show logs
echo "=== Container status ==="
docker ps -a --filter name=oxicloud-test
echo "=== Container logs ==="
docker logs oxicloud-test 2>&1 || true
# Cleanup
docker rm -f oxicloud-test || true
- name: Verify image structure
run: |
echo "=== Image size ==="
docker image ls test/oxicloud:test
echo "=== Binary exists and is executable ==="
docker run --rm --entrypoint sh test/oxicloud:test -c "test -x /usr/local/bin/oxicloud && echo 'OK: binary is executable'"
echo "=== Static files present ==="
docker run --rm --entrypoint sh test/oxicloud:test -c "ls /app/static/index.html && echo 'OK: static files present'"
echo "=== DB schema present ==="
docker run --rm --entrypoint sh test/oxicloud:test -c "ls /app/db/schema.sql && echo 'OK: schema present'"
echo "✅ Docker build and test completed successfully" echo "✅ Docker build and test completed successfully"
+45 -48
View File
@@ -6,63 +6,47 @@ on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
version: version:
description: 'Versión del release' description: 'Version tag to publish (e.g. v0.3.0)'
required: false required: true
default: '0.1.0-rc1'
env:
REGISTRY_IMAGE: diocrafts/oxicloud
jobs: jobs:
build-and-push: # Run tests before publishing
test:
name: Pre-publish Tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: steps:
matrix: - uses: actions/checkout@v4
arch: [amd64, arm64] - uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo test --workspace
# Build and push multi-arch image in a single job
build-and-push:
name: Build & Push Multi-Arch
runs-on: ubuntu-latest
needs: test
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set version tag - name: Set version tag
id: version id: version
run: | run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV VERSION="${{ github.event.inputs.version }}"
else else
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV VERSION="${GITHUB_REF#refs/tags/}"
fi fi
# Strip leading 'v' if present for Docker tag
VERSION="${VERSION#v}"
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Build and Push Docker Image - name: Set up QEMU
uses: docker/build-push-action@v5 uses: docker/setup-qemu-action@v3
with:
context: .
platforms: linux/${{ matrix.arch }}
push: true
tags: |
diocrafts/oxicloud:${{ env.VERSION }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
VERSION=${{ env.VERSION }}
# Crear el manifiesto multi-arch una vez todas las imágenes estén listas
manifest:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- name: Set version tag
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
else
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
fi
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
@@ -73,9 +57,22 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create and Push Manifest - name: Build and Push Multi-Arch Image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }}
${{ env.REGISTRY_IMAGE }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
VERSION=${{ env.VERSION }}
- name: Verify published image
run: | run: |
docker buildx imagetools create \ docker pull ${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }}
-t diocrafts/oxicloud:${{ env.VERSION }} \ docker image inspect ${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }}
diocrafts/oxicloud:${{ env.VERSION }}@linux/amd64 \ echo "✅ Image ${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }} published successfully"
diocrafts/oxicloud:${{ env.VERSION }}@linux/arm64
+3
View File
@@ -16,6 +16,9 @@ impl From<Locale> for LocaleDto {
let (code, name) = match locale { let (code, name) = match locale {
Locale::English => ("en", "English"), Locale::English => ("en", "English"),
Locale::Spanish => ("es", "Español"), Locale::Spanish => ("es", "Español"),
Locale::French => ("fr", "Français"),
Locale::German => ("de", "Deutsch"),
Locale::Portuguese => ("pt", "Português"),
}; };
Self { Self {
+9
View File
@@ -456,6 +456,15 @@ impl AppServiceFactory {
if let Err(e) = i18n_service.load_translations(Locale::Spanish).await { if let Err(e) = i18n_service.load_translations(Locale::Spanish).await {
tracing::warn!("Failed to load Spanish translations: {}", e); tracing::warn!("Failed to load Spanish translations: {}", e);
} }
if let Err(e) = i18n_service.load_translations(Locale::French).await {
tracing::warn!("Failed to load French translations: {}", e);
}
if let Err(e) = i18n_service.load_translations(Locale::German).await {
tracing::warn!("Failed to load German translations: {}", e);
}
if let Err(e) = i18n_service.load_translations(Locale::Portuguese).await {
tracing::warn!("Failed to load Portuguese translations: {}", e);
}
tracing::info!("Translations preloaded"); tracing::info!("Translations preloaded");
} }
+9
View File
@@ -22,6 +22,9 @@ pub type I18nResult<T> = Result<T, I18nError>;
pub enum Locale { pub enum Locale {
English, English,
Spanish, Spanish,
French,
German,
Portuguese,
} }
impl Locale { impl Locale {
@@ -30,6 +33,9 @@ impl Locale {
match self { match self {
Locale::English => "en", Locale::English => "en",
Locale::Spanish => "es", Locale::Spanish => "es",
Locale::French => "fr",
Locale::German => "de",
Locale::Portuguese => "pt",
} }
} }
@@ -38,6 +44,9 @@ impl Locale {
match code.to_lowercase().as_str() { match code.to_lowercase().as_str() {
"en" => Some(Locale::English), "en" => Some(Locale::English),
"es" => Some(Locale::Spanish), "es" => Some(Locale::Spanish),
"fr" => Some(Locale::French),
"de" => Some(Locale::German),
"pt" => Some(Locale::Portuguese),
_ => None, _ => None,
} }
} }
@@ -139,7 +139,7 @@ impl I18nService for FileSystemI18nService {
} }
async fn available_locales(&self) -> Vec<Locale> { async fn available_locales(&self) -> Vec<Locale> {
vec![Locale::English, Locale::Spanish] vec![Locale::English, Locale::Spanish, Locale::French, Locale::German, Locale::Portuguese]
} }
async fn is_supported(&self, locale: Locale) -> bool { async fn is_supported(&self, locale: Locale) -> bool {
+35
View File
@@ -621,6 +621,41 @@ select:focus {
transform: translateX(18px); transform: translateX(18px);
} }
.user-menu-admin {
color: #1d4ed8;
}
.user-menu-admin i {
color: #3b82f6;
}
.user-menu-admin:hover {
background: #eff6ff;
}
.user-menu-role-badge {
padding: 0 20px 4px;
}
.role-badge {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 11px;
font-weight: 600;
padding: 2px 10px;
border-radius: 10px;
}
.role-badge-admin {
background: #dbeafe;
color: #1d4ed8;
}
.role-badge i {
font-size: 10px;
}
.user-menu-logout { .user-menu-logout {
color: #ef4444; color: #ef4444;
margin-bottom: 4px; margin-bottom: 4px;
+12
View File
@@ -114,6 +114,9 @@
<div class="user-menu-email" id="user-menu-email">usuario@oxicloud.app</div> <div class="user-menu-email" id="user-menu-email">usuario@oxicloud.app</div>
</div> </div>
</div> </div>
<div class="user-menu-role-badge" id="user-menu-role-badge" style="display:none">
<span class="role-badge role-badge-admin"><i class="fas fa-shield-alt"></i> Admin</span>
</div>
<div class="user-menu-storage"> <div class="user-menu-storage">
<div class="user-menu-storage-label"> <div class="user-menu-storage-label">
<i class="fas fa-database"></i> <i class="fas fa-database"></i>
@@ -125,6 +128,15 @@
<div class="user-menu-storage-text" id="user-menu-storage-text">0% usado</div> <div class="user-menu-storage-text" id="user-menu-storage-text">0% usado</div>
</div> </div>
<div class="user-menu-divider"></div> <div class="user-menu-divider"></div>
<button class="user-menu-item user-menu-admin" id="user-menu-admin" style="display:none">
<i class="fas fa-cogs"></i>
<span data-i18n="user_menu.admin_panel">Panel de administración</span>
</button>
<button class="user-menu-item" id="user-menu-profile">
<i class="fas fa-user-circle"></i>
<span data-i18n="user_menu.profile">Mi perfil</span>
</button>
<div class="user-menu-divider" id="user-menu-admin-divider" style="display:none"></div>
<button class="user-menu-item" id="user-menu-theme"> <button class="user-menu-item" id="user-menu-theme">
<i class="fas fa-moon"></i> <i class="fas fa-moon"></i>
<span data-i18n="user_menu.appearance">Apariencia</span> <span data-i18n="user_menu.appearance">Apariencia</span>
+95
View File
@@ -143,6 +143,10 @@ function setupUserMenu() {
const logoutBtn = document.getElementById('user-menu-logout'); const logoutBtn = document.getElementById('user-menu-logout');
const themeBtn = document.getElementById('user-menu-theme'); const themeBtn = document.getElementById('user-menu-theme');
const aboutBtn = document.getElementById('user-menu-about'); const aboutBtn = document.getElementById('user-menu-about');
const adminBtn = document.getElementById('user-menu-admin');
const adminDivider = document.getElementById('user-menu-admin-divider');
const profileBtn = document.getElementById('user-menu-profile');
const roleBadge = document.getElementById('user-menu-role-badge');
if (!wrapper || !avatarBtn || !menu) return; if (!wrapper || !avatarBtn || !menu) return;
@@ -153,6 +157,13 @@ function setupUserMenu() {
wrapper.classList.toggle('open'); wrapper.classList.toggle('open');
if (!isOpen) { if (!isOpen) {
updateUserMenuData(); updateUserMenuData();
// Show/hide admin panel button based on user role
const USER_DATA_KEY = 'oxicloud_user';
const userData = JSON.parse(localStorage.getItem(USER_DATA_KEY) || '{}');
const isAdmin = userData.role === 'admin';
if (adminBtn) adminBtn.style.display = isAdmin ? 'flex' : 'none';
if (adminDivider) adminDivider.style.display = isAdmin ? 'block' : 'none';
if (roleBadge) roleBadge.style.display = isAdmin ? 'block' : 'none';
} }
}); });
@@ -192,6 +203,22 @@ function setupUserMenu() {
}); });
} }
// Admin panel link
if (adminBtn) {
adminBtn.addEventListener('click', () => {
wrapper.classList.remove('open');
window.location.href = '/admin.html';
});
}
// Profile button — shows user info modal
if (profileBtn) {
profileBtn.addEventListener('click', () => {
wrapper.classList.remove('open');
showUserProfileModal();
});
}
// About modal // About modal
if (aboutBtn) { if (aboutBtn) {
aboutBtn.addEventListener('click', () => { aboutBtn.addEventListener('click', () => {
@@ -1417,6 +1444,74 @@ async function refreshUserData() {
// Expose refreshUserData globally // Expose refreshUserData globally
window.refreshUserData = refreshUserData; window.refreshUserData = refreshUserData;
/**
* Show User Profile modal with account details
*/
function showUserProfileModal() {
const USER_DATA_KEY = 'oxicloud_user';
const userData = JSON.parse(localStorage.getItem(USER_DATA_KEY) || '{}');
const username = userData.username || 'Usuario';
const email = userData.email || '';
const role = userData.role || 'user';
const initials = username.substring(0, 2).toUpperCase();
const usedBytes = userData.storage_used_bytes || 0;
const quotaBytes = userData.storage_quota_bytes || 0;
const percentage = quotaBytes > 0 ? Math.min(Math.round((usedBytes / quotaBytes) * 100), 100) : 0;
const barColor = percentage > 90 ? '#ef4444' : percentage > 70 ? '#f59e0b' : '#22c55e';
const t = (key, fallback) => (window.i18n && window.i18n.t) ? window.i18n.t(key) || fallback : fallback;
// Remove existing modal if any
const existing = document.getElementById('profile-modal-overlay');
if (existing) existing.remove();
const overlay = document.createElement('div');
overlay.id = 'profile-modal-overlay';
overlay.className = 'about-modal-overlay';
overlay.innerHTML = `
<div class="about-modal" style="max-width:380px">
<div style="text-align:center;padding:20px 20px 0">
<div style="width:64px;height:64px;border-radius:50%;background:linear-gradient(135deg,#3b82f6,#6366f1);color:#fff;display:inline-flex;align-items:center;justify-content:center;font-size:24px;font-weight:700;margin-bottom:12px">${initials}</div>
<h3 style="margin:0;font-size:18px;color:#1a1a2e">${username}</h3>
<p style="margin:4px 0 0;font-size:13px;color:#64748b">${email}</p>
<span style="display:inline-block;margin-top:8px;padding:2px 10px;border-radius:10px;font-size:11px;font-weight:600;${
role === 'admin'
? 'background:#dbeafe;color:#1d4ed8'
: 'background:#f1f5f9;color:#64748b'
}">${role === 'admin' ? '🛡️ Admin' : '👤 ' + t('user_menu.role_user', 'User')}</span>
</div>
<div style="padding:16px 20px">
<div style="font-size:12px;color:#64748b;text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px">
<i class="fas fa-database" style="margin-right:4px"></i>${t('storage.title', 'Storage')}
</div>
<div style="background:#f1f5f9;border-radius:6px;height:8px;overflow:hidden;margin-bottom:4px">
<div style="height:100%;width:${percentage}%;background:${barColor};border-radius:6px;transition:width .3s"></div>
</div>
<div style="font-size:12px;color:#64748b;text-align:right">${percentage}% · ${formatFileSize(usedBytes)} / ${quotaBytes > 0 ? formatFileSize(quotaBytes) : '∞'}</div>
</div>
<div style="padding:0 20px 16px;display:flex;justify-content:center">
<button id="profile-modal-close" style="padding:8px 24px;border:1px solid #e2e8f0;border-radius:8px;background:#fff;color:#334155;font-size:13px;font-weight:600;cursor:pointer;transition:background .15s">${t('actions.close', 'Close')}</button>
</div>
</div>
`;
document.body.appendChild(overlay);
// Show with animation
requestAnimationFrame(() => overlay.classList.add('show'));
// Close handlers
overlay.querySelector('#profile-modal-close').addEventListener('click', () => {
overlay.classList.remove('show');
setTimeout(() => overlay.remove(), 200);
});
overlay.addEventListener('click', (e) => {
if (e.target === overlay) {
overlay.classList.remove('show');
setTimeout(() => overlay.remove(), 200);
}
});
}
/** /**
* Check if user is authenticated and load user's home folder * Check if user is authenticated and load user's home folder
*/ */
+3 -3
View File
@@ -74,9 +74,9 @@ const ALL_LANGUAGES = [
{ code: 'es', name: 'Spanish', nativeName: 'Español', flag: '🇪🇸', popular: true }, { code: 'es', name: 'Spanish', nativeName: 'Español', flag: '🇪🇸', popular: true },
{ code: 'zh', name: 'Chinese', nativeName: '中文', flag: '🇨🇳', popular: true }, { code: 'zh', name: 'Chinese', nativeName: '中文', flag: '🇨🇳', popular: true },
{ code: 'fa', name: 'Persian', nativeName: 'فارسی', flag: '🇮🇷', popular: true }, { code: 'fa', name: 'Persian', nativeName: 'فارسی', flag: '🇮🇷', popular: true },
{ code: 'fr', name: 'French', nativeName: 'Français', flag: '🇫🇷', popular: false }, { code: 'fr', name: 'French', nativeName: 'Français', flag: '🇫🇷', popular: true },
{ code: 'de', name: 'German', nativeName: 'Deutsch', flag: '🇩🇪', popular: false }, { code: 'de', name: 'German', nativeName: 'Deutsch', flag: '🇩🇪', popular: true },
{ code: 'pt', name: 'Portuguese', nativeName: 'Português', flag: '🇧🇷', popular: false }, { code: 'pt', name: 'Portuguese', nativeName: 'Português', flag: '🇧🇷', popular: true },
{ code: 'it', name: 'Italian', nativeName: 'Italiano', flag: '🇮🇹', popular: false }, { code: 'it', name: 'Italian', nativeName: 'Italiano', flag: '🇮🇹', popular: false },
{ code: 'ru', name: 'Russian', nativeName: 'Русский', flag: '🇷🇺', popular: false }, { code: 'ru', name: 'Russian', nativeName: 'Русский', flag: '🇷🇺', popular: false },
{ code: 'ja', name: 'Japanese', nativeName: '日本語', flag: '🇯🇵', popular: false }, { code: 'ja', name: 'Japanese', nativeName: '日本語', flag: '🇯🇵', popular: false },
+1 -1
View File
@@ -13,7 +13,7 @@ let currentLocale =
// Supported locales (languages that have locale files on the server) // Supported locales (languages that have locale files on the server)
// When a locale file is not found, the system gracefully falls back to English // When a locale file is not found, the system gracefully falls back to English
const supportedLocales = ['en', 'es', 'zh', 'fa']; const supportedLocales = ['en', 'es', 'zh', 'fa', 'fr', 'de', 'pt'];
// Fallback to English if locale is not supported // Fallback to English if locale is not supported
if (!supportedLocales.includes(currentLocale)) { if (!supportedLocales.includes(currentLocale)) {
+4 -1
View File
@@ -13,7 +13,10 @@ function getAvailableLanguages() {
{ code: 'en', name: 'English', flag: '🇬🇧' }, { code: 'en', name: 'English', flag: '🇬🇧' },
{ code: 'es', name: 'Español', flag: '🇪🇸' }, { code: 'es', name: 'Español', flag: '🇪🇸' },
{ code: 'zh', name: '中文', flag: '🇨🇳' }, { code: 'zh', name: '中文', flag: '🇨🇳' },
{ code: 'fa', name: 'فارسی', flag: '🇮🇷' } { code: 'fa', name: 'فارسی', flag: '🇮🇷' },
{ code: 'fr', name: 'Français', flag: '🇫🇷' },
{ code: 'de', name: 'Deutsch', flag: '🇩🇪' },
{ code: 'pt', name: 'Português', flag: '🇧🇷' }
]; ];
} }
+143 -137
View File
@@ -1,18 +1,18 @@
{ {
"app": { "app": {
"title": "OxiCloud", "title": "OxiCloud",
"description": "Minimalistisches System zur Cloud-Datenspeicherung" "description": "Minimalistisches Cloud-Speichersystem"
}, },
"nav": { "nav": {
"files": "Dateien", "files": "Dateien",
"shared": "Freigegebene Elemente", "shared": "Geteilt",
"recent": "Zuletzt verwendete Elemente", "recent": "Zuletzt verwendet",
"favorites": "Favoriten", "favorites": "Favoriten",
"trash": "Papierkorb" "trash": "Papierkorb"
}, },
"actions": { "actions": {
"search": "Dateien durchsuchen...", "search": "Dateien suchen...",
"new_folder": "Neuen Ordner erstellen", "new_folder": "Neuer Ordner",
"upload": "Hochladen", "upload": "Hochladen",
"upload_files": "Dateien hochladen", "upload_files": "Dateien hochladen",
"upload_folder": "Ordner hochladen", "upload_folder": "Ordner hochladen",
@@ -24,13 +24,13 @@
"view": "Anzeigen", "view": "Anzeigen",
"cancel": "Abbrechen", "cancel": "Abbrechen",
"confirm": "Bestätigen", "confirm": "Bestätigen",
"share": "Freigeben", "share": "Teilen",
"favorite": "Zu Favoriten hinzufügen", "favorite": "Zu Favoriten hinzufügen",
"unfavorite": "Aus Favoriten entfernen", "unfavorite": "Aus Favoriten entfernen",
"copy": "Kopieren", "copy": "Kopieren",
"notify": "Benachrichtigen", "notify": "Benachrichtigen",
"send": "Senden", "send": "Senden",
"clear_recent": "Verlauf löschen", "clear_recent": "Zuletzt verwendete löschen",
"logout": "Abmelden", "logout": "Abmelden",
"create": "Erstellen", "create": "Erstellen",
"search_btn": "Suchen", "search_btn": "Suchen",
@@ -39,55 +39,58 @@
"empty_trash": "Papierkorb leeren" "empty_trash": "Papierkorb leeren"
}, },
"user_menu": { "user_menu": {
"appearance": "Darstellung", "appearance": "Erscheinungsbild",
"about": "Über OxiCloud", "about": "Über OxiCloud",
"about_description": "Plattform zur Cloud-Datenspeicherung, entwickelt mit Rust und Clean Architecture. Leistungsstark, sicher und datenschutzorientiert." "about_description": "Cloud-Speicherplattform mit Rust und Clean Architecture. Schnell, sicher und privat.",
"admin_panel": "Admin-Panel",
"profile": "Mein Profil",
"role_user": "Benutzer"
}, },
"share": { "share": {
"dialogTitle": "Freigabelink erstellen", "dialogTitle": "Link teilen",
"linkLabel": "Freigabelink:", "linkLabel": "Geteilter Link:",
"copyLink": "Kopieren", "copyLink": "Kopieren",
"permissions": "Berechtigungen:", "permissions": "Berechtigungen:",
"permissionRead": "Leseberechtigung", "permissionRead": "Lesen",
"permissionWrite": "Schreibberechtigung", "permissionWrite": "Schreiben",
"permissionReshare": "Weiterfreigabeberechtigung", "permissionReshare": "Weiterteilen",
"password": "Passwortschutz:", "password": "Passwortschutz:",
"generatePassword": "Passwort generieren", "generatePassword": "Generieren",
"expiration": "Ablaufdatum:", "expiration": "Ablaufdatum:",
"update": "Freigabe aktualisieren", "update": "Freigabe aktualisieren",
"remove": "Freigabe entfernen", "remove": "Freigabe entfernen",
"notifyTitle": "Benachrichtigung versenden", "notifyTitle": "Benachrichtigung senden",
"notifyEmailLabel": "E-Mail-Adresse:", "notifyEmailLabel": "E-Mail-Adresse:",
"notifyMessageLabel": "Nachricht (optional):", "notifyMessageLabel": "Nachricht (optional):",
"notifySend": "Benachrichtigung senden", "notifySend": "Benachrichtigung senden",
"shareWithOthers": "Mit weiteren Personen teilen", "shareWithOthers": "Mit anderen teilen",
"sharePublicly": "Öffentlich freigeben", "sharePublicly": "Öffentlich teilen",
"shareSettings": "Freigabeeinstellungen", "shareSettings": "Freigabeeinstellungen",
"shareCopied": "Der Link wurde in die Zwischenablage kopiert.", "shareCopied": "Link in Zwischenablage kopiert",
"shareCreated": "Der Freigabelink wurde erfolgreich erstellt.", "shareCreated": "Freigabelink erfolgreich erstellt",
"shareUpdated": "Die Freigabeeinstellungen wurden erfolgreich aktualisiert.", "shareUpdated": "Freigabeeinstellungen aktualisiert",
"shareRemoved": "Die Freigabe wurde erfolgreich entfernt." "shareRemoved": "Freigabe erfolgreich entfernt"
}, },
"share_dialogTitle": "Freigabelink erstellen", "share_dialogTitle": "Link teilen",
"share_linkLabel": "Freigabelink:", "share_linkLabel": "Geteilter Link:",
"share_copyLink": "Kopieren", "share_copyLink": "Kopieren",
"share_permissions": "Berechtigungen:", "share_permissions": "Berechtigungen:",
"share_permissionRead": "Leseberechtigung", "share_permissionRead": "Lesen",
"share_permissionWrite": "Schreibberechtigung", "share_permissionWrite": "Schreiben",
"share_permissionReshare": "Weiterfreigabeberechtigung", "share_permissionReshare": "Weiterteilen",
"share_password": "Passwortschutz:", "share_password": "Passwortschutz:",
"share_generatePassword": "Passwort generieren", "share_generatePassword": "Generieren",
"share_expiration": "Ablaufdatum:", "share_expiration": "Ablaufdatum:",
"share_update": "Freigabe aktualisieren", "share_update": "Freigabe aktualisieren",
"share_remove": "Freigabe entfernen", "share_remove": "Freigabe entfernen",
"share_notifyTitle": "Benachrichtigung versenden", "share_notifyTitle": "Benachrichtigung senden",
"share_notifyEmailLabel": "E-Mail-Adresse:", "share_notifyEmailLabel": "E-Mail-Adresse:",
"share_notifyMessageLabel": "Nachricht (optional):", "share_notifyMessageLabel": "Nachricht (optional):",
"share_notifySend": "Benachrichtigung senden", "share_notifySend": "Benachrichtigung senden",
"shared": { "shared": {
"backToFiles": "Zurück zur Dateiansicht", "backToFiles": "Zurück zu Dateien",
"pageTitle": "Freigegebene Elemente", "pageTitle": "Geteilte Ressourcen",
"pageDescription": "Verwalten Sie Ihre freigegebenen Dateien und Ordner.", "pageDescription": "Verwalten Sie Ihre geteilten Dateien und Ordner",
"filterType": "Typ:", "filterType": "Typ:",
"filterAll": "Alle", "filterAll": "Alle",
"filterFiles": "Dateien", "filterFiles": "Dateien",
@@ -102,30 +105,31 @@
"colDateShared": "Freigabedatum", "colDateShared": "Freigabedatum",
"colExpiration": "Ablaufdatum", "colExpiration": "Ablaufdatum",
"colPermissions": "Berechtigungen", "colPermissions": "Berechtigungen",
"colPassword": "Passwortschutz", "colPassword": "Passwort",
"colActions": "Aktionen", "colActions": "Aktionen",
"emptyStateTitle": "Derzeit sind keine freigegebenen Elemente vorhanden.", "emptyStateTitle": "Noch keine geteilten Ressourcen",
"emptyStateDesc": "Freigegebene Dateien und Ordner werden hier angezeigt.", "emptyStateDesc": "Wenn Sie Dateien oder Ordner teilen, werden sie hier angezeigt",
"goToFiles": "Zur Dateiansicht wechseln", "goToFiles": "Zu Dateien gehen",
"typeFile": "Datei", "typeFile": "Datei",
"typeFolder": "Ordner", "typeFolder": "Ordner",
"noExpiration": "Kein Ablaufdatum festgelegt", "noExpiration": "Kein Ablaufdatum",
"hasPassword": "Ja", "hasPassword": "Ja",
"noPassword": "Nein", "noPassword": "Nein",
"editShare": "Freigabe bearbeiten", "editShare": "Freigabe bearbeiten",
"notifyShare": "Person benachrichtigen", "notifyShare": "Jemanden benachrichtigen",
"copyLink": "Link kopieren", "copyLink": "Link kopieren",
"removeShare": "Freigabe entfernen", "removeShare": "Freigabe entfernen",
"linkCopied": "Der Link wurde in die Zwischenablage kopiert.", "linkCopied": "Link in Zwischenablage kopiert!",
"linkCopyFailed": "Der Link konnte nicht kopiert werden.", "linkCopyFailed": "Link konnte nicht kopiert werden",
"itemUpdated": "Die Freigabeeinstellungen wurden erfolgreich aktualisiert.", "itemUpdated": "Freigabeeinstellungen aktualisiert",
"itemRemoved": "Die Freigabe wurde erfolgreich entfernt.", "itemRemoved": "Freigabe erfolgreich entfernt",
"invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein.", "invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein",
"notificationSent": "Die Benachrichtigung wurde erfolgreich versendet.", "notificationSent": "Benachrichtigung erfolgreich gesendet",
"notificationFailed": "Die Benachrichtigung konnte nicht versendet werden.", "notificationFailed": "Benachrichtigung konnte nicht gesendet werden"
"shared_backToFiles": "Zurück zur Dateiansicht", },
"shared_pageTitle": "Freigegebene Elemente", "shared_backToFiles": "Zurück zu Dateien",
"shared_pageDescription": "Verwalten Sie Ihre freigegebenen Dateien und Ordner.", "shared_pageTitle": "Geteilte Ressourcen",
"shared_pageDescription": "Verwalten Sie Ihre geteilten Dateien und Ordner",
"shared_filterType": "Typ:", "shared_filterType": "Typ:",
"shared_filterAll": "Alle", "shared_filterAll": "Alle",
"shared_filterFiles": "Dateien", "shared_filterFiles": "Dateien",
@@ -140,34 +144,33 @@
"shared_colDateShared": "Freigabedatum", "shared_colDateShared": "Freigabedatum",
"shared_colExpiration": "Ablaufdatum", "shared_colExpiration": "Ablaufdatum",
"shared_colPermissions": "Berechtigungen", "shared_colPermissions": "Berechtigungen",
"shared_colPassword": "Passwortschutz", "shared_colPassword": "Passwort",
"shared_colActions": "Aktionen", "shared_colActions": "Aktionen",
"shared_emptyStateTitle": "Derzeit sind keine freigegebenen Elemente vorhanden.", "shared_emptyStateTitle": "Noch keine geteilten Ressourcen",
"shared_emptyStateDesc": "Freigegebene Dateien und Ordner werden hier angezeigt.", "shared_emptyStateDesc": "Wenn Sie Dateien oder Ordner teilen, werden sie hier angezeigt",
"shared_goToFiles": "Zur Dateiansicht wechseln", "shared_goToFiles": "Zu Dateien gehen",
"shared_typeFile": "Datei", "shared_typeFile": "Datei",
"shared_typeFolder": "Ordner", "shared_typeFolder": "Ordner",
"shared_noExpiration": "Kein Ablaufdatum festgelegt", "shared_noExpiration": "Kein Ablaufdatum",
"shared_hasPassword": "Ja", "shared_hasPassword": "Ja",
"shared_noPassword": "Nein", "shared_noPassword": "Nein",
"shared_editShare": "Freigabe bearbeiten", "shared_editShare": "Freigabe bearbeiten",
"shared_notifyShare": "Person benachrichtigen", "shared_notifyShare": "Jemanden benachrichtigen",
"shared_copyLink": "Link kopieren", "shared_copyLink": "Link kopieren",
"shared_removeShare": "Freigabe entfernen", "shared_removeShare": "Freigabe entfernen",
"shared_linkCopied": "Der Link wurde in die Zwischenablage kopiert.", "shared_linkCopied": "Link in Zwischenablage kopiert!",
"shared_linkCopyFailed": "Der Link konnte nicht kopiert werden.", "shared_linkCopyFailed": "Link konnte nicht kopiert werden",
"shared_itemUpdated": "Die Freigabeeinstellungen wurden erfolgreich aktualisiert.", "shared_itemUpdated": "Freigabeeinstellungen aktualisiert",
"shared_itemRemoved": "Die Freigabe wurde erfolgreich entfernt.", "shared_itemRemoved": "Freigabe erfolgreich entfernt",
"shared_invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein.", "shared_invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein",
"shared_notificationSent": "Die Benachrichtigung wurde erfolgreich versendet.", "shared_notificationSent": "Benachrichtigung erfolgreich gesendet",
"shared_notificationFailed": "Die Benachrichtigung konnte nicht versendet werden." "shared_notificationFailed": "Benachrichtigung konnte nicht gesendet werden",
},
"files": { "files": {
"name": "Name", "name": "Name",
"type": "Typ", "type": "Typ",
"size": "Größe", "size": "Größe",
"modified": "Geändert am", "modified": "Geändert",
"no_files": "In diesem Ordner sind keine Dateien vorhanden.", "no_files": "Keine Dateien in diesem Ordner",
"loading": "Dateien werden geladen…", "loading": "Dateien werden geladen…",
"view_grid": "Rasteransicht", "view_grid": "Rasteransicht",
"view_list": "Listenansicht", "view_list": "Listenansicht",
@@ -176,8 +179,8 @@
"image": "Bild", "image": "Bild",
"video": "Video", "video": "Video",
"audio": "Audio", "audio": "Audio",
"pdf": "PDF-Dokument", "pdf": "PDF",
"text": "Textdokument", "text": "Text",
"folder": "Ordner" "folder": "Ordner"
} }
}, },
@@ -185,27 +188,27 @@
"rename_folder": "Ordner umbenennen", "rename_folder": "Ordner umbenennen",
"rename_file": "Datei umbenennen", "rename_file": "Datei umbenennen",
"new_name": "Neuer Name", "new_name": "Neuer Name",
"new_folder_title": "Neuen Ordner erstellen", "new_folder_title": "Neuer Ordner",
"folder_name": "Ordnername", "folder_name": "Ordnername",
"folder_placeholder": "Neuer Ordner", "folder_placeholder": "Mein Ordner",
"rename_title": "Umbenennen", "rename_title": "Umbenennen",
"move_file": "Datei verschieben", "move_file": "Datei verschieben",
"move_folder": "Ordner verschieben", "move_folder": "Ordner verschieben",
"select_destination": "Zielordner auswählen:", "select_destination": "Zielordner auswählen:",
"root": "Hauptverzeichnis", "root": "Stammverzeichnis",
"delete_confirmation": "Sind Sie sicher, dass Sie dieses Element löschen möchten", "delete_confirmation": "Sind Sie sicher, dass Sie löschen möchten",
"and_contents": "und alle enthaltenen Elemente", "and_contents": "und den gesamten Inhalt",
"no_undo": "Diese Aktion kann nicht rückgängig gemacht werden.", "no_undo": "Diese Aktion kann nicht rückgängig gemacht werden",
"confirm_title": "Aktion bestätigen", "confirm_title": "Aktion bestätigen",
"confirm_delete": "In den Papierkorb verschieben", "confirm_delete": "In Papierkorb verschieben",
"confirm_delete_file": "Möchten Sie die Datei \"{{name}}\" in den Papierkorb verschieben?", "confirm_delete_file": "Sind Sie sicher, dass Sie die Datei \"{{name}}\" in den Papierkorb verschieben möchten?",
"confirm_delete_folder": "Möchten Sie den Ordner \"{{name}}\" und alle enthaltenen Elemente in den Papierkorb verschieben?", "confirm_delete_folder": "Sind Sie sicher, dass Sie den Ordner \"{{name}}\" und seinen gesamten Inhalt in den Papierkorb verschieben möchten?",
"confirm_permanent_delete": "Endgültig löschen", "confirm_permanent_delete": "Endgültig löschen",
"confirm_permanent_delete_msg": "Möchten Sie dieses Element dauerhaft löschen? Diese Aktion kann nicht rückgängig gemacht werden.", "confirm_permanent_delete_msg": "Sind Sie sicher, dass Sie dieses Element endgültig löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.",
"confirm_empty_trash": "Papierkorb leeren", "confirm_empty_trash": "Papierkorb leeren",
"confirm_delete_share": "Freigabelink löschen", "confirm_delete_share": "Freigabelink löschen",
"confirm_delete_share_msg": "Möchten Sie diesen Freigabelink löschen?", "confirm_delete_share_msg": "Sind Sie sicher, dass Sie diesen Freigabelink löschen möchten?",
"share_file": "Datei freigeben", "share_file": "Datei teilen",
"existing_shares": "Bestehende Freigaben", "existing_shares": "Bestehende Freigaben",
"share_options": "Freigabeoptionen", "share_options": "Freigabeoptionen",
"password": "Passwort", "password": "Passwort",
@@ -217,78 +220,78 @@
"message": "Nachricht" "message": "Nachricht"
}, },
"dropzone": { "dropzone": {
"drag_files": "Ziehen Sie Dateien hierher oder klicken Sie, um Dateien auszuwählen.", "drag_files": "Dateien hierher ziehen oder klicken zum Auswählen",
"drop_files": "Legen Sie Dateien hier ab, um den Upload zu starten." "drop_files": "Dateien zum Hochladen ablegen"
}, },
"permissions": { "permissions": {
"read": "Leseberechtigung", "read": "Lesen",
"write": "Schreibberechtigung", "write": "Schreiben",
"reshare": "Weiterfreigabeberechtigung" "reshare": "Weiterteilen"
}, },
"errors": { "errors": {
"file_not_found": "Die Datei wurde nicht gefunden.", "file_not_found": "Datei nicht gefunden",
"folder_not_found": "Der Ordner wurde nicht gefunden.", "folder_not_found": "Ordner nicht gefunden",
"delete_error": "Beim Löschen ist ein Fehler aufgetreten.", "delete_error": "Fehler beim Löschen",
"upload_error": "Beim Hochladen ist ein Fehler aufgetreten.", "upload_error": "Fehler beim Hochladen",
"rename_error": "Beim Umbenennen ist ein Fehler aufgetreten.", "rename_error": "Fehler beim Umbenennen",
"move_error": "Beim Verschieben ist ein Fehler aufgetreten.", "move_error": "Fehler beim Verschieben",
"empty_name": "Der Name darf nicht leer sein.", "empty_name": "Der Name darf nicht leer sein",
"name_exists": "Eine Datei oder ein Ordner mit diesem Namen existiert bereits.", "name_exists": "Eine Datei oder ein Ordner mit diesem Namen existiert bereits",
"generic_error": "Es ist ein unerwarteter Fehler aufgetreten." "generic_error": "Ein Fehler ist aufgetreten"
}, },
"breadcrumb": { "breadcrumb": {
"home": "Startseite" "home": "Startseite"
}, },
"trash": { "trash": {
"empty_trash": "Papierkorb leeren", "empty_trash": "Papierkorb leeren",
"empty_state": "Der Papierkorb ist leer.", "empty_state": "Der Papierkorb ist leer",
"original_location": "Ursprünglicher Speicherort", "original_location": "Ursprünglicher Speicherort",
"deleted_date": "Löschdatum", "deleted_date": "Löschdatum",
"actions": "Aktionen", "actions": "Aktionen",
"restore": "Wiederherstellen", "restore": "Wiederherstellen",
"delete_permanently": "Endgültig löschen", "delete_permanently": "Endgültig löschen",
"empty_confirm": "Sind Sie sicher, dass Sie den Papierkorb leeren möchten? Alle enthaltenen Elemente werden dauerhaft gelöscht." "empty_confirm": "Sind Sie sicher, dass Sie den Papierkorb leeren möchten? Alle Elemente werden endgültig gelöscht."
}, },
"auth": { "auth": {
"login_title": "Anmelden", "login_title": "Anmelden",
"username": "Benutzername", "username": "Benutzername",
"username_placeholder": "Bitte geben Sie Ihren Benutzernamen ein", "username_placeholder": "Geben Sie Ihren Benutzernamen ein",
"password": "Passwort", "password": "Passwort",
"password_placeholder": "Bitte geben Sie Ihr Passwort ein", "password_placeholder": "Geben Sie Ihr Passwort ein",
"login_button": "Anmelden", "login_button": "Anmelden",
"no_account": "Verfügen Sie noch über kein Konto?", "no_account": "Kein Konto?",
"register": "Registrieren", "register": "Registrieren",
"admin_setup": "Erstmalige Nutzung?", "admin_setup": "Erstmalig?",
"setup": "Administrator einrichten", "setup": "Administrator einrichten",
"register_title": "Konto erstellen", "register_title": "Konto erstellen",
"email": "E-Mail-Adresse", "email": "E-Mail",
"email_placeholder": "Bitte geben Sie Ihre E-Mail-Adresse ein", "email_placeholder": "Geben Sie Ihre E-Mail ein",
"confirm_password": "Passwort bestätigen", "confirm_password": "Passwort bestätigen",
"confirm_password_placeholder": "Bitte bestätigen Sie Ihr Passwort", "confirm_password_placeholder": "Bestätigen Sie Ihr Passwort",
"register_button": "Konto erstellen", "register_button": "Konto erstellen",
"have_account": "Verfügen Sie bereits über ein Konto?", "have_account": "Bereits ein Konto?",
"login": "Anmelden", "login": "Anmelden",
"setup_title": "Ersteinrichtung", "setup_title": "Ersteinrichtung",
"setup_step1": "Administrator", "setup_step1": "Admin",
"setup_step2": "Systemkonfiguration", "setup_step2": "System",
"setup_step3": "Abschluss", "setup_step3": "Abgeschlossen",
"admin_username": "Administrator-Benutzername", "admin_username": "Admin-Benutzername",
"admin_email": "Administrator-E-Mail-Adresse", "admin_email": "Admin-E-Mail",
"admin_password": "Administrator-Passwort", "admin_password": "Admin-Passwort",
"create_admin": "Administrator erstellen", "create_admin": "Administrator erstellen",
"back_to_login": "System bereits eingerichtet?", "back_to_login": "Bereits eingerichtet?",
"admin_success": "Das Administrator-Konto wurde erfolgreich erstellt. Sie können sich nun anmelden.", "admin_success": "Administratorkonto erfolgreich erstellt! Sie können sich jetzt anmelden.",
"account_success": "Das Konto wurde erfolgreich erstellt. Sie können sich nun anmelden.", "account_success": "Konto erfolgreich erstellt! Sie können sich jetzt anmelden.",
"passwords_mismatch": "Die eingegebenen Passwörter stimmen nicht überein.", "passwords_mismatch": "Die Passwörter stimmen nicht überein",
"admin_create_error": "Beim Erstellen des Administrator-Kontos ist ein Fehler aufgetreten." "admin_create_error": "Fehler beim Erstellen des Administratorkontos"
}, },
"storage": { "storage": {
"title": "Speicher", "title": "Speicher",
"calculating": "Speicherplatz wird berechnet...", "calculating": "Berechnung...",
"used": "{{percentage}} % verwendet ({{used}} von {{total}})" "used": "{{percentage}}% verwendet ({{used}} / {{total}})"
}, },
"viewer": { "viewer": {
"unsupported_file": "Für diesen Dateityp ist keine Vorschau verfügbar.", "unsupported_file": "Dieser Dateityp kann nicht in der Vorschau angezeigt werden.",
"download_file": "Datei herunterladen", "download_file": "Datei herunterladen",
"zoom_in": "Vergrößern", "zoom_in": "Vergrößern",
"zoom_out": "Verkleinern", "zoom_out": "Verkleinern",
@@ -297,36 +300,39 @@
"language_selector": { "language_selector": {
"title": "Willkommen bei OxiCloud", "title": "Willkommen bei OxiCloud",
"subtitle": "Bitte wählen Sie Ihre Sprache", "subtitle": "Bitte wählen Sie Ihre Sprache",
"continue": "Fortfahren", "continue": "Weiter",
"languages": { "languages": {
"en": "Englisch", "en": "English",
"es": "Spanisch", "es": "Español",
"zh": "Chinesisch", "zh": "中文",
"fa": "Persisch" "fa": "فارسی",
"fr": "Français",
"de": "Deutsch",
"pt": "Português"
} }
}, },
"favorites": { "favorites": {
"empty_state": "Derzeit sind keine Favoriten vorhanden.", "empty_state": "Noch keine Favoriten",
"empty_hint": "Markieren Sie Dateien oder Ordner, um sie zu Ihren Favoriten hinzuzufügen.", "empty_hint": "Markieren Sie Dateien oder Ordner mit einem Stern, um sie zu Ihren Favoriten hinzuzufügen",
"add": "Zu Favoriten hinzufügen", "add": "Zu Favoriten hinzufügen",
"remove": "Aus Favoriten entfernen" "remove": "Aus Favoriten entfernen"
}, },
"recent": { "recent": {
"title": "Zuletzt verwendete Elemente", "title": "Zuletzt verwendet",
"clear": "Verlauf löschen", "clear": "Zuletzt verwendete löschen",
"accessed": "Geöffnet am", "accessed": "Zugegriffen",
"empty_state": "Keine zuletzt verwendeten Dateien vorhanden.", "empty_state": "Keine zuletzt verwendeten Dateien",
"empty_hint": "Geöffnete Dateien werden hier angezeigt." "empty_hint": "Dateien, die Sie öffnen, werden hier angezeigt"
}, },
"notifications": { "notifications": {
"file_renamed": "Datei wurde umbenannt.", "file_renamed": "Datei umbenannt",
"file_renamed_to": "Die Datei wurde in \"{{name}}\" umbenannt.", "file_renamed_to": "Datei umbenannt in \"{{name}}\"",
"folder_renamed": "Ordner wurde umbenannt.", "folder_renamed": "Ordner umbenannt",
"folder_renamed_to": "Der Ordner wurde in \"{{name}}\" umbenannt.", "folder_renamed_to": "Ordner umbenannt in \"{{name}}\"",
"file_uploaded": "Die Datei wurde erfolgreich hochgeladen.", "file_uploaded": "Datei hochgeladen",
"file_deleted": "Die Datei wurde in den Papierkorb verschoben.", "file_deleted": "Datei in Papierkorb verschoben",
"folder_deleted": "Der Ordner wurde in den Papierkorb verschoben.", "folder_deleted": "Ordner in Papierkorb verschoben",
"item_deleted_permanently": "Das Element wurde dauerhaft gelöscht.", "item_deleted_permanently": "Element endgültig gelöscht",
"trash_emptied": "Der Papierkorb wurde erfolgreich geleert." "trash_emptied": "Papierkorb erfolgreich geleert"
} }
} }
+8 -2
View File
@@ -41,7 +41,10 @@
"user_menu": { "user_menu": {
"appearance": "Appearance", "appearance": "Appearance",
"about": "About OxiCloud", "about": "About OxiCloud",
"about_description": "Cloud storage platform built with Rust & Clean Architecture. Fast, secure, and private." "about_description": "Cloud storage platform built with Rust & Clean Architecture. Fast, secure, and private.",
"admin_panel": "Admin Panel",
"profile": "My Profile",
"role_user": "User"
}, },
"share": { "share": {
"dialogTitle": "Share Link", "dialogTitle": "Share Link",
@@ -302,7 +305,10 @@
"en": "English", "en": "English",
"es": "Español", "es": "Español",
"zh": "中文", "zh": "中文",
"fa": "فارسی" "fa": "فارسی",
"fr": "Français",
"de": "Deutsch",
"pt": "Português"
} }
}, },
"favorites": { "favorites": {
+8 -2
View File
@@ -160,7 +160,10 @@
"user_menu": { "user_menu": {
"appearance": "Apariencia", "appearance": "Apariencia",
"about": "Acerca de OxiCloud", "about": "Acerca de OxiCloud",
"about_description": "Plataforma de almacenamiento en la nube creada con Rust y Arquitectura Limpia. Rápida, segura y privada." "about_description": "Plataforma de almacenamiento en la nube creada con Rust y Arquitectura Limpia. Rápida, segura y privada.",
"admin_panel": "Panel de administración",
"profile": "Mi perfil",
"role_user": "Usuario"
}, },
"files": { "files": {
"name": "Nombre", "name": "Nombre",
@@ -302,7 +305,10 @@
"en": "English", "en": "English",
"es": "Español", "es": "Español",
"zh": "中文", "zh": "中文",
"fa": "فارسی" "fa": "فارسی",
"fr": "Français",
"de": "Deutsch",
"pt": "Português"
} }
}, },
"favorites": { "favorites": {
+8 -2
View File
@@ -39,7 +39,10 @@
"user_menu": { "user_menu": {
"appearance": "ظاهر", "appearance": "ظاهر",
"about": "درباره OxiCloud", "about": "درباره OxiCloud",
"about_description": "پلتفرم ذخیره‌سازی ابری ساخته شده با Rust و معماری تمیز. سریع، امن و خصوصی." "about_description": "پلتفرم ذخیره‌سازی ابری ساخته شده با Rust و معماری تمیز. سریع، امن و خصوصی.",
"admin_panel": "پنل مدیریت",
"profile": "نمایه من",
"role_user": "کاربر"
}, },
"share": { "share": {
"dialogTitle": "پیوند هم‌رسانی", "dialogTitle": "پیوند هم‌رسانی",
@@ -288,7 +291,10 @@
"en": "English", "en": "English",
"es": "Español", "es": "Español",
"zh": "中文", "zh": "中文",
"fa": "فارسی" "fa": "فارسی",
"fr": "Français",
"de": "Deutsch",
"pt": "Português"
} }
}, },
"favorites": { "favorites": {
+338
View File
@@ -0,0 +1,338 @@
{
"app": {
"title": "OxiCloud",
"description": "Système de stockage cloud minimaliste"
},
"nav": {
"files": "Fichiers",
"shared": "Partagés",
"recent": "Récents",
"favorites": "Favoris",
"trash": "Corbeille"
},
"actions": {
"search": "Rechercher des fichiers...",
"new_folder": "Nouveau dossier",
"upload": "Téléverser",
"upload_files": "Téléverser des fichiers",
"upload_folder": "Téléverser un dossier",
"rename": "Renommer",
"move": "Déplacer vers...",
"move_to": "Déplacer vers",
"delete": "Supprimer",
"download": "Télécharger",
"view": "Afficher",
"cancel": "Annuler",
"confirm": "Confirmer",
"share": "Partager",
"favorite": "Ajouter aux favoris",
"unfavorite": "Retirer des favoris",
"copy": "Copier",
"notify": "Notifier",
"send": "Envoyer",
"clear_recent": "Effacer les récents",
"logout": "Se déconnecter",
"create": "Créer",
"search_btn": "Rechercher",
"close": "Fermer",
"delete_permanently": "Supprimer définitivement",
"empty_trash": "Vider la corbeille"
},
"user_menu": {
"appearance": "Apparence",
"about": "À propos d'OxiCloud",
"about_description": "Plateforme de stockage cloud construite avec Rust et Architecture Propre. Rapide, sécurisée et privée.",
"admin_panel": "Panneau d'administration",
"profile": "Mon profil",
"role_user": "Utilisateur"
},
"share": {
"dialogTitle": "Lien de partage",
"linkLabel": "Lien partagé :",
"copyLink": "Copier",
"permissions": "Permissions :",
"permissionRead": "Lecture",
"permissionWrite": "Écriture",
"permissionReshare": "Repartager",
"password": "Protection par mot de passe :",
"generatePassword": "Générer",
"expiration": "Date d'expiration :",
"update": "Mettre à jour le partage",
"remove": "Supprimer le partage",
"notifyTitle": "Envoyer une notification",
"notifyEmailLabel": "Adresse e-mail :",
"notifyMessageLabel": "Message (facultatif) :",
"notifySend": "Envoyer la notification",
"shareWithOthers": "Partager avec d'autres",
"sharePublicly": "Partager publiquement",
"shareSettings": "Paramètres de partage",
"shareCopied": "Lien copié dans le presse-papiers",
"shareCreated": "Lien de partage créé avec succès",
"shareUpdated": "Paramètres de partage mis à jour",
"shareRemoved": "Partage supprimé avec succès"
},
"share_dialogTitle": "Lien de partage",
"share_linkLabel": "Lien partagé :",
"share_copyLink": "Copier",
"share_permissions": "Permissions :",
"share_permissionRead": "Lecture",
"share_permissionWrite": "Écriture",
"share_permissionReshare": "Repartager",
"share_password": "Protection par mot de passe :",
"share_generatePassword": "Générer",
"share_expiration": "Date d'expiration :",
"share_update": "Mettre à jour le partage",
"share_remove": "Supprimer le partage",
"share_notifyTitle": "Envoyer une notification",
"share_notifyEmailLabel": "Adresse e-mail :",
"share_notifyMessageLabel": "Message (facultatif) :",
"share_notifySend": "Envoyer la notification",
"shared": {
"backToFiles": "Retour aux fichiers",
"pageTitle": "Ressources partagées",
"pageDescription": "Gérez vos fichiers et dossiers partagés",
"filterType": "Type :",
"filterAll": "Tous",
"filterFiles": "Fichiers",
"filterFolders": "Dossiers",
"sortBy": "Trier par :",
"sortByName": "Nom",
"sortByDate": "Date de partage",
"sortByExpiration": "Expiration",
"search": "Rechercher",
"colName": "Nom",
"colType": "Type",
"colDateShared": "Date de partage",
"colExpiration": "Expiration",
"colPermissions": "Permissions",
"colPassword": "Mot de passe",
"colActions": "Actions",
"emptyStateTitle": "Aucune ressource partagée",
"emptyStateDesc": "Lorsque vous partagerez des fichiers ou dossiers, ils apparaîtront ici",
"goToFiles": "Aller aux fichiers",
"typeFile": "Fichier",
"typeFolder": "Dossier",
"noExpiration": "Sans expiration",
"hasPassword": "Oui",
"noPassword": "Non",
"editShare": "Modifier le partage",
"notifyShare": "Notifier quelqu'un",
"copyLink": "Copier le lien",
"removeShare": "Supprimer le partage",
"linkCopied": "Lien copié dans le presse-papiers !",
"linkCopyFailed": "Erreur lors de la copie du lien",
"itemUpdated": "Paramètres de partage mis à jour",
"itemRemoved": "Partage supprimé avec succès",
"invalidEmail": "Veuillez entrer une adresse e-mail valide",
"notificationSent": "Notification envoyée avec succès",
"notificationFailed": "Erreur lors de l'envoi de la notification"
},
"shared_backToFiles": "Retour aux fichiers",
"shared_pageTitle": "Ressources partagées",
"shared_pageDescription": "Gérez vos fichiers et dossiers partagés",
"shared_filterType": "Type :",
"shared_filterAll": "Tous",
"shared_filterFiles": "Fichiers",
"shared_filterFolders": "Dossiers",
"shared_sortBy": "Trier par :",
"shared_sortByName": "Nom",
"shared_sortByDate": "Date de partage",
"shared_sortByExpiration": "Expiration",
"shared_search": "Rechercher",
"shared_colName": "Nom",
"shared_colType": "Type",
"shared_colDateShared": "Date de partage",
"shared_colExpiration": "Expiration",
"shared_colPermissions": "Permissions",
"shared_colPassword": "Mot de passe",
"shared_colActions": "Actions",
"shared_emptyStateTitle": "Aucune ressource partagée",
"shared_emptyStateDesc": "Lorsque vous partagerez des fichiers ou dossiers, ils apparaîtront ici",
"shared_goToFiles": "Aller aux fichiers",
"shared_typeFile": "Fichier",
"shared_typeFolder": "Dossier",
"shared_noExpiration": "Sans expiration",
"shared_hasPassword": "Oui",
"shared_noPassword": "Non",
"shared_editShare": "Modifier le partage",
"shared_notifyShare": "Notifier quelqu'un",
"shared_copyLink": "Copier le lien",
"shared_removeShare": "Supprimer le partage",
"shared_linkCopied": "Lien copié dans le presse-papiers !",
"shared_linkCopyFailed": "Erreur lors de la copie du lien",
"shared_itemUpdated": "Paramètres de partage mis à jour",
"shared_itemRemoved": "Partage supprimé avec succès",
"shared_invalidEmail": "Veuillez entrer une adresse e-mail valide",
"shared_notificationSent": "Notification envoyée avec succès",
"shared_notificationFailed": "Erreur lors de l'envoi de la notification",
"files": {
"name": "Nom",
"type": "Type",
"size": "Taille",
"modified": "Modifié",
"no_files": "Aucun fichier dans ce dossier",
"loading": "Chargement des fichiers…",
"view_grid": "Vue en grille",
"view_list": "Vue en liste",
"file_types": {
"document": "Document",
"image": "Image",
"video": "Vidéo",
"audio": "Audio",
"pdf": "PDF",
"text": "Texte",
"folder": "Dossier"
}
},
"dialogs": {
"rename_folder": "Renommer le dossier",
"rename_file": "Renommer le fichier",
"new_name": "Nouveau nom",
"new_folder_title": "Nouveau dossier",
"folder_name": "Nom du dossier",
"folder_placeholder": "Mon dossier",
"rename_title": "Renommer",
"move_file": "Déplacer le fichier",
"move_folder": "Déplacer le dossier",
"select_destination": "Sélectionnez le dossier de destination :",
"root": "Racine",
"delete_confirmation": "Êtes-vous sûr de vouloir supprimer",
"and_contents": "et tout son contenu",
"no_undo": "Cette action est irréversible",
"confirm_title": "Confirmer l'action",
"confirm_delete": "Déplacer vers la corbeille",
"confirm_delete_file": "Êtes-vous sûr de vouloir déplacer le fichier « {{name}} » vers la corbeille ?",
"confirm_delete_folder": "Êtes-vous sûr de vouloir déplacer le dossier « {{name}} » et tout son contenu vers la corbeille ?",
"confirm_permanent_delete": "Supprimer définitivement",
"confirm_permanent_delete_msg": "Êtes-vous sûr de vouloir supprimer définitivement cet élément ? Cette action est irréversible.",
"confirm_empty_trash": "Vider la corbeille",
"confirm_delete_share": "Supprimer le lien de partage",
"confirm_delete_share_msg": "Êtes-vous sûr de vouloir supprimer ce lien de partage ?",
"share_file": "Partager le fichier",
"existing_shares": "Partages existants",
"share_options": "Options de partage",
"password": "Mot de passe",
"expiration": "Expiration",
"permissions": "Permissions",
"generated_link": "Lien généré",
"notify": "Envoyer une notification",
"recipient": "Destinataire",
"message": "Message"
},
"dropzone": {
"drag_files": "Glissez des fichiers ici ou cliquez pour sélectionner",
"drop_files": "Déposez les fichiers pour téléverser"
},
"permissions": {
"read": "Lecture",
"write": "Écriture",
"reshare": "Repartager"
},
"errors": {
"file_not_found": "Fichier introuvable",
"folder_not_found": "Dossier introuvable",
"delete_error": "Erreur lors de la suppression",
"upload_error": "Erreur lors du téléversement",
"rename_error": "Erreur lors du renommage",
"move_error": "Erreur lors du déplacement",
"empty_name": "Le nom ne peut pas être vide",
"name_exists": "Un fichier ou dossier portant ce nom existe déjà",
"generic_error": "Une erreur est survenue"
},
"breadcrumb": {
"home": "Accueil"
},
"trash": {
"empty_trash": "Vider la corbeille",
"empty_state": "La corbeille est vide",
"original_location": "Emplacement d'origine",
"deleted_date": "Date de suppression",
"actions": "Actions",
"restore": "Restaurer",
"delete_permanently": "Supprimer définitivement",
"empty_confirm": "Êtes-vous sûr de vouloir vider la corbeille ? Tous les éléments seront définitivement supprimés."
},
"auth": {
"login_title": "Se connecter",
"username": "Nom d'utilisateur",
"username_placeholder": "Entrez votre nom d'utilisateur",
"password": "Mot de passe",
"password_placeholder": "Entrez votre mot de passe",
"login_button": "Se connecter",
"no_account": "Vous n'avez pas de compte ?",
"register": "S'inscrire",
"admin_setup": "Première fois ?",
"setup": "Configurer l'administrateur",
"register_title": "Créer un compte",
"email": "E-mail",
"email_placeholder": "Entrez votre e-mail",
"confirm_password": "Confirmer le mot de passe",
"confirm_password_placeholder": "Confirmez votre mot de passe",
"register_button": "Créer un compte",
"have_account": "Vous avez déjà un compte ?",
"login": "Se connecter",
"setup_title": "Configuration initiale",
"setup_step1": "Admin",
"setup_step2": "Système",
"setup_step3": "Terminé",
"admin_username": "Nom d'utilisateur administrateur",
"admin_email": "E-mail administrateur",
"admin_password": "Mot de passe administrateur",
"create_admin": "Créer l'administrateur",
"back_to_login": "Déjà configuré ?",
"admin_success": "Compte administrateur créé avec succès ! Vous pouvez maintenant vous connecter.",
"account_success": "Compte créé avec succès ! Vous pouvez maintenant vous connecter.",
"passwords_mismatch": "Les mots de passe ne correspondent pas",
"admin_create_error": "Erreur lors de la création du compte administrateur"
},
"storage": {
"title": "Stockage",
"calculating": "Calcul en cours...",
"used": "{{percentage}}% utilisé ({{used}} / {{total}})"
},
"viewer": {
"unsupported_file": "Ce type de fichier ne peut pas être prévisualisé.",
"download_file": "Télécharger le fichier",
"zoom_in": "Zoom avant",
"zoom_out": "Zoom arrière",
"zoom_reset": "Réinitialiser le zoom"
},
"language_selector": {
"title": "Bienvenue sur OxiCloud",
"subtitle": "Veuillez sélectionner votre langue",
"continue": "Continuer",
"languages": {
"en": "English",
"es": "Español",
"zh": "中文",
"fa": "فارسی",
"fr": "Français",
"de": "Deutsch",
"pt": "Português"
}
},
"favorites": {
"empty_state": "Aucun favori pour le moment",
"empty_hint": "Marquez des fichiers ou dossiers avec une étoile pour les ajouter à vos favoris",
"add": "Ajouter aux favoris",
"remove": "Retirer des favoris"
},
"recent": {
"title": "Récents",
"clear": "Effacer les récents",
"accessed": "Consulté",
"empty_state": "Aucun fichier récent",
"empty_hint": "Les fichiers que vous ouvrez apparaîtront ici"
},
"notifications": {
"file_renamed": "Fichier renommé",
"file_renamed_to": "Fichier renommé en « {{name}} »",
"folder_renamed": "Dossier renommé",
"folder_renamed_to": "Dossier renommé en « {{name}} »",
"file_uploaded": "Fichier téléversé",
"file_deleted": "Fichier déplacé vers la corbeille",
"folder_deleted": "Dossier déplacé vers la corbeille",
"item_deleted_permanently": "Élément supprimé définitivement",
"trash_emptied": "Corbeille vidée avec succès"
}
}
+338
View File
@@ -0,0 +1,338 @@
{
"app": {
"title": "OxiCloud",
"description": "Sistema de armazenamento em nuvem minimalista"
},
"nav": {
"files": "Arquivos",
"shared": "Compartilhados",
"recent": "Recentes",
"favorites": "Favoritos",
"trash": "Lixeira"
},
"actions": {
"search": "Pesquisar arquivos...",
"new_folder": "Nova pasta",
"upload": "Enviar",
"upload_files": "Enviar arquivos",
"upload_folder": "Enviar pasta",
"rename": "Renomear",
"move": "Mover para...",
"move_to": "Mover para",
"delete": "Excluir",
"download": "Baixar",
"view": "Visualizar",
"cancel": "Cancelar",
"confirm": "Confirmar",
"share": "Compartilhar",
"favorite": "Adicionar aos favoritos",
"unfavorite": "Remover dos favoritos",
"copy": "Copiar",
"notify": "Notificar",
"send": "Enviar",
"clear_recent": "Limpar recentes",
"logout": "Sair",
"create": "Criar",
"search_btn": "Pesquisar",
"close": "Fechar",
"delete_permanently": "Excluir permanentemente",
"empty_trash": "Esvaziar lixeira"
},
"user_menu": {
"appearance": "Aparência",
"about": "Sobre o OxiCloud",
"about_description": "Plataforma de armazenamento em nuvem construída com Rust e Arquitetura Limpa. Rápida, segura e privada.",
"admin_panel": "Painel de administração",
"profile": "Meu perfil",
"role_user": "Usuário"
},
"share": {
"dialogTitle": "Link de compartilhamento",
"linkLabel": "Link compartilhado:",
"copyLink": "Copiar",
"permissions": "Permissões:",
"permissionRead": "Leitura",
"permissionWrite": "Escrita",
"permissionReshare": "Recompartilhar",
"password": "Proteção por senha:",
"generatePassword": "Gerar",
"expiration": "Data de expiração:",
"update": "Atualizar compartilhamento",
"remove": "Remover compartilhamento",
"notifyTitle": "Enviar notificação",
"notifyEmailLabel": "Endereço de e-mail:",
"notifyMessageLabel": "Mensagem (opcional):",
"notifySend": "Enviar notificação",
"shareWithOthers": "Compartilhar com outros",
"sharePublicly": "Compartilhar publicamente",
"shareSettings": "Configurações de compartilhamento",
"shareCopied": "Link copiado para a área de transferência",
"shareCreated": "Link de compartilhamento criado com sucesso",
"shareUpdated": "Configurações de compartilhamento atualizadas",
"shareRemoved": "Compartilhamento removido com sucesso"
},
"share_dialogTitle": "Link de compartilhamento",
"share_linkLabel": "Link compartilhado:",
"share_copyLink": "Copiar",
"share_permissions": "Permissões:",
"share_permissionRead": "Leitura",
"share_permissionWrite": "Escrita",
"share_permissionReshare": "Recompartilhar",
"share_password": "Proteção por senha:",
"share_generatePassword": "Gerar",
"share_expiration": "Data de expiração:",
"share_update": "Atualizar compartilhamento",
"share_remove": "Remover compartilhamento",
"share_notifyTitle": "Enviar notificação",
"share_notifyEmailLabel": "Endereço de e-mail:",
"share_notifyMessageLabel": "Mensagem (opcional):",
"share_notifySend": "Enviar notificação",
"shared": {
"backToFiles": "Voltar aos arquivos",
"pageTitle": "Recursos compartilhados",
"pageDescription": "Gerencie seus arquivos e pastas compartilhados",
"filterType": "Tipo:",
"filterAll": "Todos",
"filterFiles": "Arquivos",
"filterFolders": "Pastas",
"sortBy": "Ordenar por:",
"sortByName": "Nome",
"sortByDate": "Data de compartilhamento",
"sortByExpiration": "Expiração",
"search": "Pesquisar",
"colName": "Nome",
"colType": "Tipo",
"colDateShared": "Data de compartilhamento",
"colExpiration": "Expiração",
"colPermissions": "Permissões",
"colPassword": "Senha",
"colActions": "Ações",
"emptyStateTitle": "Nenhum recurso compartilhado ainda",
"emptyStateDesc": "Quando você compartilhar arquivos ou pastas, eles aparecerão aqui",
"goToFiles": "Ir para arquivos",
"typeFile": "Arquivo",
"typeFolder": "Pasta",
"noExpiration": "Sem expiração",
"hasPassword": "Sim",
"noPassword": "Não",
"editShare": "Editar compartilhamento",
"notifyShare": "Notificar alguém",
"copyLink": "Copiar link",
"removeShare": "Remover compartilhamento",
"linkCopied": "Link copiado para a área de transferência!",
"linkCopyFailed": "Falha ao copiar o link",
"itemUpdated": "Configurações de compartilhamento atualizadas",
"itemRemoved": "Compartilhamento removido com sucesso",
"invalidEmail": "Por favor, insira um endereço de e-mail válido",
"notificationSent": "Notificação enviada com sucesso",
"notificationFailed": "Falha ao enviar a notificação"
},
"shared_backToFiles": "Voltar aos arquivos",
"shared_pageTitle": "Recursos compartilhados",
"shared_pageDescription": "Gerencie seus arquivos e pastas compartilhados",
"shared_filterType": "Tipo:",
"shared_filterAll": "Todos",
"shared_filterFiles": "Arquivos",
"shared_filterFolders": "Pastas",
"shared_sortBy": "Ordenar por:",
"shared_sortByName": "Nome",
"shared_sortByDate": "Data de compartilhamento",
"shared_sortByExpiration": "Expiração",
"shared_search": "Pesquisar",
"shared_colName": "Nome",
"shared_colType": "Tipo",
"shared_colDateShared": "Data de compartilhamento",
"shared_colExpiration": "Expiração",
"shared_colPermissions": "Permissões",
"shared_colPassword": "Senha",
"shared_colActions": "Ações",
"shared_emptyStateTitle": "Nenhum recurso compartilhado ainda",
"shared_emptyStateDesc": "Quando você compartilhar arquivos ou pastas, eles aparecerão aqui",
"shared_goToFiles": "Ir para arquivos",
"shared_typeFile": "Arquivo",
"shared_typeFolder": "Pasta",
"shared_noExpiration": "Sem expiração",
"shared_hasPassword": "Sim",
"shared_noPassword": "Não",
"shared_editShare": "Editar compartilhamento",
"shared_notifyShare": "Notificar alguém",
"shared_copyLink": "Copiar link",
"shared_removeShare": "Remover compartilhamento",
"shared_linkCopied": "Link copiado para a área de transferência!",
"shared_linkCopyFailed": "Falha ao copiar o link",
"shared_itemUpdated": "Configurações de compartilhamento atualizadas",
"shared_itemRemoved": "Compartilhamento removido com sucesso",
"shared_invalidEmail": "Por favor, insira um endereço de e-mail válido",
"shared_notificationSent": "Notificação enviada com sucesso",
"shared_notificationFailed": "Falha ao enviar a notificação",
"files": {
"name": "Nome",
"type": "Tipo",
"size": "Tamanho",
"modified": "Modificado",
"no_files": "Nenhum arquivo nesta pasta",
"loading": "Carregando arquivos…",
"view_grid": "Visualização em grade",
"view_list": "Visualização em lista",
"file_types": {
"document": "Documento",
"image": "Imagem",
"video": "Vídeo",
"audio": "Áudio",
"pdf": "PDF",
"text": "Texto",
"folder": "Pasta"
}
},
"dialogs": {
"rename_folder": "Renomear pasta",
"rename_file": "Renomear arquivo",
"new_name": "Novo nome",
"new_folder_title": "Nova pasta",
"folder_name": "Nome da pasta",
"folder_placeholder": "Minha pasta",
"rename_title": "Renomear",
"move_file": "Mover arquivo",
"move_folder": "Mover pasta",
"select_destination": "Selecione a pasta de destino:",
"root": "Raiz",
"delete_confirmation": "Tem certeza de que deseja excluir",
"and_contents": "e todo o seu conteúdo",
"no_undo": "Esta ação não pode ser desfeita",
"confirm_title": "Confirmar ação",
"confirm_delete": "Mover para a lixeira",
"confirm_delete_file": "Tem certeza de que deseja mover o arquivo \"{{name}}\" para a lixeira?",
"confirm_delete_folder": "Tem certeza de que deseja mover a pasta \"{{name}}\" e todo o seu conteúdo para a lixeira?",
"confirm_permanent_delete": "Excluir permanentemente",
"confirm_permanent_delete_msg": "Tem certeza de que deseja excluir permanentemente este item? Esta ação não pode ser desfeita.",
"confirm_empty_trash": "Esvaziar lixeira",
"confirm_delete_share": "Excluir link de compartilhamento",
"confirm_delete_share_msg": "Tem certeza de que deseja excluir este link de compartilhamento?",
"share_file": "Compartilhar arquivo",
"existing_shares": "Compartilhamentos existentes",
"share_options": "Opções de compartilhamento",
"password": "Senha",
"expiration": "Expiração",
"permissions": "Permissões",
"generated_link": "Link gerado",
"notify": "Enviar notificação",
"recipient": "Destinatário",
"message": "Mensagem"
},
"dropzone": {
"drag_files": "Arraste arquivos aqui ou clique para selecionar",
"drop_files": "Solte os arquivos para enviar"
},
"permissions": {
"read": "Leitura",
"write": "Escrita",
"reshare": "Recompartilhar"
},
"errors": {
"file_not_found": "Arquivo não encontrado",
"folder_not_found": "Pasta não encontrada",
"delete_error": "Erro ao excluir",
"upload_error": "Erro ao enviar o arquivo",
"rename_error": "Erro ao renomear",
"move_error": "Erro ao mover",
"empty_name": "O nome não pode estar vazio",
"name_exists": "Já existe um arquivo ou pasta com esse nome",
"generic_error": "Ocorreu um erro"
},
"breadcrumb": {
"home": "Início"
},
"trash": {
"empty_trash": "Esvaziar lixeira",
"empty_state": "A lixeira está vazia",
"original_location": "Local original",
"deleted_date": "Data de exclusão",
"actions": "Ações",
"restore": "Restaurar",
"delete_permanently": "Excluir permanentemente",
"empty_confirm": "Tem certeza de que deseja esvaziar a lixeira? Todos os itens serão excluídos permanentemente."
},
"auth": {
"login_title": "Entrar",
"username": "Usuário",
"username_placeholder": "Digite seu nome de usuário",
"password": "Senha",
"password_placeholder": "Digite sua senha",
"login_button": "Entrar",
"no_account": "Não tem uma conta?",
"register": "Cadastre-se",
"admin_setup": "Primeira vez?",
"setup": "Configurar administrador",
"register_title": "Criar conta",
"email": "E-mail",
"email_placeholder": "Digite seu e-mail",
"confirm_password": "Confirmar senha",
"confirm_password_placeholder": "Confirme sua senha",
"register_button": "Criar conta",
"have_account": "Já tem uma conta?",
"login": "Entrar",
"setup_title": "Configuração inicial",
"setup_step1": "Admin",
"setup_step2": "Sistema",
"setup_step3": "Concluído",
"admin_username": "Usuário administrador",
"admin_email": "E-mail do administrador",
"admin_password": "Senha do administrador",
"create_admin": "Criar administrador",
"back_to_login": "Já configurado?",
"admin_success": "Conta de administrador criada com sucesso! Agora você pode entrar.",
"account_success": "Conta criada com sucesso! Agora você pode entrar.",
"passwords_mismatch": "As senhas não coincidem",
"admin_create_error": "Erro ao criar conta de administrador"
},
"storage": {
"title": "Armazenamento",
"calculating": "Calculando...",
"used": "{{percentage}}% usado ({{used}} / {{total}})"
},
"viewer": {
"unsupported_file": "Este tipo de arquivo não pode ser visualizado.",
"download_file": "Baixar arquivo",
"zoom_in": "Ampliar",
"zoom_out": "Reduzir",
"zoom_reset": "Redefinir zoom"
},
"language_selector": {
"title": "Bem-vindo ao OxiCloud",
"subtitle": "Por favor, selecione seu idioma",
"continue": "Continuar",
"languages": {
"en": "English",
"es": "Español",
"zh": "中文",
"fa": "فارسی",
"fr": "Français",
"de": "Deutsch",
"pt": "Português"
}
},
"favorites": {
"empty_state": "Nenhum favorito ainda",
"empty_hint": "Marque arquivos ou pastas com estrela para adicioná-los aos seus favoritos",
"add": "Adicionar aos favoritos",
"remove": "Remover dos favoritos"
},
"recent": {
"title": "Recentes",
"clear": "Limpar recentes",
"accessed": "Acessado",
"empty_state": "Nenhum arquivo recente",
"empty_hint": "Os arquivos que você abrir aparecerão aqui"
},
"notifications": {
"file_renamed": "Arquivo renomeado",
"file_renamed_to": "Arquivo renomeado para \"{{name}}\"",
"folder_renamed": "Pasta renomeada",
"folder_renamed_to": "Pasta renomeada para \"{{name}}\"",
"file_uploaded": "Arquivo enviado",
"file_deleted": "Arquivo movido para a lixeira",
"folder_deleted": "Pasta movida para a lixeira",
"item_deleted_permanently": "Item excluído permanentemente",
"trash_emptied": "Lixeira esvaziada com sucesso"
}
}
+8 -2
View File
@@ -39,7 +39,10 @@
"user_menu": { "user_menu": {
"appearance": "外观", "appearance": "外观",
"about": "关于 OxiCloud", "about": "关于 OxiCloud",
"about_description": "基于 Rust 和整洁架构构建的云存储平台。快速、安全、私密。" "about_description": "基于 Rust 和整洁架构构建的云存储平台。快速、安全、私密。",
"admin_panel": "管理面板",
"profile": "我的资料",
"role_user": "用户"
}, },
"share": { "share": {
"dialogTitle": "共享链接", "dialogTitle": "共享链接",
@@ -250,7 +253,10 @@
"en": "English", "en": "English",
"es": "Español", "es": "Español",
"zh": "中文", "zh": "中文",
"fa": "فارسی" "fa": "فارسی",
"fr": "Français",
"de": "Deutsch",
"pt": "Português"
} }
}, },
"favorites": { "favorites": {