mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-25 14:59:21 +01:00
Compare commits
38 Commits
v0.15.1
...
tonya/lang
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
646a80f494 | ||
|
|
1268fd90ba | ||
|
|
ec5b6bb8ff | ||
|
|
c0860fc9ca | ||
|
|
8d93ab3d7f | ||
|
|
d39d109031 | ||
|
|
1d5b62fdf3 | ||
|
|
a9616911f5 | ||
|
|
3eb5ece34d | ||
|
|
77246ca57b | ||
|
|
087a328e83 | ||
|
|
8a6df8a69b | ||
|
|
c2546f06d4 | ||
|
|
3a4c78ed86 | ||
|
|
ed7670ac67 | ||
|
|
2cd50435b5 | ||
|
|
9b72419e6b | ||
|
|
a1e66854cd | ||
|
|
ab756aaa56 | ||
|
|
d45c8b2b2d | ||
|
|
f26b5e1190 | ||
|
|
8bfa930cf0 | ||
|
|
52f9306e98 | ||
|
|
483934bd5e | ||
|
|
de7ef70d40 | ||
|
|
1e020f7fae | ||
|
|
0d6ec9c427 | ||
|
|
e32683fb28 | ||
|
|
67c77a7d91 | ||
|
|
55acfa54f5 | ||
|
|
7f742738fa | ||
|
|
888973e2cb | ||
|
|
65b247573e | ||
|
|
8f255ccfd4 | ||
|
|
c9ed50afad | ||
|
|
3fd14aac47 | ||
|
|
ed780e292b | ||
|
|
c6158e7c9e |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1 +1 @@
|
||||
github: [tankerkiller125,katosdev]
|
||||
github: [tankerkiller125,katosdev,tonyaellie]
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -3,6 +3,7 @@ name: "Bug Report"
|
||||
description: "Submit a bug report for the current release"
|
||||
labels: ["🕷️ bug"]
|
||||
projects: ["sysadminsmedia/2"]
|
||||
type: "Bug"
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
1
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -3,6 +3,7 @@ name: "Feature Request"
|
||||
description: "Submit a feature request for the current release"
|
||||
labels: ["⬆️ enhancement"]
|
||||
projects: ["sysadminsmedia/2"]
|
||||
type: "Enhancement"
|
||||
body:
|
||||
- type: textarea
|
||||
id: problem-statement
|
||||
|
||||
105
.github/workflows/docker-publish-arm.yaml
vendored
Normal file
105
.github/workflows/docker-publish-arm.yaml
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
name: Docker publish ARM
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '00 0 * * *'
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- 'frontend/**'
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile.rootless'
|
||||
- '.dockerignore'
|
||||
- '.github/workflows'
|
||||
# Publish semver tags as releases.
|
||||
tags: [ 'v*.*.*' ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- 'frontend/**'
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile.rootless'
|
||||
- '.dockerignore'
|
||||
- '.github/workflows'
|
||||
|
||||
env:
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
attestations: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
# Step 1: Checkout repository
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Step 2: Set up Buildx without specifying driver
|
||||
# Let it use default settings to avoid the 'no remote endpoint' issue
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3.0.0
|
||||
with:
|
||||
install: true # Ensure Buildx is installed and set up properly
|
||||
use: true # Use Buildx instance directly for this job
|
||||
|
||||
# Step 3: Login against Docker registry except on PR
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Step 4: Extract metadata for Docker images
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5.0.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=schedule,pattern=nightly
|
||||
flavor: |
|
||||
suffix=-arm,onlatest=true
|
||||
|
||||
# Step 5: Build and push the Docker image
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v5.0.0
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: linux/arm64,linux/arm/v7
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
VERSION=${{ github.ref_name }}
|
||||
COMMIT=${{ github.sha }}
|
||||
|
||||
# Step 6: Attest built image to prove build provenance
|
||||
- name: Attest
|
||||
uses: actions/attest-build-provenance@v1
|
||||
id: attest
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
with:
|
||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
||||
push-to-registry: true
|
||||
104
.github/workflows/docker-publish-rootless-arm.yaml
vendored
Normal file
104
.github/workflows/docker-publish-rootless-arm.yaml
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
name: Docker publish rootless ARM
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '00 0 * * *'
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- 'frontend/**'
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile.rootless'
|
||||
- '.dockerignore'
|
||||
- '.github/workflows'
|
||||
# Publish semver tags as releases.
|
||||
tags: [ 'v*.*.*' ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- 'frontend/**'
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile.rootless'
|
||||
- '.dockerignore'
|
||||
- '.github/workflows'
|
||||
|
||||
env:
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build-rootless:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
attestations: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
# Step 1: Checkout repository
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Step 2: Set up Buildx without specifying driver
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3.0.0
|
||||
with:
|
||||
install: true # Ensure Buildx is installed and set up properly
|
||||
use: true # Use Buildx instance directly for this job
|
||||
|
||||
# Step 3: Login to Docker registry except on PR
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Step 4: Extract metadata for Docker images
|
||||
- name: Extract Docker metadata
|
||||
id: metadata
|
||||
uses: docker/metadata-action@v5.0.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=schedule,pattern=nightly
|
||||
flavor: |
|
||||
suffix=-rootless-arm,onlatest=true
|
||||
|
||||
# Step 5: Build and push the Docker image
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v5.0.0
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.metadata.outputs.tags }}
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
||||
platforms: linux/arm64,linux/arm/v7
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
VERSION=${{ github.ref_name }}
|
||||
COMMIT=${{ github.sha }}
|
||||
|
||||
# Step 6: Attest built image to prove build provenance
|
||||
- name: Attest
|
||||
uses: actions/attest-build-provenance@v1
|
||||
id: attest
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
with:
|
||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
||||
push-to-registry: true
|
||||
@@ -91,7 +91,7 @@ jobs:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.metadata.outputs.tags }}
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
platforms: linux/amd64
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
|
||||
2
.github/workflows/docker-publish.yaml
vendored
2
.github/workflows/docker-publish.yaml
vendored
@@ -88,7 +88,7 @@ jobs:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
platforms: linux/amd64
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
|
||||
4
.github/workflows/partial-frontend.yaml
vendored
4
.github/workflows/partial-frontend.yaml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
|
||||
- uses: pnpm/action-setup@v3.0.0
|
||||
with:
|
||||
version: 6.0.2
|
||||
version: 9.12.2
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --shamefully-hoist
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
|
||||
- uses: pnpm/action-setup@v3.0.0
|
||||
with:
|
||||
version: 6.0.2
|
||||
version: 9.12.2
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
76
Dockerfile
76
Dockerfile
@@ -1,69 +1,91 @@
|
||||
# Node dependencies
|
||||
FROM node:18-alpine AS frontend-dependencies
|
||||
# Node dependencies stage
|
||||
FROM --platform=$TARGETPLATFORM node:18-alpine AS frontend-dependencies
|
||||
WORKDIR /app
|
||||
|
||||
# Install pnpm globally (caching layer)
|
||||
RUN npm install -g pnpm
|
||||
|
||||
# Copy package.json and lockfile to leverage caching
|
||||
COPY frontend/package.json frontend/pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile --shamefully-hoist
|
||||
|
||||
# Build Nuxt
|
||||
FROM node:18-alpine AS frontend-builder
|
||||
WORKDIR /app
|
||||
# Build Nuxt (frontend) stage
|
||||
FROM --platform=$TARGETPLATFORM node:18-alpine AS frontend-builder
|
||||
WORKDIR /app
|
||||
|
||||
# Install pnpm globally again (it can reuse the cache if not changed)
|
||||
RUN npm install -g pnpm
|
||||
COPY frontend .
|
||||
|
||||
# Copy over source files and node_modules from dependencies stage
|
||||
COPY frontend .
|
||||
COPY --from=frontend-dependencies /app/node_modules ./node_modules
|
||||
RUN pnpm build
|
||||
|
||||
FROM golang:alpine AS builder-dependencies
|
||||
# Go dependencies stage
|
||||
FROM --platform=$TARGETPLATFORM golang:alpine AS builder-dependencies
|
||||
WORKDIR /go/src/app
|
||||
COPY ./backend .
|
||||
|
||||
# Copy go.mod and go.sum for better caching
|
||||
COPY ./backend/go.mod ./backend/go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
# Build API
|
||||
FROM golang:alpine AS builder
|
||||
# Build API stage
|
||||
FROM --platform=$TARGETPLATFORM golang:alpine AS builder
|
||||
ARG BUILD_TIME
|
||||
ARG COMMIT
|
||||
ARG VERSION
|
||||
|
||||
# Install necessary build tools
|
||||
RUN apk update && \
|
||||
apk upgrade && \
|
||||
apk add --update git build-base gcc g++
|
||||
apk add --no-cache git build-base gcc g++
|
||||
|
||||
WORKDIR /go/src/app
|
||||
|
||||
# Copy Go modules (from dependencies stage) and source code
|
||||
COPY --from=builder-dependencies /go/pkg/mod /go/pkg/mod
|
||||
COPY ./backend .
|
||||
|
||||
# Clear old public files and copy new ones from frontend build
|
||||
RUN rm -rf ./app/api/public
|
||||
COPY --from=frontend-builder /app/.output/public ./app/api/static/public
|
||||
COPY --from=builder-dependencies /go/pkg/mod /go/pkg/mod
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
|
||||
# Use cache for Go build artifacts
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
CGO_ENABLED=0 GOOS=linux go build \
|
||||
-ldflags "-s -w -X main.commit=$COMMIT -X main.buildTime=$BUILD_TIME -X main.version=$VERSION" \
|
||||
-ldflags "-s -w -X main.commit=$COMMIT -X main.buildTime=$BUILD_TIME -X main.version=$VERSION" \
|
||||
-o /go/bin/api \
|
||||
-v ./app/api/*.go
|
||||
|
||||
FROM gcr.io/distroless/java:latest
|
||||
|
||||
# Production Stage
|
||||
FROM alpine:latest
|
||||
|
||||
# Production stage
|
||||
FROM --platform=$TARGETPLATFORM alpine:latest
|
||||
ENV HBOX_MODE=production
|
||||
ENV HBOX_STORAGE_DATA=/data/
|
||||
ENV HBOX_STORAGE_SQLITE_URL=/data/homebox.db?_pragma=busy_timeout=2000&_pragma=journal_mode=WAL&_fk=1
|
||||
|
||||
RUN apk --no-cache add ca-certificates
|
||||
# Install necessary runtime dependencies
|
||||
RUN apk --no-cache add ca-certificates wget
|
||||
|
||||
# Create application directory and copy over built Go binary
|
||||
RUN mkdir /app
|
||||
COPY --from=builder /go/bin/api /app
|
||||
|
||||
RUN chmod +x /app/api
|
||||
RUN apk add --no-cache wget
|
||||
|
||||
# Labels and configuration for the final image
|
||||
LABEL Name=homebox Version=0.0.1
|
||||
LABEL org.opencontainers.image.source="https://github.com/sysadminsmedia/homebox"
|
||||
|
||||
# Expose necessary ports
|
||||
EXPOSE 7745
|
||||
WORKDIR /app
|
||||
HEALTHCHECK --interval=30s \
|
||||
--timeout=5s \
|
||||
--start-period=5s \
|
||||
--retries=3 \
|
||||
CMD [ "/usr/bin/wget", "--no-verbose", "--tries=1", "-O -", "http://localhost:7745/api/v1/status" ]
|
||||
|
||||
# Healthcheck configuration
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
|
||||
CMD [ "wget", "--no-verbose", "--tries=1", "-O", "-", "http://localhost:7745/api/v1/status" ]
|
||||
|
||||
# Persist volume
|
||||
VOLUME [ "/data" ]
|
||||
|
||||
# Entrypoint and CMD
|
||||
ENTRYPOINT [ "/app/api" ]
|
||||
CMD [ "/data/config.yml" ]
|
||||
|
||||
@@ -7,15 +7,15 @@ RUN pnpm install --frozen-lockfile --shamefully-hoist
|
||||
|
||||
# Build Nuxt
|
||||
FROM node:18-alpine AS frontend-builder
|
||||
WORKDIR /app
|
||||
RUN npm install -g pnpm
|
||||
COPY frontend .
|
||||
WORKDIR /app
|
||||
COPY frontend ./
|
||||
COPY --from=frontend-dependencies /app/node_modules ./node_modules
|
||||
RUN pnpm build
|
||||
|
||||
# Build Go dependencies
|
||||
FROM golang:alpine AS builder-dependencies
|
||||
WORKDIR /go/src/app
|
||||
COPY ./backend .
|
||||
COPY ./backend/go.mod ./backend/go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
# Build API
|
||||
@@ -23,48 +23,51 @@ FROM golang:alpine AS builder
|
||||
ARG BUILD_TIME
|
||||
ARG COMMIT
|
||||
ARG VERSION
|
||||
RUN apk update && \
|
||||
apk upgrade && \
|
||||
apk add --update git build-base gcc g++
|
||||
|
||||
RUN apk update && apk upgrade && apk add --no-cache git build-base gcc g++
|
||||
|
||||
WORKDIR /go/src/app
|
||||
COPY ./backend .
|
||||
RUN rm -rf ./app/api/public
|
||||
COPY --from=frontend-builder /app/.output/public ./app/api/static/public
|
||||
COPY --from=builder-dependencies /go/pkg/mod /go/pkg/mod
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
|
||||
# Use cache for Go build
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
CGO_ENABLED=0 GOOS=linux go build \
|
||||
-ldflags "-s -w -X main.commit=$COMMIT -X main.buildTime=$BUILD_TIME -X main.version=$VERSION" \
|
||||
-o /go/bin/api \
|
||||
-v ./app/api/*.go
|
||||
-ldflags "-s -w -X main.commit=$COMMIT -X main.buildTime=$BUILD_TIME -X main.version=$VERSION" \
|
||||
-o /go/bin/api ./app/api/*.go
|
||||
|
||||
FROM gcr.io/distroless/java:latest
|
||||
|
||||
# Production Stage
|
||||
# Production stage with distroless
|
||||
FROM gcr.io/distroless/static:latest
|
||||
|
||||
ENV HBOX_MODE=production
|
||||
ENV HBOX_STORAGE_DATA=/data/
|
||||
ENV HBOX_STORAGE_SQLITE_URL=/data/homebox.db?_fk=1
|
||||
|
||||
# Copy the binary and the (empty) /data dir and
|
||||
# change the ownership to the low-privileged user
|
||||
# Copy the binary and data directory, change ownership
|
||||
COPY --from=builder --chown=nonroot /go/bin/api /app
|
||||
COPY --from=builder --chown=nonroot /data /data
|
||||
|
||||
RUN apk add --no-cache wget
|
||||
# Add wget to the image
|
||||
# Note: If using distroless, this may not be applicable
|
||||
# as distroless images do not include package managers.
|
||||
# This line may be omitted if you're relying on another way to handle healthchecks.
|
||||
COPY --from=alpine:latest /bin/wget /usr/bin/wget
|
||||
|
||||
LABEL Name=homebox Version=0.0.1
|
||||
LABEL org.opencontainers.image.source="https://github.com/sysadminsmedia/homebox"
|
||||
EXPOSE 7745
|
||||
|
||||
HEALTHCHECK --interval=30s \
|
||||
--timeout=5s \
|
||||
--start-period=5s \
|
||||
--retries=3 \
|
||||
CMD [ "/usr/bin/wget", "--no-verbose", "--tries=1", "-O -", "http://localhost:7745/api/v1/status" ]
|
||||
VOLUME [ "/data" ]
|
||||
CMD ["/usr/bin/wget", "--no-verbose", "--tries=1", "-O", "-", "http://localhost:7745/api/v1/status"]
|
||||
|
||||
# Drop root and run as low-privileged user
|
||||
VOLUME ["/data"]
|
||||
|
||||
# Drop root and run as a low-privileged user
|
||||
USER nonroot
|
||||
ENTRYPOINT [ "/app" ]
|
||||
CMD [ "/data/config.yml" ]
|
||||
ENTRYPOINT ["/app"]
|
||||
CMD ["/data/config.yml"]
|
||||
|
||||
51
backend/app/api/handlers/v1/v1_ctrl_locales.go
Normal file
51
backend/app/api/handlers/v1/v1_ctrl_locales.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/httpkit/errchain"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/core/services"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/data/repo"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/web/adapters"
|
||||
)
|
||||
|
||||
type Locales struct {
|
||||
Locales []string `json:"locales"`
|
||||
}
|
||||
|
||||
// HandleLocalesGetAll godoc
|
||||
//
|
||||
// @Summary Get All Locales
|
||||
// @Tags Locales
|
||||
// @Produce json
|
||||
// @Success 200 {object} []Locales
|
||||
// @Router /v1/locales [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLocalesGetAll() errchain.HandlerFunc {
|
||||
fn := func(r *http.Request) ([]Locales, error) {
|
||||
// TODO: get a list of locales from files
|
||||
return []Locales{}, nil
|
||||
}
|
||||
|
||||
return adapters.Command(fn, http.StatusOK)
|
||||
}
|
||||
|
||||
// HandleLocalesGet godoc
|
||||
//
|
||||
// @Summary Get Locale
|
||||
// @Tags Locales
|
||||
// @Produce json
|
||||
// @Param id path string true "Locale ID"
|
||||
// @Success 200 {object} interface{}
|
||||
// @Router /v1/locales/{id} [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLocalesGet() errchain.HandlerFunc {
|
||||
fn := func(r *http.Request, ID uuid.UUID) (interface{}, error) {
|
||||
// TODO: get the current locale
|
||||
return interface{}, nil
|
||||
}
|
||||
|
||||
return adapters.CommandID("id", fn, http.StatusOK)
|
||||
}
|
||||
@@ -254,6 +254,19 @@ func run(cfg *config.Config) error {
|
||||
}
|
||||
}))
|
||||
|
||||
// TODO: read from env var0 GOOS=linux go build
|
||||
if true {
|
||||
runner.AddPlugin(NewTask("locale-update", time.Duration(24)*time.Hour, func(ctx context.Context) {
|
||||
log.Debug().Msg("running locale update")
|
||||
err := app.services.BackgroundService.UpdateLocales(ctx)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Msg("failed to update locales")
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
if cfg.Debug.Enabled {
|
||||
runner.AddFunc("debug", func(ctx context.Context) error {
|
||||
debugserver := http.Server{
|
||||
|
||||
@@ -2217,8 +2217,7 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2234,8 +2233,7 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
@@ -2323,8 +2321,7 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "integer"
|
||||
@@ -2412,7 +2409,9 @@ const docTemplate = `{
|
||||
"maxLength": 255
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "number"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2429,7 +2428,9 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "number"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
|
||||
@@ -2210,8 +2210,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2227,8 +2226,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
@@ -2316,8 +2314,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "integer"
|
||||
@@ -2405,7 +2402,9 @@
|
||||
"maxLength": 255
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "number"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2422,7 +2421,9 @@
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "number"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
|
||||
@@ -171,8 +171,7 @@ definitions:
|
||||
purchaseFrom:
|
||||
type: string
|
||||
purchasePrice:
|
||||
example: "0"
|
||||
type: string
|
||||
type: number
|
||||
purchaseTime:
|
||||
description: Purchase
|
||||
type: string
|
||||
@@ -183,8 +182,7 @@ definitions:
|
||||
soldNotes:
|
||||
type: string
|
||||
soldPrice:
|
||||
example: "0"
|
||||
type: string
|
||||
type: number
|
||||
soldTime:
|
||||
description: Sold
|
||||
type: string
|
||||
@@ -242,8 +240,7 @@ definitions:
|
||||
name:
|
||||
type: string
|
||||
purchasePrice:
|
||||
example: "0"
|
||||
type: string
|
||||
type: number
|
||||
quantity:
|
||||
type: integer
|
||||
updatedAt:
|
||||
@@ -304,6 +301,8 @@ definitions:
|
||||
type: string
|
||||
purchasePrice:
|
||||
type: number
|
||||
x-nullable: true
|
||||
x-omitempty: true
|
||||
purchaseTime:
|
||||
description: Purchase
|
||||
type: string
|
||||
@@ -316,6 +315,8 @@ definitions:
|
||||
type: string
|
||||
soldPrice:
|
||||
type: number
|
||||
x-nullable: true
|
||||
x-omitempty: true
|
||||
soldTime:
|
||||
description: Sold
|
||||
type: string
|
||||
|
||||
@@ -79,3 +79,20 @@ func (svc *BackgroundService) SendNotifiersToday(ctx context.Context) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc *BackgroundService) UpdateLocales(ctx context.Context) error {
|
||||
log.Debug().Msg("updating locales")
|
||||
// fetch list of locales from github
|
||||
// is it worth checking if any changes have been made?
|
||||
// download locales overwriting files in static/public/locales
|
||||
|
||||
// curl -H "Accept: application/vnd.github.v3+json" \
|
||||
// -H "If-Modified-Since: Thu, 31 Oct 2024 09:59:02 GMT" \
|
||||
// -o /dev/null -s -w "%{http_code}\n" \
|
||||
// https://api.github.com/repos/sysadminsmedia/homebox/contents/frontend/locales
|
||||
// keep track of last modified date
|
||||
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -87,11 +87,11 @@ func (r *AttachmentRepo) Get(ctx context.Context, id uuid.UUID) (*ent.Attachment
|
||||
Only(ctx)
|
||||
}
|
||||
|
||||
func (r *AttachmentRepo) Update(ctx context.Context, itemID uuid.UUID, data *ItemAttachmentUpdate) (*ent.Attachment, error) {
|
||||
func (r *AttachmentRepo) Update(ctx context.Context, id uuid.UUID, data *ItemAttachmentUpdate) (*ent.Attachment, error) {
|
||||
// TODO: execute within Tx
|
||||
typ := attachment.Type(data.Type)
|
||||
|
||||
bldr := r.db.Attachment.UpdateOneID(itemID).
|
||||
bldr := r.db.Attachment.UpdateOneID(id).
|
||||
SetType(typ)
|
||||
|
||||
// Primary only applies to photos
|
||||
@@ -101,7 +101,12 @@ func (r *AttachmentRepo) Update(ctx context.Context, itemID uuid.UUID, data *Ite
|
||||
bldr = bldr.SetPrimary(false)
|
||||
}
|
||||
|
||||
itm, err := bldr.Save(ctx)
|
||||
updatedAttachment, err := bldr.Save(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
attachmentItem, err := updatedAttachment.QueryItem().Only(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -109,8 +114,8 @@ func (r *AttachmentRepo) Update(ctx context.Context, itemID uuid.UUID, data *Ite
|
||||
// Ensure all other attachments are not primary
|
||||
err = r.db.Attachment.Update().
|
||||
Where(
|
||||
attachment.HasItemWith(item.ID(itemID)),
|
||||
attachment.IDNEQ(itm.ID),
|
||||
attachment.HasItemWith(item.ID(attachmentItem.ID)),
|
||||
attachment.IDNEQ(updatedAttachment.ID),
|
||||
).
|
||||
SetPrimary(false).
|
||||
Exec(ctx)
|
||||
@@ -118,7 +123,7 @@ func (r *AttachmentRepo) Update(ctx context.Context, itemID uuid.UUID, data *Ite
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.Get(ctx, itm.ID)
|
||||
return r.Get(ctx, updatedAttachment.ID)
|
||||
}
|
||||
|
||||
func (r *AttachmentRepo) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
|
||||
@@ -133,3 +133,25 @@ func TestAttachmentRepo_Delete(t *testing.T) {
|
||||
_, err = tRepos.Attachments.Get(context.Background(), entity.ID)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestAttachmentRepo_EnsureSinglePrimaryAttachment(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
attachments := useAttachments(t, 2)
|
||||
|
||||
setAndVerifyPrimary := func(primaryAttachmentID, nonPrimaryAttachmentID uuid.UUID) {
|
||||
primaryAttachment, err := tRepos.Attachments.Update(ctx, primaryAttachmentID, &ItemAttachmentUpdate{
|
||||
Type: attachment.TypePhoto.String(),
|
||||
Primary: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
nonPrimaryAttachment, err := tRepos.Attachments.Get(ctx, nonPrimaryAttachmentID)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.True(t, primaryAttachment.Primary)
|
||||
assert.False(t, nonPrimaryAttachment.Primary)
|
||||
}
|
||||
|
||||
setAndVerifyPrimary(attachments[0].ID, attachments[1].ID)
|
||||
setAndVerifyPrimary(attachments[1].ID, attachments[0].ID)
|
||||
}
|
||||
|
||||
@@ -93,12 +93,12 @@ type (
|
||||
// Purchase
|
||||
PurchaseTime types.Date `json:"purchaseTime"`
|
||||
PurchaseFrom string `json:"purchaseFrom" validate:"max=255"`
|
||||
PurchasePrice float64 `json:"purchasePrice"`
|
||||
PurchasePrice float64 `json:"purchasePrice" extensions:"x-nullable,x-omitempty"`
|
||||
|
||||
// Sold
|
||||
SoldTime types.Date `json:"soldTime"`
|
||||
SoldTo string `json:"soldTo" validate:"max=255"`
|
||||
SoldPrice float64 `json:"soldPrice"`
|
||||
SoldPrice float64 `json:"soldPrice" extensions:"x-nullable,x-omitempty"`
|
||||
SoldNotes string `json:"soldNotes"`
|
||||
|
||||
// Extras
|
||||
@@ -123,7 +123,7 @@ type (
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
|
||||
PurchasePrice float64 `json:"purchasePrice,string"`
|
||||
PurchasePrice float64 `json:"purchasePrice"`
|
||||
|
||||
// Edges
|
||||
Location *LocationSummary `json:"location,omitempty" extensions:"x-nullable,x-omitempty"`
|
||||
@@ -153,7 +153,7 @@ type (
|
||||
// Sold
|
||||
SoldTime types.Date `json:"soldTime"`
|
||||
SoldTo string `json:"soldTo"`
|
||||
SoldPrice float64 `json:"soldPrice,string"`
|
||||
SoldPrice float64 `json:"soldPrice"`
|
||||
SoldNotes string `json:"soldNotes"`
|
||||
|
||||
// Extras
|
||||
|
||||
@@ -2210,8 +2210,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2227,8 +2226,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
@@ -2316,8 +2314,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "integer"
|
||||
@@ -2340,6 +2337,9 @@
|
||||
},
|
||||
"repo.ItemUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"archived": {
|
||||
"type": "boolean"
|
||||
@@ -2348,7 +2348,8 @@
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 1000
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
@@ -2383,7 +2384,9 @@
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255,
|
||||
"minLength": 1
|
||||
},
|
||||
"notes": {
|
||||
"description": "Extras",
|
||||
@@ -2395,11 +2398,13 @@
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseFrom": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2416,15 +2421,17 @@
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
"type": "string"
|
||||
},
|
||||
"soldTo": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"warrantyDetails": {
|
||||
"type": "string"
|
||||
@@ -2756,7 +2763,6 @@
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"description": "URL field is not exposed to the client",
|
||||
"type": "string"
|
||||
},
|
||||
"userId": {
|
||||
|
||||
@@ -35,7 +35,7 @@ swagger update command `task swag`
|
||||
|
||||
### Frontend Development Notes
|
||||
|
||||
start command `task: ui:dev`
|
||||
start command `task ui:dev`
|
||||
|
||||
1. The frontend is a Vue 3 app with Nuxt.js that uses Tailwind and DaisyUI for styling.
|
||||
2. We're using Vitest for our automated testing. You can run these with `task ui:watch`.
|
||||
|
||||
@@ -28,3 +28,61 @@
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #9B9B9B;
|
||||
}
|
||||
|
||||
.scroll-bg::-webkit-scrollbar {
|
||||
width: 0.5rem;
|
||||
}
|
||||
|
||||
.scroll-bg::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.25rem;
|
||||
@apply bg-base-300;
|
||||
}
|
||||
|
||||
.markdown > :first-child {
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
.markdown :where(p, ul, ol, dl, blockquote, h1, h2, h3, h4, h5, h6) {
|
||||
margin-top: var(--y-gap);
|
||||
margin-bottom: var(--y-gap);
|
||||
}
|
||||
|
||||
.markdown :where(ul) {
|
||||
list-style: disc;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
.markdown :where(ol) {
|
||||
list-style: decimal;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
/* Heading Styles */
|
||||
.markdown :where(h1) {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown :where(h2) {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown :where(h3) {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown :where(h4) {
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown :where(h5) {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown :where(h6) {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
class="flex items-center text-3xl font-bold tracking-tight"
|
||||
:class="{
|
||||
'text-neutral-content': dark,
|
||||
'text-content': !dark,
|
||||
}"
|
||||
>
|
||||
<slot />
|
||||
|
||||
@@ -85,7 +85,10 @@
|
||||
type Props = {
|
||||
label: string;
|
||||
modelValue: SupportValues | null | undefined;
|
||||
items: string[] | object[];
|
||||
items: {
|
||||
id: string;
|
||||
treeString: string;
|
||||
}[];
|
||||
display?: string;
|
||||
multiple?: boolean;
|
||||
};
|
||||
@@ -156,11 +159,28 @@
|
||||
|
||||
const matches = index.value.search("*" + search.value + "*");
|
||||
|
||||
const resultIDs = [];
|
||||
for (let i = 0; i < matches.length; i++) {
|
||||
const match = matches[i];
|
||||
const item = props.items[parseInt(match.ref)];
|
||||
const display = extractDisplay(item);
|
||||
list.push({ id: i, display, value: item });
|
||||
resultIDs.push(item.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supplementary search,
|
||||
* Resolve the issue of language not being supported
|
||||
*/
|
||||
for (let i = 0; i < props.items.length; i++) {
|
||||
const item = props.items[i];
|
||||
if (resultIDs.find(item_ => item_ === item.id) !== undefined) {
|
||||
continue;
|
||||
}
|
||||
if (item.treeString.includes(search.value)) {
|
||||
const display = extractDisplay(item);
|
||||
list.push({ id: i, display, value: item });
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
:class="{
|
||||
'text-red-600':
|
||||
typeof value === 'string' &&
|
||||
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
|
||||
((maxLength !== -1 && value.length > maxLength) || (minLength !== -1 && value.length < minLength)),
|
||||
}"
|
||||
>
|
||||
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
|
||||
{{ typeof value === "string" && (maxLength !== -1 || minLength !== -1) ? `${value.length}/${maxLength}` : "" }}
|
||||
</span>
|
||||
</label>
|
||||
<textarea ref="el" v-model="value" class="textarea textarea-bordered h-28 w-full" :placeholder="placeholder" />
|
||||
@@ -21,10 +21,10 @@
|
||||
:class="{
|
||||
'text-red-600':
|
||||
typeof value === 'string' &&
|
||||
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
|
||||
((maxLength !== -1 && value.length > maxLength) || (minLength !== -1 && value.length < minLength)),
|
||||
}"
|
||||
>
|
||||
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
|
||||
{{ typeof value === "string" && (maxLength !== -1 || minLength !== -1) ? `${value.length}/${maxLength}` : "" }}
|
||||
</span>
|
||||
</label>
|
||||
<textarea
|
||||
@@ -63,10 +63,12 @@
|
||||
},
|
||||
maxLength: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
required: false,
|
||||
},
|
||||
minLength: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
@@ -84,7 +86,4 @@
|
||||
});
|
||||
|
||||
const value = useVModel(props, "modelValue", emit);
|
||||
const valueLen = computed(() => {
|
||||
return value.value ? value.value.length : 0;
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
:class="{
|
||||
'text-red-600':
|
||||
typeof value === 'string' &&
|
||||
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
|
||||
((maxLength !== -1 && value.length > maxLength) || (minLength !== -1 && value.length < minLength)),
|
||||
}"
|
||||
>
|
||||
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
|
||||
{{ typeof value === "string" && (maxLength !== -1 || minLength !== -1) ? `${value.length}/${maxLength}` : "" }}
|
||||
</span>
|
||||
</label>
|
||||
<input
|
||||
@@ -28,10 +28,10 @@
|
||||
:class="{
|
||||
'text-red-600':
|
||||
typeof value === 'string' &&
|
||||
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
|
||||
((maxLength !== -1 && value.length > maxLength) || (minLength !== -1 && value.length < minLength)),
|
||||
}"
|
||||
>
|
||||
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
|
||||
{{ typeof value === "string" && (maxLength !== -1 || minLength !== -1) ? `${value.length}/${maxLength}` : "" }}
|
||||
</span>
|
||||
</label>
|
||||
<input
|
||||
@@ -76,10 +76,12 @@
|
||||
},
|
||||
maxLength: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
required: false,
|
||||
},
|
||||
minLength: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
<template>
|
||||
<NuxtLink class="group card rounded-md border border-gray-300" :to="`/item/${item.id}`">
|
||||
<div class="relative h-[200px]">
|
||||
<img v-if="imageUrl" class="h-[200px] w-full rounded-t border-gray-300 object-cover shadow-sm" :src="imageUrl" />
|
||||
<div class="absolute bottom-1 left-1">
|
||||
<img
|
||||
v-if="imageUrl"
|
||||
class="h-[200px] w-full rounded-t border-gray-300 object-cover shadow-sm"
|
||||
:src="imageUrl"
|
||||
alt=""
|
||||
/>
|
||||
<div class="absolute bottom-1 left-1 text-wrap">
|
||||
<NuxtLink
|
||||
v-if="item.location"
|
||||
class="badge rounded-md text-sm shadow-md hover:link"
|
||||
:to="`/location/${item.location.id}`"
|
||||
loading="lazy"
|
||||
>
|
||||
{{ item.location.name }}
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-4 flex grow flex-col gap-y-1 rounded-b bg-base-100 p-4 pt-2">
|
||||
<h2 class="line-clamp-2 text-ellipsis text-lg font-bold">{{ item.name }}</h2>
|
||||
<h2 class="line-clamp-2 text-ellipsis text-wrap text-lg font-bold">{{ item.name }}</h2>
|
||||
<div class="divider my-0"></div>
|
||||
<div class="flex gap-2">
|
||||
<div v-if="item.insured" class="tooltip z-10" data-tip="Insured">
|
||||
|
||||
@@ -8,17 +8,27 @@
|
||||
v-model="form.name"
|
||||
:trigger-focus="focused"
|
||||
:autofocus="true"
|
||||
label="Item Name"
|
||||
:label="$t('components.item.create_modal.item_name')"
|
||||
:max-length="255"
|
||||
:min-length="1"
|
||||
/>
|
||||
<FormTextArea v-model="form.description" label="Item Description" :max-length="1000" />
|
||||
<FormMultiselect v-model="form.labels" label="Labels" :items="labels ?? []" />
|
||||
<FormTextArea
|
||||
v-model="form.description"
|
||||
:label="$t('components.item.create_modal.item_description')"
|
||||
:max-length="1000"
|
||||
/>
|
||||
<FormMultiselect v-model="form.labels" :label="$t('global.labels')" :items="labels ?? []" />
|
||||
|
||||
<div class="modal-action mb-6">
|
||||
<div>
|
||||
<label for="photo" class="btn">{{ $t("components.item.create_modal.photo_button") }}</label>
|
||||
<input id="photo" class="hidden" type="file" accept="image/png,image/jpeg,image/gif" @change="previewImage" />
|
||||
<input
|
||||
id="photo"
|
||||
class="hidden"
|
||||
type="file"
|
||||
accept="image/png,image/jpeg,image/gif,image/avif,image/webp"
|
||||
@change="previewImage"
|
||||
/>
|
||||
</div>
|
||||
<div class="grow"></div>
|
||||
<div>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
}"
|
||||
>
|
||||
<template v-if="typeof h === 'string'">{{ h }}</template>
|
||||
<template v-else>{{ h.text }}</template>
|
||||
<template v-else>{{ $t(h.text) }}</template>
|
||||
<div
|
||||
v-if="sortByProperty === h.value"
|
||||
:class="`inline-flex ${sortByProperty === h.value ? '' : 'opacity-0'}`"
|
||||
@@ -45,7 +45,7 @@
|
||||
}"
|
||||
>
|
||||
<template v-if="h.type === 'name'">
|
||||
<NuxtLink class="hover" :to="`/item/${d.id}`">
|
||||
<NuxtLink class="hover text-wrap" :to="`/item/${d.id}`">
|
||||
{{ d.name }}
|
||||
</NuxtLink>
|
||||
</template>
|
||||
@@ -83,7 +83,7 @@
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content rounded-box flex w-64 flex-col gap-2 bg-base-100 p-2 pl-3 shadow">
|
||||
<li>Headers:</li>
|
||||
<li v-for="(h, i) in headers" class="flex flex-row items-center gap-1">
|
||||
<li v-for="(h, i) in headers" :key="h.value" class="flex flex-row items-center gap-1">
|
||||
<button
|
||||
class="btn btn-square btn-ghost btn-xs"
|
||||
:class="{
|
||||
@@ -109,11 +109,11 @@
|
||||
:checked="h.enabled"
|
||||
@change="toggleHeader(h.value)"
|
||||
/>
|
||||
<label class="label-text" :for="h.value"> {{ h.text }} </label>
|
||||
<label class="label-text" :for="h.value"> {{ $t(h.text) }} </label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="hidden md:block">Rows per page</div>
|
||||
<div class="hidden md:block">{{ $t("components.item.view.table.rows_per_page") }}</div>
|
||||
<select v-model.number="pagination.rowsPerPage" class="select select-primary select-sm">
|
||||
<option :value="10">10</option>
|
||||
<option :value="25">25</option>
|
||||
@@ -122,7 +122,7 @@
|
||||
</select>
|
||||
<div class="btn-group">
|
||||
<button :disabled="!hasPrev" class="btn btn-sm" @click="prev()">«</button>
|
||||
<button class="btn btn-sm">Page {{ pagination.page }}</button>
|
||||
<button class="btn btn-sm">{{ $t("components.item.view.table.page") }} {{ pagination.page }}</button>
|
||||
<button :disabled="!hasNext" class="btn btn-sm" @click="next()">»</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -149,20 +149,29 @@
|
||||
const preferences = useViewPreferences();
|
||||
|
||||
const defaultHeaders = [
|
||||
{ text: "Name", value: "name", enabled: true, type: "name" },
|
||||
{ text: "Quantity", value: "quantity", align: "center", enabled: true },
|
||||
{ text: "Insured", value: "insured", align: "center", enabled: true, type: "boolean" },
|
||||
{ text: "Price", value: "purchasePrice", align: "center", enabled: true, type: "price" },
|
||||
{ text: "Location", value: "location", align: "center", enabled: false, type: "location" },
|
||||
{ text: "Archived", value: "archived", align: "center", enabled: false, type: "boolean" },
|
||||
{ text: "Created At", value: "createdAt", align: "center", enabled: false, type: "date" },
|
||||
{ text: "Updated At", value: "updatedAt", align: "center", enabled: false, type: "date" },
|
||||
{
|
||||
text: "items.name",
|
||||
value: "name",
|
||||
enabled: true,
|
||||
type: "name",
|
||||
},
|
||||
{ text: "items.quantity", value: "quantity", align: "center", enabled: true },
|
||||
{ text: "items.insured", value: "insured", align: "center", enabled: true, type: "boolean" },
|
||||
{ text: "items.purchase_price", value: "purchasePrice", align: "center", enabled: true, type: "price" },
|
||||
{ text: "items.location", value: "location", align: "center", enabled: false, type: "location" },
|
||||
{ text: "items.archived", value: "archived", align: "center", enabled: false, type: "boolean" },
|
||||
{ text: "items.created_at", value: "createdAt", align: "center", enabled: false, type: "date" },
|
||||
{ text: "items.updated_at", value: "updatedAt", align: "center", enabled: false, type: "date" },
|
||||
] satisfies TableHeader[];
|
||||
|
||||
const headers = ref<TableHeader[]>(
|
||||
(preferences.value.tableHeaders ?? []).concat(
|
||||
defaultHeaders.filter(h => !preferences.value.tableHeaders?.find(h2 => h2.value === h.value))
|
||||
)
|
||||
(preferences.value.tableHeaders ?? [])
|
||||
.concat(defaultHeaders.filter(h => !preferences.value.tableHeaders?.find(h2 => h2.value === h.value)))
|
||||
// this is a hack to make sure that any changes to the defaultHeaders are reflected in the preferences
|
||||
.map(h => ({
|
||||
...(defaultHeaders.find(h2 => h2.value === h.value) as TableHeader),
|
||||
enabled: h.enabled,
|
||||
}))
|
||||
);
|
||||
|
||||
console.log(headers.value);
|
||||
|
||||
@@ -7,11 +7,15 @@
|
||||
v-model="form.name"
|
||||
:trigger-focus="focused"
|
||||
:autofocus="true"
|
||||
label="Label Name"
|
||||
:label="$t('components.label.create_modal.label_name')"
|
||||
:max-length="255"
|
||||
:min-length="1"
|
||||
/>
|
||||
<FormTextArea v-model="form.description" label="Label Description" :max-length="255" />
|
||||
<FormTextArea
|
||||
v-model="form.description"
|
||||
:label="$t('components.label.create_modal.label_description')"
|
||||
:max-length="255"
|
||||
/>
|
||||
<div class="modal-action">
|
||||
<div class="flex justify-center">
|
||||
<BaseButton class="rounded-r-none" :loading="loading" type="submit"> {{ $t("global.create") }} </BaseButton>
|
||||
|
||||
@@ -8,11 +8,15 @@
|
||||
:trigger-focus="focused"
|
||||
:autofocus="true"
|
||||
:required="true"
|
||||
label="Location Name"
|
||||
:label="$t('components.location.create_modal.location_name')"
|
||||
:max-length="255"
|
||||
:min-length="1"
|
||||
/>
|
||||
<FormTextArea v-model="form.description" label="Location Description" :max-length="1000" />
|
||||
<FormTextArea
|
||||
v-model="form.description"
|
||||
:label="$t('components.location.create_modal.location_description')"
|
||||
:max-length="1000"
|
||||
/>
|
||||
<LocationSelector v-model="form.parent" />
|
||||
<div class="modal-action">
|
||||
<div class="flex justify-center">
|
||||
@@ -21,7 +25,7 @@
|
||||
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
|
||||
<MdiChevronDown class="size-5" />
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu rounded-box bg-base-100 right-0 w-64 p-2 shadow">
|
||||
<ul tabindex="0" class="dropdown-content menu rounded-box right-0 w-64 bg-base-100 p-2 shadow">
|
||||
<li>
|
||||
<button type="button" @click="create(false)">{{ $t("global.create_and_add") }}</button>
|
||||
</li>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<template>
|
||||
<FormAutocomplete2 v-if="locations" v-model="value" :items="locations" display="name" label="Parent Location">
|
||||
<FormAutocomplete2
|
||||
v-if="locations"
|
||||
v-model="value"
|
||||
:items="locations"
|
||||
display="name"
|
||||
:label="$t('components.location.selector.parent_location')"
|
||||
>
|
||||
<template #display="{ item, selected, active }">
|
||||
<div>
|
||||
<div class="flex w-full">
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- eslint-disable-next-line tailwindcss/no-custom-classname -->
|
||||
<div class="root border-2 p-4">
|
||||
<p v-if="locs.length === 0" class="text-center text-sm">
|
||||
{{ $t("location.tree.no_locations") }}
|
||||
|
||||
@@ -25,17 +25,17 @@
|
||||
},
|
||||
});
|
||||
|
||||
const { data: maintenanceDataList, refresh: refreshList } = useAsyncData<MaintenanceEntryWithDetails[]>(
|
||||
const { data: maintenanceDataList, refresh: refreshList } = useAsyncData(
|
||||
async () => {
|
||||
const { data } =
|
||||
props.currentItemId !== undefined
|
||||
? await api.items.maintenance.getLog(props.currentItemId, { status: maintenanceFilterStatus.value })
|
||||
: await api.maintenance.getAll({ status: maintenanceFilterStatus.value });
|
||||
console.log(data);
|
||||
return data as MaintenanceEntryWithDetails[];
|
||||
return data;
|
||||
},
|
||||
{
|
||||
watch: maintenanceFilterStatus,
|
||||
watch: [maintenanceFilterStatus],
|
||||
}
|
||||
);
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<StatCard
|
||||
v-for="stat in stats"
|
||||
:key="stat.id"
|
||||
class="stats border-l-primary block shadow-xl"
|
||||
class="stats block border-l-primary shadow-xl"
|
||||
:title="stat.title"
|
||||
:value="stat.value"
|
||||
:type="stat.type"
|
||||
@@ -189,7 +189,7 @@
|
||||
<div v-if="props.currentItemId" class="hidden first:block">
|
||||
<button
|
||||
type="button"
|
||||
class="border-base-content relative block w-full rounded-lg border-2 border-dashed p-12 text-center"
|
||||
class="relative block w-full rounded-lg border-2 border-dashed border-base-content p-12 text-center"
|
||||
@click="maintenanceEditModal?.openCreateModal(props.currentItemId)"
|
||||
>
|
||||
<MdiWrenchClock class="inline size-16" />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<dl class="sm:divide-y sm:divide-gray-300">
|
||||
<div v-for="(detail, i) in details" :key="i" class="group py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm font-medium text-base-content">
|
||||
{{ detail.name }}
|
||||
{{ $t(detail.name) }}
|
||||
</dt>
|
||||
<dd class="text-start text-sm text-base-content sm:col-span-2">
|
||||
<slot :name="detail.slot || detail.name" v-bind="{ detail }">
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div class="markdown text-wrap" v-html="raw"></div>
|
||||
</template>
|
||||
|
||||
@@ -31,53 +32,4 @@
|
||||
* {
|
||||
--y-gap: 0.65rem;
|
||||
}
|
||||
|
||||
.markdown > :first-child {
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
.markdown :where(p, ul, ol, dl, blockquote, h1, h2, h3, h4, h5, h6) {
|
||||
margin-top: var(--y-gap);
|
||||
margin-bottom: var(--y-gap);
|
||||
}
|
||||
|
||||
.markdown :where(ul) {
|
||||
list-style: disc;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
.markdown :where(ol) {
|
||||
list-style: decimal;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
/* Heading Styles */
|
||||
.markdown :where(h1) {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown :where(h2) {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown :where(h3) {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown :where(h4) {
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown :where(h5) {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown :where(h6) {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { type UseTimeAgoMessages, type UseTimeAgoUnitNamesDefault } from "@vueuse/core";
|
||||
|
||||
const cache = {
|
||||
currency: "",
|
||||
};
|
||||
@@ -37,6 +40,49 @@ function ordinalIndicator(num: number) {
|
||||
}
|
||||
}
|
||||
|
||||
export function useLocaleTimeAgo(date: Date) {
|
||||
const { t } = useI18n();
|
||||
|
||||
const I18N_MESSAGES: UseTimeAgoMessages<UseTimeAgoUnitNamesDefault> = {
|
||||
justNow: t("components.global.date_time.just-now"),
|
||||
past: n => (n.match(/\d/) ? t("components.global.date_time.ago", [n]) : n),
|
||||
future: n => (n.match(/\d/) ? t("components.global.date_time.in", [n]) : n),
|
||||
month: (n, past) =>
|
||||
n === 1
|
||||
? past
|
||||
? t("components.global.date_time.last-month")
|
||||
: t("components.global.date_time.next-month")
|
||||
: `${n} ${t(`components.global.date_time.months`)}`,
|
||||
year: (n, past) =>
|
||||
n === 1
|
||||
? past
|
||||
? t("components.global.date_time.last-year")
|
||||
: t("components.global.date_time.next-year")
|
||||
: `${n} ${t(`components.global.date_time.years`)}`,
|
||||
day: (n, past) =>
|
||||
n === 1
|
||||
? past
|
||||
? t("components.global.date_time.yesterday")
|
||||
: t("components.global.date_time.tomorrow")
|
||||
: `${n} ${t(`components.global.date_time.days`)}`,
|
||||
week: (n, past) =>
|
||||
n === 1
|
||||
? past
|
||||
? t("components.global.date_time.last-week")
|
||||
: t("components.global.date_time.next-week")
|
||||
: `${n} ${t(`components.global.date_time.weeks`)}`,
|
||||
hour: n => `${n} ${n === 1 ? t("components.global.date_time.hour") : t("components.global.date_time.hours")}`,
|
||||
minute: n => `${n} ${n === 1 ? t("components.global.date_time.minute") : t("components.global.date_time.minutes")}`,
|
||||
second: n => `${n} ${n === 1 ? t("components.global.date_time.second") : t("components.global.date_time.seconds")}`,
|
||||
invalid: "",
|
||||
};
|
||||
|
||||
return useTimeAgo(date, {
|
||||
fullDateFormatter: (date: Date) => date.toLocaleDateString(),
|
||||
messages: I18N_MESSAGES,
|
||||
});
|
||||
}
|
||||
|
||||
export function fmtDate(value: string | Date, fmt: DateTimeFormat = "human"): string {
|
||||
const months = [
|
||||
"January",
|
||||
@@ -64,7 +110,7 @@ export function fmtDate(value: string | Date, fmt: DateTimeFormat = "human"): st
|
||||
|
||||
switch (fmt) {
|
||||
case "relative":
|
||||
return useTimeAgo(dt).value + useDateFormat(dt, " (YYYY-MM-DD)").value;
|
||||
return useLocaleTimeAgo(dt).value + useDateFormat(dt, " (YYYY-MM-DD)").value;
|
||||
case "long":
|
||||
return useDateFormat(dt, "YYYY-MM-DD (dddd)").value;
|
||||
case "short":
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Ref } from "vue";
|
||||
import type { TableHeader } from "components/Item/View/Table.types";
|
||||
import type { TableHeader } from "~/components/Item/View/Table.types";
|
||||
import type { DaisyTheme } from "~~/lib/data/themes";
|
||||
|
||||
export type ViewType = "table" | "card" | "tree";
|
||||
|
||||
@@ -12,15 +12,15 @@
|
||||
<AppToast />
|
||||
<div class="drawer drawer-mobile">
|
||||
<input id="my-drawer-2" v-model="drawerToggle" type="checkbox" class="drawer-toggle" />
|
||||
<div class="drawer-content bg-base-300 justify-center pt-20 lg:pt-0">
|
||||
<div class="drawer-content justify-center bg-base-300 pt-20 lg:pt-0">
|
||||
<AppHeaderDecor v-if="preferences.displayHeaderDecor" class="-mt-10 hidden lg:block" />
|
||||
<!-- Button -->
|
||||
<div class="navbar drawer-button bg-primary fixed top-0 z-[99] shadow-md lg:hidden">
|
||||
<div class="navbar drawer-button fixed top-0 z-[99] bg-primary shadow-md lg:hidden">
|
||||
<label for="my-drawer-2" class="btn btn-square btn-ghost drawer-button text-base-100 lg:hidden">
|
||||
<MdiMenu class="size-6" />
|
||||
</label>
|
||||
<NuxtLink to="/home">
|
||||
<h2 class="text-base-100 flex text-3xl font-bold tracking-tight">
|
||||
<h2 class="flex text-3xl font-bold tracking-tight text-base-100">
|
||||
HomeB
|
||||
<AppLogo class="-mb-3 w-8" />
|
||||
x
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
|
||||
<slot></slot>
|
||||
<footer v-if="status" class="bg-base-300 text-secondary-content bottom-0 w-full pb-4 text-center">
|
||||
<footer v-if="status" class="bottom-0 w-full bg-base-300 pb-4 text-center text-secondary-content">
|
||||
<p class="text-center text-sm">
|
||||
{{ $t("global.version", { version: status.build.version }) }} ~
|
||||
{{ $t("global.build", { build: status.build.commit }) }}
|
||||
@@ -42,17 +42,17 @@
|
||||
<label for="my-drawer-2" class="drawer-overlay"></label>
|
||||
|
||||
<!-- Top Section -->
|
||||
<div class="bg-base-200 flex min-w-40 max-w-min flex-col p-5 md:py-10">
|
||||
<div class="flex min-w-40 max-w-min flex-col bg-base-200 p-5 md:py-10">
|
||||
<div class="space-y-8">
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<p>{{ $t("global.welcome", { username: username }) }}</p>
|
||||
<NuxtLink class="avatar placeholder" to="/home">
|
||||
<div class="bg-base-300 text-neutral-content w-24 rounded-full p-4">
|
||||
<div class="w-24 rounded-full bg-base-300 p-4 text-neutral-content">
|
||||
<AppLogo />
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div class="bg-base-200 flex flex-col">
|
||||
<div class="flex flex-col bg-base-200">
|
||||
<div class="mb-6">
|
||||
<div class="dropdown visible w-full">
|
||||
<label tabindex="0" class="text-no-transform btn btn-primary btn-block text-lg">
|
||||
@@ -61,10 +61,10 @@
|
||||
</span>
|
||||
{{ $t("global.create") }}
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu rounded-box bg-base-100 w-full p-2 shadow">
|
||||
<li v-for="btn in dropdown" :key="btn.name">
|
||||
<ul tabindex="0" class="dropdown-content menu rounded-box w-full bg-base-100 p-2 shadow">
|
||||
<li v-for="btn in dropdown" :key="btn.id">
|
||||
<button @click="btn.action">
|
||||
{{ btn.name }}
|
||||
{{ btn.name.value }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -81,7 +81,7 @@
|
||||
}"
|
||||
>
|
||||
<component :is="n.icon" class="mr-4 size-6" />
|
||||
{{ n.name }}
|
||||
{{ n.name.value }}
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -89,7 +89,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Bottom -->
|
||||
<button class="rounded-btn hover:bg-base-300 mx-2 mt-auto p-3" @click="logout">
|
||||
<button class="rounded-btn mx-2 mt-auto p-3 hover:bg-base-300" @click="logout">
|
||||
{{ $t("global.sign_out") }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -135,19 +135,22 @@
|
||||
|
||||
const dropdown = [
|
||||
{
|
||||
name: "Item / Asset",
|
||||
id: 0,
|
||||
name: computed(() => t("menu.create_item")),
|
||||
action: () => {
|
||||
modals.item = true;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Location",
|
||||
id: 1,
|
||||
name: computed(() => t("menu.create_location")),
|
||||
action: () => {
|
||||
modals.location = true;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Label",
|
||||
id: 2,
|
||||
name: computed(() => t("menu.create_label")),
|
||||
action: () => {
|
||||
modals.label = true;
|
||||
},
|
||||
@@ -168,42 +171,42 @@
|
||||
icon: MdiHome,
|
||||
active: computed(() => route.path === "/home"),
|
||||
id: 0,
|
||||
name: t("menu.home"),
|
||||
name: computed(() => t("menu.home")),
|
||||
to: "/home",
|
||||
},
|
||||
{
|
||||
icon: MdiFileTree,
|
||||
id: 1,
|
||||
active: computed(() => route.path === "/locations"),
|
||||
name: t("menu.locations"),
|
||||
name: computed(() => t("menu.locations")),
|
||||
to: "/locations",
|
||||
},
|
||||
{
|
||||
icon: MdiMagnify,
|
||||
id: 2,
|
||||
active: computed(() => route.path === "/items"),
|
||||
name: t("menu.search"),
|
||||
name: computed(() => t("menu.search")),
|
||||
to: "/items",
|
||||
},
|
||||
{
|
||||
icon: MdiWrench,
|
||||
id: 3,
|
||||
active: computed(() => route.path === "/maintenance"),
|
||||
name: t("menu.maintenance"),
|
||||
name: computed(() => t("menu.maintenance")),
|
||||
to: "/maintenance",
|
||||
},
|
||||
{
|
||||
icon: MdiAccount,
|
||||
id: 4,
|
||||
active: computed(() => route.path === "/profile"),
|
||||
name: t("menu.profile"),
|
||||
name: computed(() => t("menu.profile")),
|
||||
to: "/profile",
|
||||
},
|
||||
{
|
||||
icon: MdiCog,
|
||||
id: 5,
|
||||
active: computed(() => route.path === "/tools"),
|
||||
name: t("menu.tools"),
|
||||
name: computed(() => t("menu.tools")),
|
||||
to: "/tools",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -148,9 +148,7 @@ describe("user should be able to create an item and add an attachment", () => {
|
||||
{
|
||||
const { response, data } = await api.items.maintenance.getLog(item.id);
|
||||
expect(response.status).toBe(200);
|
||||
expect(data.entries).toHaveLength(maintenanceEntries.length);
|
||||
expect(data.costAverage).toBeGreaterThan(0);
|
||||
expect(data.costTotal).toBeGreaterThan(0);
|
||||
expect(data).toHaveLength(maintenanceEntries.length);
|
||||
}
|
||||
|
||||
cleanup();
|
||||
|
||||
@@ -12,7 +12,7 @@ import type {
|
||||
MaintenanceEntryCreate,
|
||||
MaintenanceEntryWithDetails,
|
||||
} from "../types/data-contracts";
|
||||
import type { AttachmentTypes, PaginationResult } from "../types/non-generated";
|
||||
import type { AttachmentTypes, ItemSummaryPaginationResult } from "../types/non-generated";
|
||||
import type { MaintenanceFilters } from "./maintenance.ts";
|
||||
import type { Requests } from "~~/lib/requests";
|
||||
|
||||
@@ -98,7 +98,7 @@ export class ItemsApi extends BaseAPI {
|
||||
}
|
||||
|
||||
getAll(q: ItemsQuery = {}) {
|
||||
return this.http.get<PaginationResult<ItemSummary>>({ url: route("/items", q) });
|
||||
return this.http.get<ItemSummaryPaginationResult<ItemSummary>>({ url: route("/items", q) });
|
||||
}
|
||||
|
||||
create(item: ItemCreate) {
|
||||
|
||||
@@ -106,15 +106,13 @@ export interface ItemOut {
|
||||
notes: string;
|
||||
parent?: ItemSummary | null;
|
||||
purchaseFrom: string;
|
||||
/** @example "0" */
|
||||
purchasePrice: string;
|
||||
purchasePrice: number;
|
||||
/** Purchase */
|
||||
purchaseTime: Date | string;
|
||||
quantity: number;
|
||||
serialNumber: string;
|
||||
soldNotes: string;
|
||||
/** @example "0" */
|
||||
soldPrice: string;
|
||||
soldPrice: number;
|
||||
/** Sold */
|
||||
soldTime: Date | string;
|
||||
soldTo: string;
|
||||
@@ -145,8 +143,7 @@ export interface ItemSummary {
|
||||
/** Edges */
|
||||
location?: LocationSummary | null;
|
||||
name: string;
|
||||
/** @example "0" */
|
||||
purchasePrice: string;
|
||||
purchasePrice: number;
|
||||
quantity: number;
|
||||
updatedAt: Date | string;
|
||||
}
|
||||
@@ -181,14 +178,14 @@ export interface ItemUpdate {
|
||||
parentId?: string | null;
|
||||
/** @maxLength 255 */
|
||||
purchaseFrom: string;
|
||||
purchasePrice: number;
|
||||
purchasePrice?: number | null;
|
||||
/** Purchase */
|
||||
purchaseTime: Date | string;
|
||||
quantity: number;
|
||||
/** Identifications */
|
||||
serialNumber: string;
|
||||
soldNotes: string;
|
||||
soldPrice: number;
|
||||
soldPrice?: number | null;
|
||||
/** Sold */
|
||||
soldTime: Date | string;
|
||||
/** @maxLength 255 */
|
||||
|
||||
@@ -16,3 +16,7 @@ export interface PaginationResult<T> {
|
||||
pageSize: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface ItemSummaryPaginationResult<T> extends PaginationResult<T> {
|
||||
totalPrice: number;
|
||||
}
|
||||
|
||||
52
frontend/locales/da-DK.json
Normal file
52
frontend/locales/da-DK.json
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"components": {
|
||||
"global": {
|
||||
"password_score": {
|
||||
"password_strength": "Adgangskodestyrke"
|
||||
}
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"photo_button": "Foto 📷",
|
||||
"title": "Opret genstand"
|
||||
},
|
||||
"view": {
|
||||
"selectable": {
|
||||
"card": "Kort",
|
||||
"items": "Genstande",
|
||||
"no_items": "Ingen genstande at vise",
|
||||
"table": "Tabel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"title": "Opret label"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"title": "Opret lokation"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Ingen tilgængelige lokationer. Opret nye lokationer gennem\n`<`span class=\"link-primary\">`Opret`<`/span`>` knappen i navigationslinjen."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"confirm": "Bekræft",
|
||||
"create": "Opret",
|
||||
"create_and_add": "Opret og tilføj ny",
|
||||
"created": "Oprettet",
|
||||
"email": "Email",
|
||||
"follow_dev": "Følg udvikleren",
|
||||
"github": "GitHub projekt"
|
||||
},
|
||||
"tools": {
|
||||
"import_export": "Importer/Eksporter",
|
||||
"reports": "Rapporter",
|
||||
"reports_set": {
|
||||
"bill_of_materials": "Stykliste"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,30 @@
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"date_time": {
|
||||
"ago": "vor {0}",
|
||||
"days": "Tage",
|
||||
"hour": "Stunde",
|
||||
"hours": "Stunden",
|
||||
"in": "in {0}",
|
||||
"just-now": "gerade eben",
|
||||
"last-month": "letzten Monat",
|
||||
"last-week": "Letzte Woche",
|
||||
"last-year": "letztes Jahr",
|
||||
"minute": "Minute",
|
||||
"minutes": "Minuten",
|
||||
"months": "Monate",
|
||||
"next-month": "nächster Monat",
|
||||
"next-week": "Nächste Woche",
|
||||
"next-year": "nächstes Jahr",
|
||||
"second": "Sekunde",
|
||||
"seconds": "Sekunden",
|
||||
"tomorrow": "Morgen",
|
||||
"week": "Woche",
|
||||
"weeks": "Wochen",
|
||||
"years": "Jahre",
|
||||
"yesterday": "Gestern"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "Seiten-URL"
|
||||
},
|
||||
@@ -18,6 +42,8 @@
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"item_description": "Artikelbezeichnung",
|
||||
"item_name": "Artikelname",
|
||||
"photo_button": "Foto 📷",
|
||||
"title": "Gegenstand erstellen"
|
||||
},
|
||||
@@ -27,29 +53,45 @@
|
||||
"items": "Gegenstände",
|
||||
"no_items": "Keine Gegenstände anzuzeigen",
|
||||
"table": "Tabelle"
|
||||
},
|
||||
"table": {
|
||||
"page": "Seite",
|
||||
"rows_per_page": "Zeilen pro Seite"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"title": "Etikett erstellen"
|
||||
"label_description": "Label Beschreibung",
|
||||
"label_name": "Name Etikett",
|
||||
"title": "Label erstellen"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"location_description": "Standortbeschreibung",
|
||||
"location_name": "Standortnamen",
|
||||
"title": "Standort erstellen"
|
||||
},
|
||||
"selector": {
|
||||
"parent_location": "Übergeordneter Standort"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Keine Standorte verfügbar. Fügen Sie neue Standorte über die Schaltfläche\n `<`span class=\"link-primary\"`>`Erstellen`<`/span`>` in der Navigationsleiste hinzu."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"add": "Hinzufügen",
|
||||
"build": "Build: { build }",
|
||||
"confirm": "Bestätigen",
|
||||
"create": "Erstellen",
|
||||
"create_and_add": "Erstellen und weiteren hinzufügen",
|
||||
"created": "Erstellt",
|
||||
"delete": "Löschen",
|
||||
"details": "Details",
|
||||
"duplicate": "Duplizieren",
|
||||
"edit": "Bearbeiten",
|
||||
"email": "E-Mail",
|
||||
"follow_dev": "Dem Entwickler folgen",
|
||||
"github": "GitHub-Projekt",
|
||||
@@ -57,15 +99,29 @@
|
||||
"join_discord": "Discord beitreten",
|
||||
"labels": "Etiketten",
|
||||
"locations": "Lagerorte",
|
||||
"maintenance": "Wartung",
|
||||
"name": "Name",
|
||||
"password": "Passwort",
|
||||
"read_docs": "Dokumentation lesen",
|
||||
"save": "Speichern",
|
||||
"search": "Suche",
|
||||
"sign_out": "Abmelden",
|
||||
"submit": "Einreichen",
|
||||
"update": "Aktualisieren",
|
||||
"value": "Wert",
|
||||
"version": "Version: { version }",
|
||||
"welcome": "Willkommen, { username }"
|
||||
},
|
||||
"home": {
|
||||
"labels": "Labels",
|
||||
"quick_statistics": "Schnelle Statistiken",
|
||||
"recently_added": "Kürzlich hinzugefügt",
|
||||
"storage_locations": "Lagerstandorte",
|
||||
"total_items": "Gesamtanzahl Elemente",
|
||||
"total_labels": "Gesamtanzahl Label",
|
||||
"total_locations": "Gesamtanzahl Standorte",
|
||||
"total_value": "Gesamtwert"
|
||||
},
|
||||
"index": {
|
||||
"disabled_registration": "Registrierung deaktiviert",
|
||||
"dont_join_group": "Möchtest du nicht einer Gruppe beitreten?",
|
||||
@@ -80,32 +136,71 @@
|
||||
},
|
||||
"items": {
|
||||
"add": "Hinzufügen",
|
||||
"advanced": "Erweitert",
|
||||
"archived": "Archiviert",
|
||||
"asset_id": "Asset-ID",
|
||||
"attachment": "Anhang",
|
||||
"attachments": "Anhänge",
|
||||
"changes_persisted_immediately": "Änderungen an Anhängen werden sofort gespeichert",
|
||||
"created_at": "Erstellt am",
|
||||
"custom_fields": "Benutzerdefinierte Felder",
|
||||
"description": "Beschreibung",
|
||||
"details": "Details",
|
||||
"drag_and_drop": "Ziehen Sie Dateien hierher und legen Sie sie dort ab oder klicken Sie, um Dateien auszuwählen",
|
||||
"edit_details": "Details bearbeiten",
|
||||
"field_selector": "Feldauswahl",
|
||||
"field_value": "Feldwert",
|
||||
"first": "Erste",
|
||||
"include_archive": "Archivierte Elemente einschließen",
|
||||
"insured": "Versichert",
|
||||
"last": "Letzte",
|
||||
"lifetime_warranty": "Lebenslange Garantie",
|
||||
"location": "Standort",
|
||||
"manual": "Bedienungsanleitung",
|
||||
"manuals": "Bedienungsanleitungen",
|
||||
"manufacturer": "Hersteller",
|
||||
"model_number": "Modelnummer",
|
||||
"name": "Name",
|
||||
"negate_labels": "Ausgewählte Etiketten negieren",
|
||||
"next_page": "Nächste Seite",
|
||||
"no_results": "Keine Elemente gefunden",
|
||||
"notes": "Anmerkungen",
|
||||
"options": "Optionen (Options)",
|
||||
"order_by": "Sortieren nach",
|
||||
"pages": "Seite { page } von { totalPages }",
|
||||
"parent_item": "Übergeordnetes Element",
|
||||
"photo": "Foto",
|
||||
"photos": "Fotos",
|
||||
"prev_page": "Vorherige Seite",
|
||||
"query_id": "Abfrage Asset-ID-Nummer: { id }",
|
||||
"purchase_date": "Einkaufsdatum",
|
||||
"purchase_details": "Einkaufsdetails",
|
||||
"purchase_price": "Einkaufspreis",
|
||||
"purchased_from": "Eingekauft von",
|
||||
"quantity": "Menge",
|
||||
"query_id": "Abfrage der Anlagen-ID-Nummer: { id }",
|
||||
"receipt": "Beleg",
|
||||
"receipts": "Quittungen",
|
||||
"reset_search": "Suche zurücksetzen",
|
||||
"results": "{ total } Ergebnisse",
|
||||
"serial_number": "Seriennummer",
|
||||
"show_advanced_view_options": "Erweiterter Angzeigeoptionen anzeigen",
|
||||
"sold_at": "Verkauft am",
|
||||
"sold_details": "Verkaufsdetails",
|
||||
"sold_price": "Verkaufspreis",
|
||||
"sold_to": "Verkauft an",
|
||||
"tip_1": "Standort- und Etikettenfilter verwenden die 'ODER'-Operation. Wenn mehr als eines ausgewählt ist, wird\n nur eines für eine Übereinstimmung benötigt.",
|
||||
"tip_2": "Suchen, die mit '#' beginnen, fragen nach einer Asset-ID (Beispiel '#000-001')",
|
||||
"tip_3": "Feldfilter verwenden die 'ODER'-Operation. Wenn mehr als eines ausgewählt ist, wird nur eines\n für eine Übereinstimmung benötigt.",
|
||||
"tips": "Tipps",
|
||||
"tips_sub": "Suchtipps",
|
||||
"updated_at": "Aktualisiert am"
|
||||
"updated_at": "Aktualisiert am",
|
||||
"warranty": "Gewährleistung",
|
||||
"warranty_details": "Garantiedetails",
|
||||
"warranty_expires": "Garantie läuft ab am"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Keine Labels gefunden"
|
||||
"no_results": "Keine Labels gefunden",
|
||||
"update_label": "Label aktualisieren"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Katalanisch",
|
||||
@@ -115,20 +210,26 @@
|
||||
"fr": "Französisch",
|
||||
"hu": "Ungarisch",
|
||||
"it": "Italienisch",
|
||||
"ja-JP": "Japanisch",
|
||||
"nl": "Niederländisch",
|
||||
"pl": "Polnisch",
|
||||
"pt-BR": "Portugiesisch (Brasilien)",
|
||||
"pt-PT": "Portugiesisch (Portugal)",
|
||||
"ru": "Russisch",
|
||||
"sl": "Slowenisch",
|
||||
"sv": "Schwedisch",
|
||||
"tr": "Türkisch",
|
||||
"uk-UA": "Ukrainisch",
|
||||
"zh-CN": "Chinesisch (einfach)",
|
||||
"zh-HK": "Chinesisch (Hong Kong)",
|
||||
"zh-MO": "Chinesisch (Macao)",
|
||||
"zh-TW": "Chinesisch (Traditionell)"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "Keine Standorte gefunden"
|
||||
"child_locations": "Unter-Standorte",
|
||||
"collapse_tree": "Baum einklappen",
|
||||
"no_results": "Keine Standorte gefunden",
|
||||
"update_location": "Aktualisiere Standort"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
@@ -160,12 +261,15 @@
|
||||
"toast": {
|
||||
"failed_to_create": "Eintrag konnte nicht erstellt werden",
|
||||
"failed_to_delete": "Eintrag konnte nicht gelöscht werden",
|
||||
"failed_to_update": "Fehler beim Aktualisieren des Eintrags."
|
||||
"failed_to_update": "Fehler beim Aktualisieren des Eintrags"
|
||||
},
|
||||
"total_cost": "Gesamtkosten",
|
||||
"total_entries": "Gesamteinträge"
|
||||
},
|
||||
"menu": {
|
||||
"create_item": "Artikel / Vermögenswert",
|
||||
"create_label": "Label",
|
||||
"create_location": "Standort",
|
||||
"home": "Home",
|
||||
"locations": "Lagerorte",
|
||||
"maintenance": "Wartung",
|
||||
@@ -182,6 +286,7 @@
|
||||
"delete_account_sub": "Lösche dein Konto und alle zugehörigen Daten. Dies kann nicht rückgängig gemacht werden.",
|
||||
"display_header": "{ currentValue, select, true {Header ausblenden} false {Header anzeigen} other {Kein Treffer}}",
|
||||
"enabled": "Aktiviert",
|
||||
"example": "Beispiel",
|
||||
"gen_invite": "Einladungslink generieren",
|
||||
"group_settings": "Gruppeneinstellungen",
|
||||
"group_settings_sub": "Gemeinsame Gruppeneinstellungen. Möglicherweise müssen Sie Ihren Browser aktualisieren, damit die Einstellungen wirksam werden.",
|
||||
@@ -194,7 +299,7 @@
|
||||
"notifiers_sub": "Erhalte Benachrichtigungen über bevorstehende Wartungserinnerungen",
|
||||
"test": "Test",
|
||||
"theme_settings": "Themes",
|
||||
"theme_settings_sub": "Theme-Einstellungen werden im lokalen Speicher deines Browsers gespeichert. Du kannst das Theme jederzeit ändern. Wenn du Probleme hast, dein Theme einzustellen, versuche, die Seite neu zu laden.",
|
||||
"theme_settings_sub": "Theme-Einstellungen werden im lokalen Speicher deines Browsers gespeichert. Du kannst das Theme jederzeit ändern.\nWenn du Probleme hast, dein Theme einzustellen, versuche, die Seite neu zu laden.",
|
||||
"update_group": "Gruppe aktualisieren",
|
||||
"update_language": "Sprache aktualisieren",
|
||||
"url": "URL",
|
||||
@@ -206,14 +311,14 @@
|
||||
"actions_set": {
|
||||
"ensure_ids": "Sicherstellen von Asset-IDs",
|
||||
"ensure_ids_button": "Sicherstellen von Asset-IDs",
|
||||
"ensure_ids_sub": "Es wird sichergestellt, dass alle Artikel in Ihrem Bestand ein gültiges asset_id-Feld haben. Dazu wird das Feld mit der höchsten aktuellen asset_id in der Datenbank ermittelt und der nächste Wert auf jeden Artikel mit einem nicht gesetzten asset_id-Feld angewendet. Dies geschieht in der Reihenfolge des Feldes created_at.",
|
||||
"ensure_ids_sub": "Stellt sicher, dass alle Elemente in Ihrem Inventar ein gültiges asset_id-Feld haben. Dazu wird die das höchste aktuelle asset_id-Feld in der Datenbank ermittelt und der nächste Wert auf jeden Element mit einem nicht gesetzten asset_id-Feld angewendet. Dies geschieht in der Reihenfolge des Feldes created_at.",
|
||||
"ensure_import_refs": "Sicherstellen, dass Import-Referenzen importiert wurden",
|
||||
"ensure_import_refs_button": "Sicherstellen, dass Referenzen importiert werden",
|
||||
"ensure_import_refs_sub": "Es wird sichergestellt, dass alle Gegenstände in Ihrem Inventar ein gültiges import_ref-Feld haben. Dazu wird nach dem Zufallsprinzip eine 8-stellige Zeichenkette für jeden Gegenstand mit einem ungültigen import_ref-Feld erzeugt.",
|
||||
"ensure_import_refs_sub": "Stellt sicher, dass alle Elemente in deinem Inventar ein gültiges import_ref-Feld haben. Dazu wird nach dem Zufallsprinzip eine 8-stellige Zeichenkette für jedes Element mit einem leeren import_ref-Feld erzeugt.",
|
||||
"set_primary_photo": "Primärfoto festlegen",
|
||||
"set_primary_photo_button": "Primäres Foto festlegen",
|
||||
"set_primary_photo_sub": "In Homebox Version v0.10.0 wurde die Auswahl des Primärbilds von angehängten Bildern hinzugefügt. Mit dieser Funktion wird für jeden Artikel ohne Primärbild das erste angehängt Bild als solches definiert. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/pull/576\">'See GitHub PR #576'</a>'",
|
||||
"zero_datetimes": "Null-Punkt-Datum-Zeiten",
|
||||
"zero_datetimes": "Leeren der Datum & Zeiten der Elemente",
|
||||
"zero_datetimes_button": "Null-Punkt-Datum-Zeiten",
|
||||
"zero_datetimes_sub": "Setzt den Zeitwert für alle Datums-Zeit-Felder in Ihrem Inventar auf den Anfang des Datums zurück. Damit wird ein Fehler behoben, der zu Beginn der Entwicklung der Website eingeführt wurde und dazu führte, dass das Datum zusammen mit der Uhrzeit gespeichert wurde, was zu Problemen bei der Anzeige von genauen Werten in Datumsfeldern führte. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/issues/236\" target=\"_blank\">'See Github Issue #236 for more details.'</a>'"
|
||||
},
|
||||
@@ -222,20 +327,20 @@
|
||||
"import_export_set": {
|
||||
"export": "Gesamten Bestand exportieren",
|
||||
"export_button": "Gesamten Bestand exportieren",
|
||||
"export_sub": "Exportiert das Standard-CSV-Format für Homebox",
|
||||
"export_sub": "Exportiert das Standard-CSV-Format für Homebox. Diese Aktion exportiert alle Elemente in ihrem Inventar.",
|
||||
"import": "Inventar importieren",
|
||||
"import_button": "Inventar importieren",
|
||||
"import_sub": "Importiert das Standard-CSV-Format für Homebox. Ohne eine '<code>'HB.import_ref'</code>' Spalte werden vorhandenen Artikel in Ihrem Bestand '<b>'nicht'</b>' überschrieben, sondern nur neue Artikel hinzugefügt. Zeilen mit einer '<code>'HB.import_ref'</code>' Spalte werden mit vorhandenen Artikeln mit der gleichen import_ref zusammengeführt, sofern vorhanden."
|
||||
},
|
||||
"import_export_sub": "Importieren und exportieren Sie Ihren Lagerbestand in und aus einer CSV-Datei",
|
||||
"import_export_sub": "Importieren und exportieren Sie Ihren Lagerbestand in und aus einer CSV-Datei. Dies ist nützlich zum migrieren ihres Inventars zu einer neuen Instanz von Homebox.",
|
||||
"reports": "Berichte",
|
||||
"reports_set": {
|
||||
"asset_labels": "Asset-ID-Etiketten",
|
||||
"asset_labels": "Asset-ID-Labels",
|
||||
"asset_labels_button": "Etiketten-Generator",
|
||||
"asset_labels_sub": "Erzeugt eine druckbare PDF-Datei mit Etiketten für eine Reihe von Asset-IDs. Diese sind nicht spezifisch für deine Inventargegenstände, so dass du die Etiketten im Voraus ausdrucken und bei Erhalt auf deinen Inventargegenständen anbringen kannst.",
|
||||
"bill_of_materials": "Stückliste",
|
||||
"bill_of_materials_button": "Stückliste generieren",
|
||||
"bill_of_materials_sub": "Generiert eine CSV-Datei (Comma Separated Values), die in ein Tabellenkalkulationsprogramm importiert werden kann"
|
||||
"bill_of_materials_sub": "Generiert eine CSV-Datei (Comma Separated Values), die in ein Tabellenkalkulationsprogramm importiert werden kann. Diese ist eine Zusammenfasung ihres Inventars mit einfachen Elementen- und Preisinformationen."
|
||||
},
|
||||
"reports_sub": "Erstellen Sie verschiedene Berichte für Ihr Inventar."
|
||||
}
|
||||
|
||||
@@ -9,6 +9,30 @@
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"date_time": {
|
||||
"ago": "{0} ago",
|
||||
"days": "days",
|
||||
"hour": "hour",
|
||||
"hours": "hours",
|
||||
"in": "in {0}",
|
||||
"just-now": "just now",
|
||||
"last-month": "last month",
|
||||
"last-week": "last week",
|
||||
"last-year": "last year",
|
||||
"minute": "minute",
|
||||
"minutes": "minutes",
|
||||
"months": "months",
|
||||
"next-month": "next month",
|
||||
"next-week": "next week",
|
||||
"next-year": "next year",
|
||||
"second": "second",
|
||||
"seconds": "seconds",
|
||||
"tomorrow": "tomorrow",
|
||||
"week": "week",
|
||||
"weeks": "weeks",
|
||||
"years": "years",
|
||||
"yesterday": "yesterday"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "Page URL"
|
||||
},
|
||||
@@ -18,6 +42,8 @@
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"item_description": "Item Description",
|
||||
"item_name": "Item Name",
|
||||
"photo_button": "Photo 📷",
|
||||
"title": "Create Item"
|
||||
},
|
||||
@@ -27,29 +53,45 @@
|
||||
"items": "Items",
|
||||
"no_items": "No Items to Display",
|
||||
"table": "Table"
|
||||
},
|
||||
"table": {
|
||||
"page": "Page",
|
||||
"rows_per_page": "Rows per page"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"label_description": "Label Description",
|
||||
"label_name": "Label Name",
|
||||
"title": "Create Label"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"location_description": "Location Description",
|
||||
"location_name": "Location Name",
|
||||
"title": "Create Location"
|
||||
},
|
||||
"selector": {
|
||||
"parent_location": "Parent Location"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "No locations available. Add new locations through the\n `<`span class=\"link-primary\"`>`Create`<`/span`>` button on the navigation bar."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"add": "Add",
|
||||
"build": "Build: { build }",
|
||||
"confirm": "Confirm",
|
||||
"create": "Create",
|
||||
"create_and_add": "Create and Add Another",
|
||||
"created": "Created",
|
||||
"delete": "Delete",
|
||||
"details": "Details",
|
||||
"duplicate": "Duplicate",
|
||||
"edit": "Edit",
|
||||
"email": "Email",
|
||||
"follow_dev": "Follow the Developer",
|
||||
"github": "GitHub Project",
|
||||
@@ -57,15 +99,29 @@
|
||||
"join_discord": "Join the Discord",
|
||||
"labels": "Labels",
|
||||
"locations": "Locations",
|
||||
"maintenance": "Maintenance",
|
||||
"name": "Name",
|
||||
"password": "Password",
|
||||
"read_docs": "Read the Docs",
|
||||
"save": "Save",
|
||||
"search": "Search",
|
||||
"sign_out": "Sign Out",
|
||||
"submit": "Submit",
|
||||
"update": "Update",
|
||||
"value": "Value",
|
||||
"version": "Version: { version }",
|
||||
"welcome": "Welcome, { username }"
|
||||
},
|
||||
"home": {
|
||||
"labels": "Labels",
|
||||
"quick_statistics": "Quick Statistics",
|
||||
"recently_added": "Recently Added",
|
||||
"storage_locations": "Storage Locations",
|
||||
"total_items": "Total Items",
|
||||
"total_labels": "Total Labels",
|
||||
"total_locations": "Total Locations",
|
||||
"total_value": "Total Value"
|
||||
},
|
||||
"index": {
|
||||
"disabled_registration": "Registration Disabled",
|
||||
"dont_join_group": "Don't want to join a group?",
|
||||
@@ -80,32 +136,71 @@
|
||||
},
|
||||
"items": {
|
||||
"add": "Add",
|
||||
"advanced": "Advanced",
|
||||
"archived": "Archived",
|
||||
"asset_id": "Asset ID",
|
||||
"attachment": "Attachment",
|
||||
"attachments": "Attachments",
|
||||
"changes_persisted_immediately": "Changes to attachments will be saved immediately",
|
||||
"created_at": "Created At",
|
||||
"custom_fields": "Custom Fields",
|
||||
"description": "Description",
|
||||
"details": "Details",
|
||||
"drag_and_drop": "Drag and drop files here or click to select files",
|
||||
"edit_details": "Edit Details",
|
||||
"field_selector": "Field Selector",
|
||||
"field_value": "Field Value",
|
||||
"first": "First",
|
||||
"include_archive": "Include Archived Items",
|
||||
"insured": "Insured",
|
||||
"last": "Last",
|
||||
"lifetime_warranty": "Lifetime Warranty",
|
||||
"location": "Location",
|
||||
"manual": "Manual",
|
||||
"manuals": "Manuals",
|
||||
"manufacturer": "Manufacturer",
|
||||
"model_number": "Model Number",
|
||||
"name": "Name",
|
||||
"negate_labels": "Negate Selected Labels",
|
||||
"next_page": "Next Page",
|
||||
"no_results": "No Items Found",
|
||||
"notes": "Notes",
|
||||
"options": "Options",
|
||||
"order_by": "Order By",
|
||||
"pages": "Page { page } of { totalPages }",
|
||||
"parent_item": "Parent Item",
|
||||
"photo": "Photo",
|
||||
"photos": "Photos",
|
||||
"prev_page": "Previous Page",
|
||||
"purchase_date": "Purchase Date",
|
||||
"purchase_details": "Purchase Details",
|
||||
"purchase_price": "Purchase Price",
|
||||
"purchased_from": "Purchased From",
|
||||
"quantity": "Quantity",
|
||||
"query_id": "Querying Asset ID Number: { id }",
|
||||
"receipt": "Receipt",
|
||||
"receipts": "Receipts",
|
||||
"reset_search": "Reset Search",
|
||||
"results": "{ total } Results",
|
||||
"serial_number": "Serial Number",
|
||||
"show_advanced_view_options": "Show Advanced View Options",
|
||||
"sold_at": "Sold At",
|
||||
"sold_details": "Sold Details",
|
||||
"sold_price": "Sold Price",
|
||||
"sold_to": "Sold To",
|
||||
"tip_1": "Location and label filters use the 'OR' operation. If more than one is selected only one will be\n required for a match.",
|
||||
"tip_2": "Searches prefixed with '#'' will query for a asset ID (example '#000-001')",
|
||||
"tip_3": "Field filters use the 'OR' operation. If more than one is selected only one will be required for a\n match.",
|
||||
"tips": "Tips",
|
||||
"tips_sub": "Search Tips",
|
||||
"updated_at": "Updated At"
|
||||
"updated_at": "Updated At",
|
||||
"warranty": "Warranty",
|
||||
"warranty_details": "Warranty Details",
|
||||
"warranty_expires": "Warranty Expires"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "No Labels Found"
|
||||
"no_results": "No Labels Found",
|
||||
"update_label": "Update Label"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Catalan",
|
||||
@@ -115,20 +210,26 @@
|
||||
"fr": "French",
|
||||
"hu": "Hungarian",
|
||||
"it": "Italian",
|
||||
"ja-JP": "Japanese",
|
||||
"nl": "Dutch",
|
||||
"pl": "Polish",
|
||||
"pt-BR": "Portuguese (Brazil)",
|
||||
"pt-PT": "Portuguese (Portugal)",
|
||||
"ru": "Russian",
|
||||
"sl": "Slovenian",
|
||||
"sv": "Swedish",
|
||||
"tr": "Turkish",
|
||||
"uk-UA": "Ukrainian",
|
||||
"zh-CN": "Chinese (Simplified)",
|
||||
"zh-HK": "Chinese (Hong Kong)",
|
||||
"zh-MO": "Chinese (Macau)",
|
||||
"zh-TW": "Chinese (Traditional)"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "No Locations Found"
|
||||
"child_locations": "Child Locations",
|
||||
"collapse_tree": "Collapse Tree",
|
||||
"no_results": "No Locations Found",
|
||||
"update_location": "Update Location"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
@@ -137,12 +238,12 @@
|
||||
"scheduled": "Scheduled"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Complete",
|
||||
"create_first": "Create Your First Entry",
|
||||
"delete": "Delete",
|
||||
"duplicate": "Duplicate",
|
||||
"edit": "Edit",
|
||||
"new": "New",
|
||||
"complete": "Complete",
|
||||
"duplicate" : "Duplicate"
|
||||
"new": "New"
|
||||
},
|
||||
"modal": {
|
||||
"completed_date": "Completed Date",
|
||||
@@ -166,6 +267,9 @@
|
||||
"total_entries": "Total Entries"
|
||||
},
|
||||
"menu": {
|
||||
"create_item": "Item / Asset",
|
||||
"create_label": "Label",
|
||||
"create_location": "Location",
|
||||
"home": "Home",
|
||||
"locations": "Locations",
|
||||
"maintenance": "Maintenance",
|
||||
@@ -182,6 +286,7 @@
|
||||
"delete_account_sub": "Delete your account and all its associated data. This can not be undone.",
|
||||
"display_header": "{ currentValue, select, true {Hide Header} false {Show Header} other {Not Hit}}",
|
||||
"enabled": "Enabled",
|
||||
"example": "Example",
|
||||
"gen_invite": "Generate Invite Link",
|
||||
"group_settings": "Group Settings",
|
||||
"group_settings_sub": "Shared Group Settings. You may need to refresh your browser for some settings to apply.",
|
||||
|
||||
@@ -2,13 +2,37 @@
|
||||
"components": {
|
||||
"app": {
|
||||
"import_dialog": {
|
||||
"change_warning": "Se ha modificado el comportamiento de las importaciones con import_refs existentes. Si existe una import_ref en el archivo CSV, el \nelemento se actualizará con los valores del archivo CSV.",
|
||||
"change_warning": "Se ha modificado el comportamiento de las importaciones con import_refs existentes. Si existe una import_ref en el archivo CSV, el\nelemento se actualizará con los valores del archivo CSV.",
|
||||
"description": "Importa un archivo CSV que contenga tus elementos, etiquetas y ubicaciones. Consulta la documentación para obtener más información sobre el \nformato requerido.",
|
||||
"title": "Importar Archivo CSV",
|
||||
"upload": "Subir"
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"date_time": {
|
||||
"ago": "hace {0}",
|
||||
"days": "días",
|
||||
"hour": "hora",
|
||||
"hours": "horas",
|
||||
"in": "en {0}",
|
||||
"just-now": "Justo ahora",
|
||||
"last-month": "mes pasado",
|
||||
"last-week": "semana pasada",
|
||||
"last-year": "año pasado",
|
||||
"minute": "minuto",
|
||||
"minutes": "minutos",
|
||||
"months": "meses",
|
||||
"next-month": "próximo mes",
|
||||
"next-week": "próxima semana",
|
||||
"next-year": "próximo año",
|
||||
"second": "segundo",
|
||||
"seconds": "segundos",
|
||||
"tomorrow": "mañana",
|
||||
"week": "semana",
|
||||
"weeks": "semanas",
|
||||
"years": "años",
|
||||
"yesterday": "ayer"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "URL de página"
|
||||
},
|
||||
@@ -18,6 +42,8 @@
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"item_description": "Descripción del artículo",
|
||||
"item_name": "Nombre del artículo",
|
||||
"photo_button": "Foto 📷",
|
||||
"title": "Crear Elemento"
|
||||
},
|
||||
@@ -27,26 +53,45 @@
|
||||
"items": "Elementos",
|
||||
"no_items": "No hay elementos para mostrar",
|
||||
"table": "Tabla"
|
||||
},
|
||||
"table": {
|
||||
"page": "Página",
|
||||
"rows_per_page": "Renglones por página"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"label_description": "Descripción de la etiqueta",
|
||||
"label_name": "Nombre de la etiqueta",
|
||||
"title": "Crear Etiqueta"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"location_description": "Descripción de la ubicación",
|
||||
"location_name": "Nombre de la ubicación",
|
||||
"title": "Crear Ubicación"
|
||||
},
|
||||
"selector": {
|
||||
"parent_location": "Ubicación padre"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "No hay ubicaciones disponibles. Añade nuevas ubicaciones mediante el botón de\n`<`span class=\"link-primary\"`>`Crear`<`/span`>` en la barra de navegación."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"add": "Agregar",
|
||||
"build": "Compilación: { build }",
|
||||
"confirm": "Confirmar",
|
||||
"create": "Crear",
|
||||
"create_and_add": "Crear y Añadir Otro",
|
||||
"created": "Creado",
|
||||
"delete": "Eliminar",
|
||||
"details": "Detalles",
|
||||
"duplicate": "Duplicar",
|
||||
"edit": "Editar",
|
||||
"email": "Email",
|
||||
"follow_dev": "Seguir al Desarrollador",
|
||||
"github": "Proyecto GitHub",
|
||||
@@ -54,15 +99,29 @@
|
||||
"join_discord": "Únete al Discord",
|
||||
"labels": "Etiquetas",
|
||||
"locations": "Ubicaciones",
|
||||
"maintenance": "Mantenimiento",
|
||||
"name": "Nombre",
|
||||
"password": "Contraseña",
|
||||
"read_docs": "Lee la Documentación",
|
||||
"save": "Guardar",
|
||||
"search": "Buscar",
|
||||
"sign_out": "Cerrar Sesión",
|
||||
"submit": "Enviar",
|
||||
"update": "Actualizar",
|
||||
"value": "Valor",
|
||||
"version": "Versión: { version }",
|
||||
"welcome": "Bienvenido/a, { username }"
|
||||
},
|
||||
"home": {
|
||||
"labels": "Etiquetas",
|
||||
"quick_statistics": "Estadísticas rápidas",
|
||||
"recently_added": "Añadidos recientemente",
|
||||
"storage_locations": "Ubicaciones de almacenamiento",
|
||||
"total_items": "Total artículos",
|
||||
"total_labels": "Total étiquetas",
|
||||
"total_locations": "Total ubicaciónes",
|
||||
"total_value": "Valor total"
|
||||
},
|
||||
"index": {
|
||||
"disabled_registration": "Registro Desactivado",
|
||||
"dont_join_group": "¿No quieres unirte a un grupo?",
|
||||
@@ -77,29 +136,71 @@
|
||||
},
|
||||
"items": {
|
||||
"add": "Añadir",
|
||||
"advanced": "Avanzado",
|
||||
"archived": "Archivado",
|
||||
"asset_id": "Activo ID",
|
||||
"attachment": "Adjunto",
|
||||
"attachments": "Adjuntos",
|
||||
"changes_persisted_immediately": "Los cambios a los archivos adjuntos se guardaran inmediatamente",
|
||||
"created_at": "Creado El",
|
||||
"custom_fields": "Campos Personalizados",
|
||||
"description": "Descripción",
|
||||
"details": "Detalles",
|
||||
"drag_and_drop": "Arrastra y suelta los archivos aquí o selecciona los archivos",
|
||||
"edit_details": "Editar detalles",
|
||||
"field_selector": "Selector de Campo",
|
||||
"field_value": "Valor del Campo",
|
||||
"first": "Primer",
|
||||
"include_archive": "Incluir Elementos Archivados",
|
||||
"insured": "Asegurado",
|
||||
"last": "Último",
|
||||
"lifetime_warranty": "Garantia de por vida",
|
||||
"location": "Ubicación",
|
||||
"manual": "Manual",
|
||||
"manuals": "Manuales",
|
||||
"manufacturer": "Fabricante",
|
||||
"model_number": "Número de modelo",
|
||||
"name": "Nombre",
|
||||
"negate_labels": "Negar Etiquetas Seleccionadas",
|
||||
"next_page": "Siguiente Página",
|
||||
"no_results": "No se Encontraron Elementos",
|
||||
"notes": "Notas",
|
||||
"options": "Opciones",
|
||||
"order_by": "Ordenar Por",
|
||||
"pages": "Página { page } de { totalPages }",
|
||||
"parent_item": "Articulo Padre",
|
||||
"photo": "Foto",
|
||||
"photos": "Fotos",
|
||||
"prev_page": "Anterior Página",
|
||||
"purchase_date": "Fecha de compra",
|
||||
"purchase_details": "Detalles de compra",
|
||||
"purchase_price": "Precio de compra",
|
||||
"purchased_from": "Comprado de",
|
||||
"quantity": "Cantidad",
|
||||
"query_id": "Consultar Número ID del Activo: { id }",
|
||||
"receipt": "Recibo",
|
||||
"receipts": "Recibos",
|
||||
"reset_search": "Restablecer Búsqueda",
|
||||
"results": "{ total } Resultados",
|
||||
"serial_number": "Número de serie",
|
||||
"show_advanced_view_options": "Mostrar opciones avanzadas de vista",
|
||||
"sold_at": "Vendido el",
|
||||
"sold_details": "Detalles de venta",
|
||||
"sold_price": "Precio de venta",
|
||||
"sold_to": "Vendido a",
|
||||
"tip_1": "Los filtros de ubicación y etiquetas utilizan el operador \"OR\". Si se selecciona más de uno, sólo uno será\n necesario para obtener una coincidencia.",
|
||||
"tip_2": "Las búsquedas precedidas de \"#\" buscarán un ID de activo (por ejemplo, \"#000-001\")",
|
||||
"tip_3": "Los filtros de campo utilizan el operador \"OR\". Si se selecciona más de uno, sólo se requerirá uno para una\n coincidencia.",
|
||||
"tips": "Sugerencias",
|
||||
"tips_sub": "Sugerencias de Búsqueda",
|
||||
"updated_at": "Actualizado El"
|
||||
"updated_at": "Actualizado El",
|
||||
"warranty": "Garantia",
|
||||
"warranty_details": "Detalles de garantía",
|
||||
"warranty_expires": "La garantia expira"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Etiquetas No Encontradas",
|
||||
"update_label": "Actualizar etiqueta"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Catalán",
|
||||
@@ -109,18 +210,73 @@
|
||||
"fr": "Francés",
|
||||
"hu": "Húngaro",
|
||||
"it": "Italiano",
|
||||
"ja-JP": "Japones",
|
||||
"nl": "Holandés",
|
||||
"pl": "Polaco",
|
||||
"pt-BR": "Portugués (Brasil)",
|
||||
"pt-PT": "Portugués",
|
||||
"ru": "Ruso",
|
||||
"sl": "Esloveno",
|
||||
"sv": "Sueco",
|
||||
"tr": "Turco",
|
||||
"uk-UA": "Ucraniano",
|
||||
"zh-CN": "Chino (Simplificado)",
|
||||
"zh-HK": "Chino (Hong Kong)",
|
||||
"zh-MO": "Chino (Macao)",
|
||||
"zh-TW": "Chino (Tradicional)"
|
||||
},
|
||||
"locations": {
|
||||
"child_locations": "Ubicaciones hijas",
|
||||
"collapse_tree": "Colapsar árbol",
|
||||
"no_results": "Ubicaciones No Encontradas",
|
||||
"update_location": "Actualizar ubicación"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
"both": "Ambos",
|
||||
"completed": "Completado",
|
||||
"scheduled": "Programado"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Completar",
|
||||
"create_first": "Crea Tu Primera Entrada",
|
||||
"delete": "Eliminar",
|
||||
"duplicate": "Duplicar",
|
||||
"edit": "Editar",
|
||||
"new": "Nuevo"
|
||||
},
|
||||
"modal": {
|
||||
"completed_date": "Fecha Completado",
|
||||
"cost": "Coste",
|
||||
"delete_confirmation": "¿Seguro que quieres borrar esta entrada?",
|
||||
"edit_action": "Actualizar",
|
||||
"edit_title": "Editar Entrada",
|
||||
"entry_name": "Nombre de Entrada",
|
||||
"new_action": "Crear",
|
||||
"new_title": "Nueva Entrada",
|
||||
"notes": "Notas",
|
||||
"scheduled_date": "Fecha Programada"
|
||||
},
|
||||
"monthly_average": "Promedio Mensual",
|
||||
"toast": {
|
||||
"failed_to_create": "Error al crear la entrada",
|
||||
"failed_to_delete": "Error al eliminar la entrada",
|
||||
"failed_to_update": "Error al actualizar la entrada"
|
||||
},
|
||||
"total_cost": "Coste Total",
|
||||
"total_entries": "Total de Entradas"
|
||||
},
|
||||
"menu": {
|
||||
"create_item": "Articulo / Activo",
|
||||
"create_label": "Etiqueta",
|
||||
"create_location": "Ubicación",
|
||||
"home": "Inicio",
|
||||
"locations": "Ubicaciones",
|
||||
"maintenance": "Mantenimiento",
|
||||
"profile": "Perfil",
|
||||
"search": "Buscar",
|
||||
"tools": "Herramientas"
|
||||
},
|
||||
"profile": {
|
||||
"active": "Activo",
|
||||
"change_password": "Cambiar Contraseña",
|
||||
@@ -130,12 +286,14 @@
|
||||
"delete_account_sub": "Elimina tu cuenta y todos sus datos asociados. Esto no se puede deshacer.",
|
||||
"display_header": "{ currentValue, select, true {Ocultar Encabezado} false {Mostrar Encabezado} other {Desconocido}}",
|
||||
"enabled": "Habilitado",
|
||||
"example": "Ejemplo",
|
||||
"gen_invite": "Generar Enlace de Invitación",
|
||||
"group_settings": "Ajustes de Grupo",
|
||||
"group_settings_sub": "Configuración de Grupo Compartido. Es posible que tengas que actualizar tu navegador para que se apliquen algunos ajustes.",
|
||||
"inactive": "Inactivo",
|
||||
"language": "Idioma",
|
||||
"new_password": "Nueva Contraseña",
|
||||
"no_notifiers": "No hay notificadores configurados",
|
||||
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Notificación",
|
||||
"notifiers": "Notificaciones",
|
||||
"notifiers_sub": "Recibe notificaciones de los próximos recordatorios de mantenimiento",
|
||||
|
||||
32
frontend/locales/fi-FI.json
Normal file
32
frontend/locales/fi-FI.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"languages": {
|
||||
"pl": "Puola"
|
||||
},
|
||||
"maintenance": {
|
||||
"list": {
|
||||
"complete": "Valmis",
|
||||
"delete": "Poista"
|
||||
},
|
||||
"modal": {
|
||||
"new_action": "Luo"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"home": "Koti"
|
||||
},
|
||||
"profile": {
|
||||
"delete_account": "Poista tili",
|
||||
"test": "Testi"
|
||||
},
|
||||
"tools": {
|
||||
"actions_set": {
|
||||
"set_primary_photo": "Aseta oletuskuva"
|
||||
},
|
||||
"import_export": "Tuo/Vie",
|
||||
"import_export_set": {
|
||||
"export_button": "Vie varasto",
|
||||
"import_button": "Tuo varasto"
|
||||
},
|
||||
"reports": "Raportit"
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
"components": {
|
||||
"app": {
|
||||
"import_dialog": {
|
||||
"change_warning": "Le comportement lors d’importations avec des import_ref existants a changé. Si une valeur pour import_ref est présente dans le fichier CSV, alors l’élément sera mis à jour avec celle-ci.",
|
||||
"description": "Importer un fichier CSV contenant vos articles, étiquettes, et emplacements. Voir la documentation pour plus d’informations sur le format requis.",
|
||||
"change_warning": "Le comportement lors d’importations avec des import_ref existants a changé. Si une valeur pour import_ref est présente dans le \nfichier CSV, alors l’élément sera mis à jour avec celle-ci.",
|
||||
"description": "Importer un fichier CSV contenant vos articles, étiquettes, et emplacements. Voir la documentation pour plus d’informations \nsur le format requis.",
|
||||
"title": "Importer un fichier CSV",
|
||||
"upload": "Téléverser"
|
||||
}
|
||||
@@ -40,7 +40,7 @@
|
||||
"title": "Créer un emplacement"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Aucun emplacement disponible. Ajoutez votre premiers emplacements avec le bouton `<`span class=\"link-primary\"`>`Créer`<`/span`>` dans la barre de navigation."
|
||||
"no_locations": "Aucun emplacement disponible. Ajoutez votre premiers emplacements avec\nle bouton `<`span class=\"link-primary\"`>`Créer`<`/span`>` dans la barre de navigation."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -61,7 +61,7 @@
|
||||
"password": "Mot de passe",
|
||||
"read_docs": "Lire la documentation",
|
||||
"search": "Rechercher",
|
||||
"sign_out": "Déconnexion",
|
||||
"sign_out": "Se déconnecter",
|
||||
"submit": "Soumettre",
|
||||
"version": "Version : { version }",
|
||||
"welcome": "Bienvenue, { username }"
|
||||
@@ -142,15 +142,15 @@
|
||||
"delete": "Supprimer",
|
||||
"duplicate": "Dupliquer",
|
||||
"edit": "Modifier",
|
||||
"new": "Ajouter"
|
||||
"new": "Nouveau"
|
||||
},
|
||||
"modal": {
|
||||
"completed_date": "Date d'achèvement",
|
||||
"cost": "Coût",
|
||||
"delete_confirmation": "Êtes-vous certain de vouloir supprimer cette entrée ?",
|
||||
"edit_action": "Modifier",
|
||||
"edit_action": "Mettre à jour",
|
||||
"edit_title": "Modifier l'entrée",
|
||||
"entry_name": "Nom",
|
||||
"entry_name": "Nom de l’entrée",
|
||||
"new_action": "Créer",
|
||||
"new_title": "Nouvelle entrée",
|
||||
"notes": "Notes",
|
||||
@@ -191,7 +191,7 @@
|
||||
"no_notifiers": "Aucune notification configurée",
|
||||
"notifier_modal": "Notifications { type, select, true {Edit} false {Create} other {Other}}",
|
||||
"notifiers": "Notifications",
|
||||
"notifiers_sub": "Recevez des notifications pour vous prévenir des prochaines maintenances.",
|
||||
"notifiers_sub": "Recevez des notifications pour vous prévenir des prochaines maintenances",
|
||||
"test": "Test",
|
||||
"theme_settings": "Paramètres du thème",
|
||||
"theme_settings_sub": "Les paramètres du thème sont stockés dans le navigateur. Vous pouvez les changer à tout moment. Si vous\nrencontrez des problèmes, il est conseillé de rafraichir la page.",
|
||||
@@ -214,7 +214,8 @@
|
||||
"set_primary_photo_button": "Définir la photo principale",
|
||||
"set_primary_photo_sub": "Dans la version v0.10.0 d'Homebox, le champ d'image principal à été ajouté aux pièces jointes de type photo. Cette action définira en tant qu'image principale toute première image en pièce jointe déjà présente en base de donnée, si le champ n'est pas déjà défini. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/pull/576\">'Voir GitHub PR #576'</a>'",
|
||||
"zero_datetimes": "Remettre à zéro les dates et heures",
|
||||
"zero_datetimes_button": "Remettre à zéro les dates et heures"
|
||||
"zero_datetimes_button": "Remettre à zéro les dates et heures",
|
||||
"zero_datetimes_sub": "Réinitialise la valeur de tous les champs date/heure de votre inventaire à la date de début. Il s'agit de corriger une anomalie introduite au début du développement du site qui entraînait le stockage de la valeur temporelle avec l'heure, ce qui provoquait des problèmes avec les champs de date affichant des valeurs précises. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/issues/236\" target=\"_blank\">'Voir le rapport 236 de Github pour plus de détails.'</a> '"
|
||||
},
|
||||
"actions_sub": "Appliquer des actions en masse à votre inventaire. Ces actions sont irréversibles. '<b>'Soyez vigilant.'</b>'",
|
||||
"import_export": "Importer/Exporter",
|
||||
@@ -224,13 +225,13 @@
|
||||
"export_sub": "Exporte l'inventaire au format CSV Homebox. Cela exportera l'intégralité de votre inventaire.",
|
||||
"import": "Importer l'inventaire",
|
||||
"import_button": "Importer l'inventaire",
|
||||
"import_sub": "Importer un fichier CSV au format Homebox. Sans la colonne '<code>'HB.import_ref'</code>' , cela '<b>'n'écrasera pas'</b>' d'éléments de votre inventaire actuel, seuls les nouveaux éléments seront importés. Les lignes contenant une colonne '<code>'HB.import_ref'</code>' seront fusionnées avec les éléments existants comportant le même '<code>'HB.import_ref'</code>', si existant."
|
||||
"import_sub": "Importer un fichier CSV au format Homebox. Sans la colonne '<code>'HB.import_ref'</code>' , cela '<b>'n'écrasera pas'</b>' d'éléments de votre inventaire actuel, seuls les nouveaux éléments seront importés. Les lignes contenant une colonne '<code>'HB.import_ref'</code>' seront fusionnées avec les éléments existants comportant le même import_ref, si existant."
|
||||
},
|
||||
"import_export_sub": "Importez et exportez votre inventaire vers et depuis un fichier CSV",
|
||||
"import_export_sub": "Importez et exportez votre inventaire vers et depuis un fichier CSV. Ceci est utile pour migrer votre inventaire vers une nouvelle instance de Homebox.",
|
||||
"reports": "Rapports",
|
||||
"reports_set": {
|
||||
"asset_labels": "Étiquettes d’identifiant d’actif",
|
||||
"asset_labels_button": "Générateur d’étiquettes",
|
||||
"asset_labels_button": "Générateur d'étiquettes",
|
||||
"asset_labels_sub": "Génère un fichier PDF imprimable pour une plage d'identifiants d'actifs. Ils ne sont pas spécifiques à votre inventaire donc vous pouvez les imprimer en avance et les appliquer à votre inventaire par la suite.",
|
||||
"bill_of_materials": "Nomenclature",
|
||||
"bill_of_materials_button": "Générer une nomenclature",
|
||||
|
||||
@@ -2,13 +2,37 @@
|
||||
"components": {
|
||||
"app": {
|
||||
"import_dialog": {
|
||||
"change_warning": "Il comportamento per le importazioni con import_ref esistenti è cambiato. Se un import_ref è presente nel file CSV,\n l'elemento verrà aggiornato con i valori presenti nel file CSV.",
|
||||
"description": "Importa un file CSV contenente gli oggetti, le etichette e le posizioni. Vedi la documentazione per ulteriori informazioni sul \nformato richiesto.",
|
||||
"change_warning": "Il comportamento per le importazioni con import_ref esistenti è cambiato. Se un import_ref è presente nel file CSV,\n l'articolo verrà aggiornato con i valori presenti nel file CSV.",
|
||||
"description": "Importa un file CSV contenente gli articoli, le etichette e le posizioni. Vedi la documentazione per ulteriori informazioni sul \nformato richiesto.",
|
||||
"title": "Importa File CSV",
|
||||
"upload": "Carica"
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"date_time": {
|
||||
"ago": "{0} fa",
|
||||
"days": "giorni",
|
||||
"hour": "ora",
|
||||
"hours": "ore",
|
||||
"in": "tra {0}",
|
||||
"just-now": "Adesso",
|
||||
"last-month": "mese scorso",
|
||||
"last-week": "settimana precedente",
|
||||
"last-year": "anno precedente",
|
||||
"minute": "minuto",
|
||||
"minutes": "minuti",
|
||||
"months": "mesi",
|
||||
"next-month": "prossimo mese",
|
||||
"next-week": "settimana successiva",
|
||||
"next-year": "anno successivo",
|
||||
"second": "secondo",
|
||||
"seconds": "secondi",
|
||||
"tomorrow": "domani",
|
||||
"week": "settimana",
|
||||
"weeks": "settimane",
|
||||
"years": "anni",
|
||||
"yesterday": "ieri"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "URL della Pagina"
|
||||
},
|
||||
@@ -18,38 +42,56 @@
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"item_description": "Descrizione Articolo",
|
||||
"item_name": "Nome articolo",
|
||||
"photo_button": "Foto 📷",
|
||||
"title": "Crea Oggetto"
|
||||
"title": "Crea Articolo"
|
||||
},
|
||||
"view": {
|
||||
"selectable": {
|
||||
"card": "Scheda",
|
||||
"items": "Oggetti",
|
||||
"no_items": "Nessun Oggetto da Visualizzare",
|
||||
"items": "Articoli",
|
||||
"no_items": "Nessun Articolo da Visualizzare",
|
||||
"table": "Tabella"
|
||||
},
|
||||
"table": {
|
||||
"page": "Pagina",
|
||||
"rows_per_page": "Righe per pagina"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"label_description": "Descrizione Etichetta",
|
||||
"label_name": "Nome Etichetta",
|
||||
"title": "Crea Etichetta"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"location_description": "Descrizione ubicazione",
|
||||
"location_name": "Nome ubicazione",
|
||||
"title": "Crea Posizione"
|
||||
},
|
||||
"selector": {
|
||||
"parent_location": "Ubicazione padre"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Nessuna posizione disponibile. Aggiungi nuove posizioni mediante il pulsante\n`<`span class=\"link-primary\"`>`Crea`<`/span`>` nella barra di navigazione."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"add": "Aggiungi",
|
||||
"build": "Compila: { build }",
|
||||
"confirm": "Conferma",
|
||||
"create": "Crea",
|
||||
"create_and_add": "Crea e aggiungi un altro",
|
||||
"created": "Creato",
|
||||
"delete": "Cancella",
|
||||
"details": "Dettagli",
|
||||
"duplicate": "Duplica",
|
||||
"edit": "Modifica",
|
||||
"email": "Email",
|
||||
"follow_dev": "Segui lo Sviluppatore",
|
||||
"github": "Progetto GitHub",
|
||||
@@ -57,15 +99,29 @@
|
||||
"join_discord": "Unisciti a Discord",
|
||||
"labels": "Etichette",
|
||||
"locations": "Posizioni",
|
||||
"maintenance": "Manutenzione",
|
||||
"name": "Nome",
|
||||
"password": "Password",
|
||||
"read_docs": "Leggi la Documentazione",
|
||||
"save": "Salva",
|
||||
"search": "Cerca",
|
||||
"sign_out": "Disconnetti",
|
||||
"submit": "Invia",
|
||||
"update": "Aggiorna",
|
||||
"value": "Valore",
|
||||
"version": "Versione: { version }",
|
||||
"welcome": "Benvenuto, { username }"
|
||||
},
|
||||
"home": {
|
||||
"labels": "Etichette",
|
||||
"quick_statistics": "Statistiche rapide",
|
||||
"recently_added": "Aggiunti di recente",
|
||||
"storage_locations": "Ubicazioni di magazzino",
|
||||
"total_items": "Articoli totali",
|
||||
"total_labels": "Etichette totali",
|
||||
"total_locations": "Ubicazioni totali",
|
||||
"total_value": "Valore totale"
|
||||
},
|
||||
"index": {
|
||||
"disabled_registration": "Registrazione Disabilitata",
|
||||
"dont_join_group": "Non vuoi unirti a un gruppo?",
|
||||
@@ -80,32 +136,71 @@
|
||||
},
|
||||
"items": {
|
||||
"add": "Aggiungi",
|
||||
"advanced": "Avanzate",
|
||||
"archived": "Archiviato",
|
||||
"asset_id": "ID Asset",
|
||||
"attachment": "Allegato",
|
||||
"attachments": "Allegati",
|
||||
"changes_persisted_immediately": "Le modifiche agli allegati verranno salvate immediatamente",
|
||||
"created_at": "Creato Il",
|
||||
"custom_fields": "Campi Personalizzati",
|
||||
"field_selector": "Selettore di Campo",
|
||||
"field_value": "Valore del Campo",
|
||||
"description": "Descrizione",
|
||||
"details": "Dettagli",
|
||||
"drag_and_drop": "Trascina e rilascia i file qui o fai clic per selezionare i file",
|
||||
"edit_details": "Modifica dettagli",
|
||||
"field_selector": "Campo Selezione",
|
||||
"field_value": "Campo valore",
|
||||
"first": "Primo",
|
||||
"include_archive": "Includi Articoli Archiviati",
|
||||
"insured": "Assicurato",
|
||||
"last": "Ultimo",
|
||||
"lifetime_warranty": "Garanzia a vita",
|
||||
"location": "Luogo",
|
||||
"manual": "Manuale",
|
||||
"manuals": "Manuali",
|
||||
"manufacturer": "Marca",
|
||||
"model_number": "Numero modello",
|
||||
"name": "Nome",
|
||||
"negate_labels": "Negare Etichette Selezionate",
|
||||
"next_page": "Pagina Successiva",
|
||||
"no_results": "Nessun Articolo Trovato",
|
||||
"notes": "Note",
|
||||
"options": "Opzioni",
|
||||
"order_by": "Ordina Per",
|
||||
"pages": "Pagina { page } di { totalPages }",
|
||||
"parent_item": "Articolo principale",
|
||||
"photo": "Foto",
|
||||
"photos": "Foto",
|
||||
"prev_page": "Pagina Precedente",
|
||||
"purchase_date": "Data di acquisto",
|
||||
"purchase_details": "Dettagli dell'acquisto",
|
||||
"purchase_price": "Prezzo di acquisto",
|
||||
"purchased_from": "Acqistato da",
|
||||
"quantity": "Quantità",
|
||||
"query_id": "ID dell'Asset in Ricerca: { id }",
|
||||
"receipt": "Ricevuta",
|
||||
"receipts": "Ricevute",
|
||||
"reset_search": "Reimposta Ricerca",
|
||||
"results": "{ total } Risultati",
|
||||
"serial_number": "Numero seriale",
|
||||
"show_advanced_view_options": "Mostra opzioni di visualizzazione avanzate",
|
||||
"sold_at": "Venduto su",
|
||||
"sold_details": "Dettagli di vendita",
|
||||
"sold_price": "Prezzo di vendita",
|
||||
"sold_to": "Venduto a",
|
||||
"tip_1": "I filtri di posizione ed etichetta utilizzano l'operazione 'OR'. Se ne viene selezionato più\n di uno, ne sarà richiesto solo uno per una corrispondenza.",
|
||||
"tip_2": "Le ricerche con prefisso '#' cercheranno un ID asset (esempio '#000-001')",
|
||||
"tip_3": "I filtri di campo utilizzano l'operazione 'OR'. Se ne viene selezionato più di uno, ne sarà\n richiesto solo uno per una corrispondenza.",
|
||||
"tips": "Suggerimenti",
|
||||
"tips_sub": "Suggerimenti per la Ricerca",
|
||||
"updated_at": "Aggiornato Il"
|
||||
"updated_at": "Aggiornato Il",
|
||||
"warranty": "Garanzia",
|
||||
"warranty_details": "Dettagli garanzia",
|
||||
"warranty_expires": "Garanzia scaduta"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Nessuna etichetta trovata"
|
||||
"no_results": "Nessuna etichetta trovata",
|
||||
"update_label": "Aggiorna etichetta"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Catalano",
|
||||
@@ -115,20 +210,26 @@
|
||||
"fr": "Francese",
|
||||
"hu": "Ungherese",
|
||||
"it": "Italiano",
|
||||
"ja-JP": "Giapponese",
|
||||
"nl": "Olandese",
|
||||
"pl": "Polacco",
|
||||
"pt-BR": "Portoghese (Brasile)",
|
||||
"pt-PT": "Portoghese (Portogallo)",
|
||||
"ru": "Russo",
|
||||
"sl": "Sloveno",
|
||||
"sv": "Svedese",
|
||||
"tr": "Turco",
|
||||
"uk-UA": "Ucraino",
|
||||
"zh-CN": "Cinese (semplificato)",
|
||||
"zh-HK": "Cinese Mandarino",
|
||||
"zh-MO": "Cinese (Macao)",
|
||||
"zh-TW": "Cinese (tradizionale)"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "Nessuna posizione trovata"
|
||||
"child_locations": "Ubicazione figlia",
|
||||
"collapse_tree": "Contrai albero",
|
||||
"no_results": "Nessuna posizione trovata",
|
||||
"update_location": "Aggiorna ubicazione"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
@@ -137,7 +238,7 @@
|
||||
"scheduled": "Pianificato"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Conferma",
|
||||
"complete": "Completa",
|
||||
"create_first": "Crea la tua prima voce",
|
||||
"delete": "Elimina",
|
||||
"duplicate": "Duplicare",
|
||||
@@ -163,7 +264,18 @@
|
||||
"failed_to_update": "Impossibile aggiornare la voce"
|
||||
},
|
||||
"total_cost": "Costo totale",
|
||||
"total_entries": "Iscrizioni totali"
|
||||
"total_entries": "Voci totali"
|
||||
},
|
||||
"menu": {
|
||||
"create_item": "Articolo / Asset",
|
||||
"create_label": "Etichetta",
|
||||
"create_location": "Ubicazione",
|
||||
"home": "Home",
|
||||
"locations": "Posizioni",
|
||||
"maintenance": "Manutenzione",
|
||||
"profile": "Profilo",
|
||||
"search": "Cerca",
|
||||
"tools": "Strumenti"
|
||||
},
|
||||
"profile": {
|
||||
"active": "Attivo",
|
||||
@@ -174,12 +286,14 @@
|
||||
"delete_account_sub": "Elimina il tuo account e tutti i dati associati. Questa operazione non può essere annullata.",
|
||||
"display_header": "{ currentValue, select, true {Nascondi intestazione} false {Mostra intestazione} other {Sconosciuto}}",
|
||||
"enabled": "Abilitato",
|
||||
"example": "Esempio",
|
||||
"gen_invite": "Genera Link di Invito",
|
||||
"group_settings": "Impostazioni Gruppo",
|
||||
"group_settings_sub": "Impostazioni Gruppo Condivise. Potrebbe essere necessario aggiornare il browser affinché alcune impostazioni vengano applicate.",
|
||||
"inactive": "Inattivo",
|
||||
"language": "Lingua",
|
||||
"new_password": "Nuova Password",
|
||||
"no_notifiers": "Nessun notificatore configurato",
|
||||
"notifier_modal": "{ type, select, true {Modifica} false {Crea} other {Altro}} Notifier",
|
||||
"notifiers": "Notifiche",
|
||||
"notifiers_sub": "Ricevi notifiche per i prossimi promemoria di manutenzione",
|
||||
@@ -197,15 +311,15 @@
|
||||
"actions_set": {
|
||||
"ensure_ids": "Verifica ID delle risorse",
|
||||
"ensure_ids_button": "Verifica ID delle risorse",
|
||||
"ensure_ids_sub": "Garantisce che tutti gli articoli nel tuo inventario abbiano un campo asset_id valido. Questo viene fatto trovando il campo asset_id corrente più alto nel database e applicando il valore successivo a ogni elemento che ha un campo asset_id non impostato. Questo viene fatto per il campo created_at.",
|
||||
"ensure_ids_sub": "Garantisce che tutti gli articoli nel tuo inventario abbiano un campo asset_id valido. Questo viene fatto trovando il campo asset_id corrente più alto nel database e applicando il valore successivo a ogni articolo che ha un campo asset_id non impostato. Questo viene fatto per il campo created_at.",
|
||||
"ensure_import_refs": "Verifica riferimenti di importazione",
|
||||
"ensure_import_refs_button": "Verifica riferimenti di importazione",
|
||||
"ensure_import_refs_sub": "Verifica che tutti gli articoli nel tuo inventario abbiano un campo import_ref valido. Questo viene fatto generando in modo casuale una stringa di 8 caratteri per ogni elemento che ha un campo import_ref non impostato.",
|
||||
"ensure_import_refs_sub": "Verifica che tutti gli articoli nel tuo inventario abbiano un campo import_ref valido. Questo viene fatto generando in modo casuale una stringa di 8 caratteri per ogni articolo che ha un campo import_ref non impostato.",
|
||||
"set_primary_photo": "Imposta foto principale",
|
||||
"set_primary_photo_button": "Imposta immagine principale",
|
||||
"set_primary_photo_sub": "Nella versione v0.10.0 di Homebox, il campo immagine principale è stato aggiunto agli allegati di tipo foto. Questa azione imposterà il campo immagine principale alla prima immagine nella matrice allegati nel database, se non è già impostato. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/pull/576\">'Vedi GitHub PR #576'</a>'",
|
||||
"zero_datetimes": "Azzera Data e Orario oggetti",
|
||||
"zero_datetimes_button": "Azzera Date e Ora articoli",
|
||||
"zero_datetimes": "Azzera Data e Orario articolo",
|
||||
"zero_datetimes_button": "Azzera Date e Ora articolo",
|
||||
"zero_datetimes_sub": "Reimposta il valore dell'ora per tutti i campi data e ora dell'inventario all'inizio della data. Questo è per correggere un bug che è stato introdotto all'inizio dello sviluppo del sito che ha causato il valore di orario memorizzato con il tempo che ha causato problemi con i campi data visualizzazione dei valori esatti. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/issues/236\" target=\"_blank\">'Vedi Github Issue #236 per maggiori dettagli.'</a>'"
|
||||
},
|
||||
"actions_sub": "Applica Azioni massive al tuo inventario. Questo sono azioni irreversibili. '<b>'Presta attenzione.'</b>'",
|
||||
@@ -213,10 +327,10 @@
|
||||
"import_export_set": {
|
||||
"export": "Esporta Inventario",
|
||||
"export_button": "Esporta Inventario",
|
||||
"export_sub": "Esporta il formato CSV standard per Homebox. Questo esporterà tutti gli oggetti del tuo inventario.",
|
||||
"export_sub": "Esporta il formato CSV standard per Homebox. Questo esporterà tutti gli articoli del tuo inventario.",
|
||||
"import": "Importa Inventario",
|
||||
"import_button": "Importa Inventario",
|
||||
"import_sub": "Importa il formato CSV standard per Homebox. Senza una colonna '<code>'HB.import_ref'</code>' questo '<b>'non'</b>' sovrascriverà gli oggetti esistenti nel tuo inventario, aggiungerà solamente nuovi oggetti. Le righe con una colonna '<code>'HB.import_ref'</code>' saranno unite agli oggetti esistenti con lo stesso import_ref, se presente."
|
||||
"import_sub": "Importa il formato CSV standard per Homebox. Senza una colonna '<code>'HB.import_ref'</code>' questo '<b>'non'</b>' sovrascriverà gli articoli esistenti nel tuo inventario, aggiungerà solamente nuovi articoli. Le righe con una colonna '<code>'HB.import_ref'</code>' saranno unite agli articoli esistenti con lo stesso import_ref, se presente."
|
||||
},
|
||||
"import_export_sub": "Importa ed esporta il tuo inventario da e verso un file CSV. Questo è utile per migrare il tuo inventario verso una nuova istanza di Homebox.",
|
||||
"reports": "Rapporti",
|
||||
@@ -226,7 +340,7 @@
|
||||
"asset_labels_sub": "Genera una etichetta PDF stampabile per un gruppo di ID Risorsa. Le etichette non sono specifiche per il tuo inventario così puoi stamparle in anticipo ed applicarle al tuo inventario quando lo ricevi.",
|
||||
"bill_of_materials": "Distinta base",
|
||||
"bill_of_materials_button": "Genera BOM",
|
||||
"bill_of_materials_sub": "Genera un file CSV (Comma Separated Values) che può essere importato in un foglio di calcolo. Questo è un sommario del tuo inventario con informazioni di base su oggetto e prezzo."
|
||||
"bill_of_materials_sub": "Genera un file CSV (Valori Separati dalla Virgola) che può essere importato in un foglio di calcolo. Questo è un sommario del tuo inventario con informazioni di base su articoli e prezzi."
|
||||
},
|
||||
"reports_sub": "Genera diversi report per il tuo inventario."
|
||||
}
|
||||
|
||||
98
frontend/locales/ja-JP.json
Normal file
98
frontend/locales/ja-JP.json
Normal file
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"components": {
|
||||
"app": {
|
||||
"import_dialog": {
|
||||
"change_warning": "既存のimport_refsを使用したインポートの動作が変更されました",
|
||||
"upload": "アップロード"
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"page_qr_code": {
|
||||
"page_url": "ページ URL"
|
||||
},
|
||||
"password_score": {
|
||||
"password_strength": "パスワード強度"
|
||||
}
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"photo_button": "写真📷"
|
||||
},
|
||||
"view": {
|
||||
"selectable": {
|
||||
"card": "カード",
|
||||
"items": "アイテム",
|
||||
"table": "テーブル"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"title": "ラベルを作成"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"title": "ロケーションを生産する"
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"build": "ビルド: { build }",
|
||||
"email": "メール",
|
||||
"github": "GitHub プロジェクト",
|
||||
"items": "アイテム",
|
||||
"labels": "ラベル",
|
||||
"locations": "ロケーション",
|
||||
"name": "名前",
|
||||
"password": "パスワード",
|
||||
"read_docs": "ドキュメントを読む",
|
||||
"search": "サーチ"
|
||||
},
|
||||
"index": {
|
||||
"login": "ログイン",
|
||||
"set_email": "メールは何ですか?",
|
||||
"set_name": "お名前は何ですか?"
|
||||
},
|
||||
"items": {
|
||||
"add": "足す",
|
||||
"next_page": "次の ページ",
|
||||
"prev_page": "先のページ"
|
||||
},
|
||||
"languages": {
|
||||
"en": "英語",
|
||||
"es": "スペイン語",
|
||||
"fr": "フランス語",
|
||||
"hu": "ハンガリー語",
|
||||
"it": "イタリア語",
|
||||
"nl": "オランダ語",
|
||||
"pl": "ポーランド語",
|
||||
"pt-BR": "ポルトガル語 (ブラジル)",
|
||||
"ru": "ロシア語",
|
||||
"sl": "スロベニア語",
|
||||
"sv": "スウェーデン語",
|
||||
"tr": "トルコ語"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
"both": "両方"
|
||||
},
|
||||
"modal": {
|
||||
"notes": "ノート"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"language": "言語",
|
||||
"test": "テスト",
|
||||
"url": "URL"
|
||||
},
|
||||
"tools": {
|
||||
"reports": "レポート",
|
||||
"reports_set": {
|
||||
"asset_labels": "アセット ID ラベル",
|
||||
"asset_labels_button": "レベルを生成する",
|
||||
"bill_of_materials": "部品表",
|
||||
"bill_of_materials_button": "部品表を生成する"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,30 @@
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"date_time": {
|
||||
"ago": "{0} geleden",
|
||||
"days": "dagen",
|
||||
"hour": "uur",
|
||||
"hours": "uren",
|
||||
"in": "in {0}",
|
||||
"just-now": "zojuist",
|
||||
"last-month": "afgelopen maand",
|
||||
"last-week": "vorige week",
|
||||
"last-year": "afgelopen jaar",
|
||||
"minute": "minuut",
|
||||
"minutes": "minuten",
|
||||
"months": "maanden",
|
||||
"next-month": "volgende maand",
|
||||
"next-week": "volgende week",
|
||||
"next-year": "volgend jaar",
|
||||
"second": "seconde",
|
||||
"seconds": "seconden",
|
||||
"tomorrow": "morgen",
|
||||
"week": "week",
|
||||
"weeks": "weken",
|
||||
"years": "jaren",
|
||||
"yesterday": "gisteren"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "Pagina URL"
|
||||
},
|
||||
@@ -18,6 +42,8 @@
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"item_description": "Artikelomschrijving",
|
||||
"item_name": "Artikelnaam",
|
||||
"photo_button": "Foto 📷",
|
||||
"title": "Maak object"
|
||||
},
|
||||
@@ -27,26 +53,45 @@
|
||||
"items": "Objecten",
|
||||
"no_items": "Geen objecten om te tonen",
|
||||
"table": "Tabel"
|
||||
},
|
||||
"table": {
|
||||
"page": "Pagina",
|
||||
"rows_per_page": "Rijen per pagina"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"label_description": "label beschrijving",
|
||||
"label_name": "label naam",
|
||||
"title": "Maak label"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"location_description": "Locatie omschrijving",
|
||||
"location_name": "Locatie",
|
||||
"title": "Maak locatie"
|
||||
},
|
||||
"selector": {
|
||||
"parent_location": "Hoofd locatie"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Geen locaties beschikbaar. Voeg een nieuwe locatie toe\n via de `<`span class=\"link-primary\"`>`Creeer`<`/span`> knop op het navigatie menu."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"add": "Toevoegen",
|
||||
"build": "Bouw: { build }",
|
||||
"confirm": "Bevestigen",
|
||||
"create": "Maken",
|
||||
"create_and_add": "Maak en voeg nog een toe",
|
||||
"created": "Gemaakt",
|
||||
"delete": "Verwijderen",
|
||||
"details": "Details",
|
||||
"duplicate": "Dubbel",
|
||||
"edit": "Bewerk",
|
||||
"email": "E-mail",
|
||||
"follow_dev": "Volg de ontwikkelaar",
|
||||
"github": "GitHub Project",
|
||||
@@ -54,15 +99,29 @@
|
||||
"join_discord": "Sluit je aan bij de Discord",
|
||||
"labels": "etiketten",
|
||||
"locations": "Locaties",
|
||||
"maintenance": "Onderhoud",
|
||||
"name": "Naam",
|
||||
"password": "Wachtwoord",
|
||||
"read_docs": "Lees de documentatie",
|
||||
"save": "Opslaan",
|
||||
"search": "Zoeken",
|
||||
"sign_out": "Log uit",
|
||||
"submit": "Indienen",
|
||||
"update": "Bijwerken",
|
||||
"value": "Waarde",
|
||||
"version": "Versie: { version }",
|
||||
"welcome": "Welkom, { username }"
|
||||
},
|
||||
"home": {
|
||||
"labels": "etiketten",
|
||||
"quick_statistics": "Snelle statistieken",
|
||||
"recently_added": "Recent toegevoegd",
|
||||
"storage_locations": "Verblijfplaatsen",
|
||||
"total_items": "Totale items",
|
||||
"total_labels": "Totaal aantal labels",
|
||||
"total_locations": "Totaal aantal locaties",
|
||||
"total_value": "Totale Waarde"
|
||||
},
|
||||
"index": {
|
||||
"disabled_registration": "Registratie uitgeschakeld",
|
||||
"dont_join_group": "Wil je niet aan een groep deelnemen?",
|
||||
@@ -77,32 +136,71 @@
|
||||
},
|
||||
"items": {
|
||||
"add": "Toevoegen",
|
||||
"advanced": "Geavanceerd",
|
||||
"archived": "Is gearchiveerd",
|
||||
"asset_id": "Artikel ID",
|
||||
"attachment": "Bijlage",
|
||||
"attachments": "Bijlagen",
|
||||
"changes_persisted_immediately": "Gewijzigde bijlagen worden direct opgeslagen",
|
||||
"created_at": "Aangemaakt op",
|
||||
"custom_fields": "Aangepaste velden",
|
||||
"description": "Beschrijving",
|
||||
"details": "Details",
|
||||
"drag_and_drop": "Sleep bestanden hierheen en zet ze neer of klik om bestanden te selecteren",
|
||||
"edit_details": "Details bewerken",
|
||||
"field_selector": "Veld selectie",
|
||||
"field_value": "Veldwaarde",
|
||||
"first": "Eerst",
|
||||
"include_archive": "Inclusief gearchiveerde items",
|
||||
"insured": "Verzekerde",
|
||||
"last": "Achternaam",
|
||||
"lifetime_warranty": "Levenslange garantie",
|
||||
"location": "Locatie",
|
||||
"manual": "Handmatig",
|
||||
"manuals": "Handleidingen",
|
||||
"manufacturer": "Fabrikant",
|
||||
"model_number": "Modelnummer",
|
||||
"name": "Naam",
|
||||
"negate_labels": "Negeer Geselecteerde Etiketten",
|
||||
"next_page": "Volgende pagina",
|
||||
"no_results": "Geen Items Gevonden",
|
||||
"notes": "Opmerkingen",
|
||||
"options": "Opties",
|
||||
"order_by": "Sorteren op",
|
||||
"pages": "Pagina { page } van { totalPages }",
|
||||
"parent_item": "Hoofd Item",
|
||||
"photo": "Foto",
|
||||
"photos": "Foto's",
|
||||
"prev_page": "Vorige pagina",
|
||||
"purchase_date": "Aankoopdatum",
|
||||
"purchase_details": "Aankoopdetails",
|
||||
"purchase_price": "Aankoopprijs",
|
||||
"purchased_from": "Gekocht van",
|
||||
"quantity": "Aantal",
|
||||
"query_id": "ID-nummer van object opvragen: { id }",
|
||||
"receipt": "Bewijs",
|
||||
"receipts": "Bonnetjes",
|
||||
"reset_search": "Reset Zoeken",
|
||||
"results": "{ total } Resultaten",
|
||||
"serial_number": "Serienummer",
|
||||
"show_advanced_view_options": "geavanceerde opties weergeven",
|
||||
"sold_at": "Verkocht bij",
|
||||
"sold_details": "Verkochte details",
|
||||
"sold_price": "Verkoopprijs",
|
||||
"sold_to": "Verkocht Aan",
|
||||
"tip_1": "Locatie- en labelfilters gebruiken de 'OF' -werking. Als er meer dan een is geselecteerd,\nis er maar een nodig voor een overeenkomst.",
|
||||
"tip_2": "Zoekopdrachten voorafgegaan door '#'' zullen om een object-ID vragen (bijvoorbeeld '#000-001')",
|
||||
"tip_3": "Veldfilters gebruiken de 'OF' -bewerking. Indien meer dan 1 is geselecteerd\nzal er maar 1 nodig zijn voor een match.",
|
||||
"tips": "Tips",
|
||||
"tips_sub": "Zoektips",
|
||||
"updated_at": "Bijgewerkt op"
|
||||
"updated_at": "Bijgewerkt op",
|
||||
"warranty": "Garantie",
|
||||
"warranty_details": "Garantiedetails",
|
||||
"warranty_expires": "Garantie vervalt"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Geen labels gevonden"
|
||||
"no_results": "Geen labels gevonden",
|
||||
"update_label": "Etiket bijwerken"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Catalaans",
|
||||
@@ -112,20 +210,26 @@
|
||||
"fr": "Frans",
|
||||
"hu": "Hongaars",
|
||||
"it": "Italiaans",
|
||||
"ja-JP": "Japans",
|
||||
"nl": "Nederlands",
|
||||
"pl": "Pools",
|
||||
"pt-BR": "Portugees (Brazilië)",
|
||||
"pt-PT": "Portugees (Portugal)",
|
||||
"ru": "Russisch",
|
||||
"sl": "Sloveens",
|
||||
"sv": "Zweeds",
|
||||
"tr": "Turks",
|
||||
"uk-UA": "Oekraïens",
|
||||
"zh-CN": "Chinees (vereenvoudigd)",
|
||||
"zh-HK": "Chinees (Hong Kong)",
|
||||
"zh-MO": "Chinees (Macau)",
|
||||
"zh-TW": "Chinees (traditioneel)"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "Geen locaties gevonden"
|
||||
"child_locations": "Kind Locaties",
|
||||
"collapse_tree": "Structuur invouwen",
|
||||
"no_results": "Geen locaties gevonden",
|
||||
"update_location": "Locatie bijwerken"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
@@ -156,13 +260,16 @@
|
||||
"monthly_average": "Maandelijks",
|
||||
"toast": {
|
||||
"failed_to_create": "Kan invoer niet maken",
|
||||
"failed_to_delete": "Kon item niet verwijderen.",
|
||||
"failed_to_delete": "Kon item niet verwijderen",
|
||||
"failed_to_update": "Kan invoer niet bijwerken"
|
||||
},
|
||||
"total_cost": "Totale kosten",
|
||||
"total_entries": "Totaal aantal Inzendingen"
|
||||
},
|
||||
"menu": {
|
||||
"create_item": "Artikel / Object",
|
||||
"create_label": "Label",
|
||||
"create_location": "Locatie",
|
||||
"home": "Home",
|
||||
"locations": "Locaties",
|
||||
"maintenance": "Onderhoud",
|
||||
@@ -177,10 +284,12 @@
|
||||
"current_password": "Huidig Wachtwoord",
|
||||
"delete_account": "Verwijder account",
|
||||
"delete_account_sub": "Verwijder je account en alle geassocieerde data. Deze actie kan niet ongedaan worden.",
|
||||
"display_header": "{ currentValue, select, true {Header verbergen} false {Header weergeven} other {Geen gevonden}}",
|
||||
"enabled": "ingeschakeld",
|
||||
"example": "Voorbeeld",
|
||||
"gen_invite": "Genereer Uitnodigingslink",
|
||||
"group_settings": "Groeps Instellingen",
|
||||
"group_settings_sub": "Gedeelde groepsinstellingen",
|
||||
"group_settings_sub": "Gedeelde groepsinstellingen. Het kan zijn dat je je browser moet verversen om alle instellingen te zien werken.",
|
||||
"inactive": "Inactief",
|
||||
"language": "Taal",
|
||||
"new_password": "Nieuw Wachtwoord",
|
||||
@@ -202,21 +311,26 @@
|
||||
"actions_set": {
|
||||
"ensure_ids": "Zorg voor item-ID's",
|
||||
"ensure_ids_button": "Zorg voor item-ID's",
|
||||
"ensure_ids_sub": "Zorgt ervoor dat alle artikelen in je voorraad een geldig asset_id veld hebben. Dit wordt gedaan door de hoogste huidige asset_id veld in de database te vinden en de volgende waarde toe te passen op het volgende niet ingevoerde asset_id veld. Dit gebeurt op volgorde van het created_at veld.",
|
||||
"ensure_import_refs": "Zorg ervoor dat Import Refs",
|
||||
"ensure_import_refs_button": "Zorg ervoor dat Import Refs",
|
||||
"ensure_import_refs_sub": "Zorgt ervoor dat alle artikelen in je voorraad een geldig import_ref veld hebben. Dit gebeurt door een random 8 karakter string voor elk item te maken die geen import_ref veld heeft.",
|
||||
"set_primary_photo": "Hoofdfoto instellen",
|
||||
"set_primary_photo_button": "Hoofdfoto instellen",
|
||||
"set_primary_photo_sub": "In versie v0.10.0 van Homebox is het primaire afbeeldingsveld toegevoegd aan bijlagen van het type foto. Deze actie zet de primaire afbeelding naar de eerste afbeelding in de database, indien deze nog niet ingesteld is. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/pull/576\">'Zie GitHub PR #576'</a>'",
|
||||
"zero_datetimes": "Nul item Datum Tijden",
|
||||
"zero_datetimes_button": "Nul item Datum Tijden"
|
||||
"zero_datetimes_button": "Nul item Datum Tijden",
|
||||
"zero_datetimes_sub": "Hiermee stelt u de tijdwaarde voor alle datum-/tijdvelden in uw voorraad in op het begin van de datum. Dit is een oplossing voor een fout in de applicatie geïntroduceerd in het begin van de ontwikkeling waarbij de tijd waarde verkeerd werd opgeslagen. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/issues/236\" target=\"_blank\">'Zie Github Issue #236 voor alle details.'</a>'"
|
||||
},
|
||||
"actions_sub": "Acties bulksgewijs toepassen op je voorraad. Deze zijn onomkeerbaar '<b>'Wees voorzichtig.'</b>'",
|
||||
"import_export": "Importeer/Exporteer",
|
||||
"import_export_set": {
|
||||
"export": "Export voorraad",
|
||||
"export_button": "Export voorraad",
|
||||
"export_sub": "Exporteert het standaard CSV-formaat voor Homebox",
|
||||
"export_sub": "Exporteert het standaard CSV-formaat voor Homebox. Dit exporteert alle items in jouw inventaris.",
|
||||
"import": "Inventaris Importeren",
|
||||
"import_button": "Inventaris Importeren"
|
||||
"import_button": "Inventaris Importeren",
|
||||
"import_sub": "Importeert het standaard CSV-formaat voor Homebox. Zonder een '<code>'HB.import_ref'</code>' kolom zal dit '<b>'geen'</b>' bestaande waardes overschrijven, maar enkel nieuwe items toevoegen. Rijen met een '<code>'HB.import_ref'</code>' kolom zullen samengevoegd worden met bestaande items, als die bestaan."
|
||||
},
|
||||
"import_export_sub": "Importeer en exporteer je voorraad van en naar een CSV-bestand. Dit is handig voor het migreren van je voorraad naar een nieuwe HomeBox installatie.",
|
||||
"reports": "Rapportages",
|
||||
|
||||
@@ -2,13 +2,36 @@
|
||||
"components": {
|
||||
"app": {
|
||||
"import_dialog": {
|
||||
"change_warning": "Zachowanie przy imporcie z istniejącymi import_ref zostało zmienione. Jeśli import_ref jest obecny w pliku CSV, \nprzedmiot zostanie zaktualizowany zgodnie z wartościami w pliku CSV.",
|
||||
"description": "Zaimportuj plik CSV zawierający Twoje przedmioty, etykiety i lokalizacje. Zobacz dokumentację, aby uzyskać \nwięcej informacji na temat wymaganego formatu.",
|
||||
"title": "Zaimportuj plik CSV",
|
||||
"upload": "Prześlij",
|
||||
"change_warning": "Zachowanie przy imporcie z istniejącymi import_ref zostało zmienione. Jeśli import_ref jest obecny w pliku CSV, \nprzedmiot zostanie zaktualizowany zgodnie z wartościami w pliku CSV."
|
||||
"upload": "Prześlij"
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"date_time": {
|
||||
"ago": "{0} temu",
|
||||
"days": "dni",
|
||||
"hour": "godzina",
|
||||
"hours": "godziny",
|
||||
"just-now": "teraz",
|
||||
"last-month": "ostatni miesiąc",
|
||||
"last-week": "ostatni tydzień",
|
||||
"last-year": "ostatni rok",
|
||||
"minute": "minuta",
|
||||
"minutes": "minuty",
|
||||
"months": "miesiące",
|
||||
"next-month": "następny miesiąc",
|
||||
"next-week": "następny tydzień",
|
||||
"next-year": "następny rok",
|
||||
"second": "sekunda",
|
||||
"seconds": "sekundy",
|
||||
"tomorrow": "jutro",
|
||||
"week": "tydzień",
|
||||
"weeks": "tygodnie",
|
||||
"years": "lat",
|
||||
"yesterday": "wczoraj"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "Adres URL strony"
|
||||
},
|
||||
@@ -18,8 +41,10 @@
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"title": "Utwórz przedmiot",
|
||||
"photo_button": "Zdjęcie 📷"
|
||||
"item_description": "Opis przedmiotu",
|
||||
"item_name": "Nazwa przedmiotu",
|
||||
"photo_button": "Zdjęcie 📷",
|
||||
"title": "Utwórz przedmiot"
|
||||
},
|
||||
"view": {
|
||||
"selectable": {
|
||||
@@ -27,102 +52,265 @@
|
||||
"items": "Przedmioty",
|
||||
"no_items": "Brak przedmiotów do wyświetlenia",
|
||||
"table": "Tabela"
|
||||
},
|
||||
"table": {
|
||||
"page": "Strona",
|
||||
"rows_per_page": "Wiersze na stronę"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"label_description": "Opis etykiety",
|
||||
"label_name": "Nazwa etykiety",
|
||||
"title": "Stwórz nową etykietę"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"location_description": "Opis lokalizacji",
|
||||
"location_name": "Nazwa lokalizacji",
|
||||
"title": "Utwórz lokalizację"
|
||||
},
|
||||
"selector": {
|
||||
"parent_location": "Nadrzędna lokalizacja"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Brak dostępnych lokalizacji. Dodaj nowe lokalizacje poprzez przycisk\n `<`span class=\"link-primary\"`>`Utwórz`<`/span`>` na pasku nawigacyjnym."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"add": "Dodaj",
|
||||
"build": "Kompilacja: {build}",
|
||||
"follow_dev": "Śledź dewelopera",
|
||||
"github": "Projekt na GitHubie",
|
||||
"items": "Przedmioty",
|
||||
"version": "Wersja:{version}",
|
||||
"welcome": "Witaj, {username}",
|
||||
"confirm": "Potwierdź",
|
||||
"create": "Utwórz",
|
||||
"create_and_add": "Utwórz i dodaj kolejny",
|
||||
"created": "Utworzone",
|
||||
"delete": "Usuń",
|
||||
"details": "Szczegóły",
|
||||
"duplicate": "Duplikat",
|
||||
"edit": "Edytuj",
|
||||
"email": "E-mail",
|
||||
"follow_dev": "Śledź dewelopera",
|
||||
"github": "Projekt na GitHubie",
|
||||
"items": "Przedmioty",
|
||||
"join_discord": "Dołącz do Discorda",
|
||||
"labels": "Etykiety",
|
||||
"locations": "Lokalizacje",
|
||||
"maintenance": "Konserwacja",
|
||||
"name": "Nazwa",
|
||||
"password": "Hasło",
|
||||
"read_docs": "Przeczytaj dokumentację",
|
||||
"save": "Zapisz",
|
||||
"search": "Wyszukaj",
|
||||
"sign_out": "Wyloguj się",
|
||||
"submit": "Wyślij"
|
||||
"submit": "Wyślij",
|
||||
"update": "Aktualizuj",
|
||||
"value": "Wartość",
|
||||
"version": "Wersja:{version}",
|
||||
"welcome": "Witaj, {username}"
|
||||
},
|
||||
"home": {
|
||||
"labels": "Etykiety",
|
||||
"quick_statistics": "Szybkie statystyki",
|
||||
"recently_added": "Ostatnio dodane",
|
||||
"total_items": "Łączna liczba produktów",
|
||||
"total_labels": "Łączna liczba etykiet",
|
||||
"total_locations": "Łączna liczba lokalizacji",
|
||||
"total_value": "Łączna wartość"
|
||||
},
|
||||
"index": {
|
||||
"set_password": "Ustaw swoje hasło",
|
||||
"dont_join_group": "Nie chcesz dołączyć do grupy?",
|
||||
"disabled_registration": "Rejestracja jest wyłączona",
|
||||
"dont_join_group": "Nie chcesz dołączyć do grupy?",
|
||||
"joining_group": "Dołączasz do istniejącej grupy!",
|
||||
"login": "Zaloguj się",
|
||||
"register": "Zarejestruj się",
|
||||
"remember_me": "Zapamiętaj mnie",
|
||||
"set_email": "Jaki jest Twój adres e-mail?",
|
||||
"set_name": "Jak się nazywasz?",
|
||||
"set_password": "Ustaw swoje hasło",
|
||||
"tagline": "Śledź, organizuj i zarządzaj swoimi rzeczami."
|
||||
},
|
||||
"items": {
|
||||
"add": "Dodaj",
|
||||
"advanced": "Zaawansowane",
|
||||
"archived": "Zarchiwizowane",
|
||||
"attachment": "Załącznik",
|
||||
"attachments": "Załączniki",
|
||||
"changes_persisted_immediately": "Zmiany w załącznikach zostaną natychmiast zapisane",
|
||||
"created_at": "Data utworzenia",
|
||||
"custom_fields": "Pola niestandardowe",
|
||||
"description": "Opis",
|
||||
"details": "Szczegóły",
|
||||
"drag_and_drop": "Przeciągnij i upuść pliki tutaj lub kliknij, aby wybrać pliki",
|
||||
"edit_details": "Edytuj szczegóły",
|
||||
"field_selector": "Selektor pól",
|
||||
"field_value": "Wartość pola",
|
||||
"first": "Pierwszy",
|
||||
"include_archive": "Uwzględnij zarchiwizowane przedmioty",
|
||||
"negate_labels": "Neguj wybrane etykiety",
|
||||
"no_results": "Nie znaleziono przedmiotów",
|
||||
"query_id": "Zapytanie o numer identyfikacyjny zasobu: { id }",
|
||||
"results": "{ total } wyniki",
|
||||
"tip_3": "Filtry pól używają operacji 'LUB'. Jeśli wybrano więcej niż jeden, wystarczy jeden, \naby uzyskać dopasowanie.",
|
||||
"updated_at": "Zaktualizowano",
|
||||
"tip_1": "Filtry lokalizacji i etykiet używają operacji 'LUB'. Jeśli wybrano więcej niż jeden, wystarczy jeden, \naby uzyskać dopasowanie.",
|
||||
"pages": "Strona {page} z {totalPages}",
|
||||
"add": "Dodaj",
|
||||
"custom_fields": "Pola niestandardowe",
|
||||
"insured": "Ubezpieczony",
|
||||
"last": "Ostatni",
|
||||
"lifetime_warranty": "Dożywotnia gwarancja",
|
||||
"location": "Lokalizacja",
|
||||
"manual": "Instrukcja",
|
||||
"manuals": "Instrukcje",
|
||||
"manufacturer": "Producent",
|
||||
"model_number": "Model",
|
||||
"name": "Nazwa",
|
||||
"negate_labels": "Neguj wybrane etykiety",
|
||||
"next_page": "Następna strona",
|
||||
"no_results": "Nie znaleziono przedmiotów",
|
||||
"notes": "Notatki",
|
||||
"options": "Opcje",
|
||||
"order_by": "Ułóż według",
|
||||
"pages": "Strona {page} z {totalPages}",
|
||||
"parent_item": "Nadrzędny obiekt",
|
||||
"photo": "Zdjęcie",
|
||||
"photos": "Zdjęcia",
|
||||
"prev_page": "Poprzednia strona",
|
||||
"purchase_date": "Data zakupu",
|
||||
"purchase_details": "Szczegóły zakupu",
|
||||
"purchase_price": "Cena zakupu",
|
||||
"purchased_from": "Zakupiono od",
|
||||
"quantity": "Ilość",
|
||||
"query_id": "Zapytanie o numer identyfikacyjny zasobu: { id }",
|
||||
"receipt": "Paragon",
|
||||
"receipts": "Paragony",
|
||||
"reset_search": "Zresetuj wyszukiwanie",
|
||||
"results": "{ total } wyniki",
|
||||
"serial_number": "Numer seryjny",
|
||||
"show_advanced_view_options": "Pokaż ustawienia zaawansowane",
|
||||
"sold_at": "Sprzedane w",
|
||||
"sold_details": "Szczegóły sprzedaży",
|
||||
"sold_price": "Cena sprzedaży",
|
||||
"sold_to": "Sprzedane do",
|
||||
"tip_1": "Filtry lokalizacji i etykiet używają operacji 'LUB'. Jeśli wybrano więcej niż jeden, wystarczy jeden, \naby uzyskać dopasowanie.",
|
||||
"tip_2": "Wyszukiwania poprzedzone prefiksem \"#\" będą wysyłać zapytanie o identyfikator zasobu (na przykład \"#000-001\")",
|
||||
"tip_3": "Filtry pól używają operacji 'LUB'. Jeśli wybrano więcej niż jeden, wystarczy jeden, \naby uzyskać dopasowanie.",
|
||||
"tips": "Wskazówki",
|
||||
"tips_sub": "Wskazówki wyszukiwania",
|
||||
"order_by": "Ułóż według"
|
||||
"updated_at": "Zaktualizowano",
|
||||
"warranty": "Gwarancja",
|
||||
"warranty_details": "Szczegóły gwarancji",
|
||||
"warranty_expires": "Gwarancja wygasa"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Nie znaleziono etykiet",
|
||||
"update_label": "Aktualizuj etykietę"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Kataloński",
|
||||
"de": "Niemiecki",
|
||||
"en": "Angielski",
|
||||
"es": "Hiszpański",
|
||||
"fr": "Francuski",
|
||||
"hu": "Węgierski",
|
||||
"it": "Włoski",
|
||||
"ja-JP": "Japoński",
|
||||
"nl": "Holenderski",
|
||||
"pl": "Polski",
|
||||
"pt-BR": "Portugalski (Brazylia)",
|
||||
"pt-PT": "Portugalski (Portugalia)",
|
||||
"ru": "Rosyjski",
|
||||
"sl": "Słoweński",
|
||||
"sv": "Szwedzki",
|
||||
"tr": "Turecki",
|
||||
"uk-UA": "Ukraiński",
|
||||
"zh-CN": "Chiński (uproszczony)",
|
||||
"zh-HK": "Chiński (Hong Kong)",
|
||||
"zh-MO": "Chiński (Makau)",
|
||||
"zh-TW": "Chiński (tradycyjny)"
|
||||
},
|
||||
"locations": {
|
||||
"child_locations": "Podlokalizacje",
|
||||
"collapse_tree": "Zwiń drzewo",
|
||||
"no_results": "Nie znaleziono lokalizacji",
|
||||
"update_location": "Zaktualizuj lokalizację"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
"both": "Oba",
|
||||
"completed": "Zrealizowane",
|
||||
"scheduled": "Nadchodzące"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Zakończone",
|
||||
"create_first": "Stwórz swój pierwszy wpis",
|
||||
"delete": "Usuń",
|
||||
"duplicate": "Duplikuj",
|
||||
"edit": "Edytuj",
|
||||
"new": "Nowe"
|
||||
},
|
||||
"modal": {
|
||||
"completed_date": "Data zakończenia",
|
||||
"cost": "Koszt",
|
||||
"delete_confirmation": "Czy na pewno chcesz usunąć ten wpis?",
|
||||
"edit_action": "Aktualizuj",
|
||||
"edit_title": "Edytuj wpis",
|
||||
"entry_name": "Nazwa wpisu",
|
||||
"new_action": "Utwórz",
|
||||
"new_title": "Nowy wpis",
|
||||
"notes": "Notatki",
|
||||
"scheduled_date": "Zaplanowana data"
|
||||
},
|
||||
"monthly_average": "Miesięczna średnia",
|
||||
"toast": {
|
||||
"failed_to_create": "Nie udało się utworzyć wpisu",
|
||||
"failed_to_delete": "Nie udało się usunąć wpisu",
|
||||
"failed_to_update": "Nie udało się zaktualizować wpisu"
|
||||
},
|
||||
"total_cost": "Całkowity koszt",
|
||||
"total_entries": "Suma wpisów"
|
||||
},
|
||||
"menu": {
|
||||
"create_item": "Przedmiot / Zasób",
|
||||
"create_label": "Etykieta",
|
||||
"create_location": "Lokalizacja",
|
||||
"home": "Strona główna",
|
||||
"locations": "Lokalizacje",
|
||||
"maintenance": "Konserwacja",
|
||||
"profile": "Profil",
|
||||
"search": "Wyszukaj",
|
||||
"tools": "Narzędzia"
|
||||
},
|
||||
"profile": {
|
||||
"active": "Aktywny",
|
||||
"change_password": "Zmiana hasła",
|
||||
"currency_format": "Format waluty",
|
||||
"current_password": "Bieżące hasło",
|
||||
"delete_account": "Usuń konto",
|
||||
"delete_account_sub": "Usuń swoje konto oraz wszystkie powiązane z nim dane. Tego nie można cofnąć.",
|
||||
"current_password": "Bieżące hasło",
|
||||
"group_settings_sub": "Ustawienia grupy udostępnione. Możesz potrzebować odświeżyć przeglądarkę, aby niektóre ustawienia zostały zastosowane.",
|
||||
"inactive": "Nieaktywny",
|
||||
"new_password": "Nowe hasło",
|
||||
"notifier_modal": "{type, select, true {Edytuj} false {Utwórz} other {Inny}} Powiadomiacz",
|
||||
"enabled": "Włączone",
|
||||
"example": "Przykład",
|
||||
"gen_invite": "Wygeneruj link z zaproszeniem",
|
||||
"group_settings": "Ustawienia grupy",
|
||||
"group_settings_sub": "Ustawienia grupy udostępnione. Możesz potrzebować odświeżyć przeglądarkę, aby niektóre ustawienia zostały zastosowane.",
|
||||
"inactive": "Nieaktywny",
|
||||
"language": "Język",
|
||||
"new_password": "Nowe hasło",
|
||||
"no_notifiers": "Nie skonfigurowano powiadomień",
|
||||
"notifier_modal": "{type, select, true {Edytuj} false {Utwórz} other {Inny}} Powiadomiacz",
|
||||
"notifiers": "Powiadomiacze",
|
||||
"notifiers_sub": "Otrzymuj powiadomienia o nadchodzących przypomnieniach o konserwacji",
|
||||
"theme_settings_sub": "Ustawienia motywu są przechowywane w lokalnej pamięci przeglądarki. Możesz zmienić motyw w dowolnym momencie. \nJeśli masz problemy z ustawieniem motywu, spróbuj odświeżyć przeglądarkę.",
|
||||
"test": "Test",
|
||||
"theme_settings": "Ustawienia tematu",
|
||||
"theme_settings_sub": "Ustawienia motywu są przechowywane w lokalnej pamięci przeglądarki. Możesz zmienić motyw w dowolnym momencie. \nJeśli masz problemy z ustawieniem motywu, spróbuj odświeżyć przeglądarkę.",
|
||||
"update_group": "Zaktualizuj grupę",
|
||||
"update_language": "Aktualizuj język",
|
||||
"url": "Adres URL",
|
||||
"user_profile": "Profil użytkownika",
|
||||
"user_profile_sub": "Zaproś użytkowników i zarządzaj swoim kontem."
|
||||
},
|
||||
"tools": {
|
||||
"actions": "Akcje na zasobach",
|
||||
"actions_set": {
|
||||
"ensure_ids": "Zapewnienie identyfikatorów zasobów",
|
||||
"ensure_import_refs_sub": "Zapewnia, że wszystkie przedmioty w Twoim asortymencie mają prawidłowe pole import_ref",
|
||||
"set_primary_photo": "Ustaw główne zdjęcie",
|
||||
"set_primary_photo_button": "Ustaw główne zdjęcie",
|
||||
"set_primary_photo_sub": "W wersji v0.10.0 Homebox pole głównego obrazu zostało dodane do załączników typu zdjęcie. Ta akcja ustawi pole głównego obrazu do pierwszego zdjęcia w załącznikach z bazy danych, jeżeli nie jest już ustawione. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/pull/576\">'Zobacz GitHub PR #576'</a>'"
|
||||
},
|
||||
"import_export": "Import/eksport"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,12 +75,6 @@
|
||||
"set_password": "Defina a sua senha",
|
||||
"tagline": "Acompanhe, organize e faça a gestão das suas coisas."
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Nenhuma etiqueta encontrada"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "Nenhuma localização encontrada"
|
||||
},
|
||||
"items": {
|
||||
"add": "Adicionar",
|
||||
"created_at": "Criado em",
|
||||
@@ -107,6 +101,9 @@
|
||||
"tips_sub": "Dicas de pesquisa",
|
||||
"updated_at": "Atualizado em"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Nenhuma etiqueta encontrada"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Catalão",
|
||||
"de": "Alemão",
|
||||
@@ -127,6 +124,9 @@
|
||||
"zh-MO": "Chinês (Macau)",
|
||||
"zh-TW": "Chinês (Tradicional)"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "Nenhuma localização encontrada"
|
||||
},
|
||||
"profile": {
|
||||
"active": "Ativo",
|
||||
"change_password": "Alterar Senha",
|
||||
@@ -138,17 +138,17 @@
|
||||
"enabled": "Ativado",
|
||||
"gen_invite": "Gerar link de convite",
|
||||
"group_settings": "Definições de Grupo",
|
||||
"group_settings_sub": "Definições de Grupo Partilhadas. Pode ter de atualizar a página para algumas definições serem aplicadas.",
|
||||
"group_settings_sub": "Definições de Grupo Partilhadas. Pode ter de atualizar a página para algumas definições serem aplicadas.",
|
||||
"inactive": "Inativo",
|
||||
"language": "Idioma",
|
||||
"new_password": "Nova Senha",
|
||||
"no_notifiers": "Nenhum notificador configurado",
|
||||
"notifier_modal": "{ type, select, true {Editar} false {Criar} other {Outro}} Notificador",
|
||||
"notifiers": "Notificadores",
|
||||
"notifiers_sub": "Receba notificações para os próximos lembretes de manutenção",
|
||||
"no_notifiers": "Nenhum notificador configurado",
|
||||
"test": "Testar",
|
||||
"theme_settings": "Definições do tema",
|
||||
"theme_settings_sub": "As configurações do tema são guardadas no armazenamento local do seu navegador. Pode alterar o tema em qualquer altura.\nSe encontrar algum problema com a alteração do tema, tente refrescar o browser.",
|
||||
"theme_settings_sub": "As configurações do tema são guardadas no armazenamento local do seu navegador. Pode alterar o tema em qualquer altura.\nSe encontrar algum problema com a alteração do tema, tente refrescar o browser.",
|
||||
"update_group": "Atualizar Grupo",
|
||||
"update_language": "Atualizar Idioma",
|
||||
"url": "URL",
|
||||
@@ -170,7 +170,7 @@
|
||||
"zero_datetimes": "Zero Item Data e Hora",
|
||||
"zero_datetimes_button": "Zero Data Horas do Item"
|
||||
},
|
||||
"actions_sub": "Aplicar Ações ao seu inventário em massa. Estas acções são irreversíveis. '<b>'Cuidado.'</b>'",
|
||||
"actions_sub": "Aplicar Ações ao seu inventário em massa. Estas acções são irreversíveis. '<b>'Cuidado.'</b>'",
|
||||
"import_export": "Importar/Exportar",
|
||||
"import_export_set": {
|
||||
"export": "Exportar Inventário",
|
||||
@@ -178,7 +178,7 @@
|
||||
"export_sub": "Exporta o formato CSV padrão para o Homebox. Isto vai exportar todos os items do inventário.",
|
||||
"import": "Importar inventário",
|
||||
"import_button": "Importar inventário",
|
||||
"import_sub": "Importa o formato standard do CSV para o Homebox. Sem uma coluna '<code>'HB.import_ref'</code>' , isto '<b>'não '</b>' vai escrever por cima de items existentes no inventário, apenas adiciona novos. As linhas com uma coluna '<code>'HB.import_ref'</code>' vão ser fundidas com os items que tenham o mesmo import_ref, se existirem."
|
||||
"import_sub": "Importa o formato standard do CSV para o Homebox. Sem uma coluna '<code>'HB.import_ref'</code>' , isto '<b>'não '</b>' vai escrever por cima de items existentes no inventário, apenas adiciona novos. As linhas com uma coluna '<code>'HB.import_ref'</code>' vão ser fundidas com os items que tenham o mesmo import_ref, se existirem."
|
||||
},
|
||||
"import_export_sub": "Importe e exporte o seu inventário de e para um ficheiro CSV. Isto é útil para migrar o inventário para uma nova instância do Homebox.",
|
||||
"reports": "Relatórios",
|
||||
|
||||
211
frontend/locales/ro-RO.json
Normal file
211
frontend/locales/ro-RO.json
Normal file
@@ -0,0 +1,211 @@
|
||||
{
|
||||
"components": {
|
||||
"app": {
|
||||
"import_dialog": {
|
||||
"title": "Importă fișier CSV",
|
||||
"upload": "Încarcă"
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"page_qr_code": {
|
||||
"page_url": "URL Pagină"
|
||||
},
|
||||
"password_score": {
|
||||
"password_strength": "Complexitate Parolă"
|
||||
}
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"photo_button": "Imagine 📷",
|
||||
"title": "Crează articol"
|
||||
},
|
||||
"view": {
|
||||
"selectable": {
|
||||
"card": "Cartelă",
|
||||
"items": "Articole",
|
||||
"no_items": "Nu există articole pentru afișare",
|
||||
"table": "Tabel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"title": "Crează Etichetă"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"title": "Crează Locație"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Nu există locații disponibile. Adaugă o locație nouă folosind butonul\n`<`span class=\"link-primary\"`>`Crează`<`/span`>` din bara de navigație."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"build": "Build: { build }",
|
||||
"confirm": "Confirmă",
|
||||
"create": "Crează",
|
||||
"create_and_add": "Crează și Adaugă încă un articol",
|
||||
"created": "Creat",
|
||||
"email": "Adresă de email",
|
||||
"follow_dev": "Urmărește developer-ul",
|
||||
"github": "Proiect GitHub",
|
||||
"items": "Articole",
|
||||
"join_discord": "Vino pe Discord",
|
||||
"labels": "Etichete",
|
||||
"locations": "Locații",
|
||||
"name": "Nume",
|
||||
"password": "Parolă",
|
||||
"read_docs": "Citește documentația",
|
||||
"search": "Caută",
|
||||
"sign_out": "Ieșire",
|
||||
"submit": "Trimite",
|
||||
"version": "Versiune: { version }",
|
||||
"welcome": "Bun venit, { username }"
|
||||
},
|
||||
"index": {
|
||||
"disabled_registration": "Înregistrare Dezactivată",
|
||||
"dont_join_group": "Nu vrei sa te alături unui grup?",
|
||||
"joining_group": "Te alături unui grup existent!",
|
||||
"login": "Autentificare",
|
||||
"register": "Înregistrare",
|
||||
"remember_me": "Ține-mă minte",
|
||||
"set_email": "Care este adresa ta de email?",
|
||||
"set_name": "Care este numele tău?",
|
||||
"set_password": "Setează-ți parola",
|
||||
"tagline": "Urmărește, Organizează și Gestionează lucrurile tale."
|
||||
},
|
||||
"items": {
|
||||
"add": "Adaugă",
|
||||
"created_at": "Creat la",
|
||||
"custom_fields": "Câmpuri personalizate",
|
||||
"field_selector": "Selector Câmp",
|
||||
"field_value": "Valoare Câmp",
|
||||
"first": "Primul",
|
||||
"include_archive": "Include Articole Arhivate",
|
||||
"last": "Ultimul",
|
||||
"negate_labels": "Neagă Etichetele Selectate",
|
||||
"next_page": "Următoarea Pagină",
|
||||
"no_results": "Nu s-au găsit articole",
|
||||
"options": "Opțiuni",
|
||||
"order_by": "Ordonează După",
|
||||
"pages": "Pagina { page } din { totalPages }",
|
||||
"prev_page": "Pagina Anterioară",
|
||||
"reset_search": "Resetează Căutare",
|
||||
"results": "{ total } Rezultate",
|
||||
"tip_2": "Căutările prefixate cu '#' vor efectua o căutare după ID de activ (exemplu '#000-001')",
|
||||
"tips": "Sfaturi",
|
||||
"tips_sub": "Sfaturi Căutare",
|
||||
"updated_at": "Actualizat La"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Nu s-au găsit Etichete"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Catalană",
|
||||
"de": "Germană",
|
||||
"en": "Engleză",
|
||||
"es": "Spaniolă",
|
||||
"fr": "Franceză",
|
||||
"hu": "Maghiară",
|
||||
"it": "Italiană",
|
||||
"nl": "Olandeză",
|
||||
"pl": "Poloneză",
|
||||
"pt-BR": "Portugheză (Brazilia)",
|
||||
"ru": "Rusă",
|
||||
"sl": "Slovenă",
|
||||
"sv": "Suedeză",
|
||||
"tr": "Turcă",
|
||||
"zh-CN": "Chineză (Simplificată)",
|
||||
"zh-HK": "Chineză (Hong Kong)",
|
||||
"zh-MO": "Chineză (Macau)",
|
||||
"zh-TW": "Chineză (Tradițională)"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "Nu s-au găsit Locații"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
"both": "Ambele",
|
||||
"completed": "Finalizat",
|
||||
"scheduled": "Programat"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Finalizat",
|
||||
"create_first": "Crează Prima ta Înregistrare",
|
||||
"delete": "Șterge",
|
||||
"duplicate": "Duplicat",
|
||||
"edit": "Redactare",
|
||||
"new": "Nou"
|
||||
},
|
||||
"modal": {
|
||||
"completed_date": "Dată finalizare",
|
||||
"cost": "Preț",
|
||||
"delete_confirmation": "Ești sigur ca dorești ștergerea acestei înregistrări?",
|
||||
"edit_action": "Actualizare",
|
||||
"edit_title": "Redactare Înregistrare",
|
||||
"entry_name": "Nume Înregistrare",
|
||||
"new_action": "Crează",
|
||||
"new_title": "Înregistrare Nouă",
|
||||
"notes": "Notițe",
|
||||
"scheduled_date": "Dată Programată"
|
||||
},
|
||||
"monthly_average": "Media Lunară",
|
||||
"toast": {
|
||||
"failed_to_create": "Nu s-a putut crea înregistrarea",
|
||||
"failed_to_delete": "Nu s-a putut șterge înregistrarea",
|
||||
"failed_to_update": "Nu s-a putut actualiza înregistrarea"
|
||||
},
|
||||
"total_cost": "Preț Total",
|
||||
"total_entries": "Înregistrări Totale"
|
||||
},
|
||||
"menu": {
|
||||
"home": "Acasă",
|
||||
"locations": "Locații",
|
||||
"maintenance": "Mentenanță",
|
||||
"profile": "Profil",
|
||||
"search": "Caută",
|
||||
"tools": "Unelte"
|
||||
},
|
||||
"profile": {
|
||||
"active": "Activ",
|
||||
"change_password": "Schimbă Parola",
|
||||
"currency_format": "Format monedă",
|
||||
"current_password": "Parola Actuală",
|
||||
"delete_account": "Șterge Cont",
|
||||
"enabled": "Activat",
|
||||
"gen_invite": "Generează Link Invitație",
|
||||
"group_settings": "Setări Grup",
|
||||
"inactive": "Inactiv",
|
||||
"language": "Limbă",
|
||||
"new_password": "Parolă Nouă",
|
||||
"test": "Test",
|
||||
"theme_settings": "Setări Temă",
|
||||
"update_group": "Actualizare Grup",
|
||||
"update_language": "Actualizare Limbă",
|
||||
"url": "URL",
|
||||
"user_profile": "Profil Utilizator"
|
||||
},
|
||||
"tools": {
|
||||
"actions": "Acțiuni Inventar",
|
||||
"actions_set": {
|
||||
"set_primary_photo": "Setează ca Imagine Principală",
|
||||
"set_primary_photo_button": "Setează ca Imagine Principală"
|
||||
},
|
||||
"import_export": "Import/Export",
|
||||
"import_export_set": {
|
||||
"export": "Exportă Inventar",
|
||||
"export_button": "Exportă Inventar",
|
||||
"import": "Importă Inventar",
|
||||
"import_button": "Importă Inventar"
|
||||
},
|
||||
"reports": "Rapoarte",
|
||||
"reports_set": {
|
||||
"asset_labels": "Etichete de identificare a activului",
|
||||
"asset_labels_button": "Generator de etichete",
|
||||
"bill_of_materials": "Lista Materialelor",
|
||||
"bill_of_materials_button": "Generează BOM"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,29 @@
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"date_time": {
|
||||
"ago": "{0} назад",
|
||||
"days": "дней",
|
||||
"hour": "час",
|
||||
"hours": "часов",
|
||||
"in": "через {0}",
|
||||
"last-month": "предыдущий месяц",
|
||||
"last-week": "предыдущая неделя",
|
||||
"last-year": "предыдущий год",
|
||||
"minute": "минута",
|
||||
"minutes": "минут",
|
||||
"months": "месяцев",
|
||||
"next-month": "следующий месяц",
|
||||
"next-week": "следующая неделя",
|
||||
"next-year": "следующий год",
|
||||
"second": "секунда",
|
||||
"seconds": "секунд",
|
||||
"tomorrow": "завтра",
|
||||
"week": "неделя",
|
||||
"weeks": "недели",
|
||||
"years": "лет",
|
||||
"yesterday": "вчера"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "URL-адрес страницы"
|
||||
},
|
||||
@@ -18,6 +41,8 @@
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"item_description": "Описание элемента",
|
||||
"item_name": "Имя элемента",
|
||||
"photo_button": "Фото 📷",
|
||||
"title": "Создать элемент"
|
||||
},
|
||||
@@ -27,17 +52,24 @@
|
||||
"items": "Элементы",
|
||||
"no_items": "Нет элементов для отображения",
|
||||
"table": "Таблица"
|
||||
},
|
||||
"table": {
|
||||
"page": "Страница",
|
||||
"rows_per_page": "Строк на странице"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"title": "Создать ярлык"
|
||||
"title": "Создать метку"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"title": "Создать локацию"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Нет доступных локаций. Добавьте новую локацию, \nнажав на кнопку `<`span class=\"link-primary\"`>`Создать`<`/span`>` в навигационном меню."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -49,10 +81,10 @@
|
||||
"created": "Создано",
|
||||
"email": "Email",
|
||||
"follow_dev": "Следить за разработчиком",
|
||||
"github": "Проект Github",
|
||||
"github": "Github проект",
|
||||
"items": "Элементы",
|
||||
"join_discord": "Присоединяйтесь к Discord",
|
||||
"labels": "Ярлыки",
|
||||
"labels": "Метки",
|
||||
"locations": "Локации",
|
||||
"name": "Имя",
|
||||
"password": "Пароль",
|
||||
@@ -82,7 +114,7 @@
|
||||
"field_selector": "Поле выбора",
|
||||
"field_value": "Значение поля",
|
||||
"first": "Первый",
|
||||
"include_archive": "Включить архивированные элементы",
|
||||
"include_archive": "Включая архивированные элементы",
|
||||
"last": "Последний",
|
||||
"negate_labels": "Снять выбранные ярлыки",
|
||||
"next_page": "Следующая страница",
|
||||
@@ -92,7 +124,7 @@
|
||||
"pages": "Страница {page} из {totalPages}",
|
||||
"prev_page": "Предыдущая страница",
|
||||
"query_id": "Запрос идентификационного номера актива: { id }",
|
||||
"reset_search": "Сбросить Поиск",
|
||||
"reset_search": "Сбросить поиск",
|
||||
"results": "{ total } Результатов",
|
||||
"tip_1": "При фильтрации по локации и по ярлыкам используется логический оператор «ИЛИ». Если выбрано несколько фильтров, то для срабатывания\n требуется лишь одно совпадение.",
|
||||
"tip_2": "Поисковые запросы с префиксом \"#\" должны включать в себя ID актива (прим. '#000-001')",
|
||||
@@ -101,6 +133,75 @@
|
||||
"tips_sub": "Поисковые подсказки",
|
||||
"updated_at": "Обновлено в"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Метки не найдены"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Каталанский",
|
||||
"de": "Немецкий",
|
||||
"en": "Английский",
|
||||
"es": "Испанский",
|
||||
"fr": "французский",
|
||||
"hu": "Венгерский",
|
||||
"it": "Итальянский",
|
||||
"nl": "Голландский",
|
||||
"pl": "Польский",
|
||||
"pt-BR": "Португальский (Бразилия)",
|
||||
"ru": "Русский",
|
||||
"sl": "Словенский",
|
||||
"sv": "Шведский",
|
||||
"tr": "Турецкий",
|
||||
"zh-CN": "Китайский (упрощенный)",
|
||||
"zh-HK": "Китайский (Гонконг)",
|
||||
"zh-MO": "Китайский (Макао)",
|
||||
"zh-TW": "китайский (традиционный)"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "Локаций не найдено"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
"both": "Оба",
|
||||
"completed": "Завершено",
|
||||
"scheduled": "Запланировано"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Завершить",
|
||||
"create_first": "Создайте свою первую запись",
|
||||
"delete": "Удалить",
|
||||
"duplicate": "Дубликат",
|
||||
"edit": "Изменить",
|
||||
"new": "Новое"
|
||||
},
|
||||
"modal": {
|
||||
"completed_date": "Дата завершения",
|
||||
"cost": "Стоимость",
|
||||
"delete_confirmation": "Вы уверены, что хотите удалить эту запись?",
|
||||
"edit_action": "Обновить",
|
||||
"edit_title": "Изменить запись",
|
||||
"entry_name": "Название",
|
||||
"new_action": "Создать",
|
||||
"new_title": "Новая запись",
|
||||
"notes": "Заметки",
|
||||
"scheduled_date": "Планируемая дата"
|
||||
},
|
||||
"monthly_average": "Среднемесячный показатель",
|
||||
"toast": {
|
||||
"failed_to_create": "Не удалось создать запись",
|
||||
"failed_to_delete": "Не удалось удалить запись",
|
||||
"failed_to_update": "Ошибка обновления записи"
|
||||
},
|
||||
"total_cost": "Общая стоимость",
|
||||
"total_entries": "Всего записей"
|
||||
},
|
||||
"menu": {
|
||||
"home": "Главная",
|
||||
"locations": "Локации",
|
||||
"maintenance": "Техническое обслуживание и ремонт",
|
||||
"profile": "Профиль",
|
||||
"search": "Поиск",
|
||||
"tools": "Инструменты"
|
||||
},
|
||||
"profile": {
|
||||
"active": "Активный",
|
||||
"change_password": "Изменить пароль",
|
||||
@@ -108,7 +209,7 @@
|
||||
"current_password": "Текущий пароль",
|
||||
"delete_account": "Удалить аккаунт",
|
||||
"delete_account_sub": "Удалить свой аккаунт и все связанные с ним данные. Это действие невозможно отменить.",
|
||||
"display_header": "{ currentValue, select, true {Hide Header} false {Show Header} other {Not Hit}}",
|
||||
"display_header": "{ currentValue, select, true {Скрыть заголовок} false {Показать заголовок} other {Нет результатов}}",
|
||||
"enabled": "Активен",
|
||||
"gen_invite": "Сгенерировать ссылку-приглашение",
|
||||
"group_settings": "Настройки группы",
|
||||
@@ -116,9 +217,10 @@
|
||||
"inactive": "Неактивный",
|
||||
"language": "Язык",
|
||||
"new_password": "Новый пароль",
|
||||
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Уведомитель",
|
||||
"no_notifiers": "Нет настроенных уведомлений",
|
||||
"notifier_modal": "{ type, select, true {Изменить} false {Создать} other {Другое}} Уведомитель",
|
||||
"notifiers": "Уведомители",
|
||||
"notifiers_sub": "Получить уведомление о предстоящем обслуживании",
|
||||
"notifiers_sub": "Получать уведомления о предстоящем обслуживании",
|
||||
"test": "Тест",
|
||||
"theme_settings": "Настройки темы",
|
||||
"theme_settings_sub": "Настройки темы хранятся в локальном хранилище браузера. Вы можете изменить тему в любое время. Если у вас\n не удается установить тему, попробуйте перезапустить браузер.",
|
||||
@@ -136,27 +238,33 @@
|
||||
"ensure_ids_sub": "Гарантирует, что все вещи в вашем инвентаре будут иметь корректное поле asset_id. Это производится при помощи поиска самого большого текущего значения поля asset_id в базе данных и применяет ко всем вещам новые значения, где они не были установлены в поле asset_id. Это производится в порядке сортировки по полю created_at.",
|
||||
"ensure_import_refs": "Проверка ссылок импорта",
|
||||
"ensure_import_refs_button": "Обеспечение импорта ссылок",
|
||||
"ensure_import_refs_sub": "Гарантирует что все вещи в Вашем инвентаре имеют корректное поле import_ref. Это производится при помощи генерации строки из 8 случайных символов для каждой вещи, где не поле import_ref не заполнено."
|
||||
"ensure_import_refs_sub": "Гарантирует что все вещи в Вашем инвентаре имеют корректное поле import_ref. Это производится при помощи генерации строки из 8 случайных символов для каждой вещи, где не поле import_ref не заполнено.",
|
||||
"set_primary_photo": "Установить основное фото",
|
||||
"set_primary_photo_button": "Установить основное фото",
|
||||
"set_primary_photo_sub": "В Homebox v0.10.0 мы добавили возможность отмечать вложенные фото как основное изображение. Это действие устанавливает первую фотографию во вложениях в качестве основной, если основное изображение еще не выбрано. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/pull/576\">'Посмотреть pull request #576'</a>'",
|
||||
"zero_datetimes": "Сбросить даты",
|
||||
"zero_datetimes_button": "Сбросить даты",
|
||||
"zero_datetimes_sub": "Сбрасывает значение полей даты и времени на начало даты в полном наборе. Это исправляет ошибку, когда сохранение значений времени на ранних этапах разработки сайта приводило к ошибке в точном отображении дат '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/issues/236\" target=\"_blank\">'Посмотреть Issue #236 подробнее.'</a>'"
|
||||
},
|
||||
"actions_sub": "Применить действия ко всему Вашему инвентарю. Это необратимое действие. '<b>'Будьте осторожны.'</b>'",
|
||||
"actions_sub": "Применить действия ко всему вашему инвентарю. Это необратимое действие. '<b>'Будьте осторожны.'</b>'",
|
||||
"import_export": "Импорт/Экспорт",
|
||||
"import_export_set": {
|
||||
"export": "Экспортировать инвентарь",
|
||||
"export_button": "Экспортировать инвентарь",
|
||||
"export_sub": "Экспортирует файл в стандартном CSV формате для Homebox. Это экспортирует все Ваши вещи из Вашего инвентаря.",
|
||||
"import": "Импорт из инвентаря",
|
||||
"import": "Импортировать инвентарь",
|
||||
"import_button": "Импортировать инвентарь",
|
||||
"import_sub": "Импортирует стандартный CSV формат в Homebox. Без колонки '<code>'HB.import_ref'</code>' , это '<b>'не'</b>' перезапишет какую либо существующую вещь в вашем инвентаре, только добавит новые вещи. Строки с колонкой '<code>'HB.import_ref'</code>' будут объеденены с существующими вещами с теми же import_ref, если такие существуют."
|
||||
"import_sub": "Импортировать стандартный CSV формат в Homebox. Без колонки '<code>'HB.import_ref'</code>' , это '<b>'не'</b>' перезапишет какую либо существующую вещь в вашем инвентаре, только добавит новые вещи. Строки с колонкой '<code>'HB.import_ref'</code>' будут объеденены с существующими вещами с теми же import_ref, если такие существуют."
|
||||
},
|
||||
"import_export_sub": "Импортировать или экспортировать ваш инвентарь в или из CSV файла. Это полезно при миграции вашего инвентаря в новый экземпляр Homebox.",
|
||||
"reports": "Отчеты",
|
||||
"reports_set": {
|
||||
"asset_labels": "Этикетки с ID активов",
|
||||
"asset_labels_button": "Генератор этикеток",
|
||||
"asset_labels_sub": "Генерирует PDF с этикетками для диапазона ID активов. Отсутствует привязка к Вашему инвентарю, так что Вы можете напечатать этикетки заранее и применить их к вашему инвентарю позднее.",
|
||||
"asset_labels": "Метки с ID активов",
|
||||
"asset_labels_button": "Генератор меток",
|
||||
"asset_labels_sub": "Генерирует PDF с метками для диапазона ID активов. Отсутствует привязка к Вашему инвентарю, так что вы можете напечатать метки заранее и применить их к вашему инвентарю позже.",
|
||||
"bill_of_materials": "Ведомость материалов",
|
||||
"bill_of_materials_button": "Сгенерировать BOM",
|
||||
"bill_of_materials_sub": "Генерирует файл CSV (значения, разделенные запятой), который может быть импортировать в приложении электронных таблиц. Это сводка вашего инвентаря с базовой информацией о вещах и их цене."
|
||||
"bill_of_materials_button": "Сгенерировать список запчастей",
|
||||
"bill_of_materials_sub": "Генерирует CSV файл (значения, разделенные запятой), который может быть импортирован в приложении электронных таблиц. Это сводка вашего инвентаря с базовой информацией о вещах и их цене."
|
||||
},
|
||||
"reports_sub": "Создавайте различные отчеты для вашего инвентаря."
|
||||
}
|
||||
|
||||
347
frontend/locales/sk-SK.json
Normal file
347
frontend/locales/sk-SK.json
Normal file
@@ -0,0 +1,347 @@
|
||||
{
|
||||
"components": {
|
||||
"app": {
|
||||
"import_dialog": {
|
||||
"change_warning": "Správanie pre importy s existujúcimi import_refs sa zmenilo. Ak sa v súbore CSV nachádza import_ref,\npoložka bude aktualizovaná hodnotami v súbore CSV.",
|
||||
"description": "Importujte súbor CSV obsahujúci vaše položky, štítky a miesta. Ďalšie informácie nájdete v dokumentácii\npožadovaný formát.",
|
||||
"title": "Importovať súbor CSV",
|
||||
"upload": "Nahrať"
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"date_time": {
|
||||
"ago": "{0} pred",
|
||||
"days": "dní",
|
||||
"hour": "hodina",
|
||||
"hours": "hodiny",
|
||||
"in": "v {0}",
|
||||
"just-now": "práve teraz",
|
||||
"last-month": "minulý mesiac",
|
||||
"last-week": "minulý týždeň",
|
||||
"last-year": "minulý rok",
|
||||
"minute": "minúta",
|
||||
"minutes": "minút",
|
||||
"months": "mesiacov",
|
||||
"next-month": "budúci mesiac",
|
||||
"next-week": "budúci týždeň",
|
||||
"next-year": "budúci rok",
|
||||
"second": "sekunda",
|
||||
"seconds": "sekúnd",
|
||||
"tomorrow": "zajtra",
|
||||
"week": "týždeň",
|
||||
"weeks": "týždňov",
|
||||
"years": "rokov",
|
||||
"yesterday": "včera"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "URL stránka"
|
||||
},
|
||||
"password_score": {
|
||||
"password_strength": "Sila hesla"
|
||||
}
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"item_description": "Popis položky",
|
||||
"item_name": "Názov položky",
|
||||
"photo_button": "Foto 📷",
|
||||
"title": "Vytvoriť položku"
|
||||
},
|
||||
"view": {
|
||||
"selectable": {
|
||||
"card": "Karta",
|
||||
"items": "Položky",
|
||||
"no_items": "Žiadne položky na zobrazenie",
|
||||
"table": "Tabuľka"
|
||||
},
|
||||
"table": {
|
||||
"page": "Stránka",
|
||||
"rows_per_page": "Počet riadkov na stránku"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"label_description": "Popis štítku",
|
||||
"label_name": "Názov štítku",
|
||||
"title": "Vytvoriť štítok"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"location_description": "Popis miesta",
|
||||
"location_name": "Názov miesta",
|
||||
"title": "Vytvoriť polohu"
|
||||
},
|
||||
"selector": {
|
||||
"parent_location": "Poloha rodiča"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Nie sú k dispozícii žiadne miesta. Pridajte nové miesta cez\n `<`span class=\"link-primary\"`>`Vytvoriť`<`/span`>` na navigačnom paneli."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"add": "Pridať",
|
||||
"build": "Zostava: { build }",
|
||||
"confirm": "Potvrďte",
|
||||
"create": "Vytvorte",
|
||||
"create_and_add": "Vytvoriť a pridať ďalšie",
|
||||
"created": "Vytvorené",
|
||||
"delete": "Odstrániť",
|
||||
"details": "Podrobnosti",
|
||||
"duplicate": "Duplicitné",
|
||||
"edit": "Upraviť",
|
||||
"email": "Email",
|
||||
"follow_dev": "Sledujte vývojára",
|
||||
"github": "Projekt GitHub",
|
||||
"items": "Položky",
|
||||
"join_discord": "Pripojte sa k Discordu",
|
||||
"labels": "Štítky",
|
||||
"locations": "Miesta",
|
||||
"maintenance": "Údržba",
|
||||
"name": "Meno",
|
||||
"password": "heslo",
|
||||
"read_docs": "Prečítajte si Dokumenty",
|
||||
"save": "Uložiť",
|
||||
"search": "Hľadať",
|
||||
"sign_out": "Odhlásiť sa",
|
||||
"submit": "Odoslať",
|
||||
"update": "Aktualizovať",
|
||||
"value": "Hodnota",
|
||||
"version": "Verzia: { version }",
|
||||
"welcome": "Vitajte, { username }"
|
||||
},
|
||||
"home": {
|
||||
"labels": "Štítky",
|
||||
"quick_statistics": "Rýchla štatistika",
|
||||
"recently_added": "Nedávno pridané",
|
||||
"storage_locations": "Skladovacie miesta",
|
||||
"total_items": "Celkový počet položiek",
|
||||
"total_labels": "Celkový počet štítkov",
|
||||
"total_locations": "Celkový počet miest",
|
||||
"total_value": "Celková hodnota"
|
||||
},
|
||||
"index": {
|
||||
"disabled_registration": "Registrácia zakázaná",
|
||||
"dont_join_group": "Nechcete sa pridať do skupiny?",
|
||||
"joining_group": "Pripájate sa k existujúcej skupine!",
|
||||
"login": "Prihláste sa",
|
||||
"register": "Zaregistrujte sa",
|
||||
"remember_me": "Pamätaj si ma",
|
||||
"set_email": "Aký je váš e-mail?",
|
||||
"set_name": "Ako sa voláte?",
|
||||
"set_password": "Nastavte si heslo",
|
||||
"tagline": "Sledujte, organizujte a spravujte svoje veci."
|
||||
},
|
||||
"items": {
|
||||
"add": "Pridať",
|
||||
"advanced": "Pokročilé",
|
||||
"archived": "Archivované",
|
||||
"asset_id": "ID majetku",
|
||||
"attachment": "Príloha",
|
||||
"attachments": "Prílohy",
|
||||
"changes_persisted_immediately": "Zmeny príloh sa okamžite uložia",
|
||||
"created_at": "Vytvoril v",
|
||||
"custom_fields": "Vlastné polia",
|
||||
"description": "Popis",
|
||||
"details": "Podrobnosti",
|
||||
"drag_and_drop": "Presuňte súbory sem alebo kliknutím vyberte súbory",
|
||||
"edit_details": "Upraviť podrobnosti",
|
||||
"field_selector": "Výber poľa",
|
||||
"field_value": "Hodnota poľa",
|
||||
"first": "Prvý",
|
||||
"include_archive": "Zahrnúť archivované položky",
|
||||
"insured": "Poistený",
|
||||
"last": "Posledný",
|
||||
"lifetime_warranty": "Doživotná záruka",
|
||||
"location": "Poloha",
|
||||
"manual": "Príručka",
|
||||
"manuals": "Príručky",
|
||||
"manufacturer": "Výrobca",
|
||||
"model_number": "Číslo modelu",
|
||||
"name": "Meno",
|
||||
"negate_labels": "Negovať vybrané označenia",
|
||||
"next_page": "Ďalšia strana",
|
||||
"no_results": "Nenašli sa žiadne položky",
|
||||
"notes": "Poznámky",
|
||||
"options": "Možnosti",
|
||||
"order_by": "Objednať podľa",
|
||||
"pages": "Strana { page } z { totalPages }",
|
||||
"parent_item": "Nadradená položka",
|
||||
"photo": "Fotografia",
|
||||
"photos": "Fotografie",
|
||||
"prev_page": "Predchádzajúca stránka",
|
||||
"purchase_date": "Dátum nákupu",
|
||||
"purchase_details": "Podrobnosti o nákupe",
|
||||
"purchase_price": "Kúpna cena",
|
||||
"purchased_from": "Zakúpené od",
|
||||
"quantity": "Množstvo",
|
||||
"query_id": "Dopyt na ID číslo majetku: { id }",
|
||||
"receipt": "Účtenka",
|
||||
"receipts": "Účtenky",
|
||||
"reset_search": "Obnoviť vyhľadávanie",
|
||||
"results": "{ total } Výsledky",
|
||||
"serial_number": "Sériové číslo",
|
||||
"show_advanced_view_options": "Zobraziť rozšírené možnosti zobrazenia",
|
||||
"sold_at": "Predané v",
|
||||
"sold_details": "Podrobnosti o predaji",
|
||||
"sold_price": "Predajná cena",
|
||||
"sold_to": "Predané Komu",
|
||||
"tip_1": "Filtre umiestnení a štítkov používajú operáciu 'OR'. Ak je vybratých viac ako jeden,\n bude vybraný iba jeden potrebné na zápas.",
|
||||
"tip_2": "Vyhľadávania s predponou # budú dotazovať na identifikátor diela (napríklad #000-001)",
|
||||
"tip_3": "Filtre poľa používajú operáciu 'OR' . Ak je vybratých viac ako jeden, bude potrebný iba jeden pre a\n zápas.",
|
||||
"tips": "Tipy",
|
||||
"tips_sub": "Tipy na vyhľadávanie",
|
||||
"updated_at": "Čas aktualizácie",
|
||||
"warranty": "Záruka",
|
||||
"warranty_details": "Podrobnosti o záruke",
|
||||
"warranty_expires": "Záruka vyprší"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Nenašli sa žiadne štítky",
|
||||
"update_label": "Aktualizovať štítok"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Katalánsky",
|
||||
"de": "Nemecky",
|
||||
"en": "Anglicky",
|
||||
"es": "Španielsky",
|
||||
"fr": "Francúzsky",
|
||||
"hu": "Maďarsky",
|
||||
"it": "Taliančina",
|
||||
"ja-JP": "Japonsky",
|
||||
"nl": "Holandsky",
|
||||
"pl": "Poľsky",
|
||||
"pt-BR": "Portugalsky (Brazília)",
|
||||
"pt-PT": "Portugalsky (Portugalsko)",
|
||||
"ru": "Ruština",
|
||||
"sl": "Slovinsky",
|
||||
"sv": "Švédčina",
|
||||
"tr": "Turečtina",
|
||||
"uk-UA": "Ukrajinsky",
|
||||
"zh-CN": "Čínština (zjednodušená)",
|
||||
"zh-HK": "Čínsky (Hong Kong) Name",
|
||||
"zh-MO": "Čínština (Macao)",
|
||||
"zh-TW": "Číština (tradičná)"
|
||||
},
|
||||
"locations": {
|
||||
"child_locations": "Umiestnenie dieťaťa",
|
||||
"collapse_tree": "Zbaliť strom",
|
||||
"no_results": "Žiadne lokality neboli nájdené.",
|
||||
"update_location": "Aktualizovať lokalitu"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
"both": "Obe",
|
||||
"completed": "Dokončené",
|
||||
"scheduled": "Naplánované"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Hotovo",
|
||||
"create_first": "Vytvorte si svoj prvý záznam",
|
||||
"delete": "Zmazať",
|
||||
"duplicate": "Duplikovať",
|
||||
"edit": "Upraviť",
|
||||
"new": "New"
|
||||
},
|
||||
"modal": {
|
||||
"completed_date": "Dátum dokončenia",
|
||||
"cost": "Náklady",
|
||||
"delete_confirmation": "Skutočne si prajete vymazať tento záznam?",
|
||||
"edit_action": "Aktualizácia",
|
||||
"edit_title": "Upraviť položku",
|
||||
"entry_name": "Názov záznamu",
|
||||
"new_action": "Vytvoriť",
|
||||
"new_title": "Nová položka",
|
||||
"notes": "Poznámky",
|
||||
"scheduled_date": "Plánovaný dátum"
|
||||
},
|
||||
"monthly_average": "Mesačný priemer",
|
||||
"toast": {
|
||||
"failed_to_create": "Nepodarilo sa vytvoriť položku",
|
||||
"failed_to_delete": "Nepodarilo sa odstrániť záznam",
|
||||
"failed_to_update": "Nepodarilo sa aktualizovať položku"
|
||||
},
|
||||
"total_cost": "Celkové náklady",
|
||||
"total_entries": "Počet položiek"
|
||||
},
|
||||
"menu": {
|
||||
"create_item": "Položka / Aktívum",
|
||||
"create_label": "Štítok",
|
||||
"create_location": "Poloha",
|
||||
"home": "Domovská stránka",
|
||||
"locations": "Miesta",
|
||||
"maintenance": "Údržba",
|
||||
"profile": "Profil",
|
||||
"search": "Hľadať",
|
||||
"tools": "Nástroje"
|
||||
},
|
||||
"profile": {
|
||||
"active": "Aktívne",
|
||||
"change_password": "Zmeniť heslo",
|
||||
"currency_format": "Formát meny",
|
||||
"current_password": "Aktuálne heslo",
|
||||
"delete_account": "Odstrániť účet",
|
||||
"delete_account_sub": "Odstráňte svoj účet a všetky súvisiace údaje. Toto nie je možné vrátiť späť.",
|
||||
"display_header": "{ currentValue, select, true {Skryť hlavičku} false {Zobraziť hlavičku} other {Nie Hit}}",
|
||||
"enabled": "Povolené",
|
||||
"example": "Príklad",
|
||||
"gen_invite": "Vygenerovať odkaz na pozvánku",
|
||||
"group_settings": "Nastavenie skupiny",
|
||||
"group_settings_sub": "Nastavenia zdieľanej skupiny. Možno budete musieť obnoviť prehliadač, aby sa uplatnili niektoré nastavenia.",
|
||||
"inactive": "Neaktívne",
|
||||
"language": "Jazyk",
|
||||
"new_password": "Nové heslo",
|
||||
"no_notifiers": "Nie sú nakonfigurovaní žiadni upozorňovatelia",
|
||||
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Oznamovateľ",
|
||||
"notifiers": "Oznamovatelia",
|
||||
"notifiers_sub": "Dostávajte upozornenia na nadchádzajúce pripomenutia údržby",
|
||||
"test": "Test",
|
||||
"theme_settings": "Nastavenie motívu",
|
||||
"theme_settings_sub": "Nastavenia motívu sú uložené v lokálnom úložisku vášho prehliadača. Tému môžete kedykoľvek zmeniť. Ak mate\n problémy s nastavením motívu, skúste obnoviť prehliadač.",
|
||||
"update_group": "aktualizačná skupina",
|
||||
"update_language": "Aktualizovať súbor jazyka",
|
||||
"url": "URL",
|
||||
"user_profile": "Profil používateľa",
|
||||
"user_profile_sub": "Pozvite používateľov a spravujte svoj účet."
|
||||
},
|
||||
"tools": {
|
||||
"actions": "Akcie inventára",
|
||||
"actions_set": {
|
||||
"ensure_ids": "Zabezpečenie identifikátorov aktív",
|
||||
"ensure_ids_button": "Zabezpečenie identifikátorov aktív",
|
||||
"ensure_ids_sub": "Zabezpečuje, že všetky položky vo vašom inventári majú platné pole asset_id. To sa dosiahne nájdením najvyššieho aktuálneho poľa asset_id v databáze a aplikáciou ďalšej hodnoty na každú položku, ktorá má pole asset_id nenastavené. Toto sa vykonáva v poradí podľa poľa created_at.",
|
||||
"ensure_import_refs": "Zabezpečte import referencií",
|
||||
"ensure_import_refs_button": "Zabezpečte import referencií",
|
||||
"ensure_import_refs_sub": "Zabezpečuje, že všetky položky vo vašom inventári majú platné pole import_ref. To sa dosiahne náhodným vygenerovaním 8-znakového reťazca pre každú položku, ktorá má nenastavené pole import_ref.",
|
||||
"set_primary_photo": "Nastaviť primárnu fotografiu",
|
||||
"set_primary_photo_button": "Nastaviť primárnu fotografiu",
|
||||
"set_primary_photo_sub": "Vo verzii v0.10.0 Homeboxu bolo k prílohám typu fotografia pridané pole primárneho obrázka. Táto akcia nastaví pole primárneho obrázka na prvý obrázok v poli príloh v databáze, ak ešte nie je nastavený. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/pull/576\">'See GitHub PR #576'</a>'",
|
||||
"zero_datetimes": "Dátum nulovej položky Časy",
|
||||
"zero_datetimes_button": "Dátum nulovej položky Časy",
|
||||
"zero_datetimes_sub": "Obnoví hodnotu času pre všetky polia dátumu a času vo vašom inventári na začiatok dátumu. Ide o opravu chyby, ktorá bola zavedená na začiatku vývoja stránky a ktorá spôsobila, že sa hodnota času uložila s časom, čo spôsobilo problémy s poliami dátumu zobrazujúcimi presné hodnoty. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/issues/236\" target=\"_blank\">'See Github Issue #236 for more details.'</a>'"
|
||||
},
|
||||
"actions_sub": "Hromadne použite akcie na svoj inventár. Toto sú nezvratné akcie. '<b>'Buďte opatrní.'</b>'",
|
||||
"import_export": "Import/export",
|
||||
"import_export_set": {
|
||||
"export": "Export zásob",
|
||||
"export_button": "Export zásob",
|
||||
"export_sub": "Exportuje štandardný formát CSV pre Homebox. Týmto sa exportujú všetky položky vo vašom inventári.",
|
||||
"import": "Importovať inventár",
|
||||
"import_button": "Importovať inventár",
|
||||
"import_sub": "Importuje štandardný formát CSV pre Homebox. Bez '<code>'HB.import_ref'</code>' stĺpca to bude '<b>'nie'</b>' prepísať všetky existujúce položky vo vašom inventári, iba pridať nové položky. Riadky so '<code>'HB.import_ref'</code>' stĺpcom sa zlúčia do existujúcich položiek s rovnakým import_ref, ak taký existuje."
|
||||
},
|
||||
"import_export_sub": "Importujte a exportujte svoj inventár do a zo súboru CSV. Je to užitočné pri migrácii inventára do novej inštancie Homeboxu.",
|
||||
"reports": "Správy",
|
||||
"reports_set": {
|
||||
"asset_labels": "Štítky ID diela",
|
||||
"asset_labels_button": "Generátor štítkov",
|
||||
"asset_labels_sub": "Generuje tlačiteľné PDF štítkov pre rad Asset ID. Tieto nie sú špecifické pre váš inventár, takže štítky si môžete vytlačiť vopred a aplikovať ich na váš inventár, keď ich dostanete.",
|
||||
"bill_of_materials": "Faktúra za materiály",
|
||||
"bill_of_materials_button": "Generovať kusovník",
|
||||
"bill_of_materials_sub": "Vygeneruje súbor CSV (Comma Separated Values), ktorý možno importovať do tabuľkového procesora. Toto je súhrn vášho inventára so základnými informáciami o položkách a cenách."
|
||||
},
|
||||
"reports_sub": "Generujte rôzne prehľady pre svoj inventár."
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,30 @@
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"date_time": {
|
||||
"ago": "pred {0}",
|
||||
"days": "dni",
|
||||
"hour": "ura",
|
||||
"hours": "ure",
|
||||
"in": "v {0}",
|
||||
"just-now": "Pravkar",
|
||||
"last-month": "pretekli mesec",
|
||||
"last-week": "pretekli teden",
|
||||
"last-year": "lansko leto",
|
||||
"minute": "minuta",
|
||||
"minutes": "minut",
|
||||
"months": "mesecev",
|
||||
"next-month": "prihodnji mesec",
|
||||
"next-week": "prihodnji teden",
|
||||
"next-year": "prihodnje leto",
|
||||
"second": "sekunda",
|
||||
"seconds": "sekund",
|
||||
"tomorrow": "jutri",
|
||||
"week": "teden",
|
||||
"weeks": "tedni",
|
||||
"years": "leta",
|
||||
"yesterday": "včeraj"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "URL strani"
|
||||
},
|
||||
@@ -18,6 +42,8 @@
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"item_description": "opis predmeta",
|
||||
"item_name": "ime predmeta",
|
||||
"photo_button": "Fotografija 📷",
|
||||
"title": "Ustvari predmet"
|
||||
},
|
||||
@@ -27,29 +53,45 @@
|
||||
"items": "Predmeti",
|
||||
"no_items": "Ni predmetov za prikaz",
|
||||
"table": "Tabela"
|
||||
},
|
||||
"table": {
|
||||
"page": "Stran",
|
||||
"rows_per_page": "vrstic na stran"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"label_description": "Opis nalepke",
|
||||
"label_name": "Ime nalepke",
|
||||
"title": "Ustvari oznako"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"location_description": "Opis lokacije",
|
||||
"location_name": "Naziv lokacije",
|
||||
"title": "Ustvari lokacijo"
|
||||
},
|
||||
"selector": {
|
||||
"parent_location": "Glavna lokacija"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Ni razpoložljivih lokacij. Dodaj novo lokacije preko \n `<`span class=\"link-primary\"`>`Ustvari`<`/span`>` gumba v navigacijski vrstici."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"build": "Gradnja: [ build ]",
|
||||
"add": "Dodaj",
|
||||
"build": "Gradnja: { build }",
|
||||
"confirm": "Potrdi",
|
||||
"create": "Ustvari",
|
||||
"create_and_add": "Ustvari in dodaj še enega",
|
||||
"created": "Ustvarjeno",
|
||||
"delete": "Izbriši",
|
||||
"details": "Podrobnosti",
|
||||
"duplicate": "Podvoji",
|
||||
"edit": "Uredi",
|
||||
"email": "E-pošta",
|
||||
"follow_dev": "Sledi razvijjalcu",
|
||||
"github": "GitHub projekt",
|
||||
@@ -57,15 +99,29 @@
|
||||
"join_discord": "Pridruži se na Discord",
|
||||
"labels": "Oznake",
|
||||
"locations": "Lokacije",
|
||||
"maintenance": "Vzdrževanje",
|
||||
"name": "Naziv",
|
||||
"password": "Geslo",
|
||||
"read_docs": "Preberite dokumentacijo",
|
||||
"save": "Shrani",
|
||||
"search": "Iskanje",
|
||||
"sign_out": "Odjava",
|
||||
"submit": "Pošlji",
|
||||
"update": "Posodobi",
|
||||
"value": "Vrednost",
|
||||
"version": "Verzija: { version }",
|
||||
"welcome": "Dobrodošel, { username }"
|
||||
},
|
||||
"home": {
|
||||
"labels": "Oznake",
|
||||
"quick_statistics": "Hitra statistika",
|
||||
"recently_added": "Nedavno dodano",
|
||||
"storage_locations": "Lokacije shramb",
|
||||
"total_items": "Predmetov skupaj",
|
||||
"total_labels": "Skupaj nalepk",
|
||||
"total_locations": "Skupaj lokacij",
|
||||
"total_value": "Skupna vrednost"
|
||||
},
|
||||
"index": {
|
||||
"disabled_registration": "Registracija je onemogočena",
|
||||
"dont_join_group": "Se ne želite pridružiti skupini?",
|
||||
@@ -80,32 +136,71 @@
|
||||
},
|
||||
"items": {
|
||||
"add": "Dodaj",
|
||||
"advanced": "Napredno",
|
||||
"archived": "Arhivirano",
|
||||
"asset_id": "ID sredstva",
|
||||
"attachment": "Priponka",
|
||||
"attachments": "Priponke",
|
||||
"changes_persisted_immediately": "Spremembe prilog bodo takoj shranjene",
|
||||
"created_at": "Ustvarjeno ob",
|
||||
"custom_fields": "Polje po meri",
|
||||
"description": "Opis",
|
||||
"details": "Podrobnosti",
|
||||
"drag_and_drop": "Tu povlecite in spustite datoteke ali kliknite, da izberete datoteke",
|
||||
"edit_details": "Uredi podrobnosti",
|
||||
"field_selector": "Izbirnik polj",
|
||||
"field_value": "Vrednost polja",
|
||||
"first": "Prvi",
|
||||
"include_archive": "Vključi arhivirane predmete",
|
||||
"insured": "Zavarovano",
|
||||
"last": "Zadnji",
|
||||
"lifetime_warranty": "Doživljenjska garancija",
|
||||
"location": "Lokacija",
|
||||
"manual": "Navodila",
|
||||
"manuals": "Navodila za uporabo",
|
||||
"manufacturer": "Proizvajalec",
|
||||
"model_number": "Številka modela",
|
||||
"name": "Naziv",
|
||||
"negate_labels": "Negiraj izbrane oznake",
|
||||
"next_page": "Naslednja stran",
|
||||
"no_results": "Ni najdenih predmetov",
|
||||
"notes": "Opombe",
|
||||
"options": "Možnosti",
|
||||
"order_by": "Razvrsti po",
|
||||
"pages": "Stran { page } od { totalPages }",
|
||||
"parent_item": "Matični produkt",
|
||||
"photo": "Fotografija",
|
||||
"photos": "Fotografije",
|
||||
"prev_page": "Prejšnja stran",
|
||||
"purchase_date": "Datum nabave",
|
||||
"purchase_details": "Podrobnosti nabave",
|
||||
"purchase_price": "Nakupna cena",
|
||||
"purchased_from": "Kupljeno pri",
|
||||
"quantity": "Količina",
|
||||
"query_id": "Poizvedovanje po identifikacijski številki sredstva: { id }",
|
||||
"receipt": "Račun",
|
||||
"receipts": "Računi",
|
||||
"reset_search": "Ponastavi iskanje",
|
||||
"results": "Rezultatov: { total }",
|
||||
"serial_number": "Serijska številka",
|
||||
"show_advanced_view_options": "Pokaži napredne možnosti",
|
||||
"sold_at": "Prodano pri",
|
||||
"sold_details": "Podrobnosti o prodaji",
|
||||
"sold_price": "Prodajna cena",
|
||||
"sold_to": "Prodano k",
|
||||
"tip_1": "Filtri lokacij in oznak uporabljajo operacijo 'ALI'. Če je izbranih več kot ena, bo izbrana samo ena\n potrebna za ujemanje.",
|
||||
"tip_2": "Iskanja s predpono '#' bodo iskala ID sredstva (primer '#000-001')",
|
||||
"tip_3": "Filtri polj uporabljajo operacijo 'ALI'. Če je izbranih več kot eno, bo za ujemanje dovolj samo\n eno.",
|
||||
"tips": "Nasveti",
|
||||
"tips_sub": "Nasveti za iskanje",
|
||||
"updated_at": "Posodobljeno ob"
|
||||
"updated_at": "Posodobljeno ob",
|
||||
"warranty": "Garancija",
|
||||
"warranty_details": "Podrobnosti o garanciji",
|
||||
"warranty_expires": "Garancija poteče"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Ni najdenih oznak"
|
||||
"no_results": "Ni najdenih oznak",
|
||||
"update_label": "Posodobitev oznake"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Katalonščina",
|
||||
@@ -115,20 +210,26 @@
|
||||
"fr": "Francoščina",
|
||||
"hu": "Madžarščina",
|
||||
"it": "Italijanščina",
|
||||
"ja-JP": "Japonščina",
|
||||
"nl": "Nizozemščina",
|
||||
"pl": "Polščina",
|
||||
"pt-BR": "Portugalščina (brazilska)",
|
||||
"pt-PT": "Portugalščina (Portugalska)",
|
||||
"ru": "Ruščina",
|
||||
"sl": "Slovenščina",
|
||||
"sv": "Švedščina",
|
||||
"tr": "Turkščina",
|
||||
"uk-UA": "Ukrajinščina",
|
||||
"zh-CN": "Kitajščina (splošna)",
|
||||
"zh-HK": "Kitajščina (Hong Kong)",
|
||||
"zh-MO": "Kitajščina (Macau)",
|
||||
"zh-TW": "Kitajsščina (tradicionalna)"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "Ni najdenih lokacij"
|
||||
"child_locations": "Podrejene lokacije",
|
||||
"collapse_tree": "Strni drevo",
|
||||
"no_results": "Ni najdenih lokacij",
|
||||
"update_location": "Posodobi lokacijo"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
@@ -166,6 +267,9 @@
|
||||
"total_entries": "Vseh predmetov"
|
||||
},
|
||||
"menu": {
|
||||
"create_item": "Predmet / Sredstvo",
|
||||
"create_label": "Oznaka",
|
||||
"create_location": "Lokacija",
|
||||
"home": "Domov",
|
||||
"locations": "Lokacije",
|
||||
"maintenance": "Vzdrževanje",
|
||||
@@ -182,6 +286,7 @@
|
||||
"delete_account_sub": "Izbrišite svoj račun in vse z njim povezane podatke. Tega ni mogoče razveljaviti.",
|
||||
"display_header": "{ currentValue, select, true {Skrij glavo} false {Pokaži glavo} other {Brez zadetkov}}",
|
||||
"enabled": "Omogočeno",
|
||||
"example": "Primer",
|
||||
"gen_invite": "Ustvari povezavo povabila",
|
||||
"group_settings": "Nastavitve skupine",
|
||||
"group_settings_sub": "Nastavitve skupine v skupni rabi. Morda boste morali osvežiti brskalnik, da bodo nekatere nastavitve veljale.",
|
||||
|
||||
@@ -1,128 +1,304 @@
|
||||
{
|
||||
"profile": {
|
||||
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Anmälare",
|
||||
"change_password": "Ändra Lösenord",
|
||||
"current_password": "Nuvarande lösenord",
|
||||
"new_password": "Nytt lösenord",
|
||||
"notifiers_sub": "Få aviseringar om kommande underhållspåminnelser",
|
||||
"url": "URL",
|
||||
"test": "Test",
|
||||
"gen_invite": "Skapa inbjudningslänk",
|
||||
"user_profile": "Användarprofil",
|
||||
"user_profile_sub": "Bjud in användare och hantera ditt konto.",
|
||||
"active": "Aktiv",
|
||||
"inactive": "Inaktiv",
|
||||
"notifiers": "Notiser",
|
||||
"enabled": "Aktiverad",
|
||||
"currency_format": "Valuta format",
|
||||
"delete_account": "Radera konto",
|
||||
"delete_account_sub": "Ta bort ditt konto och alla tillhörande data. Detta kan inte ångras.",
|
||||
"group_settings": "Grupp inställningar",
|
||||
"group_settings_sub": "Inställningar för delad grupp. Du kan behöva uppdatera din webbläsare för att vissa inställningar ska gälla.",
|
||||
"theme_settings": "Temainställningar",
|
||||
"theme_settings_sub": "Temainställningar sparas i din webbläsares lokala lagring. Du kan ändra tema när du vill. Om du\nhar problem att ställa in tema, pröva att ladda om din webbläsare.",
|
||||
"update_group": "Uppdatera grupp"
|
||||
},
|
||||
"index": {
|
||||
"set_name": "Vad heter du?",
|
||||
"joining_group": "Du går med i en befintlig grupp!",
|
||||
"dont_join_group": "Vill du inte gå med i en grupp?",
|
||||
"tagline": "Spåra, organisera och hantera dina saker.",
|
||||
"disabled_registration": "Registrering avaktiverad",
|
||||
"login": "Logga in",
|
||||
"register": "Registrera",
|
||||
"remember_me": "Kom ihåg mig",
|
||||
"set_email": "Vad är din e-post?",
|
||||
"set_password": "Ställ in ditt lösenord"
|
||||
},
|
||||
"components": {
|
||||
"app": {
|
||||
"import_dialog": {
|
||||
"upload": "Ladda upp",
|
||||
"title": "Importera CSV fil",
|
||||
"description": "Importera en CSV-fil som innehåller dina föremål, etiketter och platser. Se dokumentationen för mer information om \nönskat format.",
|
||||
"change_warning": "Beteendet för importer med befintliga import_refs har ändrats. Om en import_ref finns i CSV-filen, \nobjektet kommer att uppdateras med värdena i CSV-filen."
|
||||
"change_warning": "Beteendet för importer med befintliga import_refs har ändrats. Om en import_ref finns i CSV-filen, kommer\nobjektet att uppdateras med värdena i CSV-filen.",
|
||||
"description": "Importera en CSV-fil som innehåller dina föremål, etiketter och platser. Se dokumentationen för mer information om formatet som krävs.",
|
||||
"title": "Importera CSV-fil",
|
||||
"upload": "Ladda upp"
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"date_time": {
|
||||
"ago": "{0} sedan",
|
||||
"days": "dagar",
|
||||
"hour": "timme",
|
||||
"hours": "timmar",
|
||||
"in": "om {0}",
|
||||
"just-now": "nyss",
|
||||
"last-month": "förra månaden",
|
||||
"last-week": "förra veckan",
|
||||
"last-year": "förra året",
|
||||
"minute": "minut",
|
||||
"minutes": "minuter",
|
||||
"months": "månader",
|
||||
"next-month": "nästa månad",
|
||||
"next-week": "nästa vecka",
|
||||
"next-year": "nästa år",
|
||||
"second": "sekund",
|
||||
"seconds": "sekunder",
|
||||
"tomorrow": "imorgon",
|
||||
"week": "vecka",
|
||||
"weeks": "veckor",
|
||||
"years": "år",
|
||||
"yesterday": "igår"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "Sidans URL"
|
||||
},
|
||||
"password_score": {
|
||||
"password_strength": "Lösenordsstyrka"
|
||||
}
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"item_description": "Objektbeskrivning",
|
||||
"item_name": "Objektnamn",
|
||||
"photo_button": "Foto 📷",
|
||||
"title": "Skapa föremål"
|
||||
},
|
||||
"view": {
|
||||
"selectable": {
|
||||
"card": "Kort",
|
||||
"items": "Föremål",
|
||||
"table": "Tabell",
|
||||
"no_items": "Inga föremål att visa"
|
||||
"no_items": "Inga föremål att visa",
|
||||
"table": "Tabell"
|
||||
},
|
||||
"table": {
|
||||
"page": "Sida",
|
||||
"rows_per_page": "Rader per sida"
|
||||
}
|
||||
},
|
||||
"create_modal": {
|
||||
"title": "Skapa föremål",
|
||||
"photo_button": "Foto 📷"
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"label_description": "Etikettbeskrivning",
|
||||
"label_name": "Etikettnamm",
|
||||
"title": "Skapa etikett"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"location_description": "Platsbeskrivning",
|
||||
"location_name": "Platsnamn",
|
||||
"title": "Skapa plats"
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"password_score": {
|
||||
"password_strength": "Lösenordsstyrka"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "Sidans URL"
|
||||
"selector": {
|
||||
"parent_location": "Överordnad Plats"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Inga platser tillgängliga. Lägg till nya platser via\n `<`span class=\"link-primary\"`>`Skapa`<`/span`>`-knappen i navigationsmenyn."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"add": "Lägg till",
|
||||
"build": "Byggd: { build }",
|
||||
"github": "GitHub Projekt",
|
||||
"join_discord": "Gå med i Discord",
|
||||
"follow_dev": "Följ utvecklaren",
|
||||
"read_docs": "Läs dokumenten",
|
||||
"password": "Lösenord",
|
||||
"email": "Epost",
|
||||
"submit": "Skicka",
|
||||
"confirm": "Godkänn",
|
||||
"create": "Skapa",
|
||||
"create_and_add": "Skapa och lägg till en till",
|
||||
"created": "Skapad",
|
||||
"welcome": "Välkommen, { username }",
|
||||
"sign_out": "Logga ut",
|
||||
"create_and_add": "Skapa och lägg till en annan",
|
||||
"version": "Version: { version }",
|
||||
"delete": "Ta bort",
|
||||
"details": "Detaljer",
|
||||
"duplicate": "Duplicera",
|
||||
"edit": "Ändra",
|
||||
"email": "Epost",
|
||||
"follow_dev": "Följ utvecklaren",
|
||||
"github": "GitHub-projekt",
|
||||
"items": "Föremål",
|
||||
"join_discord": "Gå med i Discord",
|
||||
"labels": "Etiketter",
|
||||
"locations": "Platser",
|
||||
"maintenance": "Underhåll",
|
||||
"name": "Namn",
|
||||
"search": "Sök"
|
||||
"password": "Lösenord",
|
||||
"read_docs": "Läs dokumentationen",
|
||||
"save": "Spara",
|
||||
"search": "Sök",
|
||||
"sign_out": "Logga ut",
|
||||
"submit": "Skicka",
|
||||
"update": "Uppdatera",
|
||||
"value": "Värde",
|
||||
"version": "Version: { version }",
|
||||
"welcome": "Välkommen, { username }"
|
||||
},
|
||||
"home": {
|
||||
"labels": "Etiketter",
|
||||
"quick_statistics": "Snabb statistik",
|
||||
"recently_added": "Nyligen tillagda",
|
||||
"storage_locations": "Förvaringsplatser",
|
||||
"total_items": "Totalt antal objekt",
|
||||
"total_labels": "Totalt antal etiketter",
|
||||
"total_locations": "Totalt antal platser",
|
||||
"total_value": "Totalt Värde"
|
||||
},
|
||||
"index": {
|
||||
"disabled_registration": "Registrering avaktiverad",
|
||||
"dont_join_group": "Vill du inte gå med i en grupp?",
|
||||
"joining_group": "Du går med i en befintlig grupp!",
|
||||
"login": "Logga in",
|
||||
"register": "Registrera",
|
||||
"remember_me": "Kom ihåg mig",
|
||||
"set_email": "Vad är din e-post?",
|
||||
"set_name": "Vad heter du?",
|
||||
"set_password": "Ställ in ditt lösenord",
|
||||
"tagline": "Spåra, organisera och hantera dina saker."
|
||||
},
|
||||
"items": {
|
||||
"add": "Lägg till",
|
||||
"advanced": "Avancerat",
|
||||
"archived": "Arkiverad",
|
||||
"attachment": "Bilaga",
|
||||
"attachments": "Bilagor",
|
||||
"changes_persisted_immediately": "Ändringar av bilagor sparas omedelbart",
|
||||
"created_at": "Skapat",
|
||||
"custom_fields": "Egna fält",
|
||||
"description": "Beskrivning",
|
||||
"details": "Detaljer",
|
||||
"drag_and_drop": "Dra och släpp här eller klicka för att välja filer",
|
||||
"edit_details": "Ändra detaljer",
|
||||
"field_selector": "Fält alternativ",
|
||||
"field_value": "Fält värde",
|
||||
"first": "Första",
|
||||
"include_archive": "Inkludera arkiverade föremål",
|
||||
"insured": "Försäkrad",
|
||||
"last": "Sista",
|
||||
"lifetime_warranty": "Livstidsgaranti",
|
||||
"location": "Plats",
|
||||
"manual": "Manual",
|
||||
"manuals": "Manualer",
|
||||
"manufacturer": "Tillverkare",
|
||||
"model_number": "Modellnummer",
|
||||
"name": "Namn",
|
||||
"negate_labels": "Negera valda etiketter",
|
||||
"next_page": "Nästa sida",
|
||||
"no_results": "Inga föremål hittades",
|
||||
"notes": "Anteckningar",
|
||||
"options": "Alternativ",
|
||||
"order_by": "Ordning via",
|
||||
"pages": "Sida { page } av { totalPages }",
|
||||
"parent_item": "Överordnat objekt",
|
||||
"photo": "Foto",
|
||||
"photos": "Foton",
|
||||
"prev_page": "Föregående sida",
|
||||
"purchase_date": "Inköpsdatum",
|
||||
"purchase_details": "Inköpsdetaljer",
|
||||
"purchase_price": "Inköpspris",
|
||||
"purchased_from": "Köpt från",
|
||||
"quantity": "Antal",
|
||||
"query_id": "Fråga efter tillgångs-ID-nummer: { id }",
|
||||
"receipt": "Kvitto",
|
||||
"receipts": "Kvitton",
|
||||
"reset_search": "Återställ sökning",
|
||||
"results": "{ total } Resultat",
|
||||
"serial_number": "Serienummer",
|
||||
"show_advanced_view_options": "Visa avancerade vyalternativ",
|
||||
"sold_details": "Försäljningsdetaljer",
|
||||
"sold_price": "Försäljningspris",
|
||||
"sold_to": "Såld till",
|
||||
"tip_1": "Platser och etiketter filter använder 'OR' funktionen. Om fler än en är valda, endast en kommer\nkrävas för en träff.",
|
||||
"tip_2": "Sökningar med prefixet '#'' kommer att fråga efter ett tillgångs-ID (exempel '#000-001')",
|
||||
"tip_3": "Fältfilter använder 'OR' funktion. Om fler än en är valda endast en kommer att bli krävande för en\nträff.",
|
||||
"tips": "Tips",
|
||||
"tips_sub": "Sök Tips",
|
||||
"updated_at": "Uppdaterad",
|
||||
"results": "{ total } Resultat"
|
||||
"warranty": "Garanti",
|
||||
"warranty_details": "Garantidetaljer",
|
||||
"warranty_expires": "Garantin upphör"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Inga etiketter hittades",
|
||||
"update_label": "Uppdatera etikett"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Katalanska",
|
||||
"de": "Tyska",
|
||||
"en": "Engelska",
|
||||
"es": "Spanska",
|
||||
"fr": "Franska",
|
||||
"hu": "Ungerska",
|
||||
"it": "Italienska",
|
||||
"ja-JP": "Japanska",
|
||||
"nl": "Nederländska",
|
||||
"pl": "Polska",
|
||||
"pt-BR": "Portugisiska (Brasilien)",
|
||||
"pt-PT": "Portugisiska",
|
||||
"ru": "Ryska",
|
||||
"sl": "Slovenska",
|
||||
"sv": "Svenska",
|
||||
"tr": "Turkiska",
|
||||
"uk-UA": "Ukrainska",
|
||||
"zh-CN": "Kinesiska (förenklad)",
|
||||
"zh-HK": "kinesiska (Hongkong)",
|
||||
"zh-MO": "Kinesiska (Macao)",
|
||||
"zh-TW": "Kinesiska (traditionell)"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "Inga platser hittades",
|
||||
"update_location": "Uppdatera plats"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
"both": "Båda",
|
||||
"completed": "Klar",
|
||||
"scheduled": "Schemalagd"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Färdig",
|
||||
"create_first": "Skapa din första post",
|
||||
"delete": "Radera",
|
||||
"duplicate": "Duplicera",
|
||||
"edit": "Redigera",
|
||||
"new": "Ny"
|
||||
},
|
||||
"modal": {
|
||||
"completed_date": "Slutförd datum",
|
||||
"cost": "Kostnad",
|
||||
"delete_confirmation": "Är du säker på att du vill radera denna post?",
|
||||
"edit_action": "Uppdatera",
|
||||
"edit_title": "Redigera",
|
||||
"new_action": "Skapa",
|
||||
"notes": "Anteckningar",
|
||||
"scheduled_date": "Schemalagt datum"
|
||||
},
|
||||
"monthly_average": "Månatligt medelvärde",
|
||||
"total_cost": "Total kostnad"
|
||||
},
|
||||
"menu": {
|
||||
"create_label": "Etikett",
|
||||
"create_location": "Plats",
|
||||
"home": "Hem",
|
||||
"locations": "Platser",
|
||||
"maintenance": "Underhåll",
|
||||
"profile": "Profil",
|
||||
"search": "Sök",
|
||||
"tools": "Verktyg"
|
||||
},
|
||||
"profile": {
|
||||
"active": "Aktiv",
|
||||
"change_password": "Ändra Lösenord",
|
||||
"currency_format": "Valuta format",
|
||||
"current_password": "Nuvarande lösenord",
|
||||
"delete_account": "Radera konto",
|
||||
"delete_account_sub": "Ta bort ditt konto och alla tillhörande data. Detta kan inte ångras.",
|
||||
"enabled": "Aktiverad",
|
||||
"example": "Exempel",
|
||||
"gen_invite": "Skapa inbjudningslänk",
|
||||
"group_settings": "Grupp inställningar",
|
||||
"group_settings_sub": "Inställningar för delad grupp. Du kan behöva uppdatera din webbläsare för att vissa inställningar ska gälla.",
|
||||
"inactive": "Inaktiv",
|
||||
"language": "Språk",
|
||||
"new_password": "Nytt lösenord",
|
||||
"no_notifiers": "Inga notifierare konfigurerade",
|
||||
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Anmälare",
|
||||
"notifiers": "Notiser",
|
||||
"notifiers_sub": "Få aviseringar om kommande underhållspåminnelser",
|
||||
"test": "Test",
|
||||
"theme_settings": "Temainställningar",
|
||||
"theme_settings_sub": "Temainställningar sparas i din webbläsares lokala lagring. Du kan ändra tema när du vill. Om du\nhar problem att ställa in tema, pröva att ladda om din webbläsare.",
|
||||
"update_group": "Uppdatera grupp",
|
||||
"update_language": "Uppdatera språk",
|
||||
"url": "URL",
|
||||
"user_profile": "Användarprofil",
|
||||
"user_profile_sub": "Bjud in användare och hantera ditt konto."
|
||||
},
|
||||
"tools": {
|
||||
"actions_sub": "Utför åtgärder på dina objekt i bulk. Dessa är oåterkalleliga. '<b>'Var försiktig.'</b>'",
|
||||
"import_export": "Import/Export",
|
||||
"reports": "Rapporter",
|
||||
"reports_set": {
|
||||
"bill_of_materials": "Materialförteckning",
|
||||
"bill_of_materials_button": "Skapa materialförteckning"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,128 +1,347 @@
|
||||
{
|
||||
"global": {
|
||||
"version": "Versiyon:{ version }",
|
||||
"password": "Şifre",
|
||||
"create": "Oluştur",
|
||||
"github": "GitHub projesi",
|
||||
"join_discord": "Discord'a Katılın",
|
||||
"follow_dev": "Geliştiriciyi takip edin",
|
||||
"read_docs": "Dokümanları okuyun",
|
||||
"email": "Elektronik posta",
|
||||
"submit": "Gönder",
|
||||
"confirm": "Onaylayın",
|
||||
"build": "Sürüm: { build }",
|
||||
"create_and_add": "Oluştur ve Bir Tane Daha Ekle",
|
||||
"created": "Oluşturuldu",
|
||||
"items": "Öğeler",
|
||||
"labels": "Etiketler",
|
||||
"locations": "Konumlar",
|
||||
"name": "İsim",
|
||||
"search": "Ara",
|
||||
"sign_out": "Oturumu kapat",
|
||||
"welcome": "Hoşgeldib, { username }"
|
||||
},
|
||||
"components": {
|
||||
"app": {
|
||||
"import_dialog": {
|
||||
"change_warning": "Mevcut import_refs ile içe aktarmaların davranışı değişti. CSV dosyasında bir import_ref varsa, \nöğe CSV dosyasındaki değerlerle güncellenecektir.",
|
||||
"description": "Öğelerinizi, etiketlerinizi ve konumlarınızı içeren bir CSV dosyasını içe aktarın. Daha fazla\nbilgi için dökümanları okuyun.",
|
||||
"title": "CSV dosyasını içeri aktar",
|
||||
"upload": "Yükle",
|
||||
"description": "Öğelerinizi, etiketlerinizi ve konumlarınızı içeren bir CSV dosyasını içe aktarın. Daha fazla\nbilgi için dökümanları okuyun."
|
||||
"upload": "Yükle"
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"password_score": {
|
||||
"password_strength": "Şifre güvenlik seviyesi"
|
||||
"date_time": {
|
||||
"ago": "{0} önce",
|
||||
"days": "gün",
|
||||
"hour": "saat",
|
||||
"hours": "saat",
|
||||
"in": "{0} içinde",
|
||||
"just-now": "az önce",
|
||||
"last-month": "geçen ay",
|
||||
"last-week": "geçen hafta",
|
||||
"last-year": "geçen yıl",
|
||||
"minute": "dakika",
|
||||
"minutes": "dakika",
|
||||
"months": "ay",
|
||||
"next-month": "gelecek ay",
|
||||
"next-week": "gelecek hafta",
|
||||
"next-year": "gelecek yıl",
|
||||
"second": "saniye",
|
||||
"seconds": "saniye",
|
||||
"tomorrow": "yarın",
|
||||
"week": "hafta",
|
||||
"weeks": "hafta",
|
||||
"years": "yıl",
|
||||
"yesterday": "dün"
|
||||
},
|
||||
"page_qr_code": {
|
||||
"page_url": "Sayfa URL'si"
|
||||
},
|
||||
"password_score": {
|
||||
"password_strength": "Şifre güvenlik seviyesi"
|
||||
}
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"title": "Eşya Oluştur",
|
||||
"photo_button": "Fotoğraf 📷"
|
||||
"item_description": "Ürün Açıklaması",
|
||||
"item_name": "Ürün Adı",
|
||||
"photo_button": "Fotoğraf 📷",
|
||||
"title": "Eşya Oluştur"
|
||||
},
|
||||
"view": {
|
||||
"selectable": {
|
||||
"items": "Öğeler",
|
||||
"card": "Kart",
|
||||
"table": "Tablo",
|
||||
"no_items": "Görüntülecek Öge Yok"
|
||||
"items": "Öğeler",
|
||||
"no_items": "Görüntülecek Öge Yok",
|
||||
"table": "Tablo"
|
||||
},
|
||||
"table": {
|
||||
"page": "Sayfa",
|
||||
"rows_per_page": "Sayfa başına satır sayısı"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"label_description": "Etiket Açıklaması",
|
||||
"label_name": "Etiket Adı",
|
||||
"title": "Etiket oluştur"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"location_description": "Konum Açıklaması",
|
||||
"location_name": "Konum Adı",
|
||||
"title": "Konum oluştur"
|
||||
},
|
||||
"selector": {
|
||||
"parent_location": "Üst Konum"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Mevcut konum yok. Navigasyon çubuğundaki \n`<`span class=\"link-primary\"`>`Oluştur`<`/span`>` düğmesiyle yeni konumlar ekleyin."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"add": "Ekle",
|
||||
"build": "Sürüm: { build }",
|
||||
"confirm": "Onaylayın",
|
||||
"create": "Oluştur",
|
||||
"create_and_add": "Oluştur ve Bir Tane Daha Ekle",
|
||||
"created": "Oluşturuldu",
|
||||
"delete": "Sil",
|
||||
"details": "Detaylar",
|
||||
"duplicate": "Kopyala",
|
||||
"edit": "Düzenle",
|
||||
"email": "Elektronik posta",
|
||||
"follow_dev": "Geliştiriciyi takip edin",
|
||||
"github": "GitHub projesi",
|
||||
"items": "Öğeler",
|
||||
"join_discord": "Discord'a Katılın",
|
||||
"labels": "Etiketler",
|
||||
"locations": "Konumlar",
|
||||
"maintenance": "Bakım",
|
||||
"name": "İsim",
|
||||
"password": "Şifre",
|
||||
"read_docs": "Dokümanları okuyun",
|
||||
"save": "Kaydet",
|
||||
"search": "Ara",
|
||||
"sign_out": "Oturumu kapat",
|
||||
"submit": "Gönder",
|
||||
"update": "Güncelle",
|
||||
"value": "Değer",
|
||||
"version": "Versiyon:{ version }",
|
||||
"welcome": "Hoşgeldin, { username }"
|
||||
},
|
||||
"home": {
|
||||
"labels": "Etiket",
|
||||
"quick_statistics": "Hızlı İstatistikler",
|
||||
"recently_added": "Yakında Eklendi",
|
||||
"storage_locations": "Saklama Konumları",
|
||||
"total_items": "Toplam Ürün",
|
||||
"total_labels": "Toplam Etiket",
|
||||
"total_locations": "Toplam Konum",
|
||||
"total_value": "Toplam Değer"
|
||||
},
|
||||
"index": {
|
||||
"remember_me": "Beni Hatırla",
|
||||
"tagline": "Eşyalarınızı Takip Edin, Düzenleyin ve Yönetin.",
|
||||
"disabled_registration": "Kayıt olma devre dışı",
|
||||
"dont_join_group": "Bir gruba katılmak istemiyor musunuz?",
|
||||
"joining_group": "Mevcut bir gruba katılıyorsunuz!",
|
||||
"login": "Oturum Aç",
|
||||
"register": "Kaydolun",
|
||||
"remember_me": "Beni Hatırla",
|
||||
"set_email": "E-posta adresiniz nedir?",
|
||||
"set_password": "Şifrenizi belirleyin",
|
||||
"set_name": "Adın ne?",
|
||||
"joining_group": "Mevcut bir gruba katılıyorsunuz!",
|
||||
"dont_join_group": "Bir gruba katılmak istemiyor musunuz?"
|
||||
"set_password": "Şifrenizi belirleyin",
|
||||
"tagline": "Eşyalarınızı Takip Edin, Düzenleyin ve Yönetin."
|
||||
},
|
||||
"items": {
|
||||
"add": "Ekle",
|
||||
"advanced": "İleri Seviye",
|
||||
"archived": "Arşivlendi",
|
||||
"asset_id": "Öğe Kimliği",
|
||||
"attachment": "Ek",
|
||||
"attachments": "Ekler",
|
||||
"changes_persisted_immediately": "Eklerde yapılan değişiklikler hemen kaydedilecektir",
|
||||
"created_at": "Oluşturulma",
|
||||
"custom_fields": "Özel Alanlar",
|
||||
"description": "Açıklama",
|
||||
"details": "Detaylar",
|
||||
"drag_and_drop": "Dosyaları buraya sürükleyip bırakın veya dosyaları seçmek için tıklayın",
|
||||
"edit_details": "Detayları Düzenle",
|
||||
"field_selector": "alan seçici",
|
||||
"field_value": "Alan Değeri",
|
||||
"first": "Birinci",
|
||||
"include_archive": "Arşivlenen Öğeleri Dahil Et",
|
||||
"insured": "Sigortalı",
|
||||
"last": "Son",
|
||||
"lifetime_warranty": "Ömür Boyu Garanti",
|
||||
"location": "Konum",
|
||||
"manual": "Kılavuz",
|
||||
"manuals": "Kullanım Kılavuzları",
|
||||
"manufacturer": "Üretici",
|
||||
"model_number": "Model Numarası",
|
||||
"name": "İsim",
|
||||
"negate_labels": "Seçili Etiketleri Yoksay",
|
||||
"next_page": "Sonraki Sayfa",
|
||||
"no_results": "Öğe Bulunamadı",
|
||||
"notes": "Notlar",
|
||||
"options": "Seçenekler",
|
||||
"order_by": "Sıralama ölçütü",
|
||||
"pages": "Sayfa { page }/{ totalPages }",
|
||||
"parent_item": "Ana Öğe",
|
||||
"photo": "Fotoğraf",
|
||||
"photos": "Fotoğraflar",
|
||||
"prev_page": "Önceki Sayfa",
|
||||
"purchase_date": "Satın Alma Tarihi",
|
||||
"purchase_details": "Satın Alma Detayları",
|
||||
"purchase_price": "Satınalma Fiyatı",
|
||||
"purchased_from": "Satın Alındığı Yer",
|
||||
"quantity": "Miktar",
|
||||
"query_id": "Varlık Kimlik Numarası Sorgulanıyor: { id }",
|
||||
"tip_1": "Konum ve etiket filtreleri 'veya' işlemini kullanır. Eğer birden fazla seçilirse sadece biri \neşleştirme için kullanılacaktır.",
|
||||
"receipt": "Fatura",
|
||||
"receipts": "Faturalar",
|
||||
"reset_search": "Aramayı Sıfırla",
|
||||
"tips": "İpuçları",
|
||||
"results": "{ total } Sonuç",
|
||||
"serial_number": "Seri Numarası",
|
||||
"show_advanced_view_options": "Gelişmiş Seçenekleri Göster",
|
||||
"sold_at": "Satıldığı Yer",
|
||||
"sold_details": "Satış Detayları",
|
||||
"sold_price": "Satış Fiyatı",
|
||||
"sold_to": "Satılan Kişi",
|
||||
"tip_1": "Konum ve etiket filtreleri 'veya' işlemini kullanır. Eğer birden fazla seçilirse sadece biri \neşleştirme için kullanılacaktır.",
|
||||
"tip_2": "'#' ile başlayan aramalar bir varlık kimliğini sorgular (örneğin '#000-001')",
|
||||
"tip_3": "Alan filtreleri 'VEYA' işlemini kullanır. Birden fazla seçenek seçilirse, eşleşme için yalnızca birinin \nkarşılanması yeterlidir.",
|
||||
"tips": "İpuçları",
|
||||
"tips_sub": "Arama İpuçları",
|
||||
"updated_at": "Güncellendiği Zaman"
|
||||
"updated_at": "Güncellendiği Zaman",
|
||||
"warranty": "Garanti",
|
||||
"warranty_details": "Garanti Bilgileri",
|
||||
"warranty_expires": "Garanti Bitiş Tarihi"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Etiket Bulunamadı",
|
||||
"update_label": "Etiket Güncelle"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Katalanca",
|
||||
"de": "Almanca",
|
||||
"en": "İngilizce",
|
||||
"es": "İspanyolca",
|
||||
"fr": "Fransızca",
|
||||
"hu": "Macarca",
|
||||
"it": "İtalyanca",
|
||||
"ja-JP": "Japonca",
|
||||
"nl": "Hollandaca",
|
||||
"pl": "Lehçe",
|
||||
"pt-BR": "Brezilya Portekizcesi",
|
||||
"pt-PT": "Portekizce (Portekiz)",
|
||||
"ru": "Rusça",
|
||||
"sl": "Slovence",
|
||||
"sv": "İsveççe",
|
||||
"tr": "Türkçe",
|
||||
"uk-UA": "Ukraynaca",
|
||||
"zh-CN": "Basitleştirilmiş Çince",
|
||||
"zh-HK": "Çince (Hong Kong)",
|
||||
"zh-MO": "Çince (Macau)",
|
||||
"zh-TW": "Geleneksel Çince"
|
||||
},
|
||||
"locations": {
|
||||
"child_locations": "Alt konumlar",
|
||||
"collapse_tree": "Ağacı Daralt",
|
||||
"no_results": "Konum bulunamadı",
|
||||
"update_location": "Konumu Güncelle"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
"both": "İkisi de",
|
||||
"completed": "Tamamlandı",
|
||||
"scheduled": "Planlanmış"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Tamamla",
|
||||
"create_first": "İlk Kaydınızı Oluşturun",
|
||||
"delete": "Sil",
|
||||
"duplicate": "Kopyala",
|
||||
"edit": "Düzenle",
|
||||
"new": "Yeni"
|
||||
},
|
||||
"modal": {
|
||||
"completed_date": "Tamamlanma Tarihi",
|
||||
"cost": "Maliyet",
|
||||
"delete_confirmation": "Bu kaydı silmek istediğinizden emin misiniz?",
|
||||
"edit_action": "Güncelle",
|
||||
"edit_title": "Kaydı Düzenle",
|
||||
"entry_name": "Kayıt Adı",
|
||||
"new_action": "Oluştur",
|
||||
"new_title": "Yeni Kayıt",
|
||||
"notes": "Notlar",
|
||||
"scheduled_date": "Planlanan Tarih"
|
||||
},
|
||||
"monthly_average": "Aylık Ortalama",
|
||||
"toast": {
|
||||
"failed_to_create": "Kayıt oluşturulamadı",
|
||||
"failed_to_delete": "Kayıt silinemedi",
|
||||
"failed_to_update": "Kayıt güncellenemedi"
|
||||
},
|
||||
"total_cost": "Toplam Maliyet",
|
||||
"total_entries": "Toplam Kayıt"
|
||||
},
|
||||
"menu": {
|
||||
"create_item": "Öğe / Varlık",
|
||||
"create_label": "Etiket",
|
||||
"create_location": "Konum",
|
||||
"home": "Ev",
|
||||
"locations": "Konumlar",
|
||||
"maintenance": "Bakım",
|
||||
"profile": "Profil",
|
||||
"search": "Ara",
|
||||
"tools": "Araçlar"
|
||||
},
|
||||
"profile": {
|
||||
"url": "URL",
|
||||
"user_profile": "Kullanıcı Profili",
|
||||
"user_profile_sub": "Kullanıcıları davet edin ve hesabınızı yönetin.",
|
||||
"active": "Aktif",
|
||||
"change_password": "Şifre Değiştir",
|
||||
"currency_format": "Para Birimi Biçimi",
|
||||
"current_password": "Mevcut Şifre",
|
||||
"delete_account": "Hesabı Sil",
|
||||
"delete_account_sub": "Hesabınızı ve ona bağlı tüm verileri silin. Bu işlem geri alınamaz.",
|
||||
"display_header": "{ currentValue, select, true {Başlığı Gizle} false {Başlığı Göster} other {Etkilenmedi}}",
|
||||
"enabled": "Etkinleştirildi",
|
||||
"example": "Örnek",
|
||||
"gen_invite": "Davet Bağlantısı Oluştur",
|
||||
"group_settings": "Grup Ayarları",
|
||||
"group_settings_sub": "Paylaşılan Grup Ayarları. Bazı ayarların uygulanabilmesi için tarayıcınızı yenilemeniz gerekebilir.",
|
||||
"inactive": "Etkin Değil",
|
||||
"language": "Dil",
|
||||
"new_password": "Yeni Şifre",
|
||||
"no_notifiers": "Yapılandırılmış bildirimci yok",
|
||||
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Bildirici",
|
||||
"notifiers": "Bildirimde Bulunanlar",
|
||||
"notifiers_sub": "Yaklaşan bakım hatırlatmaları için bildirimler alın",
|
||||
"test": "Test",
|
||||
"theme_settings": "Tema Ayarları",
|
||||
"theme_settings_sub": "Tema ayarları tarayıcınızın yerel depolama alanında saklanır. Temayı istediğiniz zaman değiştirebilirsiniz. \nTemanızı ayarlamakta sorun yaşıyorsanız, tarayıcınızı yenilemeyi deneyin.",
|
||||
"update_group": "Grubu Güncelle",
|
||||
"notifiers_sub": "Yaklaşan bakım hatırlatmaları için bildirimler alın"
|
||||
"update_language": "Dili Güncelle",
|
||||
"url": "URL",
|
||||
"user_profile": "Kullanıcı Profili",
|
||||
"user_profile_sub": "Kullanıcıları davet edin ve hesabınızı yönetin."
|
||||
},
|
||||
"tools": {
|
||||
"actions": "Envanter İşlemleri",
|
||||
"actions_set": {
|
||||
"ensure_ids": "Varlık Kimliklerini Sağlayın",
|
||||
"ensure_ids_button": "Varlık Kimliklerini Sağlayın",
|
||||
"ensure_ids_sub": "Envanterinizdeki tüm öğelerin geçerli bir asset_id alanına sahip olmasını sağlar. Bu, veritabanındaki en yüksek mevcut asset_id alanını bulup, ayarlanmamış asset_id alanına sahip her öğeye bir sonraki değeri uygulayarak yapılır. Bu işlem, created_at alanına göre sıralanarak gerçekleştirilir.",
|
||||
"ensure_import_refs": "İçe Aktarma Referanslarını Sağlayın",
|
||||
"ensure_import_refs_button": "İçe Aktarma Referanslarını Sağlayın",
|
||||
"ensure_import_refs_sub": "Envanterinizdeki tüm öğelerin geçerli bir import_ref alanına sahip olmasını sağlar. Bu, ayarlanmamış import_ref alanına sahip her öğe için rastgele 8 karakterli bir dize oluşturarak yapılır.",
|
||||
"set_primary_photo": "Ana Fotoğrafı Ayarla",
|
||||
"set_primary_photo_button": "Ana Fotoğrafı Ayarla",
|
||||
"set_primary_photo_sub": "Homebox'un v0.10.0 sürümünde, fotoğraf türündeki ekler için birincil görüntü alanı eklendi. Bu işlem, veritabanındaki ekler dizisindeki ilk görüntüyü, eğer zaten ayarlanmamışsa, birincil görüntü alanı olarak ayarlayacaktır. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/pull/576\">'GitHub #576'yı Gör'</a>",
|
||||
"zero_datetimes": "Sıfır Öğesi Tarih Saatleri",
|
||||
"zero_datetimes_button": "Sıfır Öğe Tarih Saatleri",
|
||||
"zero_datetimes_sub": "Tarih saat alanlarındaki tüm zaman değerlerini en baştaki tarihe sıfırlar. Bu, sitenin geliştirilmesi sırasında erken aşamalarda ortaya çıkan ve zaman değerinin saklanmasına neden olan bir hatayı düzeltmek içindir; bu da tarih alanlarının doğru değerler göstermesinde sorunlara yol açıyordu. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/issues/236\" target=\"_blank\">'Daha fazla bilgi için Github Sorunu #236'ya Bakın.'</a>'"
|
||||
},
|
||||
"actions_sub": "Envanterinize toplu olarak işlemler uygulayın. Bu işlemler geri alınamaz. '<b>'Dikkatli olun.'</b>",
|
||||
"import_export": "İçe Aktar/Dışa Aktar",
|
||||
"import_export_set": {
|
||||
"export": "Envanteri Dışa Aktar",
|
||||
"export_button": "Envanteri Dışa Aktar",
|
||||
"export_sub": "Homebox için standart CSV formatını dışa aktarır. Bu, envanterinizdeki tüm öğeleri dışa aktaracaktır.",
|
||||
"import": "Envanteri İçe Aktar",
|
||||
"import_button": "Envanteri İçe Aktar",
|
||||
"import_sub": "Homebox için standart CSV formatını içe aktarır. '<code>'HB.import_ref'</code>' sütunu olmadan, bu mevcut envanterinizdeki herhangi bir öğeyi '<b>'üzerine yazmaz'</b>', yalnızca yeni öğeler ekler. '<code>'HB.import_ref'</code>' sütununa sahip satırlar, varsa aynı import_ref'e sahip mevcut öğelerle birleştirilir."
|
||||
},
|
||||
"import_export_sub": "Envanterinizi bir CSV dosyasına içe ve dışa aktarın. Bu, envanterinizi yeni bir Homebox örneğine taşımak için faydalıdır.",
|
||||
"reports": "Raporlar",
|
||||
"reports_set": {
|
||||
"asset_labels": "Varlık Kimlik Etiketleri",
|
||||
"asset_labels_button": "Etiket Oluşturucu",
|
||||
"asset_labels_sub": "Bir dizi Varlık Kimliği için yazdırılabilir bir PDF etiketleri oluşturur. Bu etiketler envanterinize özgü değildir, bu nedenle etiketleri önceden yazdırabilir ve onları aldığınızda envanterinize uygulayabilirsiniz.",
|
||||
"bill_of_materials": "Malzeme Listesi",
|
||||
"bill_of_materials_button": "Malzeme Listesi Oluştur",
|
||||
"bill_of_materials_sub": "Bir elektronik tablo programına içe aktarılabilen bir CSV (Virgülle Ayrılmış Değerler) dosyası oluşturur. Bu, envanterinizin temel öğe ve fiyat bilgileriyle birlikte bir özetidir."
|
||||
},
|
||||
"reports_sub": "Envanteriniz için farklı raporlar oluşturun."
|
||||
}
|
||||
}
|
||||
|
||||
242
frontend/locales/uk-UA.json
Normal file
242
frontend/locales/uk-UA.json
Normal file
@@ -0,0 +1,242 @@
|
||||
{
|
||||
"components": {
|
||||
"app": {
|
||||
"import_dialog": {
|
||||
"change_warning": "Поведінка для імпорту з існуючим параметром import_refs змінилася. Якщо цей параметр присутній у CSV файлі, \nпредмет буде оновлений значеннями з CSV.",
|
||||
"description": "Імпортувати CSV файл з предметами, мітками і локаціями. Зверніться до документації за\nдодатковою інформацією по формату.",
|
||||
"title": "Імпортувати .CSV",
|
||||
"upload": "Завантажити"
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"page_qr_code": {
|
||||
"page_url": "URL сторінки"
|
||||
},
|
||||
"password_score": {
|
||||
"password_strength": "Міцність паролю"
|
||||
}
|
||||
},
|
||||
"item": {
|
||||
"create_modal": {
|
||||
"photo_button": "Фото📷",
|
||||
"title": "Додати предмет"
|
||||
},
|
||||
"view": {
|
||||
"selectable": {
|
||||
"card": "Картка",
|
||||
"items": "Предмети",
|
||||
"no_items": "Предмети відсутні",
|
||||
"table": "Таблиця"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"create_modal": {
|
||||
"title": "Створити наліпку"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"create_modal": {
|
||||
"title": "Створити локацію"
|
||||
},
|
||||
"tree": {
|
||||
"no_locations": "Локації відсутні. Додайте нову за допомогою \n<`span class=\"link-primary\"`>`Створити`<`/span`>` клавіші ліворуч."
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"build": "Зібрати: { build }",
|
||||
"confirm": "Зберегти",
|
||||
"create": "Створити",
|
||||
"create_and_add": "Створити і додати ще один",
|
||||
"created": "Створено",
|
||||
"email": "Email",
|
||||
"follow_dev": "Підписатись на розробника",
|
||||
"github": "GitHub проекту",
|
||||
"items": "Предмети",
|
||||
"join_discord": "Доєднатися до Discord",
|
||||
"labels": "Наліпки",
|
||||
"locations": "Локації",
|
||||
"name": "Ім'я",
|
||||
"password": "Пароль",
|
||||
"read_docs": "Переглянути документацію",
|
||||
"search": "Пошук",
|
||||
"sign_out": "Вийти",
|
||||
"submit": "Підтвердити",
|
||||
"version": "Версія: { version }",
|
||||
"welcome": "Вітаю, { username }"
|
||||
},
|
||||
"index": {
|
||||
"disabled_registration": "Реєстрація недоступна",
|
||||
"dont_join_group": "Не хочете доєднуватись до групи?",
|
||||
"joining_group": "Ви доєднуєтесь до існуючої групи!",
|
||||
"login": "Логін",
|
||||
"register": "Реєстрація",
|
||||
"remember_me": "Запам'ятати мене",
|
||||
"set_email": "Який ваш e-mail?",
|
||||
"set_name": "Як вас звуть?",
|
||||
"set_password": "Оберіть пароль",
|
||||
"tagline": "Слідкуйте, організуйте і керуйте своїми предметами."
|
||||
},
|
||||
"items": {
|
||||
"add": "Додати",
|
||||
"created_at": "Створено о",
|
||||
"custom_fields": "Власні поля",
|
||||
"field_selector": "Обрати поле",
|
||||
"field_value": "Значення поля",
|
||||
"first": "Перший",
|
||||
"include_archive": "Включити заархівовані предмети",
|
||||
"last": "Останній",
|
||||
"negate_labels": "Відмінити обрані мітки",
|
||||
"next_page": "Наступна сторінка",
|
||||
"no_results": "Предметів нема",
|
||||
"options": "Налаштування",
|
||||
"order_by": "Відсортувати за",
|
||||
"pages": "Сторінка { page } з { totalPages }",
|
||||
"prev_page": "Попередня сторінка",
|
||||
"query_id": "Шукаю за ID предмета: { id }",
|
||||
"reset_search": "Скинути пошук",
|
||||
"results": "{ total } Результатів",
|
||||
"tip_1": "Фільтри по локації і міткам використовують операцію \"АБО\". Якщо більше одного обрано, тільки один\nз них має співпасти для виводу результату.",
|
||||
"tip_2": "Пошуки, що починаються з \"#\" будуть шукати за ID предмета (наприклад, \"#000-001\")",
|
||||
"tip_3": "Пошук в полях використовує операцію \"АБО\". Якщо більше одного задіяно, достатньо буде \nспівпасти лише одному для виводу результату.",
|
||||
"tips": "Підказки",
|
||||
"tips_sub": "Підказки щодо пошуку",
|
||||
"updated_at": "Оновлено"
|
||||
},
|
||||
"labels": {
|
||||
"no_results": "Мітки не знайдено"
|
||||
},
|
||||
"languages": {
|
||||
"ca": "Каталонська",
|
||||
"de": "Німецька",
|
||||
"en": "Англійська",
|
||||
"es": "Іспанська",
|
||||
"fr": "Французька",
|
||||
"hu": "Угорська",
|
||||
"it": "Італійська",
|
||||
"nl": "Голландський",
|
||||
"pl": "Польська мова",
|
||||
"pt-BR": "Португальська (Бразилія)",
|
||||
"ru": "Російська",
|
||||
"sl": "Словенська",
|
||||
"sv": "Swedish",
|
||||
"tr": "турецька",
|
||||
"zh-CN": "Китайська (спрощена)",
|
||||
"zh-HK": "Китайська (Гонконг)",
|
||||
"zh-MO": "Китайська (Макао)",
|
||||
"zh-TW": "Китайська (традиційне письмо)"
|
||||
},
|
||||
"locations": {
|
||||
"no_results": "Локації відсутні"
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
"both": "Обидва",
|
||||
"completed": "Виконано",
|
||||
"scheduled": "Заплановано"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Завершені",
|
||||
"create_first": "Створіть свій перший запис",
|
||||
"delete": "Видалити",
|
||||
"duplicate": "Дублювати",
|
||||
"edit": "Редагувати",
|
||||
"new": "Новий"
|
||||
},
|
||||
"modal": {
|
||||
"completed_date": "Дата завершення",
|
||||
"cost": "Ціна",
|
||||
"delete_confirmation": "Ви впевнені, що хочете видалити цей запис?",
|
||||
"edit_action": "Оновити",
|
||||
"edit_title": "Редагувати запис",
|
||||
"entry_name": "Назва запису",
|
||||
"new_action": "Створити",
|
||||
"new_title": "Новий запис",
|
||||
"notes": "Примітки",
|
||||
"scheduled_date": "Запланована дата"
|
||||
},
|
||||
"monthly_average": "Середнє за місяць",
|
||||
"toast": {
|
||||
"failed_to_create": "Не вдалося створити запис",
|
||||
"failed_to_delete": "Не вдалося видалити запис",
|
||||
"failed_to_update": "Не вдалося оновити запис"
|
||||
},
|
||||
"total_cost": "Загальна сума",
|
||||
"total_entries": "Всього елементів"
|
||||
},
|
||||
"menu": {
|
||||
"home": "Головна",
|
||||
"locations": "Локації",
|
||||
"maintenance": "Обслуговування",
|
||||
"profile": "Профіль",
|
||||
"search": "Пошук",
|
||||
"tools": "Інструменти"
|
||||
},
|
||||
"profile": {
|
||||
"active": "Активний",
|
||||
"change_password": "Змінити пароль",
|
||||
"currency_format": "Формат валюти",
|
||||
"current_password": "Поточний пароль",
|
||||
"delete_account": "Видалити обліковий запис",
|
||||
"delete_account_sub": "Видалити акаунт і всі пов'язані дані. Це невідворотна дія.",
|
||||
"display_header": "{ currentValue, select, true {Приховати заголовок} false {Показати заголовок} other {Відсутнє}}",
|
||||
"enabled": "Включено",
|
||||
"gen_invite": "Створити посилання для запрошення",
|
||||
"group_settings": "Налаштування групи",
|
||||
"group_settings_sub": "Налаштування спільної групи. Можливо, вам доведеться оновити сторінку для збереження параметрів.",
|
||||
"inactive": "Неактивний",
|
||||
"language": "Мова",
|
||||
"new_password": "Новий пароль",
|
||||
"no_notifiers": "Немає налаштованих сповіщувачів",
|
||||
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Сповіщувач",
|
||||
"notifiers": "Сповіщувачі",
|
||||
"notifiers_sub": "Отримувати сповіщення про майбутнє технічне обслуговування",
|
||||
"test": "Тест",
|
||||
"theme_settings": "Налаштування Теми",
|
||||
"theme_settings_sub": "Налаштування теми зберігаються в локальному сховищі вашого браузера. Ви можете змінити тему в будь-який момент. Якщо\nзберегти не вдається, спробуйте оновити сторінку (Ctrl+F5).",
|
||||
"update_group": "Оновити групу",
|
||||
"update_language": "Оновлення мови",
|
||||
"url": "URL-адреса",
|
||||
"user_profile": "Профіль користувача",
|
||||
"user_profile_sub": "Запросіть користувачів і керуйте своїм обліковим записом."
|
||||
},
|
||||
"tools": {
|
||||
"actions": "Дії з інвентарем",
|
||||
"actions_set": {
|
||||
"ensure_ids": "Перевірити наявність ID",
|
||||
"ensure_ids_button": "Перевірити наявність ID",
|
||||
"ensure_ids_sub": "Перевіряє усі ваші предмети на наявність вірного asset_id поля. Цей процес полягає в пошуці найбільшого значення asset_id у базі даних, і присвоєння настпупного за ним значення кожному предмету без asset_id. Процес йде по порядку поля created_at.",
|
||||
"ensure_import_refs": "Присвоїти дані іморту",
|
||||
"ensure_import_refs_button": "Присвоїти дані імпорту",
|
||||
"ensure_import_refs_sub": "Запевнитись, що всі предмети у вашій базі мають коректне поле import_ref. Для цього кожен предмет без встановленого import_ref отримає в це поле строку з восьми випадкових літер.",
|
||||
"set_primary_photo": "Встановити основну фотографію",
|
||||
"set_primary_photo_button": "Встановити основну фотографію",
|
||||
"set_primary_photo_sub": "У версії v0.10.0 Homebox до вкладень типу photo було додано поле зображення. Ця дія встановить основною фотографією першу картинку, що ви додали до предметів, якщо вона ще не встановлена. '<a class=\"link\" href=\"https://github.com/hay-kot/homebox/pull/576\">'Див. GitHub PR #576'</a>'",
|
||||
"zero_datetimes": "Обнулити дати предметів",
|
||||
"zero_datetimes_button": "Обнулити дати предметів",
|
||||
"zero_datetimes_sub": "Ця клавіша скидає значення \"час\" для усіх полів типу \"дата\" у списку ваших предметів. Користуйтеся для виправлення багу, що був доданий на початку розробки, і який псував збереження часу, що призводило до некоректного відображення.'<a class=\"link\" href=\"https://github.com/hay-kot/homebox/issues/236\" target=\"_blank\">'Більше даних на GitHub, #236 проблема.'</a>'"
|
||||
},
|
||||
"actions_sub": "Дії для роботи з усіма предметами одразу. Процес незворотній.'<b>'Будьте обережні.'</b>'",
|
||||
"import_export": "Імопрт/Експорт",
|
||||
"import_export_set": {
|
||||
"export": "Експортувати інвентар",
|
||||
"export_button": "Експортувати інвентар",
|
||||
"export_sub": "Експортувати у стандартному для HomeBox форматі. Це виведе у файл усі предмети з інвентара.",
|
||||
"import": "Імпортувати інвентар",
|
||||
"import_button": "Імпортувати інвентар",
|
||||
"import_sub": "Імпортувати у стандартному форматі для HomeBox .CSV-файл.Без '<code>'HB.import_ref'</code>' колонки, це '<b>не'</b>' перезапише ніякі предмети в інвентарі, лише додасть нові. Рядки з параметром '<code>'HB.import_ref'</code>' будуть злиті з існуючими предметами, якщо такі наявні і import_ref поле співпадає."
|
||||
},
|
||||
"import_export_sub": "Імпортувати і експортувати ваш інвентар у форматі .CSV. Це корисно для переносу інвентара на нову інсталяцію HomeBox.",
|
||||
"reports": "Звіти",
|
||||
"reports_set": {
|
||||
"asset_labels": "Наліпки з ID предметів",
|
||||
"asset_labels_button": "Генератор наліпок",
|
||||
"asset_labels_sub": "Створити .PDF файл з мітками, відповідно обраному діапазону ID. Ці мітки не пов'язані з присвоєними ID вашим предметам, тож ви можете надрукувати їх перед внесенням предметів у базу даних, і внести вже постфактум.",
|
||||
"bill_of_materials": "Звіт по предметам",
|
||||
"bill_of_materials_button": "Згенерувати звіт",
|
||||
"bill_of_materials_sub": "Створити .CSV файл, який можна імпортувати у відповідну програму (Excel, Spreadsheets, т.д.). Це буде повний звіт з описом усіх доданих предметів."
|
||||
},
|
||||
"reports_sub": "Створити різноманітні звіти по вашим предметам."
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@
|
||||
"password": "密码",
|
||||
"read_docs": "查阅文档",
|
||||
"search": "搜索",
|
||||
"sign_out": "注销",
|
||||
"sign_out": "登出",
|
||||
"submit": "提交",
|
||||
"version": "版本:{version}",
|
||||
"welcome": "欢迎,{username}"
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"maintenance": {
|
||||
"filter": {
|
||||
"both": "与",
|
||||
"both": "全部",
|
||||
"completed": "已完成",
|
||||
"scheduled": "已预定"
|
||||
},
|
||||
@@ -174,7 +174,7 @@
|
||||
"tools": "工具"
|
||||
},
|
||||
"profile": {
|
||||
"active": "活跃",
|
||||
"active": "启用",
|
||||
"change_password": "更改密码",
|
||||
"currency_format": "货币格式",
|
||||
"current_password": "原密码",
|
||||
@@ -185,7 +185,7 @@
|
||||
"gen_invite": "生成邀请链接",
|
||||
"group_settings": "组设置",
|
||||
"group_settings_sub": "共享组设置。您可能需要刷新浏览器来让某些设置生效。",
|
||||
"inactive": "非活跃",
|
||||
"inactive": "未启用",
|
||||
"language": "语言",
|
||||
"new_password": "新密码",
|
||||
"no_notifiers": "未配置通知程序",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"lint": "eslint --ext \".ts,.js,.vue\" --ignore-path ../.gitignore .",
|
||||
"lint:fix": "eslint --ext \".ts,.js,.vue\" --ignore-path ../.gitignore . --fix",
|
||||
"lint:ci": "eslint --ext \".ts,.js,.vue\" --ignore-path ../.gitignore . --max-warnings 1",
|
||||
"typecheck": "nuxi typecheck",
|
||||
"typecheck": "pnpm dlx vue-tsc@2.1.6 --noEmit",
|
||||
"test:ci": "TEST_SHUTDOWN_API_SERVER=true vitest --run --config ./test/vitest.config.ts",
|
||||
"test:local": "TEST_SHUTDOWN_API_SERVER=false && vitest --run --config ./test/vitest.config.ts",
|
||||
"test:watch": " TEST_SHUTDOWN_API_SERVER=false vitest --config ./test/vitest.config.ts"
|
||||
@@ -23,6 +23,7 @@
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"@typescript-eslint/parser": "^6.21.0",
|
||||
"@vite-pwa/nuxt": "^0.5.0",
|
||||
"@vue/runtime-core": "^3.5.12",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
<div>
|
||||
<BaseContainer class="flex flex-col gap-12 pb-16">
|
||||
<section>
|
||||
<Subtitle> Quick Statistics </Subtitle>
|
||||
<Subtitle> {{ $t("home.quick_statistics") }} </Subtitle>
|
||||
<div class="grid grid-cols-2 gap-2 md:grid-cols-4 md:gap-6">
|
||||
<StatCard v-for="(stat, i) in stats" :key="i" :title="stat.label" :value="stat.value" :type="stat.type" />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<Subtitle>Recently Added</Subtitle>
|
||||
<Subtitle> {{ $t("home.recently_added") }} </Subtitle>
|
||||
|
||||
<p v-if="itemTable.items.length === 0" class="ml-2 text-sm">{{ $t("items.no_results") }}</p>
|
||||
<BaseCard v-else-if="breakpoints.lg">
|
||||
@@ -47,7 +47,7 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<Subtitle> Storage Locations </Subtitle>
|
||||
<Subtitle> {{ $t("home.storage_locations") }} </Subtitle>
|
||||
<p v-if="locations.length === 0" class="ml-2 text-sm">{{ $t("locations.no_results") }}</p>
|
||||
<div v-else class="card grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3">
|
||||
<LocationCard v-for="location in locations" :key="location.id" :location="location" />
|
||||
@@ -55,7 +55,7 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<Subtitle> Labels </Subtitle>
|
||||
<Subtitle> {{ $t("home.labels") }} </Subtitle>
|
||||
<p v-if="labels.length === 0" class="ml-2 text-sm">{{ $t("labels.no_results") }}</p>
|
||||
<div v-else class="flex flex-wrap gap-4">
|
||||
<LabelChip v-for="label in labels" :key="label.id" size="lg" :label="label" class="shadow-md" />
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useI18n } from "vue-i18n";
|
||||
import type { UserClient } from "~~/lib/api/user";
|
||||
|
||||
type StatCard = {
|
||||
@@ -7,6 +8,8 @@ type StatCard = {
|
||||
};
|
||||
|
||||
export function statCardData(api: UserClient) {
|
||||
const { t } = useI18n();
|
||||
|
||||
const { data: statistics } = useAsyncData(async () => {
|
||||
const { data } = await api.stats.group();
|
||||
return data;
|
||||
@@ -15,22 +18,22 @@ export function statCardData(api: UserClient) {
|
||||
return computed(() => {
|
||||
return [
|
||||
{
|
||||
label: "Total Value",
|
||||
label: t("home.total_value"),
|
||||
value: statistics.value?.totalItemPrice || 0,
|
||||
type: "currency",
|
||||
},
|
||||
{
|
||||
label: "Total Items",
|
||||
label: t("home.total_items"),
|
||||
value: statistics.value?.totalItems || 0,
|
||||
type: "number",
|
||||
},
|
||||
{
|
||||
label: "Total Locations",
|
||||
label: t("home.total_locations"),
|
||||
value: statistics.value?.totalLocations || 0,
|
||||
type: "number",
|
||||
},
|
||||
{
|
||||
label: "Total Labels",
|
||||
label: t("home.total_labels"),
|
||||
value: statistics.value?.totalLabels || 0,
|
||||
type: "number",
|
||||
},
|
||||
|
||||
@@ -153,35 +153,35 @@
|
||||
|
||||
const ret: Details = [
|
||||
{
|
||||
name: "Quantity",
|
||||
name: "items.quantity",
|
||||
text: item.value?.quantity,
|
||||
slot: "quantity",
|
||||
},
|
||||
{
|
||||
name: "Serial Number",
|
||||
name: "items.serial_number",
|
||||
text: item.value?.serialNumber,
|
||||
copyable: true,
|
||||
},
|
||||
{
|
||||
name: "Model Number",
|
||||
name: "items.model_number",
|
||||
text: item.value?.modelNumber,
|
||||
copyable: true,
|
||||
},
|
||||
{
|
||||
name: "Manufacturer",
|
||||
name: "items.manufacturer",
|
||||
text: item.value?.manufacturer,
|
||||
copyable: true,
|
||||
},
|
||||
{
|
||||
name: "Insured",
|
||||
name: "items.insured",
|
||||
text: item.value?.insured ? "Yes" : "No",
|
||||
},
|
||||
{
|
||||
name: "Archived",
|
||||
name: "items.archived",
|
||||
text: item.value?.archived ? "Yes" : "No",
|
||||
},
|
||||
{
|
||||
name: "Notes",
|
||||
name: "items.notes",
|
||||
type: "markdown",
|
||||
text: item.value?.notes,
|
||||
},
|
||||
@@ -230,28 +230,28 @@
|
||||
const attachmentDetails = computed(() => {
|
||||
const details: Detail[] = [];
|
||||
|
||||
const push = (name: string) => {
|
||||
const push = (name: string, slot: string) => {
|
||||
details.push({
|
||||
name,
|
||||
text: "",
|
||||
slot: name.toLowerCase(),
|
||||
slot,
|
||||
});
|
||||
};
|
||||
|
||||
if (attachments.value.attachments.length > 0) {
|
||||
push("Attachments");
|
||||
push("items.attachments", "attachments");
|
||||
}
|
||||
|
||||
if (attachments.value.warranty.length > 0) {
|
||||
push("Warranty");
|
||||
push("items.warranty", "warranty");
|
||||
}
|
||||
|
||||
if (attachments.value.manuals.length > 0) {
|
||||
push("Manuals");
|
||||
push("items.manuals", "manuals");
|
||||
}
|
||||
|
||||
if (attachments.value.receipts.length > 0) {
|
||||
push("Receipts");
|
||||
push("items.receipts", "receipts");
|
||||
}
|
||||
|
||||
return details;
|
||||
@@ -303,22 +303,22 @@
|
||||
if (preferences.value.showEmpty) {
|
||||
return true;
|
||||
}
|
||||
return item.value?.purchaseFrom || item.value?.purchasePrice !== "0";
|
||||
return item.value?.purchaseFrom || item.value?.purchasePrice !== 0;
|
||||
});
|
||||
|
||||
const purchaseDetails = computed<Details>(() => {
|
||||
const v: Details = [
|
||||
{
|
||||
name: "Purchased From",
|
||||
name: "items.purchased_from",
|
||||
text: item.value?.purchaseFrom || "",
|
||||
},
|
||||
{
|
||||
name: "Purchase Price",
|
||||
text: item.value?.purchasePrice || "",
|
||||
name: "items.purchase_price",
|
||||
text: String(item.value?.purchasePrice) || "",
|
||||
type: "currency",
|
||||
},
|
||||
{
|
||||
name: "Purchase Date",
|
||||
name: "items.purchase_date",
|
||||
text: item.value?.purchaseTime || "",
|
||||
type: "date",
|
||||
date: true,
|
||||
@@ -336,22 +336,22 @@
|
||||
if (preferences.value.showEmpty) {
|
||||
return true;
|
||||
}
|
||||
return item.value?.soldTo || item.value?.soldPrice !== "0";
|
||||
return item.value?.soldTo || item.value?.soldPrice !== 0;
|
||||
});
|
||||
|
||||
const soldDetails = computed<Details>(() => {
|
||||
const v: Details = [
|
||||
{
|
||||
name: "Sold To",
|
||||
name: "items.sold_to",
|
||||
text: item.value?.soldTo || "",
|
||||
},
|
||||
{
|
||||
name: "Sold Price",
|
||||
text: item.value?.soldPrice || "",
|
||||
name: "items.sold_price",
|
||||
text: String(item.value?.soldPrice) || "",
|
||||
type: "currency",
|
||||
},
|
||||
{
|
||||
name: "Sold At",
|
||||
name: "items.sold_at",
|
||||
text: item.value?.soldTime || "",
|
||||
type: "date",
|
||||
date: true,
|
||||
@@ -394,17 +394,17 @@
|
||||
return [
|
||||
{
|
||||
id: "details",
|
||||
name: "Details",
|
||||
name: "global.details",
|
||||
to: `/item/${itemId.value}`,
|
||||
},
|
||||
{
|
||||
id: "log",
|
||||
name: "Maintenance",
|
||||
name: "global.maintenance",
|
||||
to: `/item/${itemId.value}/maintenance`,
|
||||
},
|
||||
{
|
||||
id: "edit",
|
||||
name: "Edit",
|
||||
name: "global.edit",
|
||||
to: `/item/${itemId.value}/edit`,
|
||||
},
|
||||
];
|
||||
@@ -472,15 +472,15 @@
|
||||
<div>
|
||||
<div v-if="fullpath && fullpath.length > 0" class="breadcrumbs py-0 text-sm">
|
||||
<ul class="text-base-content/70">
|
||||
<li v-for="part in fullpath" :key="part.id">
|
||||
<li v-for="part in fullpath" :key="part.id" class="text-wrap">
|
||||
<NuxtLink :to="`/${part.type}/${part.id}`"> {{ part.name }}</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<h1 class="pb-1 text-2xl">
|
||||
<h1 class="text-wrap pb-1 text-2xl">
|
||||
{{ item ? item.name : "" }}
|
||||
</h1>
|
||||
<div class="flex flex-wrap gap-1 text-xs">
|
||||
<div class="flex flex-wrap gap-1 text-wrap text-xs">
|
||||
<div>
|
||||
Created
|
||||
<DateTime :date="item?.createdAt" />
|
||||
@@ -509,7 +509,7 @@
|
||||
class="btn btn-sm"
|
||||
:class="`${t.to === currentPath ? 'btn-active' : ''}`"
|
||||
>
|
||||
{{ t.name }}
|
||||
{{ $t(t.name) }}
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
@@ -518,7 +518,7 @@
|
||||
<section>
|
||||
<div class="space-y-6">
|
||||
<BaseCard v-if="!hasNested" collapsable>
|
||||
<template #title> Details </template>
|
||||
<template #title> {{ $t("items.details") }} </template>
|
||||
<template #title-actions>
|
||||
<div class="mt-2 flex flex-wrap items-center justify-between gap-4">
|
||||
<label class="label cursor-pointer">
|
||||
@@ -548,7 +548,7 @@
|
||||
<NuxtPage :item="item" :page-key="itemId" />
|
||||
<template v-if="!hasNested">
|
||||
<BaseCard v-if="photos && photos.length > 0">
|
||||
<template #title> Photos </template>
|
||||
<template #title> {{ $t("items.photos") }} </template>
|
||||
<div
|
||||
class="scroll-bg container mx-auto flex max-h-[500px] flex-wrap gap-2 overflow-y-scroll border-t border-gray-300 p-4"
|
||||
>
|
||||
@@ -559,7 +559,7 @@
|
||||
</BaseCard>
|
||||
|
||||
<BaseCard v-if="showAttachments" collapsable>
|
||||
<template #title> Attachments </template>
|
||||
<template #title> {{ $t("items.attachments") }} </template>
|
||||
<DetailsSection v-if="attachmentDetails.length > 0" :details="attachmentDetails">
|
||||
<template #manuals>
|
||||
<ItemAttachmentsList
|
||||
@@ -596,17 +596,17 @@
|
||||
</BaseCard>
|
||||
|
||||
<BaseCard v-if="showPurchase" collapsable>
|
||||
<template #title> Purchase Details </template>
|
||||
<template #title> {{ $t("items.purchase_details") }} </template>
|
||||
<DetailsSection :details="purchaseDetails" />
|
||||
</BaseCard>
|
||||
|
||||
<BaseCard v-if="showWarranty" collapsable>
|
||||
<template #title> Warranty Details </template>
|
||||
<template #title> {{ $t("items.warranty_details") }} </template>
|
||||
<DetailsSection :details="warrantyDetails" />
|
||||
</BaseCard>
|
||||
|
||||
<BaseCard v-if="showSold" collapsable>
|
||||
<template #title> Sold Details </template>
|
||||
<template #title> {{ $t("items.sold_details") }} </template>
|
||||
<DetailsSection :details="soldDetails" />
|
||||
</BaseCard>
|
||||
</template>
|
||||
@@ -624,13 +624,4 @@
|
||||
dialog::backdrop {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.scroll-bg::-webkit-scrollbar {
|
||||
width: 0.5rem;
|
||||
}
|
||||
|
||||
.scroll-bg::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.25rem;
|
||||
@apply bg-base-300;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import MdiDelete from "~icons/mdi/delete";
|
||||
import MdiPencil from "~icons/mdi/pencil";
|
||||
import MdiContentSaveOutline from "~icons/mdi/content-save-outline";
|
||||
import MdiContentCopy from "~icons/mdi/content-copy";
|
||||
|
||||
definePageMeta({
|
||||
middleware: ["auth"],
|
||||
@@ -59,18 +60,68 @@
|
||||
refresh();
|
||||
});
|
||||
|
||||
async function duplicateItem() {
|
||||
const { error, data } = await api.items.create({
|
||||
name: `${item.value.name} Copy`,
|
||||
description: item.value.description,
|
||||
locationId: item.value.location!.id,
|
||||
parentId: item.value.parent?.id,
|
||||
labelIds: item.value.labels.map(l => l.id),
|
||||
});
|
||||
|
||||
if (error) {
|
||||
toast.error("Failed to duplicate item");
|
||||
return;
|
||||
}
|
||||
|
||||
// add extra fields
|
||||
const { error: updateError } = await api.items.update(data.id, {
|
||||
...item.value,
|
||||
id: data.id,
|
||||
labelIds: data.labels.map(l => l.id),
|
||||
locationId: data.location!.id,
|
||||
name: data.name,
|
||||
});
|
||||
|
||||
if (updateError) {
|
||||
toast.error("Failed to duplicate item");
|
||||
return;
|
||||
}
|
||||
|
||||
navigateTo(`/item/${data.id}`);
|
||||
}
|
||||
|
||||
async function saveItem() {
|
||||
if (!item.value.location?.id) {
|
||||
toast.error("Failed to save item: no location selected");
|
||||
return;
|
||||
}
|
||||
|
||||
let purchasePrice = 0;
|
||||
let soldPrice = 0;
|
||||
let purchaseTime = null;
|
||||
if (item.value.purchasePrice) {
|
||||
purchasePrice = item.value.purchasePrice;
|
||||
}
|
||||
if (item.value.soldPrice) {
|
||||
soldPrice = item.value.soldPrice;
|
||||
}
|
||||
if (item.value.purchaseTime && typeof item.value.purchaseTime !== "string") {
|
||||
purchaseTime = new Date(item.value.purchaseTime.getTime() - item.value.purchaseTime.getTimezoneOffset() * 60000);
|
||||
}
|
||||
|
||||
console.log((item.value.purchasePrice ??= 0));
|
||||
console.log((item.value.soldPrice ??= 0));
|
||||
|
||||
const payload: ItemUpdate = {
|
||||
...item.value,
|
||||
locationId: item.value.location?.id,
|
||||
labelIds: item.value.labels.map(l => l.id),
|
||||
parentId: parent.value ? parent.value.id : null,
|
||||
assetId: item.value.assetId,
|
||||
purchasePrice,
|
||||
soldPrice,
|
||||
purchaseTime: purchaseTime as Date,
|
||||
};
|
||||
|
||||
const { error } = await api.items.update(itemId.value, payload);
|
||||
@@ -131,59 +182,59 @@
|
||||
const mainFields: FormField[] = [
|
||||
{
|
||||
type: "text",
|
||||
label: "Name",
|
||||
label: "items.name",
|
||||
ref: "name",
|
||||
maxLength: 255,
|
||||
minLength: 1,
|
||||
},
|
||||
{
|
||||
type: "number",
|
||||
label: "Quantity",
|
||||
label: "items.quantity",
|
||||
ref: "quantity",
|
||||
},
|
||||
{
|
||||
type: "textarea",
|
||||
label: "Description",
|
||||
label: "items.description",
|
||||
ref: "description",
|
||||
maxLength: 1000,
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
label: "Serial Number",
|
||||
label: "items.serial_number",
|
||||
ref: "serialNumber",
|
||||
maxLength: 255,
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
label: "Model Number",
|
||||
label: "items.model_number",
|
||||
ref: "modelNumber",
|
||||
maxLength: 255,
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
label: "Manufacturer",
|
||||
label: "items.manufacturer",
|
||||
ref: "manufacturer",
|
||||
maxLength: 255,
|
||||
},
|
||||
{
|
||||
type: "textarea",
|
||||
label: "Notes",
|
||||
label: "items.notes",
|
||||
ref: "notes",
|
||||
maxLength: 1000,
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Insured",
|
||||
label: "items.insured",
|
||||
ref: "insured",
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Archived",
|
||||
label: "items.archived",
|
||||
ref: "archived",
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
label: "Asset ID",
|
||||
label: "items.asset_id",
|
||||
ref: "assetId",
|
||||
},
|
||||
];
|
||||
@@ -191,18 +242,18 @@
|
||||
const purchaseFields: FormField[] = [
|
||||
{
|
||||
type: "text",
|
||||
label: "Purchased From",
|
||||
label: "items.purchased_from",
|
||||
ref: "purchaseFrom",
|
||||
maxLength: 255,
|
||||
},
|
||||
{
|
||||
type: "number",
|
||||
label: "Purchase Price",
|
||||
label: "items.purchase_price",
|
||||
ref: "purchasePrice",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
label: "Purchase Date",
|
||||
label: "items.purchase_date",
|
||||
// @ts-expect-error - we know this is a date
|
||||
ref: "purchaseTime",
|
||||
},
|
||||
@@ -211,18 +262,18 @@
|
||||
const warrantyFields: FormField[] = [
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Lifetime Warranty",
|
||||
label: "items.lifetime_warranty",
|
||||
ref: "lifetimeWarranty",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
label: "Warranty Expires",
|
||||
label: "items.warranty_expires",
|
||||
// @ts-expect-error - we know this is a date
|
||||
ref: "warrantyExpires",
|
||||
},
|
||||
{
|
||||
type: "textarea",
|
||||
label: "Warranty Notes",
|
||||
label: "items.warranty_details",
|
||||
ref: "warrantyDetails",
|
||||
maxLength: 1000,
|
||||
},
|
||||
@@ -231,18 +282,18 @@
|
||||
const soldFields: FormField[] = [
|
||||
{
|
||||
type: "text",
|
||||
label: "Sold To",
|
||||
label: "items.sold_to",
|
||||
ref: "soldTo",
|
||||
maxLength: 255,
|
||||
},
|
||||
{
|
||||
type: "number",
|
||||
label: "Sold Price",
|
||||
label: "items.sold_price",
|
||||
ref: "soldPrice",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
label: "Sold At",
|
||||
label: "items.sold_at",
|
||||
// @ts-expect-error - we know this is a date
|
||||
ref: "soldTime",
|
||||
},
|
||||
@@ -452,39 +503,45 @@
|
||||
|
||||
<section class="relative">
|
||||
<div class="sticky top-1 z-10 my-4 flex items-center justify-end gap-2">
|
||||
<div class="tooltip tooltip-right mr-auto" data-tip="Show Advanced View Options">
|
||||
<div class="tooltip tooltip-right mr-auto" :data-tip="$t('items.show_advanced_view_options')">
|
||||
<label class="label mr-auto cursor-pointer">
|
||||
<input v-model="preferences.editorAdvancedView" type="checkbox" class="toggle toggle-primary" />
|
||||
<span class="label-text ml-4"> Advanced </span>
|
||||
<span class="label-text ml-4"> {{ $t("items.advanced") }} </span>
|
||||
</label>
|
||||
</div>
|
||||
<BaseButton size="sm" class="btn" @click="duplicateItem">
|
||||
<template #icon>
|
||||
<MdiContentCopy />
|
||||
</template>
|
||||
{{ $t("global.duplicate") }}
|
||||
</BaseButton>
|
||||
<BaseButton size="sm" @click="saveItem">
|
||||
<template #icon>
|
||||
<MdiContentSaveOutline />
|
||||
</template>
|
||||
Save
|
||||
{{ $t("global.save") }}
|
||||
</BaseButton>
|
||||
<BaseButton class="btn btn-error btn-sm" @click="deleteItem()">
|
||||
<MdiDelete class="mr-2" />
|
||||
Delete
|
||||
{{ $t("global.delete") }}
|
||||
</BaseButton>
|
||||
</div>
|
||||
<div v-if="!requestPending" class="space-y-6">
|
||||
<BaseCard class="overflow-visible">
|
||||
<template #title> Edit Details </template>
|
||||
<template #title> {{ $t("items.edit_details") }} </template>
|
||||
<template #title-actions>
|
||||
<div class="mt-2 flex flex-wrap items-center justify-between gap-4"></div>
|
||||
</template>
|
||||
<div class="mb-6 grid gap-4 border-t px-5 pt-2 md:grid-cols-2">
|
||||
<LocationSelector v-model="item.location" />
|
||||
<FormMultiselect v-model="item.labels" label="Labels" :items="labels ?? []" />
|
||||
<FormMultiselect v-model="item.labels" :label="$t('global.labels')" :items="labels ?? []" />
|
||||
<Autocomplete
|
||||
v-if="preferences.editorAdvancedView"
|
||||
v-model="parent"
|
||||
v-model:search="query"
|
||||
:items="results"
|
||||
item-text="name"
|
||||
label="Parent Item"
|
||||
:label="$t('items.parent_item')"
|
||||
no-results-text="Type to search..."
|
||||
/>
|
||||
</div>
|
||||
@@ -495,7 +552,7 @@
|
||||
<FormTextArea
|
||||
v-if="field.type === 'textarea'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
:max-length="field.maxLength"
|
||||
:min-length="field.minLength"
|
||||
@@ -503,7 +560,7 @@
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'text'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
type="text"
|
||||
:max-length="field.maxLength"
|
||||
@@ -513,19 +570,19 @@
|
||||
v-else-if="field.type === 'number'"
|
||||
v-model.number="item[field.ref]"
|
||||
type="number"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
<FormDatePicker
|
||||
v-else-if="field.type === 'date'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
<FormCheckbox
|
||||
v-else-if="field.type === 'checkbox'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
@@ -534,7 +591,7 @@
|
||||
</BaseCard>
|
||||
|
||||
<BaseCard>
|
||||
<template #title> Custom Fields </template>
|
||||
<template #title> {{ $t("items.custom_fields") }} </template>
|
||||
<div class="space-y-4 divide-y divide-gray-300 border-t px-5">
|
||||
<div
|
||||
v-for="(field, idx) in item.fields"
|
||||
@@ -542,10 +599,10 @@
|
||||
class="grid grid-cols-2 gap-2 md:grid-cols-4"
|
||||
>
|
||||
<!-- <FormSelect v-model:value="field.type" label="Field Type" :items="fieldTypes" value-key="value" /> -->
|
||||
<FormTextField v-model="field.name" label="Name" />
|
||||
<FormTextField v-model="field.name" :label="$t('global.name')" />
|
||||
<div class="col-span-3 flex items-end">
|
||||
<FormTextField v-model="field.textValue" label="Value" :max-length="500" />
|
||||
<div class="tooltip" data-tip="Delete">
|
||||
<FormTextField v-model="field.textValue" :label="$t('global.value')" :max-length="500" />
|
||||
<div class="tooltip" :data-tip="$t('global.delete')">
|
||||
<button class="btn btn-square btn-sm mb-2 ml-2" @click="item.fields.splice(idx, 1)">
|
||||
<MdiDelete />
|
||||
</button>
|
||||
@@ -554,7 +611,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 flex justify-end px-5 pb-4">
|
||||
<BaseButton size="sm" @click="addField"> Add </BaseButton>
|
||||
<BaseButton size="sm" @click="addField"> {{ $t("global.add") }} </BaseButton>
|
||||
</div>
|
||||
</BaseCard>
|
||||
|
||||
@@ -564,16 +621,16 @@
|
||||
class="card overflow-visible bg-base-100 shadow-xl sm:rounded-lg"
|
||||
>
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h3 class="text-lg font-medium leading-6">Attachments</h3>
|
||||
<p class="text-xs">Changes to attachments will be saved immediately</p>
|
||||
<h3 class="text-lg font-medium leading-6">{{ $t("items.attachments") }}</h3>
|
||||
<p class="text-xs">{{ $t("items.changes_persisted_immediately") }}</p>
|
||||
</div>
|
||||
<div class="border-t border-gray-300 p-4">
|
||||
<div v-if="attDropZoneActive" class="grid grid-cols-4 gap-4">
|
||||
<DropZone @drop="dropPhoto"> Photo </DropZone>
|
||||
<DropZone @drop="dropWarranty"> Warranty </DropZone>
|
||||
<DropZone @drop="dropManual"> Manual </DropZone>
|
||||
<DropZone @drop="dropAttachment"> Attachment </DropZone>
|
||||
<DropZone @drop="dropReceipt"> Receipt </DropZone>
|
||||
<DropZone @drop="dropPhoto"> {{ $t("items.photos") }} </DropZone>
|
||||
<DropZone @drop="dropWarranty"> {{ $t("items.warranty") }} </DropZone>
|
||||
<DropZone @drop="dropManual"> {{ $t("items.manuals") }} </DropZone>
|
||||
<DropZone @drop="dropAttachment"> {{ $t("items.attachments") }} </DropZone>
|
||||
<DropZone @drop="dropReceipt"> {{ $t("items.receipts") }} </DropZone>
|
||||
</div>
|
||||
<button
|
||||
v-else
|
||||
@@ -581,7 +638,7 @@
|
||||
@click="clickUpload"
|
||||
>
|
||||
<input ref="refAttachmentInput" hidden type="file" @change="uploadImage" />
|
||||
<p>Drag and drop files here or click to select files</p>
|
||||
<p>{{ $t("items.drag_and_drop") }}</p>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -596,15 +653,15 @@
|
||||
{{ attachment.document.title }}
|
||||
</p>
|
||||
<p class="my-auto">
|
||||
{{ capitalize(attachment.type) }}
|
||||
{{ $t(`items.${attachment.type}`) }}
|
||||
</p>
|
||||
<div class="flex justify-end gap-2">
|
||||
<div class="tooltip" data-tip="Delete">
|
||||
<div class="tooltip" :data-tip="$t('global.delete')">
|
||||
<button class="btn btn-square btn-sm" @click="deleteAttachment(attachment.id)">
|
||||
<MdiDelete />
|
||||
</button>
|
||||
</div>
|
||||
<div class="tooltip" data-tip="Edit">
|
||||
<div class="tooltip" :data-tip="$t('global.edit')">
|
||||
<button class="btn btn-square btn-sm" @click="openAttachmentEditDialog(attachment)">
|
||||
<MdiPencil />
|
||||
</button>
|
||||
@@ -617,7 +674,7 @@
|
||||
|
||||
<div v-if="preferences.editorAdvancedView" class="card overflow-visible bg-base-100 shadow-xl sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h3 class="text-lg font-medium leading-6">Purchase Details</h3>
|
||||
<h3 class="text-lg font-medium leading-6">{{ $t("items.purchase_details") }}</h3>
|
||||
</div>
|
||||
<div class="border-t border-gray-300 sm:p-0">
|
||||
<div
|
||||
@@ -629,7 +686,7 @@
|
||||
<FormTextArea
|
||||
v-if="field.type === 'textarea'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
:max-length="field.maxLength"
|
||||
:min-length="field.minLength"
|
||||
@@ -637,7 +694,7 @@
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'text'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
:max-length="field.maxLength"
|
||||
:min-length="field.minLength"
|
||||
@@ -646,19 +703,19 @@
|
||||
v-else-if="field.type === 'number'"
|
||||
v-model.number="item[field.ref]"
|
||||
type="number"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
<FormDatePicker
|
||||
v-else-if="field.type === 'date'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
<FormCheckbox
|
||||
v-else-if="field.type === 'checkbox'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
@@ -668,7 +725,7 @@
|
||||
|
||||
<div v-if="preferences.editorAdvancedView" class="card overflow-visible bg-base-100 shadow-xl sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h3 class="text-lg font-medium leading-6">Warranty Details</h3>
|
||||
<h3 class="text-lg font-medium leading-6">{{ $t("items.warranty_details") }}</h3>
|
||||
</div>
|
||||
<div class="border-t border-gray-300 sm:p-0">
|
||||
<div
|
||||
@@ -680,7 +737,7 @@
|
||||
<FormTextArea
|
||||
v-if="field.type === 'textarea'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
:max-length="field.maxLength"
|
||||
:min-length="field.minLength"
|
||||
@@ -688,7 +745,7 @@
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'text'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
:max-length="field.maxLength"
|
||||
:min-length="field.minLength"
|
||||
@@ -697,19 +754,19 @@
|
||||
v-else-if="field.type === 'number'"
|
||||
v-model.number="item[field.ref]"
|
||||
type="number"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
<FormDatePicker
|
||||
v-else-if="field.type === 'date'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
<FormCheckbox
|
||||
v-else-if="field.type === 'checkbox'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
@@ -727,7 +784,7 @@
|
||||
<FormTextArea
|
||||
v-if="field.type === 'textarea'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
:max-length="field.maxLength"
|
||||
:min-length="field.minLength"
|
||||
@@ -735,7 +792,7 @@
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'text'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
:max-length="field.maxLength"
|
||||
:min-length="field.minLength"
|
||||
@@ -744,19 +801,19 @@
|
||||
v-else-if="field.type === 'number'"
|
||||
v-model.number="item[field.ref]"
|
||||
type="number"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
<FormDatePicker
|
||||
v-else-if="field.type === 'date'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
<FormCheckbox
|
||||
v-else-if="field.type === 'checkbox'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
:label="$t(field.label)"
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -76,7 +76,10 @@
|
||||
|
||||
const items = computedAsync(async () => {
|
||||
if (!label.value) {
|
||||
return [];
|
||||
return {
|
||||
items: [],
|
||||
totalPrice: null,
|
||||
};
|
||||
}
|
||||
|
||||
const resp = await api.items.getAll({
|
||||
@@ -85,7 +88,10 @@
|
||||
|
||||
if (resp.error) {
|
||||
toast.error("Failed to load items");
|
||||
return [];
|
||||
return {
|
||||
items: [],
|
||||
totalPrice: null,
|
||||
};
|
||||
}
|
||||
|
||||
return resp.data;
|
||||
@@ -95,18 +101,22 @@
|
||||
<template>
|
||||
<BaseContainer>
|
||||
<BaseModal v-model="updateModal">
|
||||
<template #title> Update Label </template>
|
||||
<template #title> {{ $t("labels.update_label") }} </template>
|
||||
<form v-if="label" @submit.prevent="update">
|
||||
<FormTextField
|
||||
v-model="updateData.name"
|
||||
:autofocus="true"
|
||||
label="Label Name"
|
||||
:label="$t('components.label.create_modal.label_name')"
|
||||
:max-length="255"
|
||||
:min-length="1"
|
||||
/>
|
||||
<FormTextArea v-model="updateData.description" label="Label Description" :max-length="255" />
|
||||
<FormTextArea
|
||||
v-model="updateData.description"
|
||||
:label="$t('components.label.create_modal.label_description')"
|
||||
:max-length="255"
|
||||
/>
|
||||
<div class="modal-action">
|
||||
<BaseButton type="submit" :loading="updating"> Update </BaseButton>
|
||||
<BaseButton type="submit" :loading="updating"> {{ $t("global.update") }} </BaseButton>
|
||||
</div>
|
||||
</form>
|
||||
</BaseModal>
|
||||
|
||||
@@ -109,13 +109,23 @@
|
||||
<div>
|
||||
<!-- Update Dialog -->
|
||||
<BaseModal v-model="updateModal">
|
||||
<template #title> Update Location </template>
|
||||
<template #title> {{ $t("locations.update_location") }} </template>
|
||||
<form v-if="location" @submit.prevent="update">
|
||||
<FormTextField v-model="updateData.name" :autofocus="true" label="Location Name" :max-length="255" :min-length="1" />
|
||||
<FormTextArea v-model="updateData.description" label="Location Description" :max-length="1000" />
|
||||
<FormTextField
|
||||
v-model="updateData.name"
|
||||
:autofocus="true"
|
||||
:label="$t('components.location.create_modal.location_name')"
|
||||
:max-length="255"
|
||||
:min-length="1"
|
||||
/>
|
||||
<FormTextArea
|
||||
v-model="updateData.description"
|
||||
:label="$t('components.location.create_modal.location_description')"
|
||||
:max-length="1000"
|
||||
/>
|
||||
<LocationSelector v-model="parent" />
|
||||
<div class="modal-action">
|
||||
<BaseButton type="submit" :loading="updating"> Update </BaseButton>
|
||||
<BaseButton type="submit" :loading="updating"> {{ $t("global.update") }} </BaseButton>
|
||||
</div>
|
||||
</form>
|
||||
</BaseModal>
|
||||
@@ -152,7 +162,7 @@
|
||||
</h1>
|
||||
<div class="flex flex-wrap gap-1 text-xs">
|
||||
<div>
|
||||
Created
|
||||
{{ $t("global.created") }}
|
||||
<DateTime :date="location?.createdAt" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -162,12 +172,12 @@
|
||||
<PageQRCode class="dropdown-left" />
|
||||
<BaseButton size="sm" @click="openUpdate">
|
||||
<MdiPencil class="mr-1" name="mdi-pencil" />
|
||||
Edit
|
||||
{{ $t("global.edit") }}
|
||||
</BaseButton>
|
||||
</div>
|
||||
<BaseButton class="btn btn-sm" @click="confirmDelete()">
|
||||
<MdiDelete name="mdi-delete" class="mr-2" />
|
||||
Delete
|
||||
{{ $t("global.delete") }}
|
||||
</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
@@ -180,7 +190,7 @@
|
||||
</section>
|
||||
|
||||
<section v-if="location && location.children.length > 0" class="mt-6">
|
||||
<BaseSectionHeader class="mb-5"> Child Locations </BaseSectionHeader>
|
||||
<BaseSectionHeader class="mb-5"> {{ $t("locations.child_locations") }} </BaseSectionHeader>
|
||||
<div class="grid grid-cols-1 gap-2 sm:grid-cols-3">
|
||||
<LocationCard v-for="item in location.children" :key="item.id" :location="item" />
|
||||
</div>
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
<div class="p-4">
|
||||
<div class="mb-2 flex justify-end">
|
||||
<div class="btn-group">
|
||||
<button class="btn tooltip tooltip-top btn-sm" data-tip="Collapse Tree" @click="closeAll">
|
||||
<button class="btn tooltip tooltip-top btn-sm" :data-tip="$t('locations.collapse_tree')" @click="closeAll">
|
||||
<MdiCollapseAllOutline />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -105,11 +105,11 @@
|
||||
console.log(auth.user);
|
||||
return [
|
||||
{
|
||||
name: "Name",
|
||||
name: "global.name",
|
||||
text: auth.user?.name || "Unknown",
|
||||
},
|
||||
{
|
||||
name: "Email",
|
||||
name: "global.email",
|
||||
text: auth.user?.email || "Unknown",
|
||||
},
|
||||
] as Detail[];
|
||||
@@ -376,14 +376,19 @@
|
||||
<label class="label">
|
||||
<span class="label-text">{{ $t("profile.language") }}</span>
|
||||
</label>
|
||||
<select v-model="$i18n.locale" class="select select-bordered">
|
||||
<select
|
||||
v-model="$i18n.locale"
|
||||
class="select select-bordered"
|
||||
@change="
|
||||
event => {
|
||||
setLanguage((event.target as HTMLSelectElement).value);
|
||||
}
|
||||
"
|
||||
>
|
||||
<option v-for="lang in $i18n.availableLocales" :key="lang" :value="lang">
|
||||
{{ $t(`languages.${lang}`) }}
|
||||
{{ $t(`languages.${lang}`) }} ({{ $t(`languages.${lang}`, 1, { locale: lang }) }})
|
||||
</option>
|
||||
</select>
|
||||
<div class="mt-4">
|
||||
<BaseButton size="sm" @click="setLanguage($i18n.locale)"> {{ $t("profile.update_language") }} </BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
|
||||
@@ -447,7 +452,7 @@
|
||||
|
||||
<div v-if="group && currencies && currencies.length > 0" class="p-5 pt-0">
|
||||
<FormSelect v-model="currency" :label="$t('profile.currency_format')" :items="currencies" />
|
||||
<p class="m-2 text-sm">Example: {{ currencyExample }}</p>
|
||||
<p class="m-2 text-sm">{{ $t("profile.example") }}: {{ currencyExample }}</p>
|
||||
|
||||
<div class="mt-4">
|
||||
<BaseButton size="sm" @click="updateGroup"> {{ $t("profile.update_group") }} </BaseButton>
|
||||
|
||||
@@ -200,7 +200,9 @@
|
||||
const { data, error } = await api.items.getAll();
|
||||
|
||||
if (error) {
|
||||
return [];
|
||||
return {
|
||||
items: [],
|
||||
};
|
||||
}
|
||||
|
||||
return data;
|
||||
@@ -219,7 +221,12 @@
|
||||
|
||||
const items: LabelData[] = [];
|
||||
for (let i = displayProperties.assetRange; i < displayProperties.assetRangeMax; i++) {
|
||||
items.push(getItem(i, allFields?.value?.items?.[i] ?? null));
|
||||
const item = allFields?.value?.items?.[i];
|
||||
if (item?.location) {
|
||||
items.push(getItem(i, item as { location: { name: string }; name: string }));
|
||||
} else {
|
||||
items.push(getItem(i, null));
|
||||
}
|
||||
}
|
||||
return items;
|
||||
});
|
||||
@@ -419,6 +426,7 @@
|
||||
<img
|
||||
:src="item.url"
|
||||
:style="{
|
||||
minWidth: `${out.card.height * 0.9}in`,
|
||||
width: `${out.card.height * 0.9}in`,
|
||||
height: `${out.card.height * 0.9}in`,
|
||||
}"
|
||||
@@ -427,8 +435,8 @@
|
||||
<div class="ml-2 flex flex-col justify-center">
|
||||
<div class="font-bold">{{ item.assetID }}</div>
|
||||
<div class="text-xs font-light italic">Homebox</div>
|
||||
<div>{{ item.name }}</div>
|
||||
<div>{{ item.location }}</div>
|
||||
<div class="overflow-hidden text-wrap text-xs">{{ item.name }}</div>
|
||||
<div class="text-xs">{{ item.location }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
<div class="divide-y divide-gray-300 border-t border-gray-300 px-6 pb-3">
|
||||
<DetailAction @action="modals.import = true">
|
||||
<template #title> {{ $t("tools.import_export_set.import") }} </template>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-html="$t('tools.import_export_set.import_sub')"></div>
|
||||
<template #button> {{ $t("tools.import_export_set.import_button") }} </template>
|
||||
</DetailAction>
|
||||
@@ -55,6 +56,7 @@
|
||||
<MdiAlert class="mr-2" />
|
||||
<span> {{ $t("tools.actions") }} </span>
|
||||
<template #description>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-html="$t('tools.actions_sub')"></div>
|
||||
</template>
|
||||
</BaseSectionHeader>
|
||||
@@ -72,11 +74,13 @@
|
||||
</DetailAction>
|
||||
<DetailAction @action="resetItemDateTimes">
|
||||
<template #title> {{ $t("tools.actions_set.zero_datetimes") }} </template>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-html="$t('tools.actions_set.zero_datetimes_sub')"></div>
|
||||
<template #button> {{ $t("tools.actions_set.zero_datetimes_button") }} </template>
|
||||
</DetailAction>
|
||||
<DetailAction @action="setPrimaryPhotos">
|
||||
<template #title> {{ $t("tools.actions_set.set_primary_photo") }} </template>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-html="$t('tools.actions_set.set_primary_photo_sub')"></div>
|
||||
<template #button> {{ $t("tools.actions_set.set_primary_photo_button") }} </template>
|
||||
</DetailAction>
|
||||
|
||||
@@ -2,10 +2,10 @@ import type { CompileError, MessageContext } from "vue-i18n";
|
||||
import { createI18n } from "vue-i18n";
|
||||
import { IntlMessageFormat } from "intl-messageformat";
|
||||
|
||||
export default defineNuxtPlugin(({ vueApp }) => {
|
||||
function checkDefaultLanguage() {
|
||||
export default defineNuxtPlugin(async ({ vueApp }) => {
|
||||
async function checkDefaultLanguage() {
|
||||
let matched = null;
|
||||
const languages = Object.getOwnPropertyNames(messages());
|
||||
const languages = Object.getOwnPropertyNames(await messages());
|
||||
const matching = navigator.languages.filter(lang => languages.some(l => l.toLowerCase() === lang.toLowerCase()));
|
||||
if (matching.length > 0) {
|
||||
matched = matching[0];
|
||||
@@ -25,20 +25,24 @@ export default defineNuxtPlugin(({ vueApp }) => {
|
||||
fallbackLocale: "en",
|
||||
globalInjection: true,
|
||||
legacy: false,
|
||||
locale: preferences.value.language || checkDefaultLanguage() || "en",
|
||||
locale: preferences.value.language || await checkDefaultLanguage() || "en",
|
||||
messageCompiler,
|
||||
messages: messages(),
|
||||
messages: await messages(),
|
||||
});
|
||||
vueApp.use(i18n);
|
||||
});
|
||||
|
||||
export const messages: Object = () => {
|
||||
export const messages = async () => {
|
||||
const messages: Record<string, any> = {};
|
||||
const modules = import.meta.glob("~//locales/**.json", { eager: true });
|
||||
for (const path in modules) {
|
||||
const key = path.slice(9, -5);
|
||||
messages[key] = modules[path];
|
||||
}
|
||||
// const modules = import.meta.glob("~//locales/**.json", { eager: true });
|
||||
// for (const path in modules) {
|
||||
// const key = path.slice(9, -5);
|
||||
// messages[key] = modules[path];
|
||||
// }
|
||||
console.log('Fetching translations...');
|
||||
const en = await (await fetch('https://raw.githubusercontent.com/sysadminsmedia/homebox/refs/heads/main/frontend/locales/en.json')).json();
|
||||
console.log('Fetched translations.');
|
||||
messages['en'] = en;
|
||||
return messages;
|
||||
};
|
||||
|
||||
|
||||
37
frontend/pnpm-lock.yaml
generated
37
frontend/pnpm-lock.yaml
generated
@@ -105,6 +105,9 @@ importers:
|
||||
'@vite-pwa/nuxt':
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(magicast@0.3.5)(rollup@4.24.0)(vite@4.5.5(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3)(workbox-build@7.1.1)(workbox-window@7.1.0)
|
||||
'@vue/runtime-core':
|
||||
specifier: ^3.5.12
|
||||
version: 3.5.12
|
||||
eslint:
|
||||
specifier: ^8.57.1
|
||||
version: 8.57.1
|
||||
@@ -2083,9 +2086,15 @@ packages:
|
||||
'@vue/reactivity@3.4.8':
|
||||
resolution: {integrity: sha512-UJYMQ3S2rqIGw9IvKomD4Xw2uS5VlcKEEmwcfboGOdrI79oqebxnCgTvXWLMClvg3M5SF0Cyn+9eDQoyGMLu9Q==}
|
||||
|
||||
'@vue/reactivity@3.5.12':
|
||||
resolution: {integrity: sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==}
|
||||
|
||||
'@vue/runtime-core@3.4.8':
|
||||
resolution: {integrity: sha512-sMRXOy89KnwY6fWG5epgPOsCWzpo/64FrA0QkjIeNeGnoA2YyZ6bBUxpFUyqhJ8VbrDhXEFH+6LHMOYrpzX/ZQ==}
|
||||
|
||||
'@vue/runtime-core@3.5.12':
|
||||
resolution: {integrity: sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==}
|
||||
|
||||
'@vue/runtime-dom@3.4.8':
|
||||
resolution: {integrity: sha512-L4gZcYo8f3d7rQqQIHkPvyczkjjQ55cJqz2G0v6Ptmqa1mO2zkqN9F8lBT6aGPYy3hd0RDiINbs4jxhSvvy10Q==}
|
||||
|
||||
@@ -2100,6 +2109,9 @@ packages:
|
||||
'@vue/shared@3.5.11':
|
||||
resolution: {integrity: sha512-W8GgysJVnFo81FthhzurdRAWP/byq3q2qIw70e0JWblzVhjgOMiC2GyovXrZTFQJnFVryYaKGP3Tc9vYzYm6PQ==}
|
||||
|
||||
'@vue/shared@3.5.12':
|
||||
resolution: {integrity: sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==}
|
||||
|
||||
'@vuepic/vue-datepicker@8.8.1':
|
||||
resolution: {integrity: sha512-8ehfUz1m69Vuc16Pm4ukgb3Mg1VT14x4EsG1ag4O/qbSNRWztTo+pUV4JnFt0FGLl5gGb6NXlxIvR7EjLgD7Gg==}
|
||||
peerDependencies:
|
||||
@@ -7271,7 +7283,7 @@ snapshots:
|
||||
|
||||
'@nuxtjs/eslint-config-typescript@12.1.0(eslint@8.57.1)(typescript@5.6.2)':
|
||||
dependencies:
|
||||
'@nuxtjs/eslint-config': 12.0.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
|
||||
'@nuxtjs/eslint-config': 12.0.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.2)
|
||||
eslint: 8.57.1
|
||||
@@ -7285,10 +7297,10 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@nuxtjs/eslint-config@12.0.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)':
|
||||
'@nuxtjs/eslint-config@12.0.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)':
|
||||
dependencies:
|
||||
eslint: 8.57.1
|
||||
eslint-config-standard: 17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1))(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1)
|
||||
eslint-config-standard: 17.1.0(eslint-plugin-import@2.31.0)(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1)
|
||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
eslint-plugin-n: 15.7.0(eslint@8.57.1)
|
||||
eslint-plugin-node: 11.1.0(eslint@8.57.1)
|
||||
@@ -7953,11 +7965,20 @@ snapshots:
|
||||
dependencies:
|
||||
'@vue/shared': 3.4.8
|
||||
|
||||
'@vue/reactivity@3.5.12':
|
||||
dependencies:
|
||||
'@vue/shared': 3.5.12
|
||||
|
||||
'@vue/runtime-core@3.4.8':
|
||||
dependencies:
|
||||
'@vue/reactivity': 3.4.8
|
||||
'@vue/shared': 3.4.8
|
||||
|
||||
'@vue/runtime-core@3.5.12':
|
||||
dependencies:
|
||||
'@vue/reactivity': 3.5.12
|
||||
'@vue/shared': 3.5.12
|
||||
|
||||
'@vue/runtime-dom@3.4.8':
|
||||
dependencies:
|
||||
'@vue/runtime-core': 3.4.8
|
||||
@@ -7974,6 +7995,8 @@ snapshots:
|
||||
|
||||
'@vue/shared@3.5.11': {}
|
||||
|
||||
'@vue/shared@3.5.12': {}
|
||||
|
||||
'@vuepic/vue-datepicker@8.8.1(vue@3.4.8(typescript@5.6.2))':
|
||||
dependencies:
|
||||
date-fns: 3.6.0
|
||||
@@ -8981,7 +9004,7 @@ snapshots:
|
||||
dependencies:
|
||||
eslint: 8.57.1
|
||||
|
||||
eslint-config-standard@17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1))(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1):
|
||||
eslint-config-standard@17.1.0(eslint-plugin-import@2.31.0)(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1):
|
||||
dependencies:
|
||||
eslint: 8.57.1
|
||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
@@ -9002,7 +9025,7 @@ snapshots:
|
||||
debug: 4.3.7
|
||||
enhanced-resolve: 5.17.1
|
||||
eslint: 8.57.1
|
||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
|
||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
fast-glob: 3.3.2
|
||||
get-tsconfig: 4.8.1
|
||||
is-bun-module: 1.2.1
|
||||
@@ -9015,7 +9038,7 @@ snapshots:
|
||||
- eslint-import-resolver-webpack
|
||||
- supports-color
|
||||
|
||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1):
|
||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
optionalDependencies:
|
||||
@@ -9049,7 +9072,7 @@ snapshots:
|
||||
doctrine: 2.1.0
|
||||
eslint: 8.57.1
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
|
||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.15.1
|
||||
is-glob: 4.0.3
|
||||
|
||||
@@ -2,6 +2,7 @@ import path from "path";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig({
|
||||
// @ts-ignore
|
||||
test: {
|
||||
globalSetup: "./test/setup.ts",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user