Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f80ec9797e | ||
|
|
fbbd820512 | ||
|
|
5d0777f67c | ||
|
|
f1d504f985 | ||
|
|
6a4d77d904 | ||
|
|
c35d53266a | ||
|
|
dc096f5e12 | ||
|
|
a681aadcfa | ||
|
|
f15f3f5110 | ||
|
|
07ae71fd23 | ||
|
|
26270b2842 | ||
|
|
0d0596b767 | ||
|
|
eca7af2d6f | ||
|
|
3ace14fcdb | ||
|
|
99bec6c7f9 | ||
|
|
ef299f1f4a | ||
|
|
66b0709e6e | ||
|
|
a2ed33214d | ||
|
|
a3dccd690d | ||
|
|
69313fba34 | ||
|
|
1889c58598 | ||
|
|
e9f0162439 | ||
|
|
323b17185c | ||
|
|
09f44a5685 | ||
|
|
f4ab7841fb | ||
|
|
3de4f69a62 | ||
|
|
102be2c24a | ||
|
|
3a39b25e64 | ||
|
|
32248f8424 | ||
|
|
a1f8776743 | ||
|
|
7e431d645a | ||
|
|
cef4bffd69 | ||
|
|
51767ebbdb | ||
|
|
ad91148616 | ||
|
|
38df66044d | ||
|
|
75391641fd | ||
|
|
24dc99a19a | ||
|
|
907075f51d | ||
|
|
b48ac45085 | ||
|
|
b115d0a772 | ||
|
|
ad0cdfe1d9 | ||
|
|
a50ef47a52 | ||
|
|
db4240d99b | ||
|
|
bf1d48709c | ||
|
|
c3c0c288a8 | ||
|
|
79e8bb3734 | ||
|
|
a6884440a0 | ||
|
|
b9e5f396fd | ||
|
|
fc40ebcaba | ||
|
|
54642037d3 | ||
|
|
0778089ff3 | ||
|
|
ac2afd6949 | ||
|
|
8162ce65cb | ||
|
|
6e4bdea1c2 | ||
|
|
daf8ec2e0a | ||
|
|
2a3ae31e4e | ||
|
|
9c27c41a5e | ||
|
|
a328da679c | ||
|
|
122496513b | ||
|
|
7363c4c692 | ||
|
|
012e683240 | ||
|
|
b3a37df4be | ||
|
|
cb94b19e61 | ||
|
|
50c4f1a6ac |
34
.env
34
.env
@@ -1,34 +0,0 @@
|
||||
# Database configuration
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=password
|
||||
DB_NAME=worklenz_db
|
||||
DB_HOST=db
|
||||
DB_PORT=5432
|
||||
DB_MAX_CLIENTS=50
|
||||
|
||||
# Server configuration
|
||||
NODE_ENV=development
|
||||
PORT=3000
|
||||
SESSION_NAME=worklenz.sid
|
||||
SESSION_SECRET=worklenz-session-secret
|
||||
COOKIE_SECRET=worklenz-cookie-secret
|
||||
|
||||
# CORS
|
||||
SOCKET_IO_CORS=http://localhost:5000
|
||||
SERVER_CORS=*
|
||||
|
||||
# Storage configuration (MinIO)
|
||||
STORAGE_PROVIDER=s3
|
||||
AWS_REGION=us-east-1
|
||||
AWS_BUCKET=worklenz-bucket
|
||||
S3_ACCESS_KEY_ID=minioadmin
|
||||
S3_SECRET_ACCESS_KEY=minioadmin
|
||||
S3_URL=http://minio:9000
|
||||
|
||||
# Application URLs
|
||||
HOSTNAME=localhost:5000
|
||||
FRONTEND_URL=http://localhost:5000
|
||||
|
||||
# For local development, set these to the frontend service
|
||||
LOGIN_FAILURE_REDIRECT=http://localhost:5000
|
||||
LOGIN_SUCCESS_REDIRECT=http://localhost:5000/auth/authenticate
|
||||
34
.env.example
34
.env.example
@@ -1,34 +0,0 @@
|
||||
# Database configuration
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=your_db_password
|
||||
DB_NAME=worklenz_db
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_MAX_CLIENTS=50
|
||||
|
||||
# Server configuration
|
||||
NODE_ENV=development
|
||||
PORT=3000
|
||||
SESSION_NAME=worklenz.sid
|
||||
SESSION_SECRET=your_session_secret
|
||||
COOKIE_SECRET=your_cookie_secret
|
||||
|
||||
# CORS
|
||||
SOCKET_IO_CORS=http://localhost:5000
|
||||
SERVER_CORS=*
|
||||
|
||||
# Storage configuration
|
||||
STORAGE_PROVIDER=s3
|
||||
AWS_REGION=your_aws_region
|
||||
AWS_BUCKET=your_bucket_name
|
||||
S3_ACCESS_KEY_ID=your_access_key_id
|
||||
S3_SECRET_ACCESS_KEY=your_secret_access_key
|
||||
S3_URL=your_s3_url
|
||||
|
||||
# Application URLs
|
||||
HOSTNAME=localhost:5000
|
||||
FRONTEND_URL=http://localhost:5000
|
||||
|
||||
# For local development
|
||||
LOGIN_FAILURE_REDIRECT=http://localhost:5000
|
||||
LOGIN_SUCCESS_REDIRECT=http://localhost:5000/auth/authenticate
|
||||
141
README.md
141
README.md
@@ -1,6 +1,6 @@
|
||||
<h1 align="center">
|
||||
<a href="https://worklenz.com" target="_blank" rel="noopener noreferrer">
|
||||
<img src="https://app.worklenz.com/assets/icons/icon-144x144.png" alt="Worklenz Logo" width="75">
|
||||
<img src="https://s3.us-west-2.amazonaws.com/worklenz.com/assets/icon-144x144.png" alt="Worklenz Logo" width="75">
|
||||
</a>
|
||||
<br>
|
||||
Worklenz
|
||||
@@ -62,15 +62,14 @@ These instructions will help you set up and run the Worklenz project on your loc
|
||||
|
||||
1. Clone the repository
|
||||
```bash
|
||||
git clone https://github.com/yourusername/worklenz.git
|
||||
git clone https://github.com/Worklenz/worklenz.git
|
||||
cd worklenz
|
||||
```
|
||||
|
||||
2. Set up environment variables
|
||||
- Copy the example environment files
|
||||
```bash
|
||||
cp .env.example .env
|
||||
cp worklenz-backend/.env.example worklenz-backend/.env
|
||||
cp worklenz-backend/.env.template worklenz-backend/.env
|
||||
```
|
||||
- Update the environment variables with your configuration
|
||||
|
||||
@@ -124,7 +123,7 @@ The project includes a fully configured Docker setup with:
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone https://github.com/yourusername/worklenz.git
|
||||
git clone https://github.com/Worklenz/worklenz.git
|
||||
cd worklenz
|
||||
```
|
||||
|
||||
@@ -186,12 +185,33 @@ We welcome contributions from the community! If you'd like to contribute, please
|
||||
|
||||
If you believe you have found a security vulnerability in Worklenz, we encourage you to responsibly disclose this and not open a public issue. We will investigate all legitimate reports.
|
||||
|
||||
Email [your-security-email@example.com](mailto:your-security-email@example.com) to disclose any security vulnerabilities.
|
||||
Email [info@worklenz.com](mailto:info@worklenz.com) to disclose any security vulnerabilities.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the [MIT License](LICENSE).
|
||||
|
||||
## Analytics
|
||||
|
||||
Worklenz uses Google Analytics to understand how the application is being used. This helps us improve the application and make better decisions about future development.
|
||||
|
||||
### What We Track
|
||||
- Anonymous usage statistics
|
||||
- Page views and navigation patterns
|
||||
- Feature usage
|
||||
- Browser and device information
|
||||
|
||||
### Privacy
|
||||
- Analytics is opt-in only
|
||||
- No personal information is collected
|
||||
- Users can opt-out at any time
|
||||
- Data is stored according to Google's privacy policy
|
||||
|
||||
### How to Opt-Out
|
||||
If you've previously opted in and want to opt-out:
|
||||
1. Clear your browser's local storage for the Worklenz domain
|
||||
2. Or click the "Decline" button in the analytics notice if it appears
|
||||
|
||||
## Screenshots
|
||||
|
||||
<p align="center">
|
||||
@@ -272,8 +292,8 @@ The project includes a fully configured Docker setup with:
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone https://github.com/yourusername/worklenz-react-v1.git
|
||||
cd worklenz-react-v1
|
||||
git clone https://github.com/Worklenz/worklenz.git
|
||||
cd worklenz
|
||||
```
|
||||
|
||||
2. Start the Docker containers (choose one option):
|
||||
@@ -315,6 +335,7 @@ docker-compose up -d
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
|
||||
## MinIO Integration
|
||||
|
||||
The project uses MinIO as an S3-compatible object storage service, which provides an open-source alternative to AWS S3 for development and production.
|
||||
@@ -358,34 +379,96 @@ const s3Client = new S3Client({
|
||||
|
||||
### Environment Configuration
|
||||
|
||||
The `.env` file includes the necessary configuration for using MinIO:
|
||||
The project uses the following environment file structure:
|
||||
|
||||
```
|
||||
STORAGE_PROVIDER=s3
|
||||
AWS_REGION=us-east-1
|
||||
AWS_BUCKET=worklenz-bucket
|
||||
S3_ACCESS_KEY_ID=minioadmin
|
||||
S3_SECRET_ACCESS_KEY=minioadmin
|
||||
S3_URL=http://minio:9000
|
||||
- **Frontend**:
|
||||
- `worklenz-frontend/.env.development` - Development environment variables
|
||||
- `worklenz-frontend/.env.production` - Production build variables
|
||||
|
||||
- **Backend**:
|
||||
- `worklenz-backend/.env` - Backend environment variables
|
||||
|
||||
### Setting Up Environment Files
|
||||
|
||||
The Docker environment script will create or overwrite all environment files:
|
||||
|
||||
```bash
|
||||
# For HTTP/WS
|
||||
./update-docker-env.sh your-hostname
|
||||
|
||||
# For HTTPS/WSS
|
||||
./update-docker-env.sh your-hostname true
|
||||
```
|
||||
|
||||
When the backend service starts, it will use these environment variables to connect to MinIO for file storage.
|
||||
This script generates properly configured environment files for both development and production environments.
|
||||
|
||||
## Development
|
||||
## Docker Deployment
|
||||
|
||||
For development, you can use the provided Docker setup which includes all necessary dependencies. The code will be running inside containers, but you can still edit files locally and see changes reflected in real-time.
|
||||
### Local Development with Docker
|
||||
|
||||
## Production Deployment
|
||||
1. Set up the environment files:
|
||||
```bash
|
||||
# For HTTP/WS
|
||||
./update-docker-env.sh
|
||||
|
||||
# For HTTPS/WSS
|
||||
./update-docker-env.sh localhost true
|
||||
```
|
||||
|
||||
For production deployment:
|
||||
2. Run the application using Docker Compose:
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
1. Update the `.env` file with production settings
|
||||
2. Build custom Docker images or use the provided ones
|
||||
3. Deploy using Docker Compose or a container orchestration platform like Kubernetes
|
||||
3. Access the application:
|
||||
- Frontend: http://localhost:5000
|
||||
- Backend API: http://localhost:3000 (or https://localhost:3000 with SSL)
|
||||
|
||||
For MinIO in production, consider:
|
||||
- Setting up proper credentials (change default minioadmin/minioadmin)
|
||||
- Configuring persistent storage
|
||||
- Setting up proper networking and access controls
|
||||
- Using multiple MinIO instances for high availability
|
||||
4. Video Guide
|
||||
|
||||
For a visual walkthrough of the local Docker deployment process, check out our [step-by-step video guide](https://www.youtube.com/watch?v=AfwAKxJbqLg).
|
||||
|
||||
### Remote Server Deployment
|
||||
|
||||
When deploying to a remote server:
|
||||
|
||||
1. Set up the environment files with your server's hostname:
|
||||
```bash
|
||||
# For HTTP/WS
|
||||
./update-docker-env.sh your-server-hostname
|
||||
|
||||
# For HTTPS/WSS
|
||||
./update-docker-env.sh your-server-hostname true
|
||||
```
|
||||
|
||||
This ensures that the frontend correctly connects to the backend API.
|
||||
|
||||
2. Pull and run the latest Docker images:
|
||||
```bash
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
3. Access the application through your server's hostname:
|
||||
- Frontend: http://your-server-hostname:5000
|
||||
- Backend API: http://your-server-hostname:3000
|
||||
|
||||
4. Video Guide
|
||||
|
||||
For a complete walkthrough of deploying Worklenz to a remote server, check out our [deployment video guide](https://www.youtube.com/watch?v=CAZGu2iOXQs&t=10s).
|
||||
|
||||
### Environment Configuration
|
||||
|
||||
The Docker setup uses environment variables to configure the services:
|
||||
|
||||
- Frontend:
|
||||
- `VITE_API_URL`: URL of the backend API (default: http://backend:3000 for container networking)
|
||||
- `VITE_SOCKET_URL`: WebSocket URL for real-time communication (default: ws://backend:3000)
|
||||
|
||||
- Backend:
|
||||
- Database connection parameters
|
||||
- Storage configuration
|
||||
- Other backend settings
|
||||
|
||||
For custom configuration, edit the `.env` file or the `update-docker-env.sh` script.
|
||||
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
services:
|
||||
frontend:
|
||||
image: docker.io/chamikajaycey/worklenz-frontend:latest
|
||||
build:
|
||||
context: ./worklenz-frontend
|
||||
dockerfile: Dockerfile
|
||||
container_name: worklenz_frontend
|
||||
ports:
|
||||
- "5000:5000"
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_started
|
||||
- backend
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- ./worklenz-frontend/.env.production
|
||||
networks:
|
||||
- worklenz
|
||||
|
||||
backend:
|
||||
image: docker.io/chamikajaycey/worklenz-backend:latest
|
||||
build:
|
||||
context: ./worklenz-backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: worklenz_backend
|
||||
ports:
|
||||
- "3000:3000"
|
||||
@@ -20,36 +26,9 @@ services:
|
||||
condition: service_healthy
|
||||
minio:
|
||||
condition: service_started
|
||||
environment:
|
||||
- AWS_REGION=${AWS_REGION:-us-east-1}
|
||||
- BACKEND_PUBLIC_DIR
|
||||
- BACKEND_VIEWS_DIR
|
||||
- COMMIT_BUILD_IMMEDIATELY
|
||||
- COOKIE_SECRET
|
||||
- DB_HOST=${DB_HOST:-db}
|
||||
- DB_MAX_CLIENTS
|
||||
- DB_NAME=${DB_NAME:-worklenz_db}
|
||||
- DB_PASSWORD=${DB_PASSWORD:-password}
|
||||
- DB_PORT=${DB_PORT:-5432}
|
||||
- DB_USER=${DB_USER:-postgres}
|
||||
- GOOGLE_CALLBACK_URL
|
||||
- GOOGLE_CLIENT_ID
|
||||
- GOOGLE_CLIENT_SECRET
|
||||
- HOSTNAME
|
||||
- LOGIN_FAILURE_REDIRECT
|
||||
- NODE_ENV=${NODE_ENV:-development}
|
||||
- PORT=${PORT:-3000}
|
||||
- SESSION_NAME
|
||||
- SESSION_SECRET
|
||||
- SLACK_WEBHOOK
|
||||
- SOCKET_IO_CORS
|
||||
- SOURCE_EMAIL
|
||||
- USE_PG_NATIVE
|
||||
- STORAGE_PROVIDER=${STORAGE_PROVIDER:-s3}
|
||||
- AWS_BUCKET=${BUCKET:-worklenz-bucket}
|
||||
- AWS_ACCESS_KEY_ID=${S3_ACCESS_KEY_ID:-minioadmin}
|
||||
- AWS_SECRET_ACCESS_KEY=${S3_SECRET_ACCESS_KEY:-minioadmin}
|
||||
- S3_URL=${S3_URL:-http://minio:9000}
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- ./worklenz-backend/.env
|
||||
networks:
|
||||
- worklenz
|
||||
|
||||
@@ -59,6 +38,7 @@ services:
|
||||
ports:
|
||||
- "9000:9000"
|
||||
- "9001:9001"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MINIO_ROOT_USER: ${S3_ACCESS_KEY_ID:-minioadmin}
|
||||
MINIO_ROOT_PASSWORD: ${S3_SECRET_ACCESS_KEY:-minioadmin}
|
||||
@@ -74,29 +54,27 @@ services:
|
||||
container_name: worklenz_createbuckets
|
||||
depends_on:
|
||||
- minio
|
||||
restart: on-failure
|
||||
entrypoint: >
|
||||
/bin/sh -c "
|
||||
# Wait for MinIO to be available
|
||||
echo 'Waiting for MinIO to start...'
|
||||
sleep 15;
|
||||
# Retry up to 5 times
|
||||
for i in 1 2 3 4 5; do
|
||||
echo \"Attempt $$i to connect to MinIO...\"
|
||||
if /usr/bin/mc config host add myminio http://minio:9000 minioadmin minioadmin; then
|
||||
echo \"Successfully connected to MinIO!\"
|
||||
/usr/bin/mc mb --ignore-existing myminio/worklenz-bucket;
|
||||
/usr/bin/mc policy set public myminio/worklenz-bucket;
|
||||
exit 0;
|
||||
fi
|
||||
echo \"Connection failed, retrying in 5 seconds...\"
|
||||
sleep 5;
|
||||
done
|
||||
echo \"Failed to connect to MinIO after 5 attempts\"
|
||||
exit 1;
|
||||
"
|
||||
/bin/sh -c '
|
||||
echo "Waiting for MinIO to start...";
|
||||
sleep 15;
|
||||
for i in 1 2 3 4 5; do
|
||||
echo "Attempt $i to connect to MinIO...";
|
||||
if /usr/bin/mc alias set myminio http://minio:9000 minioadmin minioadmin; then
|
||||
echo "Successfully connected to MinIO!";
|
||||
/usr/bin/mc mb --ignore-existing myminio/worklenz-bucket;
|
||||
/usr/bin/mc policy set public myminio/worklenz-bucket;
|
||||
exit 0;
|
||||
fi
|
||||
echo "Connection failed, retrying in 5 seconds...";
|
||||
sleep 5;
|
||||
done;
|
||||
echo "Failed to connect to MinIO after 5 attempts";
|
||||
exit 1;
|
||||
'
|
||||
networks:
|
||||
- worklenz
|
||||
|
||||
db:
|
||||
image: postgres:15
|
||||
container_name: worklenz_db
|
||||
@@ -109,15 +87,29 @@ services:
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- worklenz
|
||||
volumes:
|
||||
- worklenz_postgres_data:/var/lib/postgresql/data
|
||||
- ./worklenz-backend/database/:/docker-entrypoint-initdb.d
|
||||
- type: bind
|
||||
source: ./worklenz-backend/database
|
||||
target: /docker-entrypoint-initdb.d
|
||||
consistency: cached
|
||||
command: >
|
||||
bash -c ' if command -v apt-get >/dev/null 2>&1; then
|
||||
apt-get update && apt-get install -y dos2unix
|
||||
elif command -v apk >/dev/null 2>&1; then
|
||||
apk add --no-cache dos2unix
|
||||
fi && find /docker-entrypoint-initdb.d -type f -name "*.sh" -exec sh -c '\''
|
||||
dos2unix "{}" 2>/dev/null || true
|
||||
chmod +x "{}"
|
||||
'\'' \; && exec docker-entrypoint.sh postgres '
|
||||
|
||||
volumes:
|
||||
worklenz_postgres_data:
|
||||
worklenz_minio_data:
|
||||
|
||||
|
||||
networks:
|
||||
worklenz:
|
||||
|
||||
24
start.bat
24
start.bat
@@ -39,6 +39,12 @@ IF %ERRORLEVEL% NEQ 0 (
|
||||
echo docker-compose is installed >> worklenz_startup.log
|
||||
)
|
||||
|
||||
REM Check for update-docker-env.sh
|
||||
IF EXIST update-docker-env.sh (
|
||||
echo [94mFound update-docker-env.sh script. You can use it to update environment variables.[0m
|
||||
echo Found update-docker-env.sh script >> worklenz_startup.log
|
||||
)
|
||||
|
||||
REM Run preflight checks
|
||||
echo Running Docker daemon check...
|
||||
docker info >nul 2>>worklenz_startup.log
|
||||
@@ -52,17 +58,6 @@ IF %ERRORLEVEL% NEQ 0 (
|
||||
echo Docker daemon is running >> worklenz_startup.log
|
||||
)
|
||||
|
||||
REM Check if .env file exists
|
||||
IF NOT EXIST .env (
|
||||
echo Warning: .env file not found. Using default configuration.
|
||||
echo Warning: .env file not found. Using default configuration. >> worklenz_startup.log
|
||||
IF EXIST .env.example (
|
||||
copy .env.example .env
|
||||
echo Created .env file from .env.example
|
||||
echo Created .env file from .env.example >> worklenz_startup.log
|
||||
)
|
||||
)
|
||||
|
||||
REM Stop any running containers
|
||||
echo Stopping any running containers...
|
||||
docker-compose down > nul 2>>worklenz_startup.log
|
||||
@@ -111,7 +106,7 @@ REM Check frontend
|
||||
findstr /C:"frontend" running_services.txt > nul
|
||||
IF %ERRORLEVEL% EQU 0 (
|
||||
echo [92m^✓[0m Frontend is running
|
||||
echo Frontend URL: http://localhost:5000
|
||||
echo Frontend URL: http://localhost:5000 (or https://localhost:5000 if SSL is enabled)
|
||||
echo Frontend is running >> worklenz_startup.log
|
||||
) ELSE (
|
||||
echo [91m^✗[0m Frontend service failed to start
|
||||
@@ -122,7 +117,7 @@ REM Check backend
|
||||
findstr /C:"backend" running_services.txt > nul
|
||||
IF %ERRORLEVEL% EQU 0 (
|
||||
echo [92m^✓[0m Backend is running
|
||||
echo Backend URL: http://localhost:3000
|
||||
echo Backend URL: http://localhost:3000 (or https://localhost:3000 if SSL is enabled)
|
||||
echo Backend is running >> worklenz_startup.log
|
||||
) ELSE (
|
||||
echo [91m^✗[0m Backend service failed to start
|
||||
@@ -180,6 +175,9 @@ IF %allRunning% EQU 1 (
|
||||
|
||||
echo You can access the application at: http://localhost:5000
|
||||
echo To stop the services, run: stop.bat
|
||||
echo To update environment variables, run: update-docker-env.sh
|
||||
echo.
|
||||
echo Note: To enable SSL, set ENABLE_SSL=true in your .env file and run update-docker-env.sh
|
||||
echo.
|
||||
echo For any errors, check worklenz_startup.log file
|
||||
echo.
|
||||
|
||||
171
start.sh
Normal file → Executable file
171
start.sh
Normal file → Executable file
@@ -4,12 +4,13 @@
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Print banner
|
||||
echo -e "${GREEN}"
|
||||
echo " __ __ _ _"
|
||||
echo " \ \ / / | | | |"
|
||||
echo " \ \ / / | | | |"
|
||||
echo " \ \ /\ / /__ _ __| | _| | ___ _ __ ____"
|
||||
echo " \ \/ \/ / _ \| '__| |/ / |/ _ \ '_ \|_ /"
|
||||
echo " \ /\ / (_) | | | <| | __/ | | |/ /"
|
||||
@@ -19,16 +20,56 @@ echo " W O R K L E N Z "
|
||||
echo -e "${NC}"
|
||||
echo "Starting Worklenz Docker Environment..."
|
||||
|
||||
# Check if .env file exists
|
||||
if [ ! -f .env ]; then
|
||||
echo -e "${YELLOW}Warning: .env file not found. Using default configuration.${NC}"
|
||||
# Copy the example .env file if it exists
|
||||
if [ -f .env.example ]; then
|
||||
cp .env.example .env
|
||||
echo "Created .env file from .env.example"
|
||||
fi
|
||||
# Check if update-docker-env.sh exists and is executable
|
||||
if [ -f update-docker-env.sh ] && [ -x update-docker-env.sh ]; then
|
||||
echo -e "${BLUE}Found update-docker-env.sh script. You can use it to update environment variables.${NC}"
|
||||
fi
|
||||
|
||||
# Function to check if a service is running
|
||||
check_service() {
|
||||
local service_name=$1
|
||||
local container_name=$2
|
||||
local url=$3
|
||||
local max_attempts=30
|
||||
local attempt=1
|
||||
|
||||
echo -e "${BLUE}Checking ${service_name} service...${NC}"
|
||||
|
||||
# First check if the container is running
|
||||
while [ $attempt -le $max_attempts ]; do
|
||||
if docker ps | grep -q "${container_name}"; then
|
||||
# Container is running
|
||||
if [ -z "$url" ]; then
|
||||
# No URL to check, assume service is up
|
||||
echo -e "${GREEN}✓${NC} ${service_name} is running"
|
||||
return 0
|
||||
else
|
||||
# Check if service endpoint is responding
|
||||
if curl -s -f -o /dev/null "$url"; then
|
||||
echo -e "${GREEN}✓${NC} ${service_name} is running and responding at ${url}"
|
||||
return 0
|
||||
else
|
||||
if [ $attempt -eq $max_attempts ]; then
|
||||
echo -e "${YELLOW}⚠${NC} ${service_name} container is running but not responding at ${url}"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ $attempt -eq $max_attempts ]; then
|
||||
echo -e "${RED}✗${NC} ${service_name} failed to start"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -n "."
|
||||
attempt=$((attempt+1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if Docker is installed
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo -e "${RED}Error: Docker is not installed or not in PATH${NC}"
|
||||
@@ -37,7 +78,7 @@ if ! command -v docker &> /dev/null; then
|
||||
fi
|
||||
|
||||
# Check if Docker daemon is running
|
||||
echo "Running preflight checks..."
|
||||
echo -e "${BLUE}Running preflight checks...${NC}"
|
||||
if ! docker info &> /dev/null; then
|
||||
echo -e "${RED}Error: Docker daemon is not running${NC}"
|
||||
echo "Please start Docker and try again"
|
||||
@@ -45,58 +86,66 @@ if ! docker info &> /dev/null; then
|
||||
fi
|
||||
echo -e "${GREEN}✓${NC} Docker is running"
|
||||
|
||||
# Check if Docker Compose is installed
|
||||
if ! command -v docker compose &> /dev/null; then
|
||||
echo "Warning: Docker Compose V2 not found, trying docker-compose command..."
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
echo "Error: Docker Compose is not installed or not in PATH"
|
||||
echo "Please install Docker Compose: https://docs.docker.com/compose/install/"
|
||||
exit 1
|
||||
# Determine Docker Compose command to use
|
||||
DOCKER_COMPOSE_CMD=""
|
||||
if command -v docker compose &> /dev/null; then
|
||||
DOCKER_COMPOSE_CMD="docker compose"
|
||||
echo -e "${GREEN}✓${NC} Using Docker Compose V2"
|
||||
elif command -v docker-compose &> /dev/null; then
|
||||
DOCKER_COMPOSE_CMD="docker-compose"
|
||||
echo -e "${YELLOW}⚠${NC} Using legacy Docker Compose"
|
||||
else
|
||||
echo -e "${RED}Error: Docker Compose is not installed or not in PATH${NC}"
|
||||
echo "Please install Docker Compose: https://docs.docker.com/compose/install/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if any of the ports are already in use
|
||||
ports=(3000 5000 9000 9001 5432)
|
||||
for port in "${ports[@]}"; do
|
||||
if lsof -i:"$port" > /dev/null 2>&1; then
|
||||
echo -e "${YELLOW}⚠ Warning: Port $port is already in use. This may cause conflicts.${NC}"
|
||||
fi
|
||||
# Use docker-compose command instead
|
||||
docker-compose down
|
||||
docker-compose up -d
|
||||
done
|
||||
|
||||
# Start the containers
|
||||
echo -e "${BLUE}Starting Worklenz services...${NC}"
|
||||
$DOCKER_COMPOSE_CMD down
|
||||
$DOCKER_COMPOSE_CMD up -d
|
||||
|
||||
# Wait for services to fully initialize
|
||||
echo -e "${BLUE}Waiting for services to initialize...${NC}"
|
||||
echo "This may take a minute or two depending on your system..."
|
||||
|
||||
# Check each service
|
||||
check_service "Database" "worklenz_db" ""
|
||||
DB_STATUS=$?
|
||||
|
||||
check_service "MinIO" "worklenz_minio" "http://localhost:9000/minio/health/live"
|
||||
MINIO_STATUS=$?
|
||||
|
||||
check_service "Backend" "worklenz_backend" "http://localhost:3000/public/health"
|
||||
BACKEND_STATUS=$?
|
||||
|
||||
check_service "Frontend" "worklenz_frontend" "http://localhost:5000"
|
||||
FRONTEND_STATUS=$?
|
||||
|
||||
# Display service URLs
|
||||
echo -e "\n${BLUE}Service URLs:${NC}"
|
||||
[ $FRONTEND_STATUS -eq 0 ] && echo " • Frontend: http://localhost:5000 (or https://localhost:5000 if SSL is enabled)"
|
||||
[ $BACKEND_STATUS -eq 0 ] && echo " • Backend API: http://localhost:3000 (or https://localhost:3000 if SSL is enabled)"
|
||||
[ $MINIO_STATUS -eq 0 ] && echo " • MinIO Console: http://localhost:9001 (login: minioadmin/minioadmin)"
|
||||
|
||||
# Check if all services are up
|
||||
if [ $DB_STATUS -eq 0 ] && [ $MINIO_STATUS -eq 0 ] && [ $BACKEND_STATUS -eq 0 ] && [ $FRONTEND_STATUS -eq 0 ]; then
|
||||
echo -e "\n${GREEN}✅ All Worklenz services are running successfully!${NC}"
|
||||
else
|
||||
# Use Docker Compose V2
|
||||
docker compose down
|
||||
docker compose up -d
|
||||
echo -e "\n${YELLOW}⚠ Some services may not be running properly. Check the logs for more details:${NC}"
|
||||
echo " $DOCKER_COMPOSE_CMD logs"
|
||||
fi
|
||||
|
||||
# Wait for services to be ready
|
||||
echo "Waiting for services to start..."
|
||||
sleep 5
|
||||
|
||||
# Check if services are running
|
||||
if docker ps | grep -q "worklenz_frontend"; then
|
||||
echo -e "${GREEN}✓${NC} Frontend is running"
|
||||
FRONTEND_URL="http://localhost:5000"
|
||||
echo " Frontend URL: $FRONTEND_URL"
|
||||
else
|
||||
echo "✗ Frontend service failed to start"
|
||||
fi
|
||||
|
||||
if docker ps | grep -q "worklenz_backend"; then
|
||||
echo -e "${GREEN}✓${NC} Backend is running"
|
||||
BACKEND_URL="http://localhost:3000"
|
||||
echo " Backend URL: $BACKEND_URL"
|
||||
else
|
||||
echo "✗ Backend service failed to start"
|
||||
fi
|
||||
|
||||
if docker ps | grep -q "worklenz_minio"; then
|
||||
echo -e "${GREEN}✓${NC} MinIO is running"
|
||||
MINIO_URL="http://localhost:9001"
|
||||
echo " MinIO Console URL: $MINIO_URL (login: minioadmin/minioadmin)"
|
||||
else
|
||||
echo "✗ MinIO service failed to start"
|
||||
fi
|
||||
|
||||
if docker ps | grep -q "worklenz_db"; then
|
||||
echo -e "${GREEN}✓${NC} Database is running"
|
||||
else
|
||||
echo "✗ Database service failed to start"
|
||||
fi
|
||||
|
||||
echo -e "\n${GREEN}Worklenz is now running!${NC}"
|
||||
echo "You can access the application at: http://localhost:5000"
|
||||
echo "To stop the services, run: docker compose down"
|
||||
echo -e "\n${BLUE}Useful commands:${NC}"
|
||||
echo " • View logs: $DOCKER_COMPOSE_CMD logs -f"
|
||||
echo " • Stop services: ./stop.sh"
|
||||
echo " • Update environment variables: ./update-docker-env.sh"
|
||||
echo -e "\n${YELLOW}Note:${NC} To enable SSL, set ENABLE_SSL=true in your .env file and run ./update-docker-env.sh"
|
||||
45
stop.sh
Normal file → Executable file
45
stop.sh
Normal file → Executable file
@@ -2,18 +2,49 @@
|
||||
|
||||
# Colors for terminal output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${RED}Stopping Worklenz Docker Environment...${NC}"
|
||||
# Print banner
|
||||
echo -e "${RED}"
|
||||
echo " __ __ _ _"
|
||||
echo " \ \ / / | | | |"
|
||||
echo " \ \ /\ / /__ _ __| | _| | ___ _ __ ____"
|
||||
echo " \ \/ \/ / _ \| '__| |/ / |/ _ \ '_ \|_ /"
|
||||
echo " \ /\ / (_) | | | <| | __/ | | |/ /"
|
||||
echo " \/ \/ \___/|_| |_|\_\_|\___|_| |_/___|"
|
||||
echo ""
|
||||
echo " W O R K L E N Z "
|
||||
echo -e "${NC}"
|
||||
echo -e "${BLUE}Stopping Worklenz Docker Environment...${NC}"
|
||||
|
||||
# Check which Docker Compose command to use
|
||||
# Determine Docker Compose command to use
|
||||
DOCKER_COMPOSE_CMD=""
|
||||
if command -v docker compose &> /dev/null; then
|
||||
# Docker Compose V2
|
||||
docker compose down
|
||||
DOCKER_COMPOSE_CMD="docker compose"
|
||||
echo -e "${GREEN}✓${NC} Using Docker Compose V2"
|
||||
elif command -v docker-compose &> /dev/null; then
|
||||
DOCKER_COMPOSE_CMD="docker-compose"
|
||||
echo -e "${YELLOW}⚠${NC} Using legacy Docker Compose"
|
||||
else
|
||||
# Legacy Docker Compose
|
||||
docker-compose down
|
||||
echo -e "${RED}Error: Docker Compose is not installed or not in PATH${NC}"
|
||||
echo "Please install Docker Compose: https://docs.docker.com/compose/install/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Worklenz services have been stopped.${NC}"
|
||||
# Stop the containers
|
||||
echo -e "${BLUE}Stopping all services...${NC}"
|
||||
$DOCKER_COMPOSE_CMD down
|
||||
|
||||
# Check if containers are still running
|
||||
if docker ps | grep -q "worklenz_"; then
|
||||
echo -e "${YELLOW}⚠ Some Worklenz containers are still running. Forcing stop...${NC}"
|
||||
docker stop $(docker ps -q --filter "name=worklenz_")
|
||||
echo -e "${GREEN}✓${NC} Forced stop completed."
|
||||
else
|
||||
echo -e "${GREEN}✓${NC} All Worklenz services have been stopped successfully."
|
||||
fi
|
||||
|
||||
echo -e "\n${BLUE}To start Worklenz again, run:${NC} ./start.sh"
|
||||
141
update-docker-env.sh
Executable file
141
update-docker-env.sh
Executable file
@@ -0,0 +1,141 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to set environment variables for Docker deployment
|
||||
# Usage: ./update-docker-env.sh [hostname] [use_ssl]
|
||||
|
||||
# Default hostname if not provided
|
||||
DEFAULT_HOSTNAME="localhost"
|
||||
HOSTNAME=${1:-$DEFAULT_HOSTNAME}
|
||||
|
||||
# Check if SSL should be used
|
||||
USE_SSL=${2:-false}
|
||||
|
||||
# Set protocol prefixes based on SSL flag
|
||||
if [ "$USE_SSL" = "true" ]; then
|
||||
HTTP_PREFIX="https://"
|
||||
WS_PREFIX="wss://"
|
||||
else
|
||||
HTTP_PREFIX="http://"
|
||||
WS_PREFIX="ws://"
|
||||
fi
|
||||
|
||||
# Frontend URLs
|
||||
FRONTEND_URL="${HTTP_PREFIX}${HOSTNAME}:5000"
|
||||
MINIO_DASHBOARD_URL="${HTTP_PREFIX}${HOSTNAME}:9001"
|
||||
|
||||
# Create or overwrite frontend .env.development file
|
||||
mkdir -p worklenz-frontend
|
||||
cat > worklenz-frontend/.env.development << EOL
|
||||
# API Connection
|
||||
VITE_API_URL=http://localhost:3000
|
||||
VITE_SOCKET_URL=ws://localhost:3000
|
||||
|
||||
# Application Environment
|
||||
VITE_APP_TITLE=Worklenz
|
||||
VITE_APP_ENV=development
|
||||
|
||||
# Mixpanel
|
||||
VITE_MIXPANEL_TOKEN=
|
||||
|
||||
# Recaptcha
|
||||
VITE_ENABLE_RECAPTCHA=false
|
||||
VITE_RECAPTCHA_SITE_KEY=
|
||||
|
||||
# Session ID
|
||||
VITE_WORKLENZ_SESSION_ID=worklenz-session-id
|
||||
EOL
|
||||
|
||||
# Create frontend .env.production file
|
||||
cat > worklenz-frontend/.env.production << EOL
|
||||
# API Connection
|
||||
VITE_API_URL=${HTTP_PREFIX}${HOSTNAME}:3000
|
||||
VITE_SOCKET_URL=${WS_PREFIX}${HOSTNAME}:3000
|
||||
|
||||
# Application Environment
|
||||
VITE_APP_TITLE=Worklenz
|
||||
VITE_APP_ENV=production
|
||||
|
||||
# Mixpanel
|
||||
VITE_MIXPANEL_TOKEN=
|
||||
|
||||
# Recaptcha
|
||||
VITE_ENABLE_RECAPTCHA=false
|
||||
VITE_RECAPTCHA_SITE_KEY=
|
||||
|
||||
# Session ID
|
||||
VITE_WORKLENZ_SESSION_ID=worklenz-session-id
|
||||
EOL
|
||||
|
||||
# Create backend environment file
|
||||
mkdir -p worklenz-backend
|
||||
cat > worklenz-backend/.env << EOL
|
||||
# Server
|
||||
NODE_ENV=production
|
||||
PORT=3000
|
||||
SESSION_NAME=worklenz.sid
|
||||
SESSION_SECRET=$(openssl rand -base64 48)
|
||||
COOKIE_SECRET=$(openssl rand -base64 48)
|
||||
|
||||
# CORS
|
||||
SOCKET_IO_CORS=${FRONTEND_URL}
|
||||
SERVER_CORS=${FRONTEND_URL}
|
||||
|
||||
|
||||
# Google Login
|
||||
GOOGLE_CLIENT_ID="your_google_client_id"
|
||||
GOOGLE_CLIENT_SECRET="your_google_client_secret"
|
||||
GOOGLE_CALLBACK_URL="${FRONTEND_URL}/secure/google/verify"
|
||||
LOGIN_FAILURE_REDIRECT="${FRONTEND_URL}/auth/authenticating"
|
||||
LOGIN_SUCCESS_REDIRECT="${FRONTEND_URL}/auth/authenticating"
|
||||
|
||||
# Database
|
||||
DB_HOST=db
|
||||
DB_PORT=5432
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=password
|
||||
DB_NAME=worklenz_db
|
||||
DB_MAX_CLIENTS=50
|
||||
USE_PG_NATIVE=true
|
||||
|
||||
# Storage Configuration
|
||||
STORAGE_PROVIDER=s3
|
||||
AWS_REGION=us-east-1
|
||||
AWS_BUCKET=worklenz-bucket
|
||||
AWS_ACCESS_KEY_ID=minioadmin
|
||||
AWS_SECRET_ACCESS_KEY=minioadmin
|
||||
S3_URL=http://minio:9000
|
||||
|
||||
# Backend Directories
|
||||
BACKEND_PUBLIC_DIR=./public
|
||||
BACKEND_VIEWS_DIR=./views
|
||||
|
||||
# Host
|
||||
HOSTNAME=${HOSTNAME}
|
||||
FRONTEND_URL=${FRONTEND_URL}
|
||||
|
||||
# Email
|
||||
SOURCE_EMAIL=no-reply@example.com
|
||||
|
||||
# Notifications
|
||||
SLACK_WEBHOOK=
|
||||
|
||||
# Other Settings
|
||||
COMMIT_BUILD_IMMEDIATELY=true
|
||||
|
||||
# JWT Secret
|
||||
JWT_SECRET=$(openssl rand -base64 48)
|
||||
EOL
|
||||
|
||||
echo "Environment configuration updated for ${HOSTNAME} with" $([ "$USE_SSL" = "true" ] && echo "HTTPS/WSS" || echo "HTTP/WS")
|
||||
echo "Created/updated environment files:"
|
||||
echo "- worklenz-frontend/.env.development (development)"
|
||||
echo "- worklenz-frontend/.env.production (production build)"
|
||||
echo "- worklenz-backend/.env"
|
||||
echo
|
||||
echo "To run with Docker Compose, use: docker-compose up -d"
|
||||
echo
|
||||
echo "Frontend URL: ${FRONTEND_URL}"
|
||||
echo "API URL: ${HTTP_PREFIX}${HOSTNAME}:3000"
|
||||
echo "Socket URL: ${WS_PREFIX}${HOSTNAME}:3000"
|
||||
echo "MinIO Dashboard URL: ${MINIO_DASHBOARD_URL}"
|
||||
echo "CORS is configured to allow requests from: ${FRONTEND_URL}"
|
||||
@@ -1,5 +1,9 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
build
|
||||
.scannerwork
|
||||
coverage
|
||||
.dockerignore
|
||||
.git
|
||||
*.md
|
||||
tests
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
# Server
|
||||
NODE_ENV=development
|
||||
PORT=3000
|
||||
SESSION_NAME=worklenz.sid
|
||||
SESSION_SECRET="your_session_secret"
|
||||
COOKIE_SECRET="your_cookie_secret"
|
||||
|
||||
# CORS
|
||||
SOCKET_IO_CORS=http://localhost:5000
|
||||
SERVER_CORS=*
|
||||
|
||||
# Database
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=your_db_password
|
||||
DB_NAME=worklenz_db
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_MAX_CLIENTS=50
|
||||
|
||||
# Google Login
|
||||
GOOGLE_CLIENT_ID="your_google_client_id"
|
||||
GOOGLE_CLIENT_SECRET="your_google_client_secret"
|
||||
GOOGLE_CALLBACK_URL="http://localhost:5000/secure/google/verify"
|
||||
LOGIN_FAILURE_REDIRECT="http://localhost:5000/auth/authenticating"
|
||||
LOGIN_SUCCESS_REDIRECT="http://localhost:5000/auth/authenticating"
|
||||
|
||||
# CLI
|
||||
ANGULAR_DIST_DIR="path/to/frontend/dist"
|
||||
ANGULAR_SRC_DIR="path/to/frontend"
|
||||
BACKEND_PUBLIC_DIR="path/to/backend/public"
|
||||
BACKEND_VIEWS_DIR="path/to/backend/views"
|
||||
COMMIT_BUILD_IMMEDIATELY=false
|
||||
|
||||
# HOST
|
||||
HOSTNAME=localhost:5000
|
||||
|
||||
# SLACK
|
||||
SLACK_WEBHOOK=your_slack_webhook_url
|
||||
USE_PG_NATIVE=false
|
||||
|
||||
# JWT SECRET
|
||||
JWT_SECRET=your_jwt_secret
|
||||
|
||||
# FRONTEND_URL
|
||||
FRONTEND_URL=http://localhost:5000
|
||||
|
||||
# STORAGE
|
||||
STORAGE_PROVIDER=s3 # values s3 or azure
|
||||
|
||||
# AWS
|
||||
AWS_REGION="your_aws_region"
|
||||
AWS_ACCESS_KEY_ID="your_aws_access_key_id"
|
||||
AWS_SECRET_ACCESS_KEY="your_aws_secret_access_key"
|
||||
AWS_BUCKET="your_s3_bucket"
|
||||
S3_URL="your_s3_url"
|
||||
|
||||
# Azure Storage
|
||||
AZURE_STORAGE_ACCOUNT_NAME="your_storage_account_name"
|
||||
AZURE_STORAGE_CONTAINER="your_storage_container"
|
||||
AZURE_STORAGE_ACCOUNT_KEY="your_storage_account_key"
|
||||
AZURE_STORAGE_URL="your_storage_url"
|
||||
|
||||
# DIRECTPAY
|
||||
DP_STAGE=DEV
|
||||
DP_URL=your_url
|
||||
DP_MERCHANT_ID=your_merchant_id
|
||||
DP_SECRET_KEY=your_secret_key
|
||||
DP_API_KEY=your_api_key
|
||||
|
||||
CONTACT_US_EMAIL=support@example.com
|
||||
|
||||
GOOGLE_CAPTCHA_SECRET_KEY=your_captcha_secret_key
|
||||
GOOGLE_CAPTCHA_PASS_SCORE=0.8
|
||||
|
||||
# Email Cronjobs
|
||||
ENABLE_EMAIL_CRONJOBS=true
|
||||
@@ -1,26 +1,39 @@
|
||||
# Use the official Node.js 20 image as a base
|
||||
FROM node:20
|
||||
# --- Stage 1: Build ---
|
||||
FROM node:20-slim AS builder
|
||||
|
||||
ARG RELEASE_VERSION
|
||||
RUN apt-get update && apt-get install -y \
|
||||
python3 \
|
||||
make \
|
||||
g++ \
|
||||
curl \
|
||||
postgresql-server-dev-all \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create and set the working directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install global dependencies
|
||||
RUN npm install -g ts-node typescript grunt grunt-cli
|
||||
|
||||
# Copy package.json and package-lock.json (if available)
|
||||
COPY package*.json ./
|
||||
|
||||
# Install app dependencies
|
||||
RUN npm ci
|
||||
|
||||
# Copy the rest of the application code
|
||||
COPY . .
|
||||
|
||||
# Run the build script to compile TypeScript to JavaScript
|
||||
RUN npm run build
|
||||
|
||||
# Expose the port the app runs on
|
||||
EXPOSE 3000
|
||||
RUN echo "$RELEASE_VERSION" > release
|
||||
|
||||
# --- Stage 2: Production Image ---
|
||||
FROM node:20-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y libpq5 && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /usr/src/app/package*.json ./
|
||||
COPY --from=builder /usr/src/app/build ./build
|
||||
COPY --from=builder /usr/src/app/node_modules ./node_modules
|
||||
COPY --from=builder /usr/src/app/release ./release
|
||||
COPY --from=builder /usr/src/app/worklenz-email-templates ./worklenz-email-templates
|
||||
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["node", "build/bin/www"]
|
||||
|
||||
# Start the application
|
||||
CMD ["npm", "start"]
|
||||
@@ -12,7 +12,7 @@ CREATE TYPE DEPENDENCY_TYPE AS ENUM ('blocked_by');
|
||||
|
||||
CREATE TYPE SCHEDULE_TYPE AS ENUM ('daily', 'weekly', 'yearly', 'monthly', 'every_x_days', 'every_x_weeks', 'every_x_months');
|
||||
|
||||
CREATE TYPE LANGUAGE_TYPE AS ENUM ('en', 'es', 'pt');
|
||||
CREATE TYPE LANGUAGE_TYPE AS ENUM ('en', 'es', 'pt', 'alb', 'de');
|
||||
|
||||
-- START: Users
|
||||
CREATE SEQUENCE IF NOT EXISTS users_user_no_seq START 1;
|
||||
|
||||
@@ -55,21 +55,25 @@ const allowedOrigins = [
|
||||
isProduction()
|
||||
? [
|
||||
`http://localhost:5000`,
|
||||
`http://127.0.0.1:5000`
|
||||
]
|
||||
`http://127.0.0.1:5000`,
|
||||
process.env.SERVER_CORS || "", // Add hostname from env
|
||||
process.env.FRONTEND_URL || "" // Support FRONTEND_URL as well
|
||||
].filter(Boolean) // Remove empty strings
|
||||
: [
|
||||
"http://localhost:3000",
|
||||
"http://localhost:5173",
|
||||
"http://127.0.0.1:5173",
|
||||
"http://127.0.0.1:3000",
|
||||
"http://127.0.0.1:5000",
|
||||
`http://localhost:5000`
|
||||
]
|
||||
`http://localhost:5000`,
|
||||
process.env.SERVER_CORS || "", // Add hostname from env
|
||||
process.env.FRONTEND_URL || "" // Support FRONTEND_URL as well
|
||||
].filter(Boolean) // Remove empty strings
|
||||
].flat();
|
||||
|
||||
app.use(cors({
|
||||
origin: (origin, callback) => {
|
||||
if (!origin || allowedOrigins.includes(origin)) {
|
||||
if (!isProduction() || !origin || allowedOrigins.includes(origin)) {
|
||||
callback(null, true);
|
||||
} else {
|
||||
console.log("Blocked origin:", origin, process.env.NODE_ENV);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export interface ISocketSession {
|
||||
session?: {
|
||||
passport?: { user?: string; }
|
||||
passport?: { user?: { id: string } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,8 @@ import safeControllerFunction from "../../shared/safe-controller-function";
|
||||
const public_router = express.Router();
|
||||
|
||||
public_router.post("/new-subscriber", safeControllerFunction(ClientsController.addSubscriber));
|
||||
public_router.get("/health", (req, res) => {
|
||||
res.status(200).json({ status: "ok" });
|
||||
});
|
||||
|
||||
export default public_router;
|
||||
|
||||
@@ -15,7 +15,10 @@ export function log_error(error: any) {
|
||||
|
||||
export function getLoggedInUserIdFromSocket(socket: Socket): string | null {
|
||||
const {session} = socket.request as ISocketSession;
|
||||
return session?.passport?.user || null;
|
||||
if (session?.passport?.user?.id) {
|
||||
return session.passport.user.id;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function notifyProjectUpdates(socket: Socket, taskId: string) {
|
||||
|
||||
6
worklenz-frontend/.dockerignore
Normal file
6
worklenz-frontend/.dockerignore
Normal file
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
.git
|
||||
.gitignore
|
||||
.dockerignore
|
||||
README.md
|
||||
@@ -7,7 +7,12 @@ COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# Create env-config.js dynamically during build
|
||||
RUN echo "window.VITE_API_URL='${VITE_API_URL:-http://backend:3000}';" > ./public/env-config.js && \
|
||||
echo "window.VITE_SOCKET_URL='${VITE_SOCKET_URL:-ws://backend:3000}';" >> ./public/env-config.js
|
||||
|
||||
RUN NODE_OPTIONS="--max-old-space-size=4096" npm run build
|
||||
|
||||
FROM node:22-alpine AS production
|
||||
|
||||
@@ -16,5 +21,24 @@ WORKDIR /app
|
||||
RUN npm install -g serve
|
||||
|
||||
COPY --from=build /app/build /app/build
|
||||
COPY --from=build /app/public/env-config.js /app/build/env-config.js
|
||||
|
||||
# Create env-config.sh script
|
||||
RUN echo '#!/bin/sh' > /app/env-config.sh && \
|
||||
echo '# Update env-config.js with runtime environment variables' >> /app/env-config.sh && \
|
||||
echo 'cat > /app/build/env-config.js << EOL' >> /app/env-config.sh && \
|
||||
echo 'window.VITE_API_URL="${VITE_API_URL:-http://backend:3000}";' >> /app/env-config.sh && \
|
||||
echo 'window.VITE_SOCKET_URL="${VITE_SOCKET_URL:-ws://backend:3000}";' >> /app/env-config.sh && \
|
||||
echo 'EOL' >> /app/env-config.sh && \
|
||||
chmod +x /app/env-config.sh
|
||||
|
||||
# Create start.sh script
|
||||
RUN echo '#!/bin/sh' > /app/start.sh && \
|
||||
echo '# Run environment configuration' >> /app/start.sh && \
|
||||
echo '/app/env-config.sh' >> /app/start.sh && \
|
||||
echo '# Start the server' >> /app/start.sh && \
|
||||
echo 'exec serve -s build -l 5000' >> /app/start.sh && \
|
||||
chmod +x /app/start.sh
|
||||
|
||||
EXPOSE 5000
|
||||
CMD ["serve", "-s", "build", "-l", "5000"]
|
||||
CMD ["/app/start.sh"]
|
||||
@@ -8,6 +8,7 @@ Worklenz is a project management application built with React, TypeScript, and A
|
||||
- [Project Structure](#project-structure)
|
||||
- [Contributing](#contributing)
|
||||
- [Learn More](#learn-more)
|
||||
- [License](#license)
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -93,3 +94,7 @@ To learn more about the technologies used in this project:
|
||||
- [TypeScript Documentation](https://www.typescriptlang.org/docs/)
|
||||
- [Ant Design Documentation](https://ant.design/docs/react/introduce)
|
||||
- [Vite Documentation](https://vitejs.dev/guide/)
|
||||
|
||||
## License
|
||||
|
||||
Worklenz is open source and released under the [GNU Affero General Public License Version 3 (AGPLv3)](LICENSE).
|
||||
|
||||
@@ -12,6 +12,83 @@
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<title>Worklenz</title>
|
||||
<!-- Environment configuration -->
|
||||
<script src="/env-config.js"></script>
|
||||
<!-- Google Analytics -->
|
||||
<script>
|
||||
// Function to initialize Google Analytics
|
||||
function initGoogleAnalytics() {
|
||||
// Load the Google Analytics script
|
||||
const script = document.createElement('script');
|
||||
script.async = true;
|
||||
|
||||
// Determine which tracking ID to use based on the environment
|
||||
const isProduction = window.location.hostname === 'worklenz.com' ||
|
||||
window.location.hostname === 'app.worklenz.com';
|
||||
|
||||
const trackingId = isProduction
|
||||
? 'G-XXXXXXXXXX'
|
||||
: 'G-3LM2HGWEXG'; // Open source tracking ID
|
||||
|
||||
script.src = `https://www.googletagmanager.com/gtag/js?id=${trackingId}`;
|
||||
document.head.appendChild(script);
|
||||
|
||||
// Initialize Google Analytics
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', trackingId);
|
||||
}
|
||||
|
||||
// Initialize analytics
|
||||
initGoogleAnalytics();
|
||||
|
||||
// Function to show privacy notice
|
||||
function showPrivacyNotice() {
|
||||
const notice = document.createElement('div');
|
||||
notice.style.cssText = `
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
right: 16px;
|
||||
background: #222;
|
||||
color: #f5f5f5;
|
||||
padding: 12px 16px 10px 16px;
|
||||
border-radius: 7px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.18);
|
||||
z-index: 1000;
|
||||
max-width: 320px;
|
||||
font-family: Inter, sans-serif;
|
||||
border: 1px solid #333;
|
||||
font-size: 0.95rem;
|
||||
`;
|
||||
notice.innerHTML = `
|
||||
<div style="margin-bottom: 6px; font-weight: 600; color: #fff; font-size: 1rem;">Analytics Notice</div>
|
||||
<div style="margin-bottom: 8px; color: #f5f5f5;">This app uses Google Analytics for anonymous usage stats. No personal data is tracked.</div>
|
||||
<button id="analytics-notice-btn" style="padding: 5px 14px; background: #1890ff; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 0.95rem;">Got it</button>
|
||||
`;
|
||||
document.body.appendChild(notice);
|
||||
// Add event listener to button
|
||||
const btn = notice.querySelector('#analytics-notice-btn');
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
localStorage.setItem('privacyNoticeShown', 'true');
|
||||
notice.remove();
|
||||
});
|
||||
}
|
||||
|
||||
// Wait for DOM to be ready
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Check if we should show the notice
|
||||
const isProduction = window.location.hostname === 'worklenz.com' ||
|
||||
window.location.hostname === 'app.worklenz.com';
|
||||
const noticeShown = localStorage.getItem('privacyNoticeShown') === 'true';
|
||||
|
||||
// Show notice if not in production and not shown before
|
||||
if (!isProduction && !noticeShown) {
|
||||
showPrivacyNotice();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
4
worklenz-frontend/public/locales/alb/404-page.json
Normal file
4
worklenz-frontend/public/locales/alb/404-page.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"doesNotExistText": "Na vjen keq, faqja që kërkoni nuk ekziston.",
|
||||
"backHomeButton": "Kthehu në Faqen Kryesore"
|
||||
}
|
||||
31
worklenz-frontend/public/locales/alb/account-setup.json
Normal file
31
worklenz-frontend/public/locales/alb/account-setup.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"continue": "Vazhdo",
|
||||
|
||||
"setupYourAccount": "Konfiguro Llogarinë Tënde në Worklenz.",
|
||||
"organizationStepTitle": "Emërtoni Organizatën Tuaj",
|
||||
"organizationStepLabel": "Zgjidhni një emër për llogarinë tuaj në Worklenz.",
|
||||
|
||||
"projectStepTitle": "Krijoni projektin tuaj të parë",
|
||||
"projectStepLabel": "Në cilin projekt po punoni aktualisht?",
|
||||
"projectStepPlaceholder": "p.sh. Plani i Marketingut",
|
||||
|
||||
"tasksStepTitle": "Krijoni detyrat tuaja të para",
|
||||
"tasksStepLabel": "Shkruani disa detyra që do të kryeni në",
|
||||
"tasksStepAddAnother": "Shto një tjetër",
|
||||
|
||||
"emailPlaceholder": "Adresa email",
|
||||
"invalidEmail": "Ju lutemi vendosni një adresë email të vlefshme",
|
||||
"or": "ose",
|
||||
"templateButton": "Importo nga shablloni",
|
||||
"goBack": "Kthehu Mbrapa",
|
||||
"cancel": "Anulo",
|
||||
"create": "Krijo",
|
||||
"templateDrawerTitle": "Zgjidh nga shabllonet",
|
||||
"step3InputLabel": "Fto me email",
|
||||
"addAnother": "Shto një tjetër",
|
||||
"skipForNow": "Kalo tani për tani",
|
||||
"formTitle": "Krijoni detyrën tuaj të parë.",
|
||||
"step3Title": "Fto ekipin tënd të punojë me",
|
||||
"maxMembers": " (Mund të ftoni deri në 5 anëtarë)",
|
||||
"maxTasks": " (Mund të krijoni deri në 5 detyra)"
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"title": "Faturimet",
|
||||
"currentBill": "Fatura Aktuale",
|
||||
"configuration": "Konfigurimi",
|
||||
"currentPlanDetails": "Detajet e Planit Aktual",
|
||||
"upgradePlan": "Përmirëso Planin",
|
||||
"cardBodyText01": "Provë falas",
|
||||
"cardBodyText02": "(Plani juaj i provës skadon në 1 muaj 19 ditë)",
|
||||
"redeemCode": "Kodi i Zbritjes",
|
||||
"accountStorage": "Depozita e Llogarisë",
|
||||
"used": "Përdorur:",
|
||||
"remaining": "E mbetur:",
|
||||
"charges": "Tarifat",
|
||||
"tooltip": "Tarifat për ciklin aktual të faturimit",
|
||||
"description": "Përshkrimi",
|
||||
"billingPeriod": "Periudha e Faturimit",
|
||||
"billStatus": "Statusi i Faturës",
|
||||
"perUserValue": "Vlera për Përdorues",
|
||||
"users": "Përdoruesit",
|
||||
|
||||
"amount": "Shuma",
|
||||
"invoices": "Faturat",
|
||||
"transactionId": "ID e Transaksionit",
|
||||
"transactionDate": "Data e Transaksionit",
|
||||
"paymentMethod": "Metoda e Pagesës",
|
||||
"status": "Statusi",
|
||||
"ltdUsers": "Mund të shtoni deri në {{ltd_users}} përdorues.",
|
||||
|
||||
"totalSeats": "Vende totale",
|
||||
"availableSeats": "Vende të disponueshme",
|
||||
"addMoreSeats": "Shto më shumë vende",
|
||||
|
||||
"drawerTitle": "Kodi i Zbritjes",
|
||||
"label": "Kodi i Zbritjes",
|
||||
"drawerPlaceholder": "Vendosni kodin tuaj të zbritjes",
|
||||
"redeemSubmit": "Paraqit",
|
||||
|
||||
"modalTitle": "Zgjidhni planin më të mirë për ekipin tuaj",
|
||||
"seatLabel": "Numri i vendeve",
|
||||
"freePlan": "Plan Falas",
|
||||
"startup": "Startup",
|
||||
"business": "Biznes",
|
||||
"tag": "Më i Popullarizuar",
|
||||
"enterprise": "Ndërmarrje",
|
||||
|
||||
"freeSubtitle": "falas përgjithmonë",
|
||||
"freeUsers": "Më e mira për përdorim personal",
|
||||
"freeText01": "100MB depozitë",
|
||||
"freeText02": "3 projekte",
|
||||
"freeText03": "5 anëtarë të ekipit",
|
||||
|
||||
"startupSubtitle": "ÇMIM I RASTËSISHËM / muaj",
|
||||
"startupUsers": "Deri në 15 përdorues",
|
||||
"startupText01": "25GB depozitë",
|
||||
"startupText02": "Projekte të pakufizuara aktive",
|
||||
"startupText03": "Orar",
|
||||
"startupText04": "Raportim",
|
||||
"startupText05": "Abonohu në projekte",
|
||||
|
||||
"businessSubtitle": "përdorues / muaj",
|
||||
"businessUsers": "16 - 200 përdorues",
|
||||
|
||||
"enterpriseUsers": "200 - 500+ përdorues",
|
||||
|
||||
"footerTitle": "Ju lutemi na jepni një numër kontakti që mund të përdorim për t'ju kontaktuar.",
|
||||
"footerLabel": "Numri i Kontaktit",
|
||||
"footerButton": "Na kontaktoni",
|
||||
|
||||
"redeemCodePlaceHolder": "Vendosni kodin tuaj të zbritjes",
|
||||
"submit": "Paraqit",
|
||||
|
||||
"trialPlan": "Provë Falas",
|
||||
"trialExpireDate": "E vlefshme deri më {{trial_expire_date}}",
|
||||
"trialExpired": "Provat tuaja falas skaduan {{trial_expire_string}}",
|
||||
"trialInProgress": "Provat tuaja falas skadojnë {{trial_expire_string}}",
|
||||
|
||||
"required": "Kjo fushë është e detyrueshme",
|
||||
"invalidCode": "Kod i pavlefshëm",
|
||||
|
||||
"selectPlan": "Zgjidhni planin më të mirë për ekipin tuaj",
|
||||
"changeSubscriptionPlan": "Ndryshoni planin tuaj të abonimit",
|
||||
"noOfSeats": "Numri i vendeve",
|
||||
"annualPlan": "Pro - Vjetor",
|
||||
"monthlyPlan": "Pro - Mujor",
|
||||
"freeForever": "Falas Përgjithmonë",
|
||||
"bestForPersonalUse": "Më e mira për përdorim personal",
|
||||
"storage": "Depozitë",
|
||||
"projects": "Projekte",
|
||||
"teamMembers": "Anëtarët e Ekipit",
|
||||
"unlimitedTeamMembers": "Anëtarë të pakufizuar të ekipit",
|
||||
"unlimitedActiveProjects": "Projekte të pakufizuara aktive",
|
||||
"schedule": "Orar",
|
||||
"reporting": "Raportim",
|
||||
"subscribeToProjects": "Abonohu në projekte",
|
||||
"billedAnnually": "Faturuar çdo vit",
|
||||
"billedMonthly": "Faturuar çdo muaj",
|
||||
|
||||
"pausePlan": "Pauzë Planin",
|
||||
"resumePlan": "Rifillo Planin",
|
||||
"changePlan": "Ndrysho Planin",
|
||||
"cancelPlan": "Anulo Planin",
|
||||
|
||||
"perMonthPerUser": "për përdorues/muaj",
|
||||
"viewInvoice": "Shiko Faturën",
|
||||
"switchToFreePlan": "Kalo në Planin Falas",
|
||||
|
||||
"expirestoday": "sot",
|
||||
"expirestomorrow": "nesër",
|
||||
"expiredDaysAgo": "{{days}} ditë më parë",
|
||||
|
||||
"continueWith": "Vazhdo me {{plan}}",
|
||||
"changeToPlan": "Ndrysho në {{plan}}"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"overview": "Përmbledhje",
|
||||
"name": "Emri i Organizatës",
|
||||
"owner": "Pronari i Organizatës",
|
||||
"admins": "Administruesit e Organizatës",
|
||||
"contactNumber": "Shto Numrin e Kontaktit",
|
||||
"edit": "Redakto"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"membersCount": "Numri i Anëtarëve",
|
||||
"createdAt": "Krijuar më",
|
||||
"projectName": "Emri i Projektit",
|
||||
"teamName": "Emri i Ekipit",
|
||||
"refreshProjects": "Rifresko Projektet",
|
||||
"searchPlaceholder": "Kërkoni sipas emrit të projektit",
|
||||
"deleteProject": "Jeni i sigurt që dëshironi të fshini këtë projekt?",
|
||||
"confirm": "Konfirmo",
|
||||
"cancel": "Anulo",
|
||||
"delete": "Fshi Projektin"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"overview": "Përmbledhje",
|
||||
"users": "Përdoruesit",
|
||||
"teams": "Ekipet",
|
||||
"billing": "Faturimi",
|
||||
"projects": "Projektet",
|
||||
"adminCenter": "Qendra Administrative"
|
||||
}
|
||||
33
worklenz-frontend/public/locales/alb/admin-center/teams.json
Normal file
33
worklenz-frontend/public/locales/alb/admin-center/teams.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"title": "Ekipet",
|
||||
"subtitle": "ekipet",
|
||||
"tooltip": "Rifresko ekipet",
|
||||
"placeholder": "Kërko sipas emrit",
|
||||
"addTeam": "Shto Ekip",
|
||||
"team": "Ekipi",
|
||||
"membersCount": "Numri i Anëtarëve",
|
||||
"members": "Anëtarët",
|
||||
"drawerTitle": "Krijo Ekip të Ri",
|
||||
"label": "Emri i Ekipit",
|
||||
"drawerPlaceholder": "Emri",
|
||||
"create": "Krijo",
|
||||
"delete": "Fshi",
|
||||
"settings": "Cilësimet",
|
||||
"popTitle": "Jeni i sigurt?",
|
||||
"message": "Ju lutemi shkruani një Emër",
|
||||
"teamSettings": "Cilësimet e Ekipit",
|
||||
"teamName": "Emri i Ekipit",
|
||||
"teamDescription": "Përshkrimi i Ekipit",
|
||||
"teamMembers": "Anëtarët e Ekipit",
|
||||
"teamMembersCount": "Numri i Anëtarëve të Ekipit",
|
||||
"teamMembersPlaceholder": "Kërko sipas emrit",
|
||||
"addMember": "Shto Anëtar",
|
||||
"add": "Shto",
|
||||
"update": "Përditëso",
|
||||
"teamNamePlaceholder": "Emri i ekipit",
|
||||
"user": "Përdoruesi",
|
||||
"role": "Roli",
|
||||
"owner": "Pronari",
|
||||
"admin": "Administruesi",
|
||||
"member": "Anëtari"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"title": "Përdoruesit",
|
||||
"subTitle": "përdoruesit",
|
||||
"placeholder": "Kërko sipas emrit",
|
||||
"user": "Përdoruesi",
|
||||
"email": "Email",
|
||||
"lastActivity": "Aktiviteti i Fundit",
|
||||
"refresh": "Rifresko përdoruesit"
|
||||
}
|
||||
23
worklenz-frontend/public/locales/alb/all-project-list.json
Normal file
23
worklenz-frontend/public/locales/alb/all-project-list.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "Emri",
|
||||
"client": "Klienti",
|
||||
"category": "Kategoria",
|
||||
"status": "Statusi",
|
||||
"tasksProgress": "Progresi i Detyrave",
|
||||
"updated_at": "Përditësuar Së Fundi",
|
||||
"members": "Anëtarët",
|
||||
"setting": "Cilësimet",
|
||||
"projects": "Projektet",
|
||||
"refreshProjects": "Rifresko projektet",
|
||||
"all": "Të Gjitha",
|
||||
"favorites": "Të Preferuarat",
|
||||
"archived": "Të Arkivuara",
|
||||
"placeholder": "Kërko sipas emrit",
|
||||
"archive": "Arkivo",
|
||||
"unarchive": "Ç'arkivo",
|
||||
"archiveConfirm": "Jeni i sigurt që doni ta arkivoni këtë projekt?",
|
||||
"unarchiveConfirm": "Jeni i sigurt që doni ta çarkivoni këtë projekt?",
|
||||
"clickToFilter": "Klikoni për të filtruar sipas",
|
||||
"noProjects": "Nuk u gjetën projekte",
|
||||
"addToFavourites": "Shto në të preferuarat"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"loggingOut": "Po dilni...",
|
||||
"authenticating": "Po autentikoheni...",
|
||||
"gettingThingsReady": "Po përgatiten gjërat për ju..."
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"headerDescription": "Rivendosni fjalëkalimin tuaj",
|
||||
"emailLabel": "Email",
|
||||
"emailPlaceholder": "Vendosni email-in tuaj",
|
||||
"emailRequired": "Ju lutemi vendosni Email-in tuaj!",
|
||||
"resetPasswordButton": "Rivendos Fjalëkalimin",
|
||||
"returnToLoginButton": "Kthehu te Hyrja",
|
||||
"passwordResetSuccessMessage": "Një lidhje për rivendosjen e fjalëkalimit është dërguar në email-in tuaj.",
|
||||
"orText": "OSE",
|
||||
"successTitle": "U dërguan udhëzimet për rivendosje!",
|
||||
"successMessage": "Informacioni për rivendosje është dërguar në email-in tuaj. Ju lutemi kontrolloni email-in."
|
||||
}
|
||||
27
worklenz-frontend/public/locales/alb/auth/login.json
Normal file
27
worklenz-frontend/public/locales/alb/auth/login.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"headerDescription": "Hyni në llogarinë tuaj",
|
||||
"emailLabel": "Email",
|
||||
"emailPlaceholder": "Vendosni email-in tuaj",
|
||||
"emailRequired": "Ju lutemi vendosni Email-in tuaj!",
|
||||
"passwordLabel": "Fjalëkalimi",
|
||||
"passwordPlaceholder": "Vendosni fjalëkalimin",
|
||||
"passwordRequired": "Ju lutemi vendosni Fjalëkalimin!",
|
||||
"rememberMe": "Më mbaj mend",
|
||||
"loginButton": "Hyr",
|
||||
"signupButton": "Regjistrohu",
|
||||
"forgotPasswordButton": "Keni harruar fjalëkalimin?",
|
||||
"signInWithGoogleButton": "Hyr me Google",
|
||||
"dontHaveAccountText": "Nuk keni llogari?",
|
||||
"orText": "OSE",
|
||||
"successMessage": "Jeni futur me sukses!",
|
||||
"loginError": "Hyrja dështoi",
|
||||
"googleLoginError": "Hyrja përmes Google dështoi",
|
||||
"validationMessages": {
|
||||
"email": "Ju lutemi vendosni një adresë email të vlefshme",
|
||||
"password": "Fjalëkalimi duhet të jetë së paku 8 karaktere"
|
||||
},
|
||||
"errorMessages": {
|
||||
"loginErrorTitle": "Hyrja dështoi",
|
||||
"loginErrorMessage": "Ju lutemi kontrolloni email-in dhe fjalëkalimin dhe provoni përsëri"
|
||||
}
|
||||
}
|
||||
29
worklenz-frontend/public/locales/alb/auth/signup.json
Normal file
29
worklenz-frontend/public/locales/alb/auth/signup.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"headerDescription": "Regjistrohuni për të filluar",
|
||||
"nameLabel": "Emri i Plotë",
|
||||
"namePlaceholder": "Shkruani emrin tuaj të plotë",
|
||||
"nameRequired": "Ju lutemi shkruani emrin tuaj të plotë!",
|
||||
"nameMinCharacterRequired": "Emri duhet të jetë së paku 4 karaktere!",
|
||||
"emailLabel": "Email",
|
||||
"emailPlaceholder": "Shkruani email-in tuaj",
|
||||
"emailRequired": "Ju lutemi shkruani Email-in tuaj!",
|
||||
"passwordLabel": "Fjalëkalimi",
|
||||
"passwordPlaceholder": "Krijoni një fjalëkalim",
|
||||
"passwordRequired": "Ju lutemi krijoni një Fjalëkalim!",
|
||||
"passwordMinCharacterRequired": "Fjalëkalimi duhet të jetë së paku 8 karaktere!",
|
||||
"passwordPatternRequired": "Fjalëkalimi nuk plotëson kërkesat!",
|
||||
"strongPasswordPlaceholder": "Vendosni një fjalëkalim më të fortë",
|
||||
"passwordValidationAltText": "Fjalëkalimi duhet të përmbajë së paku 8 karaktere me shkronja të mëdha dhe të vogla, një numër dhe një simbol.",
|
||||
"signupSuccessMessage": "Jeni regjistruar me sukses!",
|
||||
"privacyPolicyLink": "Politika e Privatësisë",
|
||||
"termsOfUseLink": "Kushtet e Përdorimit",
|
||||
"bySigningUpText": "Duke u regjistruar, ju pranoni",
|
||||
"andText": "dhe",
|
||||
"signupButton": "Regjistrohu",
|
||||
"signInWithGoogleButton": "Hyr me Google",
|
||||
"alreadyHaveAccountText": "Keni tashmë një llogari?",
|
||||
"loginButton": "Hyr",
|
||||
"orText": "OSE",
|
||||
"reCAPTCHAVerificationError": "Gabim në Verifikimin e reCAPTCHA",
|
||||
"reCAPTCHAVerificationErrorMessage": "Nuk mundëm të verifikojmë reCAPTCHA-n tuaj. Ju lutemi provoni përsëri."
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "Verifikoni Email-in për Rivendosje",
|
||||
"description": "Vendosni fjalëkalimin tuaj të ri",
|
||||
"placeholder": "Vendosni fjalëkalimin tuaj të ri",
|
||||
"confirmPasswordPlaceholder": "Konfirmoni fjalëkalimin e ri",
|
||||
"passwordHint": "Të paktën 8 karaktere, me shkronja të mëdha dhe të vogla, një numër dhe një simbol.",
|
||||
"resetPasswordButton": "Rivendos fjalëkalimin",
|
||||
"orText": "Ose",
|
||||
"resendResetEmail": "Dërgo përsëri email-in e rivendosjes",
|
||||
"passwordRequired": "Ju lutemi vendosni fjalëkalimin e ri",
|
||||
"returnToLoginButton": "Kthehu te Hyrja",
|
||||
"confirmPasswordRequired": "Ju lutemi konfirmoni fjalëkalimin e ri",
|
||||
"passwordMismatch": "Fjalëkalimet nuk përputhen"
|
||||
}
|
||||
9
worklenz-frontend/public/locales/alb/common.json
Normal file
9
worklenz-frontend/public/locales/alb/common.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"login-success": "Hyrja u krye me sukses!",
|
||||
"login-failed": "Hyrja dështoi. Ju lutemi kontrolloni kredencialet dhe provoni përsëri.",
|
||||
"signup-success": "Regjistrimi u krye me sukses! Mirë se erdhët.",
|
||||
"signup-failed": "Regjistrimi dështoi. Ju lutemi sigurohuni që të gjitha fushat e nevojshme janë plotësuar dhe provoni përsëri.",
|
||||
"reconnecting": "Jeni shkëputur nga serveri.",
|
||||
"connection-lost": "Lidhja me serverin dështoi. Ju lutemi kontrolloni lidhjen tuaj me internet.",
|
||||
"connection-restored": "U lidhët me serverin me sukses"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"formTitle": "Krijoni projektin tuaj të parë",
|
||||
"inputLabel": "Në cilin projekt po punoni aktualisht?",
|
||||
"or": "ose",
|
||||
"templateButton": "Importo nga shablloni",
|
||||
"createFromTemplate": "Krijo nga shablloni",
|
||||
"goBack": "Kthehu Mbrapa",
|
||||
"continue": "Vazhdo",
|
||||
"cancel": "Anulo",
|
||||
"create": "Krijo",
|
||||
"templateDrawerTitle": "Zgjidh nga shabllonet",
|
||||
"createProject": "Krijo Projekt"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"formTitle": "Krijo detyrën tënde të parë.",
|
||||
"inputLabel": "Shkruaj disa detyra që do të kryesh në",
|
||||
"addAnother": "Shto një tjetër",
|
||||
"goBack": "Kthehu mbrapa",
|
||||
"continue": "Vazhdo"
|
||||
}
|
||||
46
worklenz-frontend/public/locales/alb/home.json
Normal file
46
worklenz-frontend/public/locales/alb/home.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"todoList": {
|
||||
"title": "Lista e Detyrave",
|
||||
"refreshTasks": "Rifresko detyrat",
|
||||
"addTask": "+ Shto Detyrë",
|
||||
"noTasks": "Asnjë detyrë",
|
||||
"pressEnter": "Shtyp",
|
||||
"toCreate": "për të krijuar.",
|
||||
"markAsDone": "Shëno si të përfunduar"
|
||||
},
|
||||
"projects": {
|
||||
"title": "Projektet",
|
||||
"refreshProjects": "Rifresko projektet",
|
||||
"noRecentProjects": "Aktualisht nuk jeni caktuar në asnjë projekt.",
|
||||
"noFavouriteProjects": "Asnjë projekt i shënuar si i preferuar.",
|
||||
"recent": "Të Fundit",
|
||||
"favourites": "Të Preferuarat"
|
||||
},
|
||||
"tasks": {
|
||||
"assignedToMe": "Më janë caktuar",
|
||||
"assignedByMe": "I kam caktuar",
|
||||
"all": "Të Gjitha",
|
||||
"today": "Sot",
|
||||
"upcoming": "Ardhj",
|
||||
"overdue": "Të vonuara",
|
||||
"noDueDate": "Pa afat",
|
||||
"noTasks": "Asnjë detyrë për të shfaqur.",
|
||||
"addTask": "+ Shto detyrë",
|
||||
"name": "Emri",
|
||||
"project": "Projekti",
|
||||
"status": "Statusi",
|
||||
"dueDate": "Afati",
|
||||
"dueDatePlaceholder": "Cakto Afatin",
|
||||
"tomorrow": "Nesër",
|
||||
"nextWeek": "Javën e Ardhshme",
|
||||
"nextMonth": "Muajin e Ardhshëm",
|
||||
"projectRequired": "Ju lutemi zgjidhni një projekt",
|
||||
"pressTabToSelectDueDateAndProject": "Shtyp Tab për të zgjedhur afatin dhe projektin",
|
||||
"dueOn": "Detyrat me afat më",
|
||||
"taskRequired": "Ju lutemi shtoni një detyrë",
|
||||
"list": "Listë",
|
||||
"calendar": "Kalendar",
|
||||
"tasks": "Detyrat",
|
||||
"refresh": "Rifresko"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"formTitle": "Fto ekipin tënd të punojë me",
|
||||
"inputLabel": "Fto me email",
|
||||
"addAnother": "Shto një tjetër",
|
||||
"goBack": "Kthehu mbrapa",
|
||||
"continue": "Vazhdo",
|
||||
"skipForNow": "Anashkalo tani për tani"
|
||||
}
|
||||
23
worklenz-frontend/public/locales/alb/kanban-board.json
Normal file
23
worklenz-frontend/public/locales/alb/kanban-board.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"rename": "Riemërto",
|
||||
"delete": "Fshi",
|
||||
"addTask": "Shto Detyrë",
|
||||
"addSectionButton": "Shto Seksion",
|
||||
"changeCategory": "Ndrysho kategorinë",
|
||||
|
||||
"deleteTooltip": "Fshi",
|
||||
"deleteConfirmationTitle": "Jeni i sigurt?",
|
||||
"deleteConfirmationOk": "Po",
|
||||
"deleteConfirmationCancel": "Anulo",
|
||||
|
||||
"dueDate": "Data e përfundimit",
|
||||
"cancel": "Anulo",
|
||||
|
||||
"today": "Sot",
|
||||
"tomorrow": "Nesër",
|
||||
"assignToMe": "Cakto mua",
|
||||
"archive": "Arkivo",
|
||||
|
||||
"newTaskNamePlaceholder": "Shkruaj emrin e detyrës",
|
||||
"newSubtaskNamePlaceholder": "Shkruaj emrin e nëndetyrës"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"title": "Prova juaj e Worklenz ka skaduar!",
|
||||
"subtitle": "Ju lutemi përmirësoni tani.",
|
||||
"button": "Përmirëso tani",
|
||||
"checking": "Po kontrollohet statusi i abonimit..."
|
||||
}
|
||||
31
worklenz-frontend/public/locales/alb/navbar.json
Normal file
31
worklenz-frontend/public/locales/alb/navbar.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"logoAlt": "Logoja e Worklenz",
|
||||
"home": "Kryefaqja",
|
||||
"projects": "Projektet",
|
||||
"schedule": "Orari",
|
||||
"reporting": "Raportimi",
|
||||
"clients": "Klientët",
|
||||
"teams": "Ekipet",
|
||||
"labels": "Etiketa",
|
||||
"jobTitles": "Tituj Pune",
|
||||
"upgradePlan": "Përmirëso Abonimin",
|
||||
"upgradePlanTooltip": "Përmirëso abonimin",
|
||||
"invite": "Fto",
|
||||
"inviteTooltip": "Fto anëtarë të ekipit të bashkohen",
|
||||
"switchTeamTooltip": "Ndrysho ekipin",
|
||||
"help": "Ndihmë",
|
||||
"notificationTooltip": "Shiko njoftimet",
|
||||
"profileTooltip": "Shiko profilin",
|
||||
"adminCenter": "Qendra Administrative",
|
||||
"settings": "Cilësimet",
|
||||
"logOut": "Dil",
|
||||
"notificationsDrawer": {
|
||||
"read": "Lexuara e njoftimet ",
|
||||
"unread": "Njoftimet e palexuara",
|
||||
"markAsRead": "Shëno si të lexuara",
|
||||
"readAndJoin": "Lexo & Bashkohu",
|
||||
"accept": "Prano",
|
||||
"acceptAndJoin": "Prano & Bashkohu",
|
||||
"noNotifications": "Asnjë njoftim"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"nameYourOrganization": "Emërtoni organizatën tuaj.",
|
||||
"worklenzAccountTitle": "Zgjidhni një emër për llogarinë tuaj në Worklenz.",
|
||||
"continue": "Vazhdo"
|
||||
}
|
||||
7
worklenz-frontend/public/locales/alb/phases-drawer.json
Normal file
7
worklenz-frontend/public/locales/alb/phases-drawer.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"configurePhases": "Konfiguro Fazat",
|
||||
"phaseLabel": "Etiketa e Fazës",
|
||||
"enterPhaseName": "Vendosni një emër për etiketën e fazës",
|
||||
"addOption": "Shto Opsion",
|
||||
"phaseOptions": "Opsionet e Fazës:"
|
||||
}
|
||||
42
worklenz-frontend/public/locales/alb/project-drawer.json
Normal file
42
worklenz-frontend/public/locales/alb/project-drawer.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"createProject": "Krijo Projekt",
|
||||
"editProject": "Modifiko Projektin",
|
||||
"enterCategoryName": "Vendosni emër për kategorinë",
|
||||
"hitEnterToCreate": "Shtyp Enter për të krijuar!",
|
||||
"enterNotes": "Shënime",
|
||||
"youCanManageClientsUnderSettings": "Mund të menaxhoni klientët nën Cilësimet",
|
||||
"addCategory": "Shto kategori projektit",
|
||||
"newCategory": "Kategori e Re",
|
||||
"notes": "Shënime",
|
||||
"startDate": "Data e Fillimit",
|
||||
"endDate": "Data e Përfundimit",
|
||||
"estimateWorkingDays": "Vlerëso ditët e punës",
|
||||
"estimateManDays": "Vlerëso ditët e punëtorëve",
|
||||
"hoursPerDay": "Orë në ditë",
|
||||
"create": "Krijo",
|
||||
"update": "Përditëso",
|
||||
"delete": "Fshi",
|
||||
"typeToSearchClients": "Shkruani për të kërkuar klientë",
|
||||
"projectColor": "Ngjyra e Projektit",
|
||||
"pleaseEnterAName": "Ju lutemi vendosni një emër",
|
||||
"enterProjectName": "Vendosni emrin e projektit",
|
||||
"name": "Emri",
|
||||
"status": "Statusi",
|
||||
"health": "Gjendja",
|
||||
"category": "Kategoria",
|
||||
"projectManager": "Menaxheri i Projektit",
|
||||
"client": "Klienti",
|
||||
"deleteConfirmation": "Jeni i sigurt që doni të fshini?",
|
||||
"deleteConfirmationDescription": "Kjo do të fshijë të gjitha të dhënat e lidhura dhe nuk mund të zhbëhet.",
|
||||
"yes": "Po",
|
||||
"no": "Jo",
|
||||
"createdAt": "Krijuar më",
|
||||
"updatedAt": "Përditësuar më",
|
||||
"by": "nga",
|
||||
"add": "Shto",
|
||||
"asClient": "si klient",
|
||||
"createClient": "Krijo klient",
|
||||
"searchInputPlaceholder": "Kërko sipas emrit ose emailit",
|
||||
"hoursPerDayValidationMessage": "Orët në ditë duhet të jenë një numër midis 1 dhe 24",
|
||||
"noPermission": "Nuk ka leje"
|
||||
}
|
||||
14
worklenz-frontend/public/locales/alb/project-view-files.json
Normal file
14
worklenz-frontend/public/locales/alb/project-view-files.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"nameColumn": "Emri",
|
||||
"attachedTaskColumn": "Detyra e Bashkangjitur",
|
||||
"sizeColumn": "Madhësia",
|
||||
"uploadedByColumn": "Ngarkuar Nga",
|
||||
"uploadedAtColumn": "Ngarkuar Më",
|
||||
"fileIconAlt": "Ikona e skedarit",
|
||||
"titleDescriptionText": "Të gjitha bashkëngjitjet e detyrave në këtë projekt do të shfahen këtu.",
|
||||
"deleteConfirmationTitle": "Jeni i sigurt?",
|
||||
"deleteConfirmationOk": "Po",
|
||||
"deleteConfirmationCancel": "Anulo",
|
||||
"segmentedTooltip": "Së shpejti! Kaloni midis pamjes listë dhe pamjes miniaturash.",
|
||||
"emptyText": "Nuk ka bashkëngjitje në projekt."
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"overview": {
|
||||
"title": "Përmbledhje",
|
||||
"statusOverview": "Përmbledhje Statusi",
|
||||
"priorityOverview": "Përmbledhje Prioriteti",
|
||||
"lastUpdatedTasks": "Detyrat e Përditësuara Së Fundi"
|
||||
},
|
||||
"members": {
|
||||
"title": "Anëtarët",
|
||||
"tooltip": "Anëtarët",
|
||||
"tasksByMembers": "Detyrat sipas anëtarëve",
|
||||
"tasksByMembersTooltip": "Detyrat sipas anëtarëve",
|
||||
"name": "Emri",
|
||||
"taskCount": "Numri i Detyrave",
|
||||
"contribution": "Kontributi",
|
||||
"completed": "Të Përfunduara",
|
||||
"incomplete": "Të Papërfunduara",
|
||||
"overdue": "Të Vonuara",
|
||||
"progress": "Progresi"
|
||||
},
|
||||
"tasks": {
|
||||
"overdueTasks": "Detyrat e Vonuara",
|
||||
"overLoggedTasks": "Detyrat me regjistrim të tepërt",
|
||||
"tasksCompletedEarly": "Detyrat e përfunduara para afatit",
|
||||
"tasksCompletedLate": "Detyrat e përfunduara pas afatit",
|
||||
"overLoggedTasksTooltip": "Detyrat me kohë të regjistruar mbi kohën e vlerësuar",
|
||||
"overdueTasksTooltip": "Detyrat që kanë kaluar afatin e tyre"
|
||||
},
|
||||
"common": {
|
||||
"seeAll": "Shiko të gjitha",
|
||||
"totalLoggedHours": "Orët totale të regjistruara",
|
||||
"totalEstimation": "Vlerësimi total",
|
||||
"completedTasks": "Detyrat e përfunduara",
|
||||
"incompleteTasks": "Detyrat e papërfunduara",
|
||||
"overdueTasks": "Detyrat e vonuara",
|
||||
"overdueTasksTooltip": "Detyrat që kanë kaluar afatin e tyre",
|
||||
"totalLoggedHoursTooltip": "Vlerësimi dhe koha e regjistruar për detyrat.",
|
||||
"includeArchivedTasks": "Përfshi Detyrat e Arkivuara",
|
||||
"export": "Eksporto"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"nameColumn": "Emri",
|
||||
"jobTitleColumn": "Titulli i Punës",
|
||||
"emailColumn": "Email",
|
||||
"tasksColumn": "Detyrat",
|
||||
"taskProgressColumn": "Progresi i Detyrave",
|
||||
"accessColumn": "Qasja",
|
||||
"fileIconAlt": "Ikona e skedarit",
|
||||
"deleteConfirmationTitle": "Jeni i sigurt?",
|
||||
"deleteConfirmationOk": "Po",
|
||||
"deleteConfirmationCancel": "Anulo",
|
||||
"refreshButtonTooltip": "Rifresko anëtarët",
|
||||
"deleteButtonTooltip": "Hiq nga projekti",
|
||||
"memberCount": "Anëtar",
|
||||
"membersCountPlural": "Anëtarë",
|
||||
"emptyText": "Nuk ka bashkëngjitje në projekt."
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inputPlaceholder": "Shto një koment..",
|
||||
"addButton": "Shto",
|
||||
"cancelButton": "Anulo",
|
||||
"deleteButton": "Fshi"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"importTaskTemplate": "Importo Shabllon Detyrash",
|
||||
"templateName": "Emri i Shabllonit",
|
||||
"templateDescription": "Përshkrimi i Shabllonit",
|
||||
"selectedTasks": "Detyrat e Përzgjedhura",
|
||||
"tasks": "Detyrat",
|
||||
"templates": "Shabllonet",
|
||||
"remove": "Hiq",
|
||||
"cancel": "Anulo",
|
||||
"import": "Importo"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"title": "Anëtarët e Projektit",
|
||||
"searchLabel": "Shtoni anëtarë duke shkruar emrin ose email-in e tyre",
|
||||
"searchPlaceholder": "Shkruani emrin ose email-in",
|
||||
"inviteAsAMember": "Fto si anëtar",
|
||||
"inviteNewMemberByEmail": "Fto anëtar të ri me email"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"importTasks": "Importo detyra",
|
||||
"createTask": "Krijo detyrë",
|
||||
"settings": "Cilësimet",
|
||||
"subscribe": "Abonohu",
|
||||
"unsubscribe": "Ç'abonohu",
|
||||
"deleteProject": "Fshi projektin",
|
||||
"startDate": "Data e fillimit",
|
||||
"endDate": "Data e përfundimit",
|
||||
"projectSettings": "Cilësimet e projektit",
|
||||
"projectSummary": "Përmbledhja e projektit",
|
||||
"receiveProjectSummary": "Merrni një përmbledhje të projektit çdo mbrëmje."
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"title": "Ruaj si Shabllon",
|
||||
"templateName": "Emri i Shabllonit",
|
||||
"includes": "Çfarë duhet të përfshihet në shabllon nga projekti?",
|
||||
"includesOptions": {
|
||||
"statuses": "Statuset",
|
||||
"phases": "Fazat",
|
||||
"labels": "Etiketat"
|
||||
},
|
||||
"taskIncludes": "Çfarë duhet të përfshihet në shabllon nga detyrat?",
|
||||
"taskIncludesOptions": {
|
||||
"statuses": "Statuset",
|
||||
"phases": "Fazat",
|
||||
"labels": "Etiketat",
|
||||
"name": "Emri",
|
||||
"priority": "Prioriteti",
|
||||
"status": "Statusi",
|
||||
"phase": "Faza",
|
||||
"label": "Etiketa",
|
||||
"timeEstimate": "Vlerësimi i Kohës",
|
||||
"description": "Përshkrimi",
|
||||
"subTasks": "Nëndetyrat"
|
||||
},
|
||||
"cancel": "Anulo",
|
||||
"save": "Ruaj",
|
||||
"templateNamePlaceholder": "Shkruani emrin e shabllonit"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"exportButton": "Eksporto",
|
||||
"timeLogsButton": "Regjistrimet e Kohës",
|
||||
"activityLogsButton": "Regjistrimet e Aktivitetit",
|
||||
"tasksButton": "Detyrat",
|
||||
"searchByNameInputPlaceholder": "Kërko sipas emrit",
|
||||
|
||||
"overviewTab": "Përmbledhje",
|
||||
"timeLogsTab": "Regjistrimet e Kohës",
|
||||
"activityLogsTab": "Regjistrimet e Aktivitetit",
|
||||
"tasksTab": "Detyrat",
|
||||
|
||||
"projectsText": "Projektet",
|
||||
"totalTasksText": "Detyrat Gjithsej",
|
||||
"assignedTasksText": "Detyrat e Caktuara",
|
||||
"completedTasksText": "Detyrat e Përfunduara",
|
||||
"ongoingTasksText": "Detyrat në Vazhdim",
|
||||
"overdueTasksText": "Detyrat e Vonuara",
|
||||
"loggedHoursText": "Orët e Regjistruara",
|
||||
|
||||
"tasksText": "Detyrat",
|
||||
"allText": "Të Gjitha",
|
||||
|
||||
"tasksByProjectsText": "Detyrat Sipas Projekteve",
|
||||
"tasksByStatusText": "Detyrat Sipas Statusit",
|
||||
"tasksByPriorityText": "Detyrat Sipas Prioritetit",
|
||||
|
||||
"todoText": "Për Të Bërë",
|
||||
"doingText": "Duke bërë",
|
||||
"doneText": "E Përfunduar",
|
||||
"lowText": "I Ulët",
|
||||
"mediumText": "I Mesëm",
|
||||
"highText": "I Lartë",
|
||||
|
||||
"billableButton": "Fakturueshme",
|
||||
"billableText": "Fakturueshme",
|
||||
"nonBillableText": "Jo Fakturueshme",
|
||||
|
||||
"timeLogsEmptyPlaceholder": "Asnjë regjistrim kohe për të shfaqur",
|
||||
"loggedText": "Regjistruar",
|
||||
"forText": "për",
|
||||
"inText": "në",
|
||||
"updatedText": "Përditësuar",
|
||||
"fromText": "Nga",
|
||||
"toText": "në",
|
||||
"withinText": "brenda",
|
||||
|
||||
"activityLogsEmptyPlaceholder": "Asnjë regjistrim aktiviteti për të shfaqur",
|
||||
|
||||
"filterByText": "Filtro sipas:",
|
||||
"selectProjectPlaceholder": "Zgjidh Projektin",
|
||||
|
||||
"taskColumn": "Detyra",
|
||||
"nameColumn": "Emri",
|
||||
"projectColumn": "Projekti",
|
||||
"statusColumn": "Statusi",
|
||||
"priorityColumn": "Prioriteti",
|
||||
"dueDateColumn": "Afati",
|
||||
"completedDateColumn": "Data e Përfundimit",
|
||||
"estimatedTimeColumn": "Koha e Vlerësuar",
|
||||
"loggedTimeColumn": "Koha e Regjistruar",
|
||||
"overloggedTimeColumn": "Koha e Tepërt",
|
||||
"daysLeftColumn": "Ditë të Mbetura/Vonuar",
|
||||
"startDateColumn": "Data e Fillimit",
|
||||
"endDateColumn": "Data e Përfundimit",
|
||||
"actualTimeColumn": "Koha Aktuale",
|
||||
"projectHealthColumn": "Gjendja e Projektit",
|
||||
"categoryColumn": "Kategoria",
|
||||
"projectManagerColumn": "Menaxheri i Projektit",
|
||||
|
||||
"tasksStatsOverviewDrawerTitle": "Detyrat e ",
|
||||
"projectsStatsOverviewDrawerTitle": "Projektet e ",
|
||||
|
||||
"cancelledText": "Anuluar",
|
||||
"blockedText": "E Bllokuar",
|
||||
"onHoldText": "Në Pritje",
|
||||
"proposedText": "E Propozuar",
|
||||
"inPlanningText": "Në Planifikim",
|
||||
"inProgressText": "Në Progres",
|
||||
"completedText": "E Përfunduar",
|
||||
"continuousText": "E Vazhdueshme",
|
||||
|
||||
"daysLeftText": "ditë të mbetura",
|
||||
"daysOverdueText": "ditë vonuar",
|
||||
|
||||
"notSetText": "Pa Caktuar",
|
||||
"needsAttentionText": "Kërkon Vëmendje",
|
||||
"atRiskText": "Në Rrezik",
|
||||
"goodText": "Në Rregull"
|
||||
}
|
||||
35
worklenz-frontend/public/locales/alb/reporting-members.json
Normal file
35
worklenz-frontend/public/locales/alb/reporting-members.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"yesterdayText": "Dje",
|
||||
"lastSevenDaysText": "7 Ditët e Fundit",
|
||||
"lastWeekText": "Javën e Kaluar",
|
||||
"lastThirtyDaysText": "30 Ditët e Fundit",
|
||||
"lastMonthText": "Muajin e Kaluar",
|
||||
"lastThreeMonthsText": "3 Muajt e Fundit",
|
||||
"allTimeText": "Të Gjitha",
|
||||
"customRangeText": "Interval i Përshtatur",
|
||||
"startDateInputPlaceholder": "Data e fillimit",
|
||||
"EndDateInputPlaceholder": "Data e përfundimit",
|
||||
"filterButton": "Filtro",
|
||||
|
||||
"membersTitle": "Anëtarët",
|
||||
"includeArchivedButton": "Përfshij Projektet e Arkivuara",
|
||||
"exportButton": "Eksporto",
|
||||
"excelButton": "Excel",
|
||||
"searchByNameInputPlaceholder": "Kërko sipas emrit",
|
||||
|
||||
"memberColumn": "Anëtari",
|
||||
"tasksProgressColumn": "Progresi i Detyrave",
|
||||
"tasksAssignedColumn": "Detyrat e Caktuara",
|
||||
"completedTasksColumn": "Detyrat e Përfunduara",
|
||||
"overdueTasksColumn": "Detyrat e Vonuara",
|
||||
"ongoingTasksColumn": "Detyrat në Vazhdim",
|
||||
|
||||
"tasksAssignedColumnTooltip": "Detyrat e caktuara në intervalin e zgjedhur",
|
||||
"overdueTasksColumnTooltip": "Detyrat e vonuara deri në fund të intervalit të zgjedhur",
|
||||
"completedTasksColumnTooltip": "Detyrat e përfunduara në intervalin e zgjedhur",
|
||||
"ongoingTasksColumnTooltip": "Detyrat e filluara por jo të përfunduara ende",
|
||||
|
||||
"todoText": "Për Të Bërë",
|
||||
"doingText": "Duke bërë",
|
||||
"doneText": "E Përfunduar"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"exportButton": "Eksporto",
|
||||
"projectsButton": "Projektet",
|
||||
"membersButton": "Anëtarët",
|
||||
"searchByNameInputPlaceholder": "Kërko sipas emrit",
|
||||
|
||||
"overviewTab": "Përmbledhje",
|
||||
"projectsTab": "Projektet",
|
||||
"membersTab": "Anëtarët",
|
||||
|
||||
"projectsByStatusText": "Projektet Sipas Statusit",
|
||||
"projectsByCategoryText": "Projektet Sipas Kategorisë",
|
||||
"projectsByHealthText": "Projektet Sipas Gjendjes",
|
||||
|
||||
"projectsText": "Projektet",
|
||||
"allText": "Të Gjitha",
|
||||
|
||||
"cancelledText": "Anuluar",
|
||||
"blockedText": "E Bllokuar",
|
||||
"onHoldText": "Në Pritje",
|
||||
"proposedText": "E Propozuar",
|
||||
"inPlanningText": "Në Planifikim",
|
||||
"inProgressText": "Në Progres",
|
||||
"completedText": "E Përfunduar",
|
||||
"continuousText": "E Vazhdueshme",
|
||||
|
||||
"notSetText": "Pa Caktuar",
|
||||
"needsAttentionText": "Kërkon Vëmendje",
|
||||
"atRiskText": "Në Rrezik",
|
||||
"goodText": "Në Rregull",
|
||||
|
||||
"nameColumn": "Emri",
|
||||
"emailColumn": "Email",
|
||||
"projectsColumn": "Projektet",
|
||||
"tasksColumn": "Detyrat",
|
||||
"overdueTasksColumn": "Detyrat e Vonuara",
|
||||
"completedTasksColumn": "Detyrat e Përfunduara",
|
||||
"ongoingTasksColumn": "Detyrat në Vazhdim"
|
||||
}
|
||||
25
worklenz-frontend/public/locales/alb/reporting-overview.json
Normal file
25
worklenz-frontend/public/locales/alb/reporting-overview.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"overviewTitle": "Përmbledhje",
|
||||
"includeArchivedButton": "Përfshij Projektet e Arkivuara",
|
||||
|
||||
"teamCount": "Ekip",
|
||||
"teamCountPlural": "Ekipe",
|
||||
"projectCount": "Projekt",
|
||||
"projectCountPlural": "Projekte",
|
||||
"memberCount": "Anëtar",
|
||||
"memberCountPlural": "Anëtarë",
|
||||
"activeProjectCount": "Projekt Aktiv",
|
||||
"activeProjectCountPlural": "Projekte Aktive",
|
||||
"overdueProjectCount": "Projekt i Vonuar",
|
||||
"overdueProjectCountPlural": "Projekte të Vonuara",
|
||||
"unassignedMemberCount": "Anëtar i Pacaktuar",
|
||||
"unassignedMemberCountPlural": "Anëtarë të Pacaktuar",
|
||||
"memberWithOverdueTaskCount": "Anëtar me Detyrë të Vonuar",
|
||||
"memberWithOverdueTaskCountPlural": "Anëtarë me Detyra të Vonuara",
|
||||
|
||||
"teamsText": "Ekipet",
|
||||
|
||||
"nameColumn": "Emri",
|
||||
"projectsColumn": "Projektet",
|
||||
"membersColumn": "Anëtarët"
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"exportButton": "Eksporto",
|
||||
"membersButton": "Anëtarët",
|
||||
"tasksButton": "Detyrat",
|
||||
"searchByNameInputPlaceholder": "Kërko sipas emrit",
|
||||
|
||||
"overviewTab": "Përmbledhje",
|
||||
"membersTab": "Anëtarët",
|
||||
"tasksTab": "Detyrat",
|
||||
|
||||
"completedTasksText": "Detyrat e Përfunduara",
|
||||
"incompleteTasksText": "Detyrat e Papërfunduara",
|
||||
"overdueTasksText": "Detyrat e Vonuara",
|
||||
"allocatedHoursText": "Orët e Alokuara",
|
||||
"loggedHoursText": "Orët e Regjistruara",
|
||||
|
||||
"tasksText": "Detyrat",
|
||||
"allText": "Të Gjitha",
|
||||
|
||||
"tasksByStatusText": "Detyrat Sipas Statusit",
|
||||
"tasksByPriorityText": "Detyrat Sipas Prioritetit",
|
||||
"tasksByDueDateText": "Detyrat Sipas Afatit",
|
||||
|
||||
"todoText": "Për Të Bërë",
|
||||
"doingText": "Duke bërë",
|
||||
"doneText": "E Përfunduar",
|
||||
"lowText": "I Ulët",
|
||||
"mediumText": "I Mesëm",
|
||||
"highText": "I Lartë",
|
||||
"completedText": "E Përfunduar",
|
||||
"upcomingText": "Në Ardhje",
|
||||
"overdueText": "E Vonuar",
|
||||
"noDueDateText": "Pa Afat",
|
||||
|
||||
"nameColumn": "Emri",
|
||||
"tasksCountColumn": "Numri i Detyrave",
|
||||
"completedTasksColumn": "Detyrat e Përfunduara",
|
||||
"incompleteTasksColumn": "Detyrat e Papërfunduara",
|
||||
"overdueTasksColumn": "Detyrat e Vonuara",
|
||||
"contributionColumn": "Kontributi",
|
||||
"progressColumn": "Progresi",
|
||||
"loggedTimeColumn": "Koha e Regjistruar",
|
||||
"taskColumn": "Detyra",
|
||||
"projectColumn": "Projekti",
|
||||
"statusColumn": "Statusi",
|
||||
"priorityColumn": "Prioriteti",
|
||||
"phaseColumn": "Faza",
|
||||
"dueDateColumn": "Afati",
|
||||
"completedDateColumn": "Data e Përfundimit",
|
||||
"estimatedTimeColumn": "Koha e Vlerësuar",
|
||||
"overloggedTimeColumn": "Koha e Tepërt",
|
||||
"completedOnColumn": "Përfunduar Më",
|
||||
"daysOverdueColumn": "Ditë vonim",
|
||||
|
||||
"groupByText": "Grupo Sipas:",
|
||||
"statusText": "Statusi",
|
||||
"priorityText": "Prioriteti",
|
||||
"phaseText": "Faza"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"searchByNamePlaceholder": "Kërko sipas emrit",
|
||||
"searchByCategoryPlaceholder": "Kërko sipas kategorisë",
|
||||
|
||||
"statusText": "Statusi",
|
||||
"healthText": "Gjendja",
|
||||
"categoryText": "Kategoria",
|
||||
"projectManagerText": "Menaxheri i Projektit",
|
||||
"showFieldsText": "Shfaq fushat",
|
||||
|
||||
"cancelledText": "Anuluar",
|
||||
"blockedText": "E bllokuar",
|
||||
"onHoldText": "Në pritje",
|
||||
"proposedText": "E propozuar",
|
||||
"inPlanningText": "Në planifikim",
|
||||
"inProgressText": "Në progres",
|
||||
"completedText": "E përfunduar",
|
||||
"continuousText": "E vazhdueshme",
|
||||
|
||||
"notSetText": "Pa caktuar",
|
||||
"needsAttentionText": "Kërkon vëmendje",
|
||||
"atRiskText": "Në rrezik",
|
||||
"goodText": "Në rregull",
|
||||
|
||||
"nameText": "Projekti",
|
||||
"estimatedVsActualText": "Vlerësuar vs Aktual",
|
||||
"tasksProgressText": "Progresi i detyrave",
|
||||
"lastActivityText": "Aktiviteti i fundit",
|
||||
"datesText": "Datat e Fillimit/Përfundimit",
|
||||
"daysLeftText": "Ditë të mbetura/vonuar",
|
||||
"projectHealthText": "Gjendja e projektit",
|
||||
"projectUpdateText": "Përditësimi i projektit",
|
||||
"clientText": "Klienti",
|
||||
"teamText": "Ekipi"
|
||||
}
|
||||
52
worklenz-frontend/public/locales/alb/reporting-projects.json
Normal file
52
worklenz-frontend/public/locales/alb/reporting-projects.json
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"projectCount": "Projekt",
|
||||
"projectCountPlural": "Projekte",
|
||||
"includeArchivedButton": "Përfshij Projektet e Arkivuara",
|
||||
"exportButton": "Eksporto",
|
||||
"excelButton": "Excel",
|
||||
|
||||
"projectColumn": "Projekti",
|
||||
"estimatedVsActualColumn": "Vlerësuar vs Aktual",
|
||||
"tasksProgressColumn": "Progresi i Detyrave",
|
||||
"lastActivityColumn": "Aktiviteti i Fundit",
|
||||
"statusColumn": "Statusi",
|
||||
"datesColumn": "Data e Fillimit/Përfundimit",
|
||||
"daysLeftColumn": "Ditë të Mbetura/Vonuar",
|
||||
"projectHealthColumn": "Gjendja e Projektit",
|
||||
"categoryColumn": "Kategoria",
|
||||
"projectUpdateColumn": "Përditësimi i Projektit",
|
||||
"clientColumn": "Klienti",
|
||||
"teamColumn": "Ekipi",
|
||||
"projectManagerColumn": "Menaxheri i Projektit",
|
||||
|
||||
"openButton": "Hap",
|
||||
|
||||
"estimatedText": "Vlerësuar",
|
||||
"actualText": "Aktual",
|
||||
|
||||
"todoText": "Për të Bërë",
|
||||
"doingText": "duke bërë",
|
||||
"doneText": "E Përfunduar",
|
||||
|
||||
"cancelledText": "Anuluar",
|
||||
"blockedText": "E Bllokuar",
|
||||
"onHoldText": "Në Pritje",
|
||||
"proposedText": "E Propozuar",
|
||||
"inPlanningText": "Në Planifikim",
|
||||
"inProgressText": "Në Progres",
|
||||
"completedText": "E Përfunduar",
|
||||
"continuousText": "E Vazhdueshme",
|
||||
|
||||
"daysLeftText": "ditë të mbetura",
|
||||
"dayLeftText": "ditë e mbetur",
|
||||
"daysOverdueText": "ditë vonuar",
|
||||
|
||||
"notSetText": "Pa Caktuar",
|
||||
"needsAttentionText": "Kërkon Vëmendje",
|
||||
"atRiskText": "Në Rrezik",
|
||||
"goodText": "Në Rregull",
|
||||
|
||||
"setCategoryText": "Cakto Kategorinë",
|
||||
"searchByNameInputPlaceholder": "Kërko sipas emrit",
|
||||
"todayText": "Sot"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"overview": "Përmbledhje",
|
||||
"projects": "Projektet",
|
||||
"members": "Anëtarët",
|
||||
"timeReports": "Raportet e Kohës",
|
||||
"estimateVsActual": "Vlerësimi vs Aktual",
|
||||
"currentOrganizationTooltip": "Organizata aktuale"
|
||||
}
|
||||
39
worklenz-frontend/public/locales/alb/schedule.json
Normal file
39
worklenz-frontend/public/locales/alb/schedule.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"today": "Sot",
|
||||
"week": "Javë",
|
||||
"month": "Muaj",
|
||||
|
||||
"settings": "Cilësimet",
|
||||
"workingDays": "Ditët e punës",
|
||||
"monday": "E hënë",
|
||||
"tuesday": "E martë",
|
||||
"wednesday": "E mërkurë",
|
||||
"thursday": "E enjte",
|
||||
"friday": "E premte",
|
||||
"saturday": "E shtunë",
|
||||
"sunday": "E diel",
|
||||
"workingHours": "Orët e punës",
|
||||
"hours": "Orë",
|
||||
"saveButton": "Ruaj",
|
||||
|
||||
"totalAllocation": "Alokimi Total",
|
||||
"timeLogged": "Koha e Regjistruar",
|
||||
"remainingTime": "Koha e Mbetur",
|
||||
"total": "Total",
|
||||
"perDay": "Në Ditë",
|
||||
"tasks": "detyra",
|
||||
"startDate": "Data e Fillimit",
|
||||
"endDate": "Data e Përfundimit",
|
||||
|
||||
"hoursPerDay": "Orë Në Ditë",
|
||||
"totalHours": "Orë Totale",
|
||||
"deleteButton": "Fshi",
|
||||
"cancelButton": "Anulo",
|
||||
|
||||
"tabTitle": "Detyra pa Data Fillimi & Përfundimi",
|
||||
|
||||
"allocatedTime": "Koha e alokuar",
|
||||
"totalLogged": "Total i Regjistruar",
|
||||
"loggedBillable": "Regjistruar Fakturueshme",
|
||||
"loggedNonBillable": "Regjistruar Jo Fakturueshme"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"categoryColumn": "Kategoria",
|
||||
"deleteConfirmationTitle": "Jeni të sigurt?",
|
||||
"deleteConfirmationOk": "Po",
|
||||
"deleteConfirmationCancel": "Anulo",
|
||||
"associatedTaskColumn": "Projektet e Lidhura",
|
||||
"searchPlaceholder": "Kërko sipas emrit",
|
||||
"emptyText": "Kategoritë mund të krijohen gjatë përditësimit ose krijimit të projekteve.",
|
||||
"colorChangeTooltip": "Klikoni për të ndryshuar ngjyrën"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"title": "Ndrysho Fjalëkalimin",
|
||||
"currentPassword": "Fjalëkalimi Aktual",
|
||||
"newPassword": "Fjalëkalimi i Ri",
|
||||
"confirmPassword": "Konfirmo Fjalëkalimin",
|
||||
"currentPasswordPlaceholder": "Vendosni fjalëkalimin aktual",
|
||||
"newPasswordPlaceholder": "Fjalëkalimi i Ri",
|
||||
"confirmPasswordPlaceholder": "Konfirmo Fjalëkalimin",
|
||||
"currentPasswordRequired": "Ju lutemi vendosni fjalëkalimin aktual!",
|
||||
"newPasswordRequired": "Ju lutemi vendosni fjalëkalimin e ri!",
|
||||
"passwordValidationError": "Fjalëkalimi duhet të përmbajë të paktën 8 karaktere, me një shkronjë të madhe, një numër dhe një simbol.",
|
||||
"passwordMismatch": "Fjalëkalimet nuk përputhen!",
|
||||
"passwordRequirements": "Fjalëkalimi i ri duhet të jetë së paku 8 karaktere, me një shkronjë të madhe, një numër dhe një simbol.",
|
||||
"updateButton": "Përditëso Fjalëkalimin"
|
||||
}
|
||||
22
worklenz-frontend/public/locales/alb/settings/clients.json
Normal file
22
worklenz-frontend/public/locales/alb/settings/clients.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"nameColumn": "Emri",
|
||||
"projectColumn": "Projekti",
|
||||
"noProjectsAvailable": "Nuk ka projekte të disponueshme",
|
||||
"deleteConfirmationTitle": "Jeni i sigurt?",
|
||||
"deleteConfirmationOk": "Po",
|
||||
"deleteConfirmationCancel": "Anulo",
|
||||
"searchPlaceholder": "Kërko sipas emrit",
|
||||
"createClient": "Krijo Klient",
|
||||
"pinTooltip": "Klikoni për ta fiksuar në menynë kryesore",
|
||||
"createClientDrawerTitle": "Krijo Klient",
|
||||
"updateClientDrawerTitle": "Përditëso Klientin",
|
||||
"nameLabel": "Emri",
|
||||
"namePlaceholder": "Emri",
|
||||
"nameRequiredError": "Ju lutemi shkruani një Emër",
|
||||
"createButton": "Krijo",
|
||||
"updateButton": "Përditëso",
|
||||
"createClientSuccessMessage": "Klienti u krijua me sukses!",
|
||||
"createClientErrorMessage": "Krijimi i klientit dështoi!",
|
||||
"updateClientSuccessMessage": "Klienti u përditësua me sukses!",
|
||||
"updateClientErrorMessage": "Përditësimi i klientit dështoi!"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"nameColumn": "Emri",
|
||||
"deleteConfirmationTitle": "Jeni i sigurt?",
|
||||
"deleteConfirmationOk": "Po",
|
||||
"deleteConfirmationCancel": "Anulo",
|
||||
"searchPlaceholder": "Kërko sipas emrit",
|
||||
"createJobTitleButton": "Krijo Titull Pune",
|
||||
"pinTooltip": "Klikoni për ta fiksuar në menynë kryesore",
|
||||
"createJobTitleDrawerTitle": "Krijo Titull Pune",
|
||||
"updateJobTitleDrawerTitle": "Përditëso Titullin e Punës",
|
||||
"nameLabel": "Emri",
|
||||
"namePlaceholder": "Emri",
|
||||
"nameRequiredError": "Ju lutemi shkruani një Emër",
|
||||
"createButton": "Krijo",
|
||||
"updateButton": "Përditëso",
|
||||
"createJobTitleSuccessMessage": "Titulli i punës u krijua me sukses!",
|
||||
"createJobTitleErrorMessage": "Krijimi i titullit të punës dështoi!",
|
||||
"updateJobTitleSuccessMessage": "Titulli i punës u përditësua me sukses!",
|
||||
"updateJobTitleErrorMessage": "Përditësimi i titullit të punës dështoi!"
|
||||
}
|
||||
11
worklenz-frontend/public/locales/alb/settings/labels.json
Normal file
11
worklenz-frontend/public/locales/alb/settings/labels.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"labelColumn": "Etiketa",
|
||||
"deleteConfirmationTitle": "Jeni i sigurt?",
|
||||
"deleteConfirmationOk": "Po",
|
||||
"deleteConfirmationCancel": "Anulo",
|
||||
"associatedTaskColumn": "Numri i Detyrave të Lidhura",
|
||||
"searchPlaceholder": "Kërko sipas emrit",
|
||||
"emptyText": "Etiketat mund të krijohen gjatë përditësimit ose krijimit të detyrave.",
|
||||
"pinTooltip": "Klikoni për ta fiksuar në menynë kryesore",
|
||||
"colorChangeTooltip": "Klikoni për të ndryshuar ngjyrën"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"language": "Gjuha",
|
||||
"language_required": "Gjuha është e detyrueshme",
|
||||
"time_zone": "Zona kohore",
|
||||
"time_zone_required": "Zona kohore është e detyrueshme",
|
||||
"save_changes": "Ruaj Ndryshimet"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"title": "Cilësimet e Njoftimeve",
|
||||
"emailTitle": "Më dërgo njoftime me email",
|
||||
"emailDescription": "Kjo përfshin caktimet e reja të detyrave",
|
||||
"dailyDigestTitle": "Më dërgo një përmbledhje ditore",
|
||||
"dailyDigestDescription": "Çdo mbrëmje, do të merrni një përmbledhje të aktivitetit të fundit në detyra.",
|
||||
"popupTitle": "Shfaq njoftimet në kompjuterin tim kur Worklenz është i hapur",
|
||||
"popupDescription": "Njoftimet e shfaqura mund të çaktivizohen nga shfletuesi juaj. Ndryshoni cilësimet e shfletuesit për t'i lejuar ato.",
|
||||
"unreadItemsTitle": "Shfaq numrin e artikujve të palexuar",
|
||||
"unreadItemsDescription": "Do të shihni numërimin për çdo njoftim."
|
||||
}
|
||||
13
worklenz-frontend/public/locales/alb/settings/profile.json
Normal file
13
worklenz-frontend/public/locales/alb/settings/profile.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"uploadError": "Mund të ngarkoni vetëm skedarë JPG/PNG!",
|
||||
"uploadSizeError": "Imazhi duhet të jetë më i vogël se 2MB!",
|
||||
"upload": "Ngarko",
|
||||
"nameLabel": "Emri",
|
||||
"nameRequiredError": "Emri është i detyrueshëm",
|
||||
"emailLabel": "Email",
|
||||
"emailRequiredError": "Email-i është i detyrueshëm",
|
||||
"saveChanges": "Ruaj Ndryshimet",
|
||||
"profileJoinedText": "U bashkua një muaj më parë",
|
||||
"profileLastUpdatedText": "Përditësuar një muaj më parë",
|
||||
"avatarTooltip": "Klikoni për të ngarkuar një avatar"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"nameColumn": "Emri",
|
||||
"editToolTip": "Modifiko",
|
||||
"deleteToolTip": "Fshi",
|
||||
"confirmText": "Jeni i sigurt?",
|
||||
"okText": "Po",
|
||||
"cancelText": "Anulo"
|
||||
}
|
||||
14
worklenz-frontend/public/locales/alb/settings/sidebar.json
Normal file
14
worklenz-frontend/public/locales/alb/settings/sidebar.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"profile": "Profili",
|
||||
"notifications": "Njoftimet",
|
||||
"clients": "Klientët",
|
||||
"job-titles": "Tituj Pune",
|
||||
"labels": "Etiketa",
|
||||
"categories": "Kategoritë",
|
||||
"project-templates": "Shabllonet e Projekteve",
|
||||
"task-templates": "Shabllonet e Detyrave",
|
||||
"team-members": "Anëtarët e Ekipit",
|
||||
"teams": "Ekipet",
|
||||
"change-password": "Ndrysho Fjalëkalimin",
|
||||
"language-and-region": "Gjuha dhe Rajoni"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"nameColumn": "Emri",
|
||||
"createdColumn": "Krijuar",
|
||||
"editToolTip": "Redakto",
|
||||
"deleteToolTip": "Fshi",
|
||||
"confirmText": "Jeni i sigurt?",
|
||||
"okText": "Po",
|
||||
"cancelText": "Anulo"
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"nameColumn": "Emri",
|
||||
"projectsColumn": "Projektet",
|
||||
"emailColumn": "Email",
|
||||
"teamAccessColumn": "Qasja në Ekip",
|
||||
"memberCount": "Anëtar",
|
||||
"membersCountPlural": "Anëtarë",
|
||||
"searchPlaceholder": "Kërko anëtarë sipas emrit",
|
||||
"pinTooltip": "Rifresko listën e anëtarëve",
|
||||
"addMemberButton": "Shto Anëtar të Ri",
|
||||
"editTooltip": "Modifiko anëtarin",
|
||||
"deactivateTooltip": "Çaktivizo anëtarin",
|
||||
"activateTooltip": "Aktivizo anëtarin",
|
||||
"deleteTooltip": "Fshi anëtarin",
|
||||
"confirmDeleteTitle": "Jeni i sigurt që doni të fshini këtë anëtar?",
|
||||
"confirmActivateTitle": "Jeni i sigurt që doni të ndryshoni statusin e këtij anëtari?",
|
||||
"okText": "Po, vazhdo",
|
||||
"cancelText": "Jo, anulo",
|
||||
"deactivatedText": "(Aktualisht i çaktivizuar)",
|
||||
"pendingInvitationText": "(Ftesë në pritje)",
|
||||
"addMemberDrawerTitle": "Shto Anëtar të Ri në Ekip",
|
||||
"updateMemberDrawerTitle": "Përditëso Anëtarin e Ekipit",
|
||||
"addMemberEmailHint": "Anëtarët do të shtohen në ekip pavarësisht nga statusi i pranimit të ftesës",
|
||||
"memberEmailLabel": "Email(o)",
|
||||
"memberEmailPlaceholder": "Vendos adresën email të anëtarit të ekipit",
|
||||
"memberEmailRequiredError": "Ju lutemi vendosni një adresë email të vlefshme",
|
||||
"jobTitleLabel": "Titulli i Punës",
|
||||
"jobTitlePlaceholder": "Zgjidh ose kërko titull pune (Opsionale)",
|
||||
"memberAccessLabel": "Niveli i Qasjes",
|
||||
"addToTeamButton": "Shto Anëtar në Ekip",
|
||||
"updateButton": "Ruaj Ndryshimet",
|
||||
"resendInvitationButton": "Dërgo Përsëri Email-in e Ftesës",
|
||||
"invitationSentSuccessMessage": "Ftesa për ekip u dërgua me sukses!",
|
||||
"createMemberSuccessMessage": "Anëtari i ri i ekipit u shtua me sukses!",
|
||||
"createMemberErrorMessage": "Dështoi shtimi i anëtarit të ri. Ju lutemi provoni përsëri.",
|
||||
"updateMemberSuccessMessage": "Anëtari i ekipit u përditësua me sukses!",
|
||||
"updateMemberErrorMessage": "Dështoi përditësimi i anëtarit. Ju lutemi provoni përsëri.",
|
||||
"memberText": "Anëtar",
|
||||
"adminText": "Administrues",
|
||||
"ownerText": "Pronar i Ekipit",
|
||||
"addedText": "Shtuar",
|
||||
"updatedText": "Përditësuar",
|
||||
"noResultFound": "Shkruani një adresë email dhe shtypni Enter..."
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"details": {
|
||||
"task-key": "Çelësi i Detyrës",
|
||||
"phase": "Faza",
|
||||
"assignees": "Përgjegjësit",
|
||||
"due-date": "Data e Përfundimit",
|
||||
"time-estimation": "Vlerësimi i Kohës",
|
||||
"priority": "Prioriteti",
|
||||
"labels": "Etiketa",
|
||||
"billable": "Fakturueshme",
|
||||
"notify": "Njofto",
|
||||
"when-done-notify": "Kur të përfundojë, njofto",
|
||||
"start-date": "Data e Fillimit",
|
||||
"end-date": "Data e Përfundimit",
|
||||
"hide-start-date": "Fshih Datën e Fillimit",
|
||||
"show-start-date": "Shfaq Datën e Fillimit",
|
||||
"hours": "Orë",
|
||||
"minutes": "Minuta"
|
||||
},
|
||||
"description": {
|
||||
"title": "Përshkrimi",
|
||||
"placeholder": "Shtoni një përshkrim më të detajuar..."
|
||||
},
|
||||
"subTasks": {
|
||||
"title": "Nën-Detyrat",
|
||||
"add-sub-task": "+ Shto Nën-Detyrë",
|
||||
"refresh-sub-tasks": "Rifresko Nën-Detyrat"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"taskHeader": {
|
||||
"taskNamePlaceholder": "Shkruani detyrën tuaj",
|
||||
"deleteTask": "Fshi Detyrën"
|
||||
},
|
||||
"taskInfoTab": {
|
||||
"title": "Info",
|
||||
"details": {
|
||||
"title": "Detajet",
|
||||
"task-key": "Çelësi i Detyrës",
|
||||
"phase": "Faza",
|
||||
"assignees": "Përgjegjësit",
|
||||
"due-date": "Afati i Përfundimit",
|
||||
"time-estimation": "Vlerësimi i Kohës",
|
||||
"priority": "Prioriteti",
|
||||
"labels": "Etiketa",
|
||||
"billable": "Fakturueshme",
|
||||
"notify": "Njofto",
|
||||
"when-done-notify": "Kur të përfundojë, njofto",
|
||||
"start-date": "Data e Fillimit",
|
||||
"end-date": "Data e Përfundimit",
|
||||
"hide-start-date": "Fshih Datën e Fillimit",
|
||||
"show-start-date": "Shfaq Datën e Fillimit",
|
||||
"hours": "Orë",
|
||||
"minutes": "Minuta"
|
||||
},
|
||||
"labels": {
|
||||
"labelInputPlaceholder": "Kërko ose krijo",
|
||||
"labelsSelectorInputTip": "Shtyp Enter për të krijuar"
|
||||
},
|
||||
"description": {
|
||||
"title": "Përshkrimi",
|
||||
"placeholder": "Shtoni një përshkrim më të detajuar..."
|
||||
},
|
||||
"subTasks": {
|
||||
"title": "Nën-Detyrat",
|
||||
"addSubTask": "+ Shto Nën-Detyrë",
|
||||
"addSubTaskInputPlaceholder": "Shkruani detyrën dhe shtypni Enter",
|
||||
"refreshSubTasks": "Rifresko Nën-Detyrat",
|
||||
"edit": "Modifiko",
|
||||
"delete": "Fshi",
|
||||
"confirmDeleteSubTask": "Jeni i sigurt që doni të fshini këtë nën-detyrë?",
|
||||
"deleteSubTask": "Fshi Nën-Detyrën"
|
||||
},
|
||||
"dependencies": {
|
||||
"title": "Varësitë",
|
||||
"addDependency": "+ Shto varësi të re",
|
||||
"blockedBy": "I bllokuar nga",
|
||||
"searchTask": "Shkruani për të kërkuar detyra",
|
||||
"noTasksFound": "Asnjë detyrë nuk u gjet",
|
||||
"confirmDeleteDependency": "Jeni i sigurt që doni të fshini?"
|
||||
},
|
||||
"attachments": {
|
||||
"title": "Bashkëngjitjet",
|
||||
"chooseOrDropFileToUpload": "Zgjidhni ose lëshoni skedar për ngarkim",
|
||||
"uploading": "Po ngarkohet..."
|
||||
},
|
||||
"comments": {
|
||||
"title": "Komentet",
|
||||
"addComment": "+ Shto koment të ri",
|
||||
"noComments": "Asnjë koment ende. Bëhu i pari që komenton!",
|
||||
"delete": "Fshi",
|
||||
"confirmDeleteComment": "Jeni i sigurt që doni të fshini këtë koment?"
|
||||
},
|
||||
"searchInputPlaceholder": "Kërko sipas emrit",
|
||||
"pendingInvitation": "Ftesë në Pritje"
|
||||
},
|
||||
"taskTimeLogTab": {
|
||||
"title": "Regjistri i Kohës",
|
||||
"addTimeLog": "Shto regjistrim të ri kohe",
|
||||
"totalLogged": "Koha totale e regjistruar",
|
||||
"exportToExcel": "Eksporto në Excel",
|
||||
"noTimeLogsFound": "Asnjë regjistrim kohe nuk u gjet"
|
||||
},
|
||||
"taskActivityLogTab": {
|
||||
"title": "Regjistri i Aktivitetit"
|
||||
}
|
||||
}
|
||||
59
worklenz-frontend/public/locales/alb/task-list-filters.json
Normal file
59
worklenz-frontend/public/locales/alb/task-list-filters.json
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"searchButton": "Kërko",
|
||||
"resetButton": "Rivendos",
|
||||
"searchInputPlaceholder": "Kërko sipas emrit",
|
||||
|
||||
"sortText": "Rendit",
|
||||
"statusText": "Statusi",
|
||||
"phaseText": "Faza",
|
||||
"memberText": "Anëtarët",
|
||||
"assigneesText": "Përgjegjësit",
|
||||
"priorityText": "Prioriteti",
|
||||
"labelsText": "Etiketa",
|
||||
"membersText": "Anëtarët",
|
||||
"groupByText": "Grupo sipas",
|
||||
"showArchivedText": "Shfaq të arkivuara",
|
||||
"showFieldsText": "Shfaq fushat",
|
||||
"keyText": "Çelësi",
|
||||
"taskText": "Detyra",
|
||||
"descriptionText": "Përshkrimi",
|
||||
"phasesText": "Fazat",
|
||||
"listText": "Listë",
|
||||
"progressText": "Progresi",
|
||||
"timeTrackingText": "Gjurmimi i Kohës",
|
||||
"timetrackingText": "Gjurmimi i Kohës",
|
||||
"estimationText": "Vlerësimi",
|
||||
"startDateText": "Data e Fillimit",
|
||||
"startdateText": "Data e Fillimit",
|
||||
"endDateText": "Data e Përfundimit",
|
||||
"dueDateText": "Afati",
|
||||
"duedateText": "Afati",
|
||||
"completedDateText": "Data e Përfundimit",
|
||||
"completeddateText": "Data e Përfundimit",
|
||||
"createdDateText": "Data e Krijimit",
|
||||
"createddateText": "Data e Krijimit",
|
||||
"lastUpdatedText": "Përditësuar Së Fundi",
|
||||
"lastupdatedText": "Përditësuar Së Fundi",
|
||||
"reporterText": "Raportuesi",
|
||||
"dueTimeText": "Koha e Afatit",
|
||||
"duetimeText": "Koha e Afatit",
|
||||
|
||||
"lowText": "I ulët",
|
||||
"mediumText": "I mesëm",
|
||||
"highText": "I lartë",
|
||||
|
||||
"createStatusButtonTooltip": "Cilësimet e statusit",
|
||||
"configPhaseButtonTooltip": "Cilësimet e fazës",
|
||||
"noLabelsFound": "Nuk u gjetën etiketa",
|
||||
|
||||
"addStatusButton": "Shto Status",
|
||||
"addPhaseButton": "Shto Fazë",
|
||||
|
||||
"createStatus": "Krijo Status",
|
||||
"name": "Emri",
|
||||
"category": "Kategoria",
|
||||
"selectCategory": "Zgjidh një kategori",
|
||||
"pleaseEnterAName": "Ju lutemi vendosni një emër",
|
||||
"pleaseSelectACategory": "Ju lutemi zgjidhni një kategori",
|
||||
"create": "Krijo"
|
||||
}
|
||||
63
worklenz-frontend/public/locales/alb/task-list-table.json
Normal file
63
worklenz-frontend/public/locales/alb/task-list-table.json
Normal file
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"keyColumn": "Çelësi",
|
||||
"taskColumn": "Detyra",
|
||||
"descriptionColumn": "Përshkrimi",
|
||||
"progressColumn": "Progresi",
|
||||
"membersColumn": "Anëtarët",
|
||||
"assigneesColumn": "Përgjegjësit",
|
||||
"labelsColumn": "Etiketa",
|
||||
"phasesColumn": "Fazat",
|
||||
"phaseColumn": "Faza",
|
||||
"statusColumn": "Statusi",
|
||||
"priorityColumn": "Prioriteti",
|
||||
"timeTrackingColumn": "Gjurmimi i Kohës",
|
||||
"timetrackingColumn": "Gjurmimi i Kohës",
|
||||
"estimationColumn": "Vlerësimi",
|
||||
"startDateColumn": "Data e Fillimit",
|
||||
"startdateColumn": "Data e Fillimit",
|
||||
"dueDateColumn": "Data e Afatit",
|
||||
"duedateColumn": "Data e Afatit",
|
||||
"completedDateColumn": "Data e Përfundimit",
|
||||
"completeddateColumn": "Data e Përfundimit",
|
||||
"createdDateColumn": "Data e Krijimit",
|
||||
"createddateColumn": "Data e Krijimit",
|
||||
"lastUpdatedColumn": "Përditësuar Së Fundi",
|
||||
"lastupdatedColumn": "Përditësuar Së Fundi",
|
||||
"reporterColumn": "Raportuesi",
|
||||
"dueTimeColumn": "Koha e Afatit",
|
||||
"todoSelectorText": "Për të Bërë",
|
||||
"doingSelectorText": "Duke bërë",
|
||||
"doneSelectorText": "E Përfunduar",
|
||||
|
||||
"lowSelectorText": "I ulët",
|
||||
"mediumSelectorText": "I mesëm",
|
||||
"highSelectorText": "I lartë",
|
||||
|
||||
"selectText": "Zgjidh",
|
||||
"labelsSelectorInputTip": "Shtyp Enter për të krijuar!",
|
||||
|
||||
"addTaskText": "+ Shto Detyrë",
|
||||
"addSubTaskText": "+ Shto Nën-Detyrë",
|
||||
"addTaskInputPlaceholder": "Shkruaj detyrën dhe shtyp Enter",
|
||||
|
||||
"openButton": "Hap",
|
||||
"okButton": "Në rregull",
|
||||
|
||||
"noLabelsFound": "Nuk u gjetën etiketa",
|
||||
"searchInputPlaceholder": "Kërko ose krijo",
|
||||
"assigneeSelectorInviteButton": "Fto një anëtar të ri me email",
|
||||
"labelInputPlaceholder": "Kërko ose krijo",
|
||||
|
||||
"pendingInvitation": "Ftesë në Pritje",
|
||||
|
||||
"contextMenu": {
|
||||
"assignToMe": "Cakto mua",
|
||||
"moveTo": "Zhvendos në",
|
||||
"unarchive": "Ç'arkivizo",
|
||||
"archive": "Arkivizo",
|
||||
"convertToSubTask": "Shndërro në Nën-Detyrë",
|
||||
"convertToTask": "Shndërro në Detyrë",
|
||||
"delete": "Fshi",
|
||||
"searchByNameInputPlaceholder": "Kërko sipas emrit"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"createTaskTemplate": "Krijo Shabllon Detyre",
|
||||
"editTaskTemplate": "Modifiko Shabllon Detyre",
|
||||
"cancelText": "Anulo",
|
||||
"saveText": "Ruaj",
|
||||
"templateNameText": "Emri i Shabllonit",
|
||||
"selectedTasks": "Detyrat e Përzgjedhura",
|
||||
"removeTask": "Hiq",
|
||||
"cancelButton": "Anulo",
|
||||
"saveButton": "Ruaj"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"taskSelected": "detyrë e zgjedhur",
|
||||
"tasksSelected": "detyra të zgjedhura",
|
||||
"changeStatus": "Ndrysho Statusin/ Prioritetin/ Fazat",
|
||||
"changeLabel": "Ndrysho Etiketën",
|
||||
"assignToMe": "Cakto mua",
|
||||
"changeAssignees": "Ndrysho Përgjegjësit",
|
||||
"archive": "Arkivo",
|
||||
"unarchive": "Ç'arkivo",
|
||||
"delete": "Fshi",
|
||||
"moreOptions": "Më shumë opsione",
|
||||
"deselectAll": "Zgjidhja të gjitha",
|
||||
"status": "Statusi",
|
||||
"priority": "Prioriteti",
|
||||
"phase": "Faza",
|
||||
"member": "Anëtar",
|
||||
"createTaskTemplate": "Krijo Shabllon Detyre",
|
||||
"apply": "Apliko",
|
||||
"createLabel": "+ Krijo Etiketë",
|
||||
"hitEnterToCreate": "Shtyp Enter për të krijuar",
|
||||
"pendingInvitation": "Ftesë në Pritje",
|
||||
"noMatchingLabels": "Asnjë etiketë që përputhet",
|
||||
"noLabels": "Asnjë etiketë"
|
||||
}
|
||||
19
worklenz-frontend/public/locales/alb/template-drawer.json
Normal file
19
worklenz-frontend/public/locales/alb/template-drawer.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "Modifiko Shabllon Detyre",
|
||||
"cancelText": "Anulo",
|
||||
"saveText": "Ruaj",
|
||||
"templateNameText": "Emri i Shabllonit",
|
||||
"selectedTasks": "Detyrat e Përzgjedhura",
|
||||
"removeTask": "Hiq",
|
||||
"description": "Përshkrimi",
|
||||
"phase": "Faza",
|
||||
"statuses": "Statuset",
|
||||
"priorities": "Prioritetet",
|
||||
"labels": "Etiketa",
|
||||
"tasks": "Detyrat",
|
||||
"noTemplateSelected": "Asnjë shabllon i përzgjedhur",
|
||||
"noDescription": "Pa përshkrim",
|
||||
"worklenzTemplates": "Shabllonet Worklenz",
|
||||
"yourTemplatesLibrary": "Biblioteka Juaj",
|
||||
"searchTemplates": "Kërko Shabllone"
|
||||
}
|
||||
23
worklenz-frontend/public/locales/alb/templateDrawer.json
Normal file
23
worklenz-frontend/public/locales/alb/templateDrawer.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"bugTracking": "Gjurmimi i Gabimeve",
|
||||
"construction": "Ndërtim",
|
||||
"designCreative": "Dizajn & Kreativ",
|
||||
"education": "Arsim",
|
||||
"finance": "Financë",
|
||||
"hrRecruiting": "Burime Njerëzore & Rekrutim",
|
||||
"informationTechnology": "Teknologji Informacioni",
|
||||
"legal": "Juridik",
|
||||
"manufacturing": "Prodhim",
|
||||
"marketing": "Marketing",
|
||||
"nonprofit": "Jo-fitimprurës",
|
||||
"personalUse": "Përdorim Personal",
|
||||
"salesCRM": "Shitje & CRM",
|
||||
"serviceConsulting": "Shërbime & Këshillim",
|
||||
"softwareDevelopment": "Zhvillim Softueri",
|
||||
"description": "Përshkrimi",
|
||||
"phase": "Faza",
|
||||
"statuses": "Statuset",
|
||||
"priorities": "Prioritetet",
|
||||
"labels": "Etiketa",
|
||||
"tasks": "Detyrat"
|
||||
}
|
||||
44
worklenz-frontend/public/locales/alb/time-report.json
Normal file
44
worklenz-frontend/public/locales/alb/time-report.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"includeArchivedProjects": "Përfshij Projektet e Arkivuara",
|
||||
"export": "Eksporto",
|
||||
"timeSheet": "Fletë Kohore",
|
||||
|
||||
"searchByName": "Kërko sipas emrit",
|
||||
"selectAll": "Zgjidh të Gjitha",
|
||||
"teams": "Ekipet",
|
||||
|
||||
"searchByProject": "Kërko sipas emrit të projektit",
|
||||
"projects": "Projektet",
|
||||
|
||||
"searchByCategory": "Kërko sipas emrit të kategorisë",
|
||||
"categories": "Kategoritë",
|
||||
|
||||
"billable": "Fakturueshme",
|
||||
"nonBillable": "Jo Fakturueshme",
|
||||
|
||||
"total": "Total",
|
||||
|
||||
"projectsTimeSheet": "Fletë Kohore e Projekteve",
|
||||
|
||||
"loggedTime": "Koha e Regjistruar(orë)",
|
||||
|
||||
"exportToExcel": "Eksporto në Excel",
|
||||
"logged": "regjistruar",
|
||||
"for": "për",
|
||||
|
||||
"membersTimeSheet": "Fletë Kohore e Anëtarëve",
|
||||
"member": "Anëtar",
|
||||
|
||||
"estimatedVsActual": "Vlerësuar vs Aktual",
|
||||
"workingDays": "Ditë Pune",
|
||||
"manDays": "Ditë Njeri",
|
||||
"days": "Ditë",
|
||||
"estimatedDays": "Ditë të Vlerësuara",
|
||||
"actualDays": "Ditë Aktuale",
|
||||
|
||||
"noCategories": "Nuk u gjetën kategori",
|
||||
"noCategory": "Pa Kategori",
|
||||
"noProjects": "Nuk u gjetën projekte",
|
||||
"noTeams": "Nuk u gjetën ekipe",
|
||||
"noData": "Nuk u gjetën të dhëna"
|
||||
}
|
||||
5
worklenz-frontend/public/locales/alb/unauthorized.json
Normal file
5
worklenz-frontend/public/locales/alb/unauthorized.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "E paautorizuar!",
|
||||
"subtitle": "Nuk jeni të autorizuar të hyni në këtë faqe",
|
||||
"button": "Kthehu në Faqen Kryesore"
|
||||
}
|
||||
4
worklenz-frontend/public/locales/de/404-page.json
Normal file
4
worklenz-frontend/public/locales/de/404-page.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"doesNotExistText": "Entschuldigung, die von Ihnen besuchte Seite existiert nicht.",
|
||||
"backHomeButton": "Zurück zur Startseite"
|
||||
}
|
||||
31
worklenz-frontend/public/locales/de/account-setup.json
Normal file
31
worklenz-frontend/public/locales/de/account-setup.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"continue": "Weiter",
|
||||
|
||||
"setupYourAccount": "Richten Sie Ihr Worklenz-Konto ein.",
|
||||
"organizationStepTitle": "Organisation benennen",
|
||||
"organizationStepLabel": "Wählen Sie einen Namen für Ihr Worklenz-Konto.",
|
||||
|
||||
"projectStepTitle": "Erstellen Sie Ihr erstes Projekt",
|
||||
"projectStepLabel": "An welchem Projekt arbeiten Sie gerade?",
|
||||
"projectStepPlaceholder": "z.B. Marketingplan",
|
||||
|
||||
"tasksStepTitle": "Erstellen Sie Ihre ersten Aufgaben",
|
||||
"tasksStepLabel": "Geben Sie einige Aufgaben ein, die Sie in",
|
||||
"tasksStepAddAnother": "Weitere hinzufügen",
|
||||
|
||||
"emailPlaceholder": "E-Mail-Adresse",
|
||||
"invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein",
|
||||
"or": "oder",
|
||||
"templateButton": "Aus Vorlage importieren",
|
||||
"goBack": "Zurück",
|
||||
"cancel": "Abbrechen",
|
||||
"create": "Erstellen",
|
||||
"templateDrawerTitle": "Aus Vorlagen auswählen",
|
||||
"step3InputLabel": "Per E-Mail einladen",
|
||||
"addAnother": "Weitere hinzufügen",
|
||||
"skipForNow": "Jetzt überspringen",
|
||||
"formTitle": "Erstellen Sie Ihre erste Aufgabe.",
|
||||
"step3Title": "Laden Sie Ihr Team zur Zusammenarbeit ein",
|
||||
"maxMembers": " (Sie können bis zu 5 Mitglieder einladen)",
|
||||
"maxTasks": " (Sie können bis zu 5 Aufgaben erstellen)"
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"title": "Abrechnungen",
|
||||
"currentBill": "Aktuelle Rechnung",
|
||||
"configuration": "Konfiguration",
|
||||
"currentPlanDetails": "Aktuelle Plan Details",
|
||||
"upgradePlan": "Plan upgraden",
|
||||
"cardBodyText01": "Kostenlose Testversion",
|
||||
"cardBodyText02": "(Ihr Testplan läuft in 1 Monat 19 Tagen ab)",
|
||||
"redeemCode": "Gutscheincode einlösen",
|
||||
"accountStorage": "Kontospeicher",
|
||||
"used": "Verwendet:",
|
||||
"remaining": "Verbleibend:",
|
||||
"charges": "Gebühren",
|
||||
"tooltip": "Gebühren für den aktuellen Abrechnungszeitraum",
|
||||
"description": "Beschreibung",
|
||||
"billingPeriod": "Abrechnungszeitraum",
|
||||
"billStatus": "Rechnungsstatus",
|
||||
"perUserValue": "Pro Benutzer Wert",
|
||||
"users": "Benutzer",
|
||||
|
||||
"amount": "Betrag",
|
||||
"invoices": "Rechnungen",
|
||||
"transactionId": "Transaktions-ID",
|
||||
"transactionDate": "Transaktionsdatum",
|
||||
"paymentMethod": "Zahlungsmethode",
|
||||
"status": "Status",
|
||||
"ltdUsers": "Sie können bis zu {{ltd_users}} Benutzer hinzufügen.",
|
||||
|
||||
"totalSeats": "Gesamte Plätze",
|
||||
"availableSeats": "Verfügbare Plätze",
|
||||
"addMoreSeats": "Weitere Plätze hinzufügen",
|
||||
|
||||
"drawerTitle": "Gutscheincode einlösen",
|
||||
"label": "Gutscheincode",
|
||||
"drawerPlaceholder": "Geben Sie Ihren Gutscheincode ein",
|
||||
"redeemSubmit": "Einreichen",
|
||||
|
||||
"modalTitle": "Wählen Sie den besten Plan für Ihr Team",
|
||||
"seatLabel": "Anzahl der Plätze",
|
||||
"freePlan": "Kostenloser Plan",
|
||||
"startup": "Startup",
|
||||
"business": "Business",
|
||||
"tag": "Am beliebtesten",
|
||||
"enterprise": "Enterprise",
|
||||
|
||||
"freeSubtitle": "kostenlos für immer",
|
||||
"freeUsers": "Ideal für die persönliche Nutzung",
|
||||
"freeText01": "100MB Speicher",
|
||||
"freeText02": "3 Projekte",
|
||||
"freeText03": "5 Teammitglieder",
|
||||
|
||||
"startupSubtitle": "PAUSCHALPREIS / Monat",
|
||||
"startupUsers": "Bis zu 15 Benutzer",
|
||||
"startupText01": "25GB Speicher",
|
||||
"startupText02": "Unbegrenzte aktive Projekte",
|
||||
"startupText03": "Zeitplan",
|
||||
"startupText04": "Berichterstattung",
|
||||
"startupText05": "Projekte abonnieren",
|
||||
|
||||
"businessSubtitle": "Benutzer / Monat",
|
||||
"businessUsers": "16 - 200 Benutzer",
|
||||
|
||||
"enterpriseUsers": "200 - 500+ Benutzer",
|
||||
|
||||
"footerTitle": "Bitte geben Sie uns eine Kontaktnummer, unter der wir Sie erreichen können.",
|
||||
"footerLabel": "Kontaktnummer",
|
||||
"footerButton": "Kontaktieren Sie uns",
|
||||
|
||||
"redeemCodePlaceHolder": "Geben Sie Ihren Gutscheincode ein",
|
||||
"submit": "Einreichen",
|
||||
|
||||
"trialPlan": "Kostenlose Testversion",
|
||||
"trialExpireDate": "Gültig bis {{trial_expire_date}}",
|
||||
"trialExpired": "Ihre kostenlose Testversion ist {{trial_expire_string}} abgelaufen",
|
||||
"trialInProgress": "Ihre kostenlose Testversion läuft {{trial_expire_string}} ab",
|
||||
|
||||
"required": "Dieses Feld ist erforderlich",
|
||||
"invalidCode": "Ungültiger Code",
|
||||
|
||||
"selectPlan": "Wählen Sie den besten Plan für Ihr Team",
|
||||
"changeSubscriptionPlan": "Ändern Sie Ihren Abonnementplan",
|
||||
"noOfSeats": "Anzahl der Plätze",
|
||||
"annualPlan": "Pro - Jährlich",
|
||||
"monthlyPlan": "Pro - Monatlich",
|
||||
"freeForever": "Kostenlos für immer",
|
||||
"bestForPersonalUse": "Ideal für die persönliche Nutzung",
|
||||
"storage": "Speicher",
|
||||
"projects": "Projekte",
|
||||
"teamMembers": "Teammitglieder",
|
||||
"unlimitedTeamMembers": "Unbegrenzte Teammitglieder",
|
||||
"unlimitedActiveProjects": "Unbegrenzte aktive Projekte",
|
||||
"schedule": "Zeitplan",
|
||||
"reporting": "Berichterstattung",
|
||||
"subscribeToProjects": "Projekte abonnieren",
|
||||
"billedAnnually": "Jährlich abgerechnet",
|
||||
"billedMonthly": "Monatlich abgerechnet",
|
||||
|
||||
"pausePlan": "Plan pausieren",
|
||||
"resumePlan": "Plan fortsetzen",
|
||||
"changePlan": "Plan ändern",
|
||||
"cancelPlan": "Plan kündigen",
|
||||
|
||||
"perMonthPerUser": "pro Benutzer/Monat",
|
||||
"viewInvoice": "Rechnung anzeigen",
|
||||
"switchToFreePlan": "Wechsel zum kostenlosen Plan",
|
||||
|
||||
"expirestoday": "heute",
|
||||
"expirestomorrow": "morgen",
|
||||
"expiredDaysAgo": "vor {{days}} Tagen",
|
||||
|
||||
"continueWith": "Fortfahren mit {{plan}}",
|
||||
"changeToPlan": "Wechseln zu {{plan}}"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"overview": "Übersicht",
|
||||
"name": "Organisationsname",
|
||||
"owner": "Organisationsinhaber",
|
||||
"admins": "Organisationsadministratoren",
|
||||
"contactNumber": "Kontaktnummer hinzufügen",
|
||||
"edit": "Bearbeiten"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"membersCount": "Mitgliederanzahl",
|
||||
"createdAt": "Erstellt am",
|
||||
"projectName": "Projektname",
|
||||
"teamName": "Teamname",
|
||||
"refreshProjects": "Projekte aktualisieren",
|
||||
"searchPlaceholder": "Nach Projektname suchen",
|
||||
"deleteProject": "Sind Sie sicher, dass Sie dieses Projekt löschen möchten?",
|
||||
"confirm": "Bestätigen",
|
||||
"cancel": "Abbrechen",
|
||||
"delete": "Projekt löschen"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"overview": "Übersicht",
|
||||
"users": "Benutzer",
|
||||
"teams": "Teams",
|
||||
"billing": "Abrechnung",
|
||||
"projects": "Projekte",
|
||||
"adminCenter": "Admin-Center"
|
||||
}
|
||||
33
worklenz-frontend/public/locales/de/admin-center/teams.json
Normal file
33
worklenz-frontend/public/locales/de/admin-center/teams.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"title": "Teams",
|
||||
"subtitle": "Teams",
|
||||
"tooltip": "Teams aktualisieren",
|
||||
"placeholder": "Nach Namen suchen",
|
||||
"addTeam": "Team hinzufügen",
|
||||
"team": "Team",
|
||||
"membersCount": "Mitgliederanzahl",
|
||||
"members": "Mitglieder",
|
||||
"drawerTitle": "Neues Team erstellen",
|
||||
"label": "Teamname",
|
||||
"drawerPlaceholder": "Name",
|
||||
"create": "Erstellen",
|
||||
"delete": "Löschen",
|
||||
"settings": "Einstellungen",
|
||||
"popTitle": "Sind Sie sicher?",
|
||||
"message": "Bitte geben Sie einen Namen ein",
|
||||
"teamSettings": "Team-Einstellungen",
|
||||
"teamName": "Teamname",
|
||||
"teamDescription": "Teambeschreibung",
|
||||
"teamMembers": "Teammitglieder",
|
||||
"teamMembersCount": "Anzahl der Teammitglieder",
|
||||
"teamMembersPlaceholder": "Nach Namen suchen",
|
||||
"addMember": "Mitglied hinzufügen",
|
||||
"add": "Hinzufügen",
|
||||
"update": "Aktualisieren",
|
||||
"teamNamePlaceholder": "Name des Teams",
|
||||
"user": "Benutzer",
|
||||
"role": "Rolle",
|
||||
"owner": "Besitzer",
|
||||
"admin": "Administrator",
|
||||
"member": "Mitglied"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"title": "Benutzer",
|
||||
"subTitle": "Benutzer",
|
||||
"placeholder": "Nach Namen suchen",
|
||||
"user": "Benutzer",
|
||||
"email": "E-Mail",
|
||||
"lastActivity": "Letzte Aktivität",
|
||||
"refresh": "Benutzer aktualisieren"
|
||||
}
|
||||
23
worklenz-frontend/public/locales/de/all-project-list.json
Normal file
23
worklenz-frontend/public/locales/de/all-project-list.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "Name",
|
||||
"client": "Kunde",
|
||||
"category": "Kategorie",
|
||||
"status": "Status",
|
||||
"tasksProgress": "Aufgabenfortschritt",
|
||||
"updated_at": "Zuletzt aktualisiert",
|
||||
"members": "Mitglieder",
|
||||
"setting": "Einstellungen",
|
||||
"projects": "Projekte",
|
||||
"refreshProjects": "Projekte aktualisieren",
|
||||
"all": "Alle",
|
||||
"favorites": "Favoriten",
|
||||
"archived": "Archiviert",
|
||||
"placeholder": "Nach Namen suchen",
|
||||
"archive": "Archivieren",
|
||||
"unarchive": "Dearchivieren",
|
||||
"archiveConfirm": "Sind Sie sicher, dass Sie dieses Projekt archivieren möchten?",
|
||||
"unarchiveConfirm": "Sind Sie sicher, dass Sie dieses Projekt dearchivieren möchten?",
|
||||
"clickToFilter": "Zum Filtern klicken nach",
|
||||
"noProjects": "Keine Projekte gefunden",
|
||||
"addToFavourites": "Zu Favoriten hinzufügen"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"loggingOut": "Abmelden...",
|
||||
"authenticating": "Authentifizierung läuft...",
|
||||
"gettingThingsReady": "Bereite alles für Sie vor..."
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"headerDescription": "Passwort zurücksetzen",
|
||||
"emailLabel": "E-Mail",
|
||||
"emailPlaceholder": "Ihre E-Mail eingeben",
|
||||
"emailRequired": "Bitte geben Sie Ihre E-Mail-Adresse ein!",
|
||||
"resetPasswordButton": "Passwort zurücksetzen",
|
||||
"returnToLoginButton": "Zurück zum Login",
|
||||
"passwordResetSuccessMessage": "Ein Link zum Zurücksetzen des Passworts wurde an Ihre E-Mail gesendet.",
|
||||
"orText": "ODER",
|
||||
"successTitle": "Anweisung zum Zurücksetzen gesendet!",
|
||||
"successMessage": "Die Informationen zum Zurücksetzen wurden an Ihre E-Mail gesendet. Bitte überprüfen Sie Ihr E-Mail-Postfach."
|
||||
}
|
||||
27
worklenz-frontend/public/locales/de/auth/login.json
Normal file
27
worklenz-frontend/public/locales/de/auth/login.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"headerDescription": "Melden Sie sich an",
|
||||
"emailLabel": "E-Mail",
|
||||
"emailPlaceholder": "Ihre E-Mail-Adresse eingeben",
|
||||
"emailRequired": "Bitte geben Sie Ihre E-Mail-Adresse ein!",
|
||||
"passwordLabel": "Passwort",
|
||||
"passwordPlaceholder": "Ihr Passwort eingeben",
|
||||
"passwordRequired": "Bitte geben Sie Ihr Passwort ein!",
|
||||
"rememberMe": "Erinnere dich an mich",
|
||||
"loginButton": "Anmelden",
|
||||
"signupButton": "Registrieren",
|
||||
"forgotPasswordButton": "Passwort vergessen?",
|
||||
"signInWithGoogleButton": "Mit Google anmelden",
|
||||
"dontHaveAccountText": "Noch kein Konto?",
|
||||
"orText": "ODER",
|
||||
"successMessage": "Sie haben sich erfolgreich angemeldet!",
|
||||
"loginError": "Anmeldung fehlgeschlagen",
|
||||
"googleLoginError": "Google-Anmeldung fehlgeschlagen",
|
||||
"validationMessages": {
|
||||
"email": "Bitte geben Sie eine gültige E-Mail-Adresse ein",
|
||||
"password": "Das Passwort muss mindestens 8 Zeichen lang sein"
|
||||
},
|
||||
"errorMessages": {
|
||||
"loginErrorTitle": "Anmeldung fehlgeschlagen",
|
||||
"loginErrorMessage": "Bitte überprüfen Sie Ihre E-Mail-Adresse und Ihr Passwort und versuchen Sie es erneut"
|
||||
}
|
||||
}
|
||||
29
worklenz-frontend/public/locales/de/auth/signup.json
Normal file
29
worklenz-frontend/public/locales/de/auth/signup.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"headerDescription": "Registrieren Sie sich, um loszulegen",
|
||||
"nameLabel": "Vollständiger Name",
|
||||
"namePlaceholder": "Ihren vollständigen Namen eingeben",
|
||||
"nameRequired": "Bitte geben Sie Ihren vollständigen Namen ein!",
|
||||
"nameMinCharacterRequired": "Der Name muss mindestens 4 Zeichen lang sein!",
|
||||
"emailLabel": "E-Mail",
|
||||
"emailPlaceholder": "Ihre E-Mail-Adresse eingeben",
|
||||
"emailRequired": "Bitte geben Sie Ihre E-Mail-Adresse ein!",
|
||||
"passwordLabel": "Passwort",
|
||||
"passwordPlaceholder": "Ihr Passwort eingeben",
|
||||
"passwordRequired": "Bitte geben Sie Ihr Passwort ein!",
|
||||
"passwordMinCharacterRequired": "Das Passwort muss mindestens 8 Zeichen lang sein!",
|
||||
"passwordPatternRequired": "Das Passwort erfüllt nicht die Anforderungen!",
|
||||
"strongPasswordPlaceholder": "Ein stärkeres Passwort eingeben",
|
||||
"passwordValidationAltText": "Das Passwort muss mindestens 8 Zeichen enthalten, mit Groß- und Kleinbuchstaben, einer Zahl und einem Sonderzeichen.",
|
||||
"signupSuccessMessage": "Sie haben sich erfolgreich registriert!",
|
||||
"privacyPolicyLink": "Datenschutzrichtlinie",
|
||||
"termsOfUseLink": "Nutzungsbedingungen",
|
||||
"bySigningUpText": "Mit der Registrierung stimmen Sie unseren",
|
||||
"andText": "und",
|
||||
"signupButton": "Registrieren",
|
||||
"signInWithGoogleButton": "Mit Google anmelden",
|
||||
"alreadyHaveAccountText": "Sie haben bereits ein Konto?",
|
||||
"loginButton": "Anmelden",
|
||||
"orText": "ODER",
|
||||
"reCAPTCHAVerificationError": "reCAPTCHA-Verifizierungsfehler",
|
||||
"reCAPTCHAVerificationErrorMessage": "Wir konnten Ihre reCAPTCHA nicht verifizieren. Bitte versuchen Sie es erneut."
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "E-Mail zurücksetzen bestätigen",
|
||||
"description": "Geben Sie Ihr neues Passwort ein",
|
||||
"placeholder": "Neues Passwort eingeben",
|
||||
"confirmPasswordPlaceholder": "Neues Passwort bestätigen",
|
||||
"passwordHint": "Mindestens 8 Zeichen, mit Groß- und Kleinbuchstaben, einer Zahl und einem Sonderzeichen.",
|
||||
"resetPasswordButton": "Passwort zurücksetzen",
|
||||
"orText": "Oder",
|
||||
"resendResetEmail": "Zurücksetz-E-Mail erneut senden",
|
||||
"passwordRequired": "Bitte geben Sie Ihr neues Passwort ein",
|
||||
"returnToLoginButton": "Zurück zur Anmeldung",
|
||||
"confirmPasswordRequired": "Bitte bestätigen Sie Ihr neues Passwort",
|
||||
"passwordMismatch": "Die beiden Passwörter stimmen nicht überein"
|
||||
}
|
||||
9
worklenz-frontend/public/locales/de/common.json
Normal file
9
worklenz-frontend/public/locales/de/common.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"login-success": "Anmeldung erfolgreich!",
|
||||
"login-failed": "Anmeldung fehlgeschlagen. Bitte überprüfen Sie Ihre Anmeldedaten und versuchen Sie es erneut.",
|
||||
"signup-success": "Registrierung erfolgreich! Willkommen an Bord.",
|
||||
"signup-failed": "Registrierung fehlgeschlagen. Bitte füllen Sie alle erforderlichen Felder aus und versuchen Sie es erneut.",
|
||||
"reconnecting": "Vom Server getrennt.",
|
||||
"connection-lost": "Verbindung zum Server fehlgeschlagen. Bitte überprüfen Sie Ihre Internetverbindung.",
|
||||
"connection-restored": "Erfolgreich mit dem Server verbunden"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"formTitle": "Erstellen Sie Ihr erstes Projekt",
|
||||
"inputLabel": "An welchem Projekt arbeiten Sie gerade?",
|
||||
"or": "oder",
|
||||
"templateButton": "Aus Vorlage importieren",
|
||||
"createFromTemplate": "Aus Vorlage erstellen",
|
||||
"goBack": "Zurück",
|
||||
"continue": "Weitermachen",
|
||||
"cancel": "Abbrechen",
|
||||
"create": "Erstellen",
|
||||
"templateDrawerTitle": "Aus Vorlagen auswählen",
|
||||
"createProject": "Projekt erstellen"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user