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:
@@ -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):"
|
||||
@@ -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
|
||||
@@ -1,6 +1,5 @@
|
||||
name: Docker Build and Test
|
||||
|
||||
# Trigger on push to main branch or on pull requests
|
||||
on:
|
||||
push:
|
||||
branches: [ "main", "dev" ]
|
||||
@@ -8,21 +7,18 @@ on:
|
||||
branches: [ "main", "dev" ]
|
||||
|
||||
jobs:
|
||||
# Build and test Docker image but don't push
|
||||
build-and-test:
|
||||
name: Build and Test Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 120 # Aumentado a 2 horas para dar más tiempo a la compilación
|
||||
timeout-minutes: 45
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Set up Docker Buildx
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
# Extract metadata (tags, labels) for Docker
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
@@ -33,7 +29,6 @@ jobs:
|
||||
type=ref,event=pr
|
||||
type=sha
|
||||
|
||||
# Build Docker image but don't push
|
||||
- name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
@@ -41,16 +36,41 @@ jobs:
|
||||
push: false
|
||||
load: true
|
||||
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: Test Docker image
|
||||
- name: Verify image starts correctly
|
||||
run: |
|
||||
docker run --rm test/oxicloud:test --version || true
|
||||
docker run --rm test/oxicloud:test --help || true
|
||||
# Start the container in background
|
||||
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
|
||||
echo "✅ Checking Docker image layers and size"
|
||||
docker image inspect test/oxicloud:test
|
||||
# Give it a moment to start (or fail)
|
||||
sleep 3
|
||||
|
||||
# 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"
|
||||
|
||||
@@ -6,63 +6,47 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Versión del release'
|
||||
required: false
|
||||
default: '0.1.0-rc1'
|
||||
description: 'Version tag to publish (e.g. v0.3.0)'
|
||||
required: true
|
||||
|
||||
env:
|
||||
REGISTRY_IMAGE: diocrafts/oxicloud
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
# Run tests before publishing
|
||||
test:
|
||||
name: Pre-publish Tests
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [amd64, arm64]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- 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:
|
||||
- name: Checkout
|
||||
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
|
||||
id: version
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
|
||||
echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
|
||||
VERSION="${{ github.event.inputs.version }}"
|
||||
else
|
||||
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
||||
VERSION="${GITHUB_REF#refs/tags/}"
|
||||
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
|
||||
uses: docker/build-push-action@v5
|
||||
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 QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
@@ -73,9 +57,22 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
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: |
|
||||
docker buildx imagetools create \
|
||||
-t diocrafts/oxicloud:${{ env.VERSION }} \
|
||||
diocrafts/oxicloud:${{ env.VERSION }}@linux/amd64 \
|
||||
diocrafts/oxicloud:${{ env.VERSION }}@linux/arm64
|
||||
docker pull ${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }}
|
||||
docker image inspect ${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }}
|
||||
echo "✅ Image ${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }} published successfully"
|
||||
|
||||
@@ -16,6 +16,9 @@ impl From<Locale> for LocaleDto {
|
||||
let (code, name) = match locale {
|
||||
Locale::English => ("en", "English"),
|
||||
Locale::Spanish => ("es", "Español"),
|
||||
Locale::French => ("fr", "Français"),
|
||||
Locale::German => ("de", "Deutsch"),
|
||||
Locale::Portuguese => ("pt", "Português"),
|
||||
};
|
||||
|
||||
Self {
|
||||
|
||||
@@ -456,6 +456,15 @@ impl AppServiceFactory {
|
||||
if let Err(e) = i18n_service.load_translations(Locale::Spanish).await {
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@ pub type I18nResult<T> = Result<T, I18nError>;
|
||||
pub enum Locale {
|
||||
English,
|
||||
Spanish,
|
||||
French,
|
||||
German,
|
||||
Portuguese,
|
||||
}
|
||||
|
||||
impl Locale {
|
||||
@@ -30,6 +33,9 @@ impl Locale {
|
||||
match self {
|
||||
Locale::English => "en",
|
||||
Locale::Spanish => "es",
|
||||
Locale::French => "fr",
|
||||
Locale::German => "de",
|
||||
Locale::Portuguese => "pt",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +44,9 @@ impl Locale {
|
||||
match code.to_lowercase().as_str() {
|
||||
"en" => Some(Locale::English),
|
||||
"es" => Some(Locale::Spanish),
|
||||
"fr" => Some(Locale::French),
|
||||
"de" => Some(Locale::German),
|
||||
"pt" => Some(Locale::Portuguese),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ impl I18nService for FileSystemI18nService {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@@ -621,6 +621,41 @@ select:focus {
|
||||
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 {
|
||||
color: #ef4444;
|
||||
margin-bottom: 4px;
|
||||
|
||||
@@ -114,6 +114,9 @@
|
||||
<div class="user-menu-email" id="user-menu-email">usuario@oxicloud.app</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-label">
|
||||
<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>
|
||||
<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">
|
||||
<i class="fas fa-moon"></i>
|
||||
<span data-i18n="user_menu.appearance">Apariencia</span>
|
||||
|
||||
@@ -143,6 +143,10 @@ function setupUserMenu() {
|
||||
const logoutBtn = document.getElementById('user-menu-logout');
|
||||
const themeBtn = document.getElementById('user-menu-theme');
|
||||
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;
|
||||
|
||||
@@ -153,6 +157,13 @@ function setupUserMenu() {
|
||||
wrapper.classList.toggle('open');
|
||||
if (!isOpen) {
|
||||
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
|
||||
if (aboutBtn) {
|
||||
aboutBtn.addEventListener('click', () => {
|
||||
@@ -1417,6 +1444,74 @@ async function refreshUserData() {
|
||||
// Expose refreshUserData globally
|
||||
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
|
||||
*/
|
||||
|
||||
+3
-3
@@ -74,9 +74,9 @@ const ALL_LANGUAGES = [
|
||||
{ code: 'es', name: 'Spanish', nativeName: 'Español', flag: '🇪🇸', popular: true },
|
||||
{ code: 'zh', name: 'Chinese', nativeName: '中文', flag: '🇨🇳', popular: true },
|
||||
{ code: 'fa', name: 'Persian', nativeName: 'فارسی', flag: '🇮🇷', popular: true },
|
||||
{ code: 'fr', name: 'French', nativeName: 'Français', flag: '🇫🇷', popular: false },
|
||||
{ code: 'de', name: 'German', nativeName: 'Deutsch', flag: '🇩🇪', popular: false },
|
||||
{ code: 'pt', name: 'Portuguese', nativeName: 'Português', flag: '🇧🇷', popular: false },
|
||||
{ code: 'fr', name: 'French', nativeName: 'Français', flag: '🇫🇷', popular: true },
|
||||
{ code: 'de', name: 'German', nativeName: 'Deutsch', flag: '🇩🇪', popular: true },
|
||||
{ code: 'pt', name: 'Portuguese', nativeName: 'Português', flag: '🇧🇷', popular: true },
|
||||
{ code: 'it', name: 'Italian', nativeName: 'Italiano', flag: '🇮🇹', popular: false },
|
||||
{ code: 'ru', name: 'Russian', nativeName: 'Русский', flag: '🇷🇺', popular: false },
|
||||
{ code: 'ja', name: 'Japanese', nativeName: '日本語', flag: '🇯🇵', popular: false },
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ let currentLocale =
|
||||
|
||||
// Supported locales (languages that have locale files on the server)
|
||||
// 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
|
||||
if (!supportedLocales.includes(currentLocale)) {
|
||||
|
||||
@@ -13,7 +13,10 @@ function getAvailableLanguages() {
|
||||
{ code: 'en', name: 'English', flag: '🇬🇧' },
|
||||
{ code: 'es', name: 'Español', 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
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "OxiCloud",
|
||||
"description": "Minimalistisches System zur Cloud-Datenspeicherung"
|
||||
"description": "Minimalistisches Cloud-Speichersystem"
|
||||
},
|
||||
"nav": {
|
||||
"files": "Dateien",
|
||||
"shared": "Freigegebene Elemente",
|
||||
"recent": "Zuletzt verwendete Elemente",
|
||||
"shared": "Geteilt",
|
||||
"recent": "Zuletzt verwendet",
|
||||
"favorites": "Favoriten",
|
||||
"trash": "Papierkorb"
|
||||
},
|
||||
"actions": {
|
||||
"search": "Dateien durchsuchen...",
|
||||
"new_folder": "Neuen Ordner erstellen",
|
||||
"search": "Dateien suchen...",
|
||||
"new_folder": "Neuer Ordner",
|
||||
"upload": "Hochladen",
|
||||
"upload_files": "Dateien hochladen",
|
||||
"upload_folder": "Ordner hochladen",
|
||||
@@ -24,13 +24,13 @@
|
||||
"view": "Anzeigen",
|
||||
"cancel": "Abbrechen",
|
||||
"confirm": "Bestätigen",
|
||||
"share": "Freigeben",
|
||||
"share": "Teilen",
|
||||
"favorite": "Zu Favoriten hinzufügen",
|
||||
"unfavorite": "Aus Favoriten entfernen",
|
||||
"copy": "Kopieren",
|
||||
"notify": "Benachrichtigen",
|
||||
"send": "Senden",
|
||||
"clear_recent": "Verlauf löschen",
|
||||
"clear_recent": "Zuletzt verwendete löschen",
|
||||
"logout": "Abmelden",
|
||||
"create": "Erstellen",
|
||||
"search_btn": "Suchen",
|
||||
@@ -39,55 +39,58 @@
|
||||
"empty_trash": "Papierkorb leeren"
|
||||
},
|
||||
"user_menu": {
|
||||
"appearance": "Darstellung",
|
||||
"appearance": "Erscheinungsbild",
|
||||
"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": {
|
||||
"dialogTitle": "Freigabelink erstellen",
|
||||
"linkLabel": "Freigabelink:",
|
||||
"dialogTitle": "Link teilen",
|
||||
"linkLabel": "Geteilter Link:",
|
||||
"copyLink": "Kopieren",
|
||||
"permissions": "Berechtigungen:",
|
||||
"permissionRead": "Leseberechtigung",
|
||||
"permissionWrite": "Schreibberechtigung",
|
||||
"permissionReshare": "Weiterfreigabeberechtigung",
|
||||
"permissionRead": "Lesen",
|
||||
"permissionWrite": "Schreiben",
|
||||
"permissionReshare": "Weiterteilen",
|
||||
"password": "Passwortschutz:",
|
||||
"generatePassword": "Passwort generieren",
|
||||
"generatePassword": "Generieren",
|
||||
"expiration": "Ablaufdatum:",
|
||||
"update": "Freigabe aktualisieren",
|
||||
"remove": "Freigabe entfernen",
|
||||
"notifyTitle": "Benachrichtigung versenden",
|
||||
"notifyTitle": "Benachrichtigung senden",
|
||||
"notifyEmailLabel": "E-Mail-Adresse:",
|
||||
"notifyMessageLabel": "Nachricht (optional):",
|
||||
"notifySend": "Benachrichtigung senden",
|
||||
"shareWithOthers": "Mit weiteren Personen teilen",
|
||||
"sharePublicly": "Öffentlich freigeben",
|
||||
"shareWithOthers": "Mit anderen teilen",
|
||||
"sharePublicly": "Öffentlich teilen",
|
||||
"shareSettings": "Freigabeeinstellungen",
|
||||
"shareCopied": "Der Link wurde in die Zwischenablage kopiert.",
|
||||
"shareCreated": "Der Freigabelink wurde erfolgreich erstellt.",
|
||||
"shareUpdated": "Die Freigabeeinstellungen wurden erfolgreich aktualisiert.",
|
||||
"shareRemoved": "Die Freigabe wurde erfolgreich entfernt."
|
||||
"shareCopied": "Link in Zwischenablage kopiert",
|
||||
"shareCreated": "Freigabelink erfolgreich erstellt",
|
||||
"shareUpdated": "Freigabeeinstellungen aktualisiert",
|
||||
"shareRemoved": "Freigabe erfolgreich entfernt"
|
||||
},
|
||||
"share_dialogTitle": "Freigabelink erstellen",
|
||||
"share_linkLabel": "Freigabelink:",
|
||||
"share_dialogTitle": "Link teilen",
|
||||
"share_linkLabel": "Geteilter Link:",
|
||||
"share_copyLink": "Kopieren",
|
||||
"share_permissions": "Berechtigungen:",
|
||||
"share_permissionRead": "Leseberechtigung",
|
||||
"share_permissionWrite": "Schreibberechtigung",
|
||||
"share_permissionReshare": "Weiterfreigabeberechtigung",
|
||||
"share_permissionRead": "Lesen",
|
||||
"share_permissionWrite": "Schreiben",
|
||||
"share_permissionReshare": "Weiterteilen",
|
||||
"share_password": "Passwortschutz:",
|
||||
"share_generatePassword": "Passwort generieren",
|
||||
"share_generatePassword": "Generieren",
|
||||
"share_expiration": "Ablaufdatum:",
|
||||
"share_update": "Freigabe aktualisieren",
|
||||
"share_remove": "Freigabe entfernen",
|
||||
"share_notifyTitle": "Benachrichtigung versenden",
|
||||
"share_notifyTitle": "Benachrichtigung senden",
|
||||
"share_notifyEmailLabel": "E-Mail-Adresse:",
|
||||
"share_notifyMessageLabel": "Nachricht (optional):",
|
||||
"share_notifySend": "Benachrichtigung senden",
|
||||
"shared": {
|
||||
"backToFiles": "Zurück zur Dateiansicht",
|
||||
"pageTitle": "Freigegebene Elemente",
|
||||
"pageDescription": "Verwalten Sie Ihre freigegebenen Dateien und Ordner.",
|
||||
"backToFiles": "Zurück zu Dateien",
|
||||
"pageTitle": "Geteilte Ressourcen",
|
||||
"pageDescription": "Verwalten Sie Ihre geteilten Dateien und Ordner",
|
||||
"filterType": "Typ:",
|
||||
"filterAll": "Alle",
|
||||
"filterFiles": "Dateien",
|
||||
@@ -102,30 +105,31 @@
|
||||
"colDateShared": "Freigabedatum",
|
||||
"colExpiration": "Ablaufdatum",
|
||||
"colPermissions": "Berechtigungen",
|
||||
"colPassword": "Passwortschutz",
|
||||
"colPassword": "Passwort",
|
||||
"colActions": "Aktionen",
|
||||
"emptyStateTitle": "Derzeit sind keine freigegebenen Elemente vorhanden.",
|
||||
"emptyStateDesc": "Freigegebene Dateien und Ordner werden hier angezeigt.",
|
||||
"goToFiles": "Zur Dateiansicht wechseln",
|
||||
"emptyStateTitle": "Noch keine geteilten Ressourcen",
|
||||
"emptyStateDesc": "Wenn Sie Dateien oder Ordner teilen, werden sie hier angezeigt",
|
||||
"goToFiles": "Zu Dateien gehen",
|
||||
"typeFile": "Datei",
|
||||
"typeFolder": "Ordner",
|
||||
"noExpiration": "Kein Ablaufdatum festgelegt",
|
||||
"noExpiration": "Kein Ablaufdatum",
|
||||
"hasPassword": "Ja",
|
||||
"noPassword": "Nein",
|
||||
"editShare": "Freigabe bearbeiten",
|
||||
"notifyShare": "Person benachrichtigen",
|
||||
"notifyShare": "Jemanden benachrichtigen",
|
||||
"copyLink": "Link kopieren",
|
||||
"removeShare": "Freigabe entfernen",
|
||||
"linkCopied": "Der Link wurde in die Zwischenablage kopiert.",
|
||||
"linkCopyFailed": "Der Link konnte nicht kopiert werden.",
|
||||
"itemUpdated": "Die Freigabeeinstellungen wurden erfolgreich aktualisiert.",
|
||||
"itemRemoved": "Die Freigabe wurde erfolgreich entfernt.",
|
||||
"invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein.",
|
||||
"notificationSent": "Die Benachrichtigung wurde erfolgreich versendet.",
|
||||
"notificationFailed": "Die Benachrichtigung konnte nicht versendet werden.",
|
||||
"shared_backToFiles": "Zurück zur Dateiansicht",
|
||||
"shared_pageTitle": "Freigegebene Elemente",
|
||||
"shared_pageDescription": "Verwalten Sie Ihre freigegebenen Dateien und Ordner.",
|
||||
"linkCopied": "Link in Zwischenablage kopiert!",
|
||||
"linkCopyFailed": "Link konnte nicht kopiert werden",
|
||||
"itemUpdated": "Freigabeeinstellungen aktualisiert",
|
||||
"itemRemoved": "Freigabe erfolgreich entfernt",
|
||||
"invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein",
|
||||
"notificationSent": "Benachrichtigung erfolgreich gesendet",
|
||||
"notificationFailed": "Benachrichtigung konnte nicht gesendet werden"
|
||||
},
|
||||
"shared_backToFiles": "Zurück zu Dateien",
|
||||
"shared_pageTitle": "Geteilte Ressourcen",
|
||||
"shared_pageDescription": "Verwalten Sie Ihre geteilten Dateien und Ordner",
|
||||
"shared_filterType": "Typ:",
|
||||
"shared_filterAll": "Alle",
|
||||
"shared_filterFiles": "Dateien",
|
||||
@@ -140,34 +144,33 @@
|
||||
"shared_colDateShared": "Freigabedatum",
|
||||
"shared_colExpiration": "Ablaufdatum",
|
||||
"shared_colPermissions": "Berechtigungen",
|
||||
"shared_colPassword": "Passwortschutz",
|
||||
"shared_colPassword": "Passwort",
|
||||
"shared_colActions": "Aktionen",
|
||||
"shared_emptyStateTitle": "Derzeit sind keine freigegebenen Elemente vorhanden.",
|
||||
"shared_emptyStateDesc": "Freigegebene Dateien und Ordner werden hier angezeigt.",
|
||||
"shared_goToFiles": "Zur Dateiansicht wechseln",
|
||||
"shared_emptyStateTitle": "Noch keine geteilten Ressourcen",
|
||||
"shared_emptyStateDesc": "Wenn Sie Dateien oder Ordner teilen, werden sie hier angezeigt",
|
||||
"shared_goToFiles": "Zu Dateien gehen",
|
||||
"shared_typeFile": "Datei",
|
||||
"shared_typeFolder": "Ordner",
|
||||
"shared_noExpiration": "Kein Ablaufdatum festgelegt",
|
||||
"shared_noExpiration": "Kein Ablaufdatum",
|
||||
"shared_hasPassword": "Ja",
|
||||
"shared_noPassword": "Nein",
|
||||
"shared_editShare": "Freigabe bearbeiten",
|
||||
"shared_notifyShare": "Person benachrichtigen",
|
||||
"shared_notifyShare": "Jemanden benachrichtigen",
|
||||
"shared_copyLink": "Link kopieren",
|
||||
"shared_removeShare": "Freigabe entfernen",
|
||||
"shared_linkCopied": "Der Link wurde in die Zwischenablage kopiert.",
|
||||
"shared_linkCopyFailed": "Der Link konnte nicht kopiert werden.",
|
||||
"shared_itemUpdated": "Die Freigabeeinstellungen wurden erfolgreich aktualisiert.",
|
||||
"shared_itemRemoved": "Die Freigabe wurde erfolgreich entfernt.",
|
||||
"shared_invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein.",
|
||||
"shared_notificationSent": "Die Benachrichtigung wurde erfolgreich versendet.",
|
||||
"shared_notificationFailed": "Die Benachrichtigung konnte nicht versendet werden."
|
||||
},
|
||||
"shared_linkCopied": "Link in Zwischenablage kopiert!",
|
||||
"shared_linkCopyFailed": "Link konnte nicht kopiert werden",
|
||||
"shared_itemUpdated": "Freigabeeinstellungen aktualisiert",
|
||||
"shared_itemRemoved": "Freigabe erfolgreich entfernt",
|
||||
"shared_invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein",
|
||||
"shared_notificationSent": "Benachrichtigung erfolgreich gesendet",
|
||||
"shared_notificationFailed": "Benachrichtigung konnte nicht gesendet werden",
|
||||
"files": {
|
||||
"name": "Name",
|
||||
"type": "Typ",
|
||||
"size": "Größe",
|
||||
"modified": "Geändert am",
|
||||
"no_files": "In diesem Ordner sind keine Dateien vorhanden.",
|
||||
"modified": "Geändert",
|
||||
"no_files": "Keine Dateien in diesem Ordner",
|
||||
"loading": "Dateien werden geladen…",
|
||||
"view_grid": "Rasteransicht",
|
||||
"view_list": "Listenansicht",
|
||||
@@ -176,8 +179,8 @@
|
||||
"image": "Bild",
|
||||
"video": "Video",
|
||||
"audio": "Audio",
|
||||
"pdf": "PDF-Dokument",
|
||||
"text": "Textdokument",
|
||||
"pdf": "PDF",
|
||||
"text": "Text",
|
||||
"folder": "Ordner"
|
||||
}
|
||||
},
|
||||
@@ -185,27 +188,27 @@
|
||||
"rename_folder": "Ordner umbenennen",
|
||||
"rename_file": "Datei umbenennen",
|
||||
"new_name": "Neuer Name",
|
||||
"new_folder_title": "Neuen Ordner erstellen",
|
||||
"new_folder_title": "Neuer Ordner",
|
||||
"folder_name": "Ordnername",
|
||||
"folder_placeholder": "Neuer Ordner",
|
||||
"folder_placeholder": "Mein Ordner",
|
||||
"rename_title": "Umbenennen",
|
||||
"move_file": "Datei verschieben",
|
||||
"move_folder": "Ordner verschieben",
|
||||
"select_destination": "Zielordner auswählen:",
|
||||
"root": "Hauptverzeichnis",
|
||||
"delete_confirmation": "Sind Sie sicher, dass Sie dieses Element löschen möchten",
|
||||
"and_contents": "und alle enthaltenen Elemente",
|
||||
"no_undo": "Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"root": "Stammverzeichnis",
|
||||
"delete_confirmation": "Sind Sie sicher, dass Sie löschen möchten",
|
||||
"and_contents": "und den gesamten Inhalt",
|
||||
"no_undo": "Diese Aktion kann nicht rückgängig gemacht werden",
|
||||
"confirm_title": "Aktion bestätigen",
|
||||
"confirm_delete": "In den Papierkorb verschieben",
|
||||
"confirm_delete_file": "Möchten Sie die Datei \"{{name}}\" in den Papierkorb verschieben?",
|
||||
"confirm_delete_folder": "Möchten Sie den Ordner \"{{name}}\" und alle enthaltenen Elemente in den Papierkorb verschieben?",
|
||||
"confirm_delete": "In Papierkorb verschieben",
|
||||
"confirm_delete_file": "Sind Sie sicher, dass Sie die Datei \"{{name}}\" in den Papierkorb verschieben möchten?",
|
||||
"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_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_delete_share": "Freigabelink löschen",
|
||||
"confirm_delete_share_msg": "Möchten Sie diesen Freigabelink löschen?",
|
||||
"share_file": "Datei freigeben",
|
||||
"confirm_delete_share_msg": "Sind Sie sicher, dass Sie diesen Freigabelink löschen möchten?",
|
||||
"share_file": "Datei teilen",
|
||||
"existing_shares": "Bestehende Freigaben",
|
||||
"share_options": "Freigabeoptionen",
|
||||
"password": "Passwort",
|
||||
@@ -217,78 +220,78 @@
|
||||
"message": "Nachricht"
|
||||
},
|
||||
"dropzone": {
|
||||
"drag_files": "Ziehen Sie Dateien hierher oder klicken Sie, um Dateien auszuwählen.",
|
||||
"drop_files": "Legen Sie Dateien hier ab, um den Upload zu starten."
|
||||
"drag_files": "Dateien hierher ziehen oder klicken zum Auswählen",
|
||||
"drop_files": "Dateien zum Hochladen ablegen"
|
||||
},
|
||||
"permissions": {
|
||||
"read": "Leseberechtigung",
|
||||
"write": "Schreibberechtigung",
|
||||
"reshare": "Weiterfreigabeberechtigung"
|
||||
"read": "Lesen",
|
||||
"write": "Schreiben",
|
||||
"reshare": "Weiterteilen"
|
||||
},
|
||||
"errors": {
|
||||
"file_not_found": "Die Datei wurde nicht gefunden.",
|
||||
"folder_not_found": "Der Ordner wurde nicht gefunden.",
|
||||
"delete_error": "Beim Löschen ist ein Fehler aufgetreten.",
|
||||
"upload_error": "Beim Hochladen ist ein Fehler aufgetreten.",
|
||||
"rename_error": "Beim Umbenennen ist ein Fehler aufgetreten.",
|
||||
"move_error": "Beim Verschieben ist ein Fehler aufgetreten.",
|
||||
"empty_name": "Der Name darf nicht leer sein.",
|
||||
"name_exists": "Eine Datei oder ein Ordner mit diesem Namen existiert bereits.",
|
||||
"generic_error": "Es ist ein unerwarteter Fehler aufgetreten."
|
||||
"file_not_found": "Datei nicht gefunden",
|
||||
"folder_not_found": "Ordner nicht gefunden",
|
||||
"delete_error": "Fehler beim Löschen",
|
||||
"upload_error": "Fehler beim Hochladen",
|
||||
"rename_error": "Fehler beim Umbenennen",
|
||||
"move_error": "Fehler beim Verschieben",
|
||||
"empty_name": "Der Name darf nicht leer sein",
|
||||
"name_exists": "Eine Datei oder ein Ordner mit diesem Namen existiert bereits",
|
||||
"generic_error": "Ein Fehler ist aufgetreten"
|
||||
},
|
||||
"breadcrumb": {
|
||||
"home": "Startseite"
|
||||
},
|
||||
"trash": {
|
||||
"empty_trash": "Papierkorb leeren",
|
||||
"empty_state": "Der Papierkorb ist leer.",
|
||||
"empty_state": "Der Papierkorb ist leer",
|
||||
"original_location": "Ursprünglicher Speicherort",
|
||||
"deleted_date": "Löschdatum",
|
||||
"actions": "Aktionen",
|
||||
"restore": "Wiederherstellen",
|
||||
"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": {
|
||||
"login_title": "Anmelden",
|
||||
"username": "Benutzername",
|
||||
"username_placeholder": "Bitte geben Sie Ihren Benutzernamen ein",
|
||||
"username_placeholder": "Geben Sie Ihren Benutzernamen ein",
|
||||
"password": "Passwort",
|
||||
"password_placeholder": "Bitte geben Sie Ihr Passwort ein",
|
||||
"password_placeholder": "Geben Sie Ihr Passwort ein",
|
||||
"login_button": "Anmelden",
|
||||
"no_account": "Verfügen Sie noch über kein Konto?",
|
||||
"no_account": "Kein Konto?",
|
||||
"register": "Registrieren",
|
||||
"admin_setup": "Erstmalige Nutzung?",
|
||||
"admin_setup": "Erstmalig?",
|
||||
"setup": "Administrator einrichten",
|
||||
"register_title": "Konto erstellen",
|
||||
"email": "E-Mail-Adresse",
|
||||
"email_placeholder": "Bitte geben Sie Ihre E-Mail-Adresse ein",
|
||||
"email": "E-Mail",
|
||||
"email_placeholder": "Geben Sie Ihre E-Mail ein",
|
||||
"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",
|
||||
"have_account": "Verfügen Sie bereits über ein Konto?",
|
||||
"have_account": "Bereits ein Konto?",
|
||||
"login": "Anmelden",
|
||||
"setup_title": "Ersteinrichtung",
|
||||
"setup_step1": "Administrator",
|
||||
"setup_step2": "Systemkonfiguration",
|
||||
"setup_step3": "Abschluss",
|
||||
"admin_username": "Administrator-Benutzername",
|
||||
"admin_email": "Administrator-E-Mail-Adresse",
|
||||
"admin_password": "Administrator-Passwort",
|
||||
"setup_step1": "Admin",
|
||||
"setup_step2": "System",
|
||||
"setup_step3": "Abgeschlossen",
|
||||
"admin_username": "Admin-Benutzername",
|
||||
"admin_email": "Admin-E-Mail",
|
||||
"admin_password": "Admin-Passwort",
|
||||
"create_admin": "Administrator erstellen",
|
||||
"back_to_login": "System bereits eingerichtet?",
|
||||
"admin_success": "Das Administrator-Konto wurde erfolgreich erstellt. Sie können sich nun anmelden.",
|
||||
"account_success": "Das Konto wurde erfolgreich erstellt. Sie können sich nun anmelden.",
|
||||
"passwords_mismatch": "Die eingegebenen Passwörter stimmen nicht überein.",
|
||||
"admin_create_error": "Beim Erstellen des Administrator-Kontos ist ein Fehler aufgetreten."
|
||||
"back_to_login": "Bereits eingerichtet?",
|
||||
"admin_success": "Administratorkonto erfolgreich erstellt! Sie können sich jetzt anmelden.",
|
||||
"account_success": "Konto erfolgreich erstellt! Sie können sich jetzt anmelden.",
|
||||
"passwords_mismatch": "Die Passwörter stimmen nicht überein",
|
||||
"admin_create_error": "Fehler beim Erstellen des Administratorkontos"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Speicher",
|
||||
"calculating": "Speicherplatz wird berechnet...",
|
||||
"used": "{{percentage}} % verwendet ({{used}} von {{total}})"
|
||||
"calculating": "Berechnung...",
|
||||
"used": "{{percentage}}% verwendet ({{used}} / {{total}})"
|
||||
},
|
||||
"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",
|
||||
"zoom_in": "Vergrößern",
|
||||
"zoom_out": "Verkleinern",
|
||||
@@ -297,36 +300,39 @@
|
||||
"language_selector": {
|
||||
"title": "Willkommen bei OxiCloud",
|
||||
"subtitle": "Bitte wählen Sie Ihre Sprache",
|
||||
"continue": "Fortfahren",
|
||||
"continue": "Weiter",
|
||||
"languages": {
|
||||
"en": "Englisch",
|
||||
"es": "Spanisch",
|
||||
"zh": "Chinesisch",
|
||||
"fa": "Persisch"
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"zh": "中文",
|
||||
"fa": "فارسی",
|
||||
"fr": "Français",
|
||||
"de": "Deutsch",
|
||||
"pt": "Português"
|
||||
}
|
||||
},
|
||||
"favorites": {
|
||||
"empty_state": "Derzeit sind keine Favoriten vorhanden.",
|
||||
"empty_hint": "Markieren Sie Dateien oder Ordner, um sie zu Ihren Favoriten hinzuzufügen.",
|
||||
"empty_state": "Noch keine Favoriten",
|
||||
"empty_hint": "Markieren Sie Dateien oder Ordner mit einem Stern, um sie zu Ihren Favoriten hinzuzufügen",
|
||||
"add": "Zu Favoriten hinzufügen",
|
||||
"remove": "Aus Favoriten entfernen"
|
||||
},
|
||||
"recent": {
|
||||
"title": "Zuletzt verwendete Elemente",
|
||||
"clear": "Verlauf löschen",
|
||||
"accessed": "Geöffnet am",
|
||||
"empty_state": "Keine zuletzt verwendeten Dateien vorhanden.",
|
||||
"empty_hint": "Geöffnete Dateien werden hier angezeigt."
|
||||
"title": "Zuletzt verwendet",
|
||||
"clear": "Zuletzt verwendete löschen",
|
||||
"accessed": "Zugegriffen",
|
||||
"empty_state": "Keine zuletzt verwendeten Dateien",
|
||||
"empty_hint": "Dateien, die Sie öffnen, werden hier angezeigt"
|
||||
},
|
||||
"notifications": {
|
||||
"file_renamed": "Datei wurde umbenannt.",
|
||||
"file_renamed_to": "Die Datei wurde in \"{{name}}\" umbenannt.",
|
||||
"folder_renamed": "Ordner wurde umbenannt.",
|
||||
"folder_renamed_to": "Der Ordner wurde in \"{{name}}\" umbenannt.",
|
||||
"file_uploaded": "Die Datei wurde erfolgreich hochgeladen.",
|
||||
"file_deleted": "Die Datei wurde in den Papierkorb verschoben.",
|
||||
"folder_deleted": "Der Ordner wurde in den Papierkorb verschoben.",
|
||||
"item_deleted_permanently": "Das Element wurde dauerhaft gelöscht.",
|
||||
"trash_emptied": "Der Papierkorb wurde erfolgreich geleert."
|
||||
"file_renamed": "Datei umbenannt",
|
||||
"file_renamed_to": "Datei umbenannt in \"{{name}}\"",
|
||||
"folder_renamed": "Ordner umbenannt",
|
||||
"folder_renamed_to": "Ordner umbenannt in \"{{name}}\"",
|
||||
"file_uploaded": "Datei hochgeladen",
|
||||
"file_deleted": "Datei in Papierkorb verschoben",
|
||||
"folder_deleted": "Ordner in Papierkorb verschoben",
|
||||
"item_deleted_permanently": "Element endgültig gelöscht",
|
||||
"trash_emptied": "Papierkorb erfolgreich geleert"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,10 @@
|
||||
"user_menu": {
|
||||
"appearance": "Appearance",
|
||||
"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": {
|
||||
"dialogTitle": "Share Link",
|
||||
@@ -302,7 +305,10 @@
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"zh": "中文",
|
||||
"fa": "فارسی"
|
||||
"fa": "فارسی",
|
||||
"fr": "Français",
|
||||
"de": "Deutsch",
|
||||
"pt": "Português"
|
||||
}
|
||||
},
|
||||
"favorites": {
|
||||
|
||||
@@ -160,7 +160,10 @@
|
||||
"user_menu": {
|
||||
"appearance": "Apariencia",
|
||||
"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": {
|
||||
"name": "Nombre",
|
||||
@@ -302,7 +305,10 @@
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"zh": "中文",
|
||||
"fa": "فارسی"
|
||||
"fa": "فارسی",
|
||||
"fr": "Français",
|
||||
"de": "Deutsch",
|
||||
"pt": "Português"
|
||||
}
|
||||
},
|
||||
"favorites": {
|
||||
|
||||
@@ -39,7 +39,10 @@
|
||||
"user_menu": {
|
||||
"appearance": "ظاهر",
|
||||
"about": "درباره OxiCloud",
|
||||
"about_description": "پلتفرم ذخیرهسازی ابری ساخته شده با Rust و معماری تمیز. سریع، امن و خصوصی."
|
||||
"about_description": "پلتفرم ذخیرهسازی ابری ساخته شده با Rust و معماری تمیز. سریع، امن و خصوصی.",
|
||||
"admin_panel": "پنل مدیریت",
|
||||
"profile": "نمایه من",
|
||||
"role_user": "کاربر"
|
||||
},
|
||||
"share": {
|
||||
"dialogTitle": "پیوند همرسانی",
|
||||
@@ -288,7 +291,10 @@
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"zh": "中文",
|
||||
"fa": "فارسی"
|
||||
"fa": "فارسی",
|
||||
"fr": "Français",
|
||||
"de": "Deutsch",
|
||||
"pt": "Português"
|
||||
}
|
||||
},
|
||||
"favorites": {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,10 @@
|
||||
"user_menu": {
|
||||
"appearance": "外观",
|
||||
"about": "关于 OxiCloud",
|
||||
"about_description": "基于 Rust 和整洁架构构建的云存储平台。快速、安全、私密。"
|
||||
"about_description": "基于 Rust 和整洁架构构建的云存储平台。快速、安全、私密。",
|
||||
"admin_panel": "管理面板",
|
||||
"profile": "我的资料",
|
||||
"role_user": "用户"
|
||||
},
|
||||
"share": {
|
||||
"dialogTitle": "共享链接",
|
||||
@@ -250,7 +253,10 @@
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"zh": "中文",
|
||||
"fa": "فارسی"
|
||||
"fa": "فارسی",
|
||||
"fr": "Français",
|
||||
"de": "Deutsch",
|
||||
"pt": "Português"
|
||||
}
|
||||
},
|
||||
"favorites": {
|
||||
|
||||
Reference in New Issue
Block a user