fix: address onboarding review feedback
This commit is contained in:
1 parent
07770e862c
commit
d89bf25e21
72 files changed
+7783
-280
No files matched your search
@@ -10,12 +10,11 @@ If you are still on a version before 0.15.10, please update to 0.15.10 where we
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
## Export your data
|
||||
## Preserve your old installation
|
||||
|
||||
As 1.0 is a complete rewrite of Homarr and therefor not compatible with the old docker mounts, we need to export your data first.
|
||||
For this you can navigate to the `Migrate to 1.0` page which you can find under `Management` > `Tools` > `Migrate to 1.0`.
|
||||
Here you can select which things you want to export and download the zip file.
|
||||
It will also show you a secret key which you will need to import the secret data like user password hashes, salts and integration secrets.
|
||||
Homarr 1.0 is a complete rewrite and cannot reuse the old Docker mounts. Keep the 0.15 installation and its data intact while you build the replacement. The historical `Management` > `Tools` > `Migrate to 1.0` export can still be kept as a record, but current Homarr releases cannot import that ZIP or its secret key.
|
||||
|
||||
Plan to recreate your apps, integrations, and boards manually in the new installation. A SQLite database backup can be restored from the onboarding welcome screen only when it was created by a compatible current Homarr release; it is not a conversion path for a 0.15 database.
|
||||
|
||||

|
||||
|
||||
@@ -31,7 +30,7 @@ So in your compose file the ports would be `7576:7575` instead of `7575:7575`.
|
||||
|
||||
:::warning Legacy guide
|
||||
|
||||
The pre-1.0 ZIP importer described by this historical migration guide is no longer included in current Homarr releases. Keep the old installation and export available while you recreate the required apps and boards in a supported release. SQLite database backups from current Homarr releases can still be restored from the onboarding welcome screen.
|
||||
The pre-1.0 ZIP importer is no longer included in current Homarr releases. Keep the old installation available until you have manually verified the replacement. Compatible SQLite backups from current releases can still be restored from the onboarding welcome screen.
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@@ -20,8 +20,18 @@ import { AppDeleteButton } from "./_app-delete-button";
|
||||
|
||||
const searchParamsSchema = z.object({
|
||||
search: z.string().optional(),
|
||||
pageSize: z.string().regex(/\d+/).transform(Number).catch(10),
|
||||
page: z.string().regex(/\d+/).transform(Number).catch(1),
|
||||
pageSize: z
|
||||
.string()
|
||||
.regex(/^[1-9]\d*$/u)
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
.catch(10),
|
||||
page: z
|
||||
.string()
|
||||
.regex(/^[1-9]\d*$/u)
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
.catch(1),
|
||||
});
|
||||
|
||||
interface AppsPageProps {
|
||||
@@ -87,7 +97,13 @@ export default async function AppsPage(props: AppsPageProps) {
|
||||
floatingPrimaryAction={canCreate}
|
||||
>
|
||||
{apps.map((app) => (
|
||||
<AppItem key={app.id} app={app} canModify={canModify} canDelete={canDelete} />
|
||||
<AppItem
|
||||
key={app.id}
|
||||
app={app}
|
||||
canModify={canModify}
|
||||
canDelete={canDelete}
|
||||
editLabel={t("page.list.action.edit", { name: app.name })}
|
||||
/>
|
||||
))}
|
||||
</ManageCollectionPage>
|
||||
);
|
||||
@@ -99,10 +115,10 @@ interface AppItemProps {
|
||||
app: RouterOutputs["app"]["getPaginated"]["items"][number];
|
||||
canModify: boolean;
|
||||
canDelete: boolean;
|
||||
editLabel: string;
|
||||
}
|
||||
|
||||
const AppItem = async ({ app, canModify, canDelete }: AppItemProps) => {
|
||||
const t = await getScopedI18n("app");
|
||||
const AppItem = ({ app, canModify, canDelete, editLabel }: AppItemProps) => {
|
||||
const descriptionLines = app.description?.split("\n");
|
||||
const safeHref = getSafeAppHref(app.href);
|
||||
|
||||
@@ -150,7 +166,7 @@ const AppItem = async ({ app, canModify, canDelete }: AppItemProps) => {
|
||||
variant="subtle"
|
||||
color="gray"
|
||||
size={44}
|
||||
aria-label={t("page.list.action.edit", { name: app.name })}
|
||||
aria-label={editLabel}
|
||||
>
|
||||
<IconPencil size={18} stroke={1.5} />
|
||||
</ActionIcon>
|
||||
|
||||
@@ -22,7 +22,7 @@ const iconProps = {
|
||||
|
||||
interface BoardCardMenuDropdownProps {
|
||||
board: Pick<
|
||||
RouterOutputs["board"]["getAllBoards"][number],
|
||||
RouterOutputs["board"]["getManageOverview"][number],
|
||||
"id" | "name" | "creator" | "userPermissions" | "groupPermissions" | "isPublic"
|
||||
>;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ export default async function ManageBoardsPage() {
|
||||
name: board.name,
|
||||
count: String(board.preview?.items.length ?? 0),
|
||||
}),
|
||||
unknownCreator: t("preview.unknownCreator"),
|
||||
home: t("action.setHomeBoard.badge.label"),
|
||||
homeTooltip: t("action.setHomeBoard.badge.tooltip"),
|
||||
mobileHome: t("action.setMobileHomeBoard.badge.label"),
|
||||
@@ -93,6 +94,7 @@ interface BoardCardProps {
|
||||
labels: {
|
||||
visibility: string;
|
||||
preview: string;
|
||||
unknownCreator: string;
|
||||
home: string;
|
||||
homeTooltip: string;
|
||||
mobileHome: string;
|
||||
@@ -139,7 +141,7 @@ const BoardCard = ({ board, isMenuVisible, labels }: BoardCardProps) => {
|
||||
)}
|
||||
|
||||
{board.creator && (
|
||||
<Tooltip label={board.creator.name ?? board.creator.email}>
|
||||
<Tooltip label={board.creator.name ?? labels.unknownCreator}>
|
||||
<UserAvatar user={board.creator} size="sm" />
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
@@ -13,7 +13,7 @@ const noStoreHeaders = { "Cache-Control": "no-store" };
|
||||
export async function POST(request: Request) {
|
||||
const fetchSite = request.headers.get("sec-fetch-site");
|
||||
if (fetchSite && fetchSite !== "same-origin" && fetchSite !== "none") {
|
||||
return NextResponse.json({ error: "Cross-site onboarding claims are not allowed." }, { status: 403 });
|
||||
return NextResponse.json({ code: "cross_site" }, { status: 403 });
|
||||
}
|
||||
|
||||
const session = await auth();
|
||||
@@ -22,21 +22,18 @@ export async function POST(request: Request) {
|
||||
force: session?.user.permissions.includes("admin") ?? false,
|
||||
});
|
||||
if (result.status === "finished") {
|
||||
const response = NextResponse.json({ error: "Onboarding is already complete." }, { status: 409 });
|
||||
const response = NextResponse.json({ code: "finished" }, { status: 409 });
|
||||
response.cookies.delete(onboardingClaimCookieName);
|
||||
return response;
|
||||
}
|
||||
if (result.status === "forbidden") {
|
||||
return NextResponse.json({ error: "Administrator access is required." }, { status: 403 });
|
||||
return NextResponse.json({ code: "administrator_required" }, { status: 403 });
|
||||
}
|
||||
if (result.status === "locked") {
|
||||
return NextResponse.json(
|
||||
{ error: "Another browser has already claimed onboarding.", expiresAt: result.expiresAt },
|
||||
{ status: 423, headers: noStoreHeaders },
|
||||
);
|
||||
return NextResponse.json({ code: "locked", expiresAt: result.expiresAt }, { status: 423, headers: noStoreHeaders });
|
||||
}
|
||||
if (result.status !== "issued" && result.status !== "active") {
|
||||
return NextResponse.json({ error: "Onboarding could not be claimed." }, { status: 409 });
|
||||
return NextResponse.json({ code: "unavailable" }, { status: 409 });
|
||||
}
|
||||
|
||||
const forwardedProtocol = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
|
||||
|
||||
@@ -15,7 +15,7 @@ interface BoardLayoutThumbnailProps {
|
||||
const maxThumbnailRows = 12;
|
||||
|
||||
export const BoardLayoutThumbnail = ({ preview, label }: BoardLayoutThumbnailProps) => {
|
||||
const layout = preview?.layouts.at(0);
|
||||
const layout = preview?.layouts.find((candidate) => candidate.role === "base") ?? preview?.layouts.at(0);
|
||||
if (!preview || !layout) {
|
||||
return (
|
||||
<Center className={classes.canvas} role="img" aria-label={label}>
|
||||
@@ -25,7 +25,9 @@ export const BoardLayoutThumbnail = ({ preview, label }: BoardLayoutThumbnailPro
|
||||
}
|
||||
|
||||
const elements = projectBoardLayout(preview, layout, layout);
|
||||
const roots = preview.sections.filter((section) => section.kind === "empty");
|
||||
const roots = preview.sections
|
||||
.filter((section) => section.kind === "empty")
|
||||
.toSorted((first, second) => (first.xOffset ?? 0) - (second.xOffset ?? 0) || first.id.localeCompare(second.id));
|
||||
const lanes = boardLanes.flatMap((lane) => {
|
||||
const root = roots.find((section) => getRootSectionLane(section.xOffset) === lane);
|
||||
const columnCount = getBoardLaneColumnCount(layout, lane);
|
||||
|
||||
@@ -52,7 +52,7 @@ export const ManageCollectionItem = ({
|
||||
<Stack gap={4} flex={1} miw={0}>
|
||||
<Group gap="xs" wrap="wrap">
|
||||
{title}
|
||||
{badges}
|
||||
{badges && <Box style={{ flexShrink: 0 }}>{badges}</Box>}
|
||||
</Group>
|
||||
{description}
|
||||
{metadata}
|
||||
|
||||
@@ -72,6 +72,17 @@ describe("locale and onboarding proxy", () => {
|
||||
expect(mocks.getOnboardingStep).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not treat nested routes ending in init or auth/login as onboarding access routes", async () => {
|
||||
mocks.getOnboardingStep.mockResolvedValue("setup");
|
||||
const { proxy } = await loadProxy();
|
||||
|
||||
const initResponse = await proxy(createRequest("/en/boards/init"));
|
||||
const loginResponse = await proxy(createRequest("/en/settings/auth/login"));
|
||||
|
||||
expect(initResponse.headers.get("location")).toBe("http://localhost/init");
|
||||
expect(loginResponse.headers.get("location")).toBe("http://localhost/init");
|
||||
});
|
||||
|
||||
it("uses the configured default locale for a missing or invalid locale cookie", async () => {
|
||||
mocks.getDefaultLocale.mockResolvedValue("de");
|
||||
const { proxy } = await loadProxy();
|
||||
|
||||
@@ -42,7 +42,11 @@ const getDefaultLocaleDedupedAsync = () => {
|
||||
export async function proxy(request: NextRequest) {
|
||||
// Redirect to onboarding if it's not finished yet
|
||||
const pathname = request.nextUrl.pathname;
|
||||
const isOnboardingAccessRoute = /\/(?:init|auth\/login)\/?$/.test(pathname);
|
||||
const segments = pathname.split("/").filter(Boolean);
|
||||
const routeSegments = supportedLanguages.includes(segments[0] as SupportedLanguage) ? segments.slice(1) : segments;
|
||||
const isOnboardingAccessRoute =
|
||||
(routeSegments.length === 1 && routeSegments[0] === "init") ||
|
||||
(routeSegments.length === 2 && routeSegments[0] === "auth" && routeSegments[1] === "login");
|
||||
|
||||
if (!isOnboardingFinished && !isOnboardingAccessRoute) {
|
||||
const currentOnboardingStep = await getOnboardingStepDedupedAsync();
|
||||
|
||||
+98
-51
@@ -1,4 +1,4 @@
|
||||
import { mkdir, readFile } from "node:fs/promises";
|
||||
import { mkdir, readFile, rm } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
import { chromium } from "@playwright/test";
|
||||
@@ -23,41 +23,53 @@ const captureScreenshotAsync = async (page: Page, name: string) => {
|
||||
await page.screenshot({ path: path.join(directory, `onboarding-${name}.png`), fullPage: true });
|
||||
};
|
||||
|
||||
const createRestoreArchiveAsync = async () => {
|
||||
const { db, localMountPath } = await createSqliteDbFileAsync();
|
||||
await db.insert(sqliteSchema.onboarding).values({ id: "onboarding", step: "finish", previousStep: "setup" });
|
||||
await db.insert(sqliteSchema.boards).values({ id: "restored-board", name: "restored", isPublic: true });
|
||||
await db.insert(sqliteSchema.layouts).values({
|
||||
id: "restored-base",
|
||||
boardId: "restored-board",
|
||||
name: "Base",
|
||||
role: "base",
|
||||
columnCount: 10,
|
||||
breakpoint: 768,
|
||||
});
|
||||
await db.insert(sqliteSchema.sections).values({
|
||||
id: "restored-root",
|
||||
boardId: "restored-board",
|
||||
kind: "empty",
|
||||
xOffset: 0,
|
||||
yOffset: 0,
|
||||
});
|
||||
db.$client.close();
|
||||
type SqliteTestDatabase = Awaited<ReturnType<typeof createSqliteDbFileAsync>>;
|
||||
|
||||
const zip = new AdmZip();
|
||||
zip.addFile("db.sqlite", await readFile(path.join(localMountPath, "db", "db.sqlite")));
|
||||
zip.addFile(
|
||||
"metadata.json",
|
||||
Buffer.from(
|
||||
JSON.stringify({
|
||||
homarrVersion: "e2e",
|
||||
exportedAt: new Date().toISOString(),
|
||||
dbDialect: "sqlite",
|
||||
encryptionKey: "0".repeat(64),
|
||||
}),
|
||||
),
|
||||
);
|
||||
return zip.toBuffer();
|
||||
const cleanupSqliteDbAsync = async ({ db, localMountPath }: SqliteTestDatabase) => {
|
||||
if (db.$client.open) db.$client.close();
|
||||
await rm(localMountPath, { recursive: true, force: true });
|
||||
};
|
||||
|
||||
const createRestoreArchiveAsync = async () => {
|
||||
const sqlite = await createSqliteDbFileAsync();
|
||||
const { db, localMountPath } = sqlite;
|
||||
try {
|
||||
await db.insert(sqliteSchema.onboarding).values({ id: "onboarding", step: "finish", previousStep: "setup" });
|
||||
await db.insert(sqliteSchema.boards).values({ id: "restored-board", name: "restored", isPublic: true });
|
||||
await db.insert(sqliteSchema.layouts).values({
|
||||
id: "restored-base",
|
||||
boardId: "restored-board",
|
||||
name: "Base",
|
||||
role: "base",
|
||||
columnCount: 10,
|
||||
breakpoint: 768,
|
||||
});
|
||||
await db.insert(sqliteSchema.sections).values({
|
||||
id: "restored-root",
|
||||
boardId: "restored-board",
|
||||
kind: "empty",
|
||||
xOffset: 0,
|
||||
yOffset: 0,
|
||||
});
|
||||
db.$client.close();
|
||||
|
||||
const zip = new AdmZip();
|
||||
zip.addFile("db.sqlite", await readFile(path.join(localMountPath, "db", "db.sqlite")));
|
||||
zip.addFile(
|
||||
"metadata.json",
|
||||
Buffer.from(
|
||||
JSON.stringify({
|
||||
homarrVersion: "e2e",
|
||||
exportedAt: new Date().toISOString(),
|
||||
dbDialect: "sqlite",
|
||||
encryptionKey: "0".repeat(64),
|
||||
}),
|
||||
),
|
||||
);
|
||||
return zip.toBuffer();
|
||||
} finally {
|
||||
await cleanupSqliteDbAsync(sqlite);
|
||||
}
|
||||
};
|
||||
|
||||
describe("Onboarding", () => {
|
||||
@@ -68,7 +80,8 @@ describe("Onboarding", () => {
|
||||
])(
|
||||
"Onboarding is usable at the $name viewport",
|
||||
async ({ name, width, height }) => {
|
||||
const { localMountPath } = await createSqliteDbFileAsync();
|
||||
const sqlite = await createSqliteDbFileAsync();
|
||||
const { localMountPath } = sqlite;
|
||||
const homarrContainer = await createHomarrContainer({ mounts: { "/appdata": localMountPath } }).start();
|
||||
const browser = await chromium.launch();
|
||||
const context = await browser.newContext({ viewport: { width, height }, reducedMotion: "reduce" });
|
||||
@@ -159,7 +172,11 @@ describe("Onboarding", () => {
|
||||
expect(await boardCanvas.locator("[data-grid-item-id]").count()).toBeGreaterThanOrEqual(3);
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth + 1)).toBe(true);
|
||||
} finally {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
try {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
} finally {
|
||||
await cleanupSqliteDbAsync(sqlite);
|
||||
}
|
||||
}
|
||||
},
|
||||
90_000,
|
||||
@@ -169,7 +186,8 @@ describe("Onboarding", () => {
|
||||
const restoreArchive = await createRestoreArchiveAsync();
|
||||
const invalidArchive = new AdmZip();
|
||||
invalidArchive.addFile("db.sqlite", Buffer.from("not-a-database"));
|
||||
const { localMountPath } = await createSqliteDbFileAsync();
|
||||
const sqlite = await createSqliteDbFileAsync();
|
||||
const { localMountPath } = sqlite;
|
||||
const initialContainer = await createHomarrContainer({ mounts: { "/appdata": localMountPath } }).start();
|
||||
let initialContainerStopped = false;
|
||||
let restoredContainer: StartedTestContainer | undefined;
|
||||
@@ -209,15 +227,20 @@ describe("Onboarding", () => {
|
||||
await page.locator('[data-testid="board-canvas"][data-board-hydrated="true"]').waitFor({ timeout: 30_000 });
|
||||
expect(page.url()).toMatch(/\/boards\/restored(?:[/?#]|$)/);
|
||||
} finally {
|
||||
await browser.close();
|
||||
if (!initialContainerStopped) await initialContainer.stop();
|
||||
if (restoredContainer) await restoredContainer.stop();
|
||||
try {
|
||||
await browser.close();
|
||||
if (!initialContainerStopped) await initialContainer.stop();
|
||||
if (restoredContainer) await restoredContainer.stop();
|
||||
} finally {
|
||||
await cleanupSqliteDbAsync(sqlite);
|
||||
}
|
||||
}
|
||||
}, 120_000);
|
||||
|
||||
test("Credentials onboarding should be successful", async () => {
|
||||
// Arrange
|
||||
const { db, localMountPath } = await createSqliteDbFileAsync();
|
||||
const sqlite = await createSqliteDbFileAsync();
|
||||
const { db, localMountPath } = sqlite;
|
||||
const homarrContainer = await createHomarrContainer({
|
||||
mounts: {
|
||||
"/appdata": localMountPath,
|
||||
@@ -255,12 +278,17 @@ describe("Onboarding", () => {
|
||||
await assertions.assertUserAndAdminGroupInsertedAsync("admin");
|
||||
await assertions.assertDbOnboardingStepAsync("finish");
|
||||
} finally {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
try {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
} finally {
|
||||
await cleanupSqliteDbAsync(sqlite);
|
||||
}
|
||||
}
|
||||
}, 60_000);
|
||||
|
||||
test("Credentials onboarding recovers when automatic sign-in fails after account creation", async () => {
|
||||
const { db, localMountPath } = await createSqliteDbFileAsync();
|
||||
const sqlite = await createSqliteDbFileAsync();
|
||||
const { db, localMountPath } = sqlite;
|
||||
const homarrContainer = await createHomarrContainer({ mounts: { "/appdata": localMountPath } }).start();
|
||||
const browser = await chromium.launch();
|
||||
const context = await browser.newContext();
|
||||
@@ -286,13 +314,18 @@ describe("Onboarding", () => {
|
||||
expect((await db.query.users.findMany()).length).toBe(1);
|
||||
expect((await db.query.onboarding.findFirst())?.step).toBe("setup");
|
||||
} finally {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
try {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
} finally {
|
||||
await cleanupSqliteDbAsync(sqlite);
|
||||
}
|
||||
}
|
||||
}, 60_000);
|
||||
|
||||
test("External provider onboarding requires sign-in before privileged setup", async () => {
|
||||
// Arrange
|
||||
const { db, localMountPath } = await createSqliteDbFileAsync();
|
||||
const sqlite = await createSqliteDbFileAsync();
|
||||
const { db, localMountPath } = sqlite;
|
||||
const homarrContainer = await createHomarrContainer({
|
||||
environment: {
|
||||
AUTH_PROVIDERS: "ldap",
|
||||
@@ -329,13 +362,18 @@ describe("Onboarding", () => {
|
||||
await assertions.assertExternalGroupInsertedAsync(externalGroupName);
|
||||
await assertions.assertDbOnboardingStepAsync("setup");
|
||||
} finally {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
try {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
} finally {
|
||||
await cleanupSqliteDbAsync(sqlite);
|
||||
}
|
||||
}
|
||||
}, 60_000);
|
||||
|
||||
test("Legacy setup requires sign-in without exposing private board metadata", async () => {
|
||||
const credentials = { username: "admin", password: "Comp(exP4sswOrd" };
|
||||
const { db, localMountPath } = await createSqliteDbFileAsync();
|
||||
const sqlite = await createSqliteDbFileAsync();
|
||||
const { db, localMountPath } = sqlite;
|
||||
await seedAdminUserAsync(db, credentials);
|
||||
await db.update(sqliteSchema.onboarding).set({ step: "import" as never });
|
||||
const privateBoardName = "private-board-must-not-leak";
|
||||
@@ -376,13 +414,18 @@ describe("Onboarding", () => {
|
||||
await page.getByRole("heading", { name: "Start with familiar defaults" }).waitFor();
|
||||
expect(await page.getByRole("heading", { name: "Create your administrator" }).count()).toBe(0);
|
||||
} finally {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
try {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
} finally {
|
||||
await cleanupSqliteDbAsync(sqlite);
|
||||
}
|
||||
}
|
||||
}, 90_000);
|
||||
|
||||
test("Assistant setup restores saved configuration and accepts a manual model", async () => {
|
||||
const credentials = { username: "admin", password: "Comp(exP4sswOrd" };
|
||||
const { db, localMountPath } = await createSqliteDbFileAsync();
|
||||
const sqlite = await createSqliteDbFileAsync();
|
||||
const { db, localMountPath } = sqlite;
|
||||
await seedAdminUserAsync(db, credentials);
|
||||
await db.update(sqliteSchema.onboarding).set({ step: "setup", previousStep: "group" });
|
||||
await db.insert(sqliteSchema.assistantConfigurations).values({
|
||||
@@ -419,7 +462,11 @@ describe("Onboarding", () => {
|
||||
expect(await page.getByLabel("Default model").inputValue()).toBe("local-model");
|
||||
expect(await page.getByText("Model discovery is unavailable.").count()).toBe(1);
|
||||
} finally {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
try {
|
||||
await Promise.all([browser.close(), homarrContainer.stop()]);
|
||||
} finally {
|
||||
await cleanupSqliteDbAsync(sqlite);
|
||||
}
|
||||
}
|
||||
}, 90_000);
|
||||
});
|
||||
@@ -49,7 +49,12 @@ export const getOnboardingClaimTokenFromCookieHeader = (cookieHeader: string | n
|
||||
const name = part.slice(0, separator).trim();
|
||||
if (name !== onboardingClaimCookieName) continue;
|
||||
const value = part.slice(separator + 1).trim();
|
||||
return value || undefined;
|
||||
if (!value) return undefined;
|
||||
try {
|
||||
return decodeURIComponent(value);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
@@ -19,8 +19,6 @@ const defaultIcon = "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@mas
|
||||
|
||||
export const appRouter = createTRPCRouter({
|
||||
getPaginated: protectedProcedure
|
||||
.input(paginatedSchema)
|
||||
.output(z.object({ items: z.array(selectAppSchema), totalCount: z.number() }))
|
||||
.meta({
|
||||
openapi: {
|
||||
method: "GET",
|
||||
@@ -34,6 +32,8 @@ export const appRouter = createTRPCRouter({
|
||||
"List apps with pagination. OPTIONAL: search (string to filter by name), pageSize (number, default 10), page (number, default 1). All fields are optional — call with no arguments to get the first page",
|
||||
},
|
||||
})
|
||||
.input(paginatedSchema)
|
||||
.output(z.object({ items: z.array(selectAppSchema), totalCount: z.number() }))
|
||||
.query(async ({ input, ctx }) => {
|
||||
const whereQuery = input.search ? like(apps.name, `%${input.search.trim()}%`) : undefined;
|
||||
const totalCount = await ctx.db.$count(apps, whereQuery);
|
||||
|
||||
@@ -242,7 +242,6 @@ export const boardRouter = createTRPCRouter({
|
||||
id: true,
|
||||
name: true,
|
||||
image: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
userPermissions: {
|
||||
|
||||
@@ -7,7 +7,6 @@ export const nextOnboardingStepAsync = async (db: Database) => {
|
||||
const { current } = await getOnboardingOrFallbackAsync(db);
|
||||
if (current !== "start") return;
|
||||
const nextStep = await getNextOnboardingStepAsync(db);
|
||||
if (!nextStep) return;
|
||||
|
||||
await db.update(onboarding).set({ previousStep: current, step: nextStep });
|
||||
};
|
||||
|
||||
@@ -8,6 +8,8 @@ import { z } from "zod/v4";
|
||||
|
||||
import { createId } from "@homarr/common";
|
||||
import { encryptSecret } from "@homarr/common/server";
|
||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||
import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error";
|
||||
import { handleTransactionsAsync, eq, inArray, like, or } from "@homarr/db";
|
||||
import { getServerSettingByKeyAsync } from "@homarr/db/queries";
|
||||
import {
|
||||
@@ -50,6 +52,8 @@ import { MissingSecretError, testConnectionAsync } from "../integration/integrat
|
||||
import { getOnboardingOrFallbackAsync, nextOnboardingStepAsync } from "./onboard-queries";
|
||||
import { probeRuntimeCapabilitiesAsync } from "./capability-probes";
|
||||
|
||||
const logger = createLogger({ module: "onboardRouter" });
|
||||
|
||||
interface PortInfo {
|
||||
IP?: string;
|
||||
PublicPort?: number;
|
||||
@@ -159,7 +163,7 @@ export const onboardRouter = createTRPCRouter({
|
||||
const empty = { integrations: [] as DiscoveredIntegration[], apps: [] as DiscoveredApp[] };
|
||||
|
||||
try {
|
||||
const { listDiscoveredContainersAsync, dockerLabels } = await import("@homarr/docker");
|
||||
const { createDockerSourceId, listDiscoveredContainersAsync, dockerLabels } = await import("@homarr/docker");
|
||||
const discovery = await listDiscoveredContainersAsync();
|
||||
const successfulHosts = discovery.hosts.filter((host) => host.status === "success");
|
||||
const unavailableHosts = discovery.hosts.filter((host) => host.status === "unavailable");
|
||||
@@ -169,14 +173,15 @@ export const onboardRouter = createTRPCRouter({
|
||||
.map((container) => ({ ...container, host: hostResult.host })),
|
||||
);
|
||||
const labeledContainerKeys = new Set(
|
||||
discovery.services.map((service) => `${service.host}:${service.containerId}`),
|
||||
discovery.services.map((service) => createDockerSourceId(service.host, service.containerId)),
|
||||
);
|
||||
const imageCandidates = containers.filter(
|
||||
(container) => !labeledContainerKeys.has(`${container.host}:${container.Id}`),
|
||||
);
|
||||
const likeQueries = imageCandidates.map((container) =>
|
||||
like(icons.name, `%${extractContainerImageName(container.Image)}%`),
|
||||
(container) => !labeledContainerKeys.has(createDockerSourceId(container.host, container.Id)),
|
||||
);
|
||||
const candidateImageNames = [
|
||||
...new Set(imageCandidates.map((container) => extractContainerImageName(container.Image)).filter(Boolean)),
|
||||
].slice(0, 64);
|
||||
const likeQueries = candidateImageNames.map((imageName) => like(icons.name, `%${imageName}%`));
|
||||
const dbIcons = likeQueries.length > 0 ? await ctx.db.query.icons.findMany({ where: or(...likeQueries) }) : [];
|
||||
const cdnIconUrl = (slug: string) =>
|
||||
`https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/${slug}.svg`;
|
||||
@@ -237,7 +242,7 @@ export const onboardRouter = createTRPCRouter({
|
||||
const iconUrl = dbIcon ?? cdnIconUrl(imageName.toLowerCase());
|
||||
const { url: suggestedUrl, publishedPort } = buildSuggestedUrl(container.Ports, container.host);
|
||||
const kind = matchIntegrationKindFromContainer({ image: container.Image, name: containerName });
|
||||
const sourceId = `docker:${container.host}:${container.Id}`;
|
||||
const sourceId = createDockerSourceId(container.host, container.Id);
|
||||
|
||||
if (kind) {
|
||||
discoveredIntegrations.push({
|
||||
@@ -281,6 +286,7 @@ export const onboardRouter = createTRPCRouter({
|
||||
|
||||
return { status, hosts, integrations: discoveredIntegrations, apps: discoveredApps };
|
||||
} catch (error) {
|
||||
logger.warn(new ErrorWithMetadata("Docker discovery failed during onboarding", {}, { cause: error }));
|
||||
const reason = error instanceof Error ? error.message : "Docker discovery failed";
|
||||
return {
|
||||
status: "unavailable" as const,
|
||||
@@ -306,6 +312,9 @@ export const onboardRouter = createTRPCRouter({
|
||||
: boardList.length === 1
|
||||
? boardList[0]
|
||||
: undefined;
|
||||
if (input.board.id !== undefined && !existingTargetBoard) {
|
||||
throw new TRPCError({ code: "NOT_FOUND", message: "The selected board no longer exists." });
|
||||
}
|
||||
const pendingBoardRow =
|
||||
boardList.length === 0 && input.board.id === undefined
|
||||
? {
|
||||
@@ -701,6 +710,48 @@ export const onboardRouter = createTRPCRouter({
|
||||
return id;
|
||||
};
|
||||
|
||||
const getDockerWidgetPlan = (service: (typeof selectedDockerSources)[number]) => {
|
||||
const widgetKind = service.widgetKind;
|
||||
if (!widgetKind || !input.selectedWidgetKinds.includes(widgetKind)) return null;
|
||||
const integration = service.integrationKind
|
||||
? selectedIntegrations.find(
|
||||
(candidate) => candidate.id === stableOnboardingId("integration", service.sourceId),
|
||||
)
|
||||
: undefined;
|
||||
const issue = getWidgetIntegrationIssue(widgetKind, integration ? [integration.kind] : []);
|
||||
if (issue) {
|
||||
if (issue.code !== "integration-limit") {
|
||||
skippedWidgets.push({
|
||||
sourceId: service.sourceId,
|
||||
widgetKind,
|
||||
code: issue.code,
|
||||
integrationKind: integration?.kind,
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const config = getDefaultWidgetConfig(widgetKind);
|
||||
return config.skip ? null : { widgetKind, integration, config };
|
||||
};
|
||||
|
||||
const linkExistingDockerWidget = (
|
||||
widgetKind: WidgetKind,
|
||||
integration: (typeof selectedIntegrations)[number] | undefined,
|
||||
) => {
|
||||
const existing = existingItemsByKind.get(widgetKind);
|
||||
if (!existing) return false;
|
||||
if (!integration) return true;
|
||||
const linkedIds = new Set([
|
||||
...existing.integrations.map((row) => row.integrationId),
|
||||
...newIntegrationItems.filter((row) => row.itemId === existing.id).map((row) => row.integrationId),
|
||||
]);
|
||||
if (linkedIds.has(integration.id)) return true;
|
||||
const limit = widgetIntegrationLimits[widgetKind] ?? Number.POSITIVE_INFINITY;
|
||||
if (linkedIds.size >= limit) return false;
|
||||
newIntegrationItems.push({ itemId: existing.id, integrationId: integration.id });
|
||||
return true;
|
||||
};
|
||||
|
||||
const selectedIntegrationIdsByWidget = new Map<WidgetKind, string[]>();
|
||||
const labeledIntegrationSourceById = new Map(
|
||||
selectedDockerSources
|
||||
@@ -780,48 +831,15 @@ export const onboardRouter = createTRPCRouter({
|
||||
if (app && !existingAppIds.has(app.id)) {
|
||||
placeNewItem("app", SuperJSON.stringify({ appId: app.id, openInNewTab: true, showTitle: true }), 1, 1);
|
||||
}
|
||||
if (!service.widgetKind || !input.selectedWidgetKinds.includes(service.widgetKind)) continue;
|
||||
const integration = service.integrationKind
|
||||
? selectedIntegrations.find(
|
||||
(candidate) => candidate.id === stableOnboardingId("integration", service.sourceId),
|
||||
)
|
||||
: undefined;
|
||||
const issue = getWidgetIntegrationIssue(service.widgetKind, integration ? [integration.kind] : []);
|
||||
if (issue) {
|
||||
if (issue.code !== "integration-limit") {
|
||||
skippedWidgets.push({
|
||||
sourceId: service.sourceId,
|
||||
widgetKind: service.widgetKind,
|
||||
code: issue.code,
|
||||
integrationKind: integration?.kind,
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const existing = existingItemsByKind.get(service.widgetKind);
|
||||
if (existing && integration) {
|
||||
const linkedIds = new Set([
|
||||
...existing.integrations.map((row) => row.integrationId),
|
||||
...newIntegrationItems.filter((row) => row.itemId === existing.id).map((row) => row.integrationId),
|
||||
]);
|
||||
const limit = widgetIntegrationLimits[service.widgetKind] ?? Number.POSITIVE_INFINITY;
|
||||
if (!linkedIds.has(integration.id) && linkedIds.size < limit) {
|
||||
newIntegrationItems.push({ itemId: existing.id, integrationId: integration.id });
|
||||
continue;
|
||||
}
|
||||
if (linkedIds.has(integration.id)) continue;
|
||||
} else if (existing) {
|
||||
continue;
|
||||
}
|
||||
const config = getDefaultWidgetConfig(service.widgetKind);
|
||||
if (config.skip) continue;
|
||||
const plan = getDockerWidgetPlan(service);
|
||||
if (!plan || linkExistingDockerWidget(plan.widgetKind, plan.integration)) continue;
|
||||
const itemId = placeNewItem(
|
||||
service.widgetKind,
|
||||
config.options ? SuperJSON.stringify(config.options) : emptySuperJSON,
|
||||
config.width,
|
||||
config.height,
|
||||
plan.widgetKind,
|
||||
plan.config.options ? SuperJSON.stringify(plan.config.options) : emptySuperJSON,
|
||||
plan.config.width,
|
||||
plan.config.height,
|
||||
);
|
||||
if (integration) newIntegrationItems.push({ itemId, integrationId: integration.id });
|
||||
if (plan.integration) newIntegrationItems.push({ itemId, integrationId: plan.integration.id });
|
||||
}
|
||||
|
||||
const groupedSourcesByName = Map.groupBy(
|
||||
@@ -857,49 +875,14 @@ export const onboardRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
if (!service.widgetKind || !input.selectedWidgetKinds.includes(service.widgetKind)) continue;
|
||||
const integration = service.integrationKind
|
||||
? selectedIntegrations.find(
|
||||
(candidate) => candidate.id === stableOnboardingId("integration", service.sourceId),
|
||||
)
|
||||
: undefined;
|
||||
const issue = getWidgetIntegrationIssue(service.widgetKind, integration ? [integration.kind] : []);
|
||||
if (issue) {
|
||||
if (issue.code !== "integration-limit") {
|
||||
skippedWidgets.push({
|
||||
sourceId: service.sourceId,
|
||||
widgetKind: service.widgetKind,
|
||||
code: issue.code,
|
||||
integrationKind: integration?.kind,
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const existing = existingItemsByKind.get(service.widgetKind);
|
||||
if (existing && integration) {
|
||||
const linkedIds = new Set([
|
||||
...existing.integrations.map((row) => row.integrationId),
|
||||
...newIntegrationItems.filter((row) => row.itemId === existing.id).map((row) => row.integrationId),
|
||||
]);
|
||||
const limit = widgetIntegrationLimits[service.widgetKind] ?? Number.POSITIVE_INFINITY;
|
||||
if (!linkedIds.has(integration.id) && linkedIds.size < limit) {
|
||||
newIntegrationItems.push({ itemId: existing.id, integrationId: integration.id });
|
||||
continue;
|
||||
}
|
||||
if (linkedIds.has(integration.id)) continue;
|
||||
} else if (existing) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const config = getDefaultWidgetConfig(service.widgetKind);
|
||||
if (config.skip) continue;
|
||||
const plan = getDockerWidgetPlan(service);
|
||||
if (!plan || linkExistingDockerWidget(plan.widgetKind, plan.integration)) continue;
|
||||
groupedItemPlans.push({
|
||||
kind: service.widgetKind,
|
||||
options: config.options ? SuperJSON.stringify(config.options) : emptySuperJSON,
|
||||
width: config.width,
|
||||
height: config.height,
|
||||
integrationId: integration?.id,
|
||||
kind: plan.widgetKind,
|
||||
options: plan.config.options ? SuperJSON.stringify(plan.config.options) : emptySuperJSON,
|
||||
width: plan.config.width,
|
||||
height: plan.config.height,
|
||||
integrationId: plan.integration?.id,
|
||||
});
|
||||
}
|
||||
if (groupedItemPlans.length === 0) continue;
|
||||
@@ -982,10 +965,12 @@ export const onboardRouter = createTRPCRouter({
|
||||
}
|
||||
}
|
||||
|
||||
const currentAppearance = await getServerSettingByKeyAsync(ctx.db, "appearance");
|
||||
const currentCulture = await getServerSettingByKeyAsync(ctx.db, "culture");
|
||||
const currentAnalytics = await getServerSettingByKeyAsync(ctx.db, "analytics");
|
||||
const currentBoardSettings = await getServerSettingByKeyAsync(ctx.db, "board");
|
||||
const [currentAppearance, currentCulture, currentAnalytics, currentBoardSettings] = await Promise.all([
|
||||
getServerSettingByKeyAsync(ctx.db, "appearance"),
|
||||
getServerSettingByKeyAsync(ctx.db, "culture"),
|
||||
getServerSettingByKeyAsync(ctx.db, "analytics"),
|
||||
getServerSettingByKeyAsync(ctx.db, "board"),
|
||||
]);
|
||||
const settingValues = {
|
||||
appearance: SuperJSON.stringify({ ...currentAppearance, defaultColorScheme: input.server.defaultColorScheme }),
|
||||
culture: SuperJSON.stringify({ ...currentCulture, defaultLocale: input.server.defaultLocale }),
|
||||
|
||||
@@ -288,6 +288,20 @@ describe("getAllBoards should return all boards accessable to the current user",
|
||||
});
|
||||
|
||||
describe("getManageOverview", () => {
|
||||
test("does not expose a public board creator email to anonymous callers", async () => {
|
||||
const db = createDb();
|
||||
const caller = boardRouter.createCaller({ db, deviceType: undefined, session: null });
|
||||
const creatorId = createId();
|
||||
|
||||
await db.insert(users).values({ id: creatorId, name: "Board creator", email: "private@example.com" });
|
||||
await db.insert(boards).values({ id: createId(), name: "public-overview", creatorId, isPublic: true });
|
||||
|
||||
const [board] = await caller.getManageOverview();
|
||||
|
||||
expect(board?.creator).toEqual({ id: creatorId, name: "Board creator", image: null });
|
||||
expect(board?.creator).not.toHaveProperty("email");
|
||||
});
|
||||
|
||||
test("returns the same accessible board set as getAllBoards", async () => {
|
||||
const db = createDb();
|
||||
const caller = boardRouter.createCaller({ db, deviceType: undefined, session: defaultSession });
|
||||
@@ -433,6 +447,8 @@ describe("getManageOverview", () => {
|
||||
const result = await caller.getManageOverview();
|
||||
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]?.creator).toEqual({ id: defaultCreatorId, name: null, image: null });
|
||||
expect(result[0]?.creator).not.toHaveProperty("email");
|
||||
expect(result[0]).toMatchObject({
|
||||
id: boardId,
|
||||
isHome: true,
|
||||
|
||||
@@ -43,6 +43,8 @@ vi.mock("@homarr/common", async (importOriginal) => ({
|
||||
createId: createIdMock,
|
||||
}));
|
||||
vi.mock("@homarr/docker", () => ({
|
||||
createDockerSourceId: (host: string, externalId: string) =>
|
||||
`docker:${encodeURIComponent(host)}:${encodeURIComponent(externalId)}`,
|
||||
dockerLabels: { hide: "homarr.hide" },
|
||||
listDiscoveredContainersAsync,
|
||||
}));
|
||||
@@ -267,6 +269,20 @@ describe("onboard.completeSetup", () => {
|
||||
expect(await db.query.onboarding.findFirst()).toMatchObject({ step: "setup", previousStep: "group" });
|
||||
});
|
||||
|
||||
it("rejects an explicit board id that no longer exists", async () => {
|
||||
const db = createDb();
|
||||
const claimToken = await seedOnboardingAsync(db);
|
||||
await seedBoardAsync(db, { boardId: "target" });
|
||||
|
||||
await expect(createCaller(db, claimToken).completeSetup(completionInput("missing"))).rejects.toMatchObject({
|
||||
code: "NOT_FOUND",
|
||||
message: "The selected board no longer exists.",
|
||||
});
|
||||
|
||||
expect(await db.query.boards.findFirst({ where: eq(boards.id, "target") })).toMatchObject({ name: "target" });
|
||||
expect(await db.query.onboarding.findFirst()).toMatchObject({ step: "setup", previousStep: "group" });
|
||||
});
|
||||
|
||||
it("rejects a board rename that only differs by case from another board", async () => {
|
||||
const db = createDb();
|
||||
const claimToken = await seedOnboardingAsync(db);
|
||||
@@ -899,6 +915,7 @@ describe("onboard.completeSetup", () => {
|
||||
for (const layoutId of ["target-base", "target-mobile"]) {
|
||||
const positions = groupedLayouts.filter((layout) => layout.layoutId === layoutId);
|
||||
const containerLayout = containerLayouts.find((layout) => layout.layoutId === layoutId);
|
||||
expect(positions.length).toBeGreaterThan(0);
|
||||
expect(containerLayout).toBeDefined();
|
||||
expect(Math.max(...positions.map((position) => position.yOffset + position.height))).toBeLessThanOrEqual(
|
||||
containerLayout?.height ?? 0,
|
||||
|
||||
@@ -77,6 +77,8 @@ describe("onboarding claim", () => {
|
||||
expect(
|
||||
getOnboardingClaimTokenFromCookieHeader(`theme=dark; ${onboardingClaimCookieName}=secret-token; other=x`),
|
||||
).toBe("secret-token");
|
||||
expect(getOnboardingClaimTokenFromCookieHeader(`${onboardingClaimCookieName}=secret%2Dtoken`)).toBe("secret-token");
|
||||
expect(getOnboardingClaimTokenFromCookieHeader(`${onboardingClaimCookieName}=%E0%A4%A`)).toBeUndefined();
|
||||
expect(getOnboardingClaimTokenFromCookieHeader(`${onboardingClaimCookieName}-copy=wrong`)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -70,6 +70,7 @@ export const userRouter = createTRPCRouter({
|
||||
ownerId: userId,
|
||||
position: maxPosition + 1,
|
||||
};
|
||||
const nextStep = isProviderEnabled("ldap") || isProviderEnabled("oidc") ? "group" : "setup";
|
||||
|
||||
await handleTransactionsAsync(ctx.db, {
|
||||
async handleAsync(db, schema) {
|
||||
@@ -78,7 +79,6 @@ export const userRouter = createTRPCRouter({
|
||||
await transaction.insert(schema.groups).values(groupRow);
|
||||
await transaction.insert(schema.groupPermissions).values({ groupId, permission: "admin" });
|
||||
await transaction.insert(schema.groupMembers).values({ groupId, userId });
|
||||
const nextStep = isProviderEnabled("ldap") || isProviderEnabled("oidc") ? "group" : "setup";
|
||||
await transaction.update(schema.onboarding).set({ previousStep: "user", step: nextStep });
|
||||
});
|
||||
},
|
||||
@@ -88,7 +88,6 @@ export const userRouter = createTRPCRouter({
|
||||
transaction.insert(groups).values(groupRow).run();
|
||||
transaction.insert(groupPermissions).values({ groupId, permission: "admin" }).run();
|
||||
transaction.insert(groupMembers).values({ groupId, userId }).run();
|
||||
const nextStep = isProviderEnabled("ldap") || isProviderEnabled("oidc") ? "group" : "setup";
|
||||
transaction.update(onboarding).set({ previousStep: "user", step: nextStep }).run();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -12,12 +12,18 @@ const normalizeBaseHost = (value: string) => {
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) return null;
|
||||
try {
|
||||
const parsed = new URL(trimmed.includes("://") ? trimmed : `http://${trimmed}`);
|
||||
const url = trimmed.includes("://") ? trimmed : `http://${trimmed}`;
|
||||
const authority = url
|
||||
.match(/^[a-z][a-z0-9+.-]*:\/\/([^/?#]*)/iu)?.[1]
|
||||
?.split("@")
|
||||
.at(-1);
|
||||
const explicitPort = authority?.match(/^(?:\[[^\]]+\]|[^:]+):(\d+)$/u)?.[1];
|
||||
const parsed = new URL(url);
|
||||
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
|
||||
return {
|
||||
protocol: parsed.protocol,
|
||||
hostname: parsed.hostname,
|
||||
port: parsed.port ? Number(parsed.port) : undefined,
|
||||
port: parsed.port ? Number(parsed.port) : explicitPort ? Number(explicitPort) : undefined,
|
||||
pathname: parsed.pathname.replace(/\/+$/, ""),
|
||||
};
|
||||
} catch {
|
||||
@@ -32,8 +38,7 @@ const buildUrl = (slug: string, rawHost: string, mode: UrlTemplateMode, port?: n
|
||||
const modeBuilders: Record<UrlTemplateMode, () => string> = {
|
||||
subdomain: () => (base.hostname.startsWith("[") ? "" : `https://${slug}.${base.hostname}`),
|
||||
hostPort: () => (effectivePort ? `http://${base.hostname}:${effectivePort}` : `http://${base.hostname}`),
|
||||
path: () =>
|
||||
`${base.protocol}//${base.hostname}${base.port ? `:${base.port}` : ""}${base.pathname}/${slug}`,
|
||||
path: () => `${base.protocol}//${base.hostname}${base.port ? `:${base.port}` : ""}${base.pathname}/${slug}`,
|
||||
};
|
||||
return modeBuilders[mode]();
|
||||
};
|
||||
|
||||
@@ -38,9 +38,7 @@ describe("buildIntegrationUrl", () => {
|
||||
expect(buildIntegrationUrl("sonarr", "https://home.example.com/services", "path")).toBe(
|
||||
"https://home.example.com/services/sonarr",
|
||||
);
|
||||
expect(buildAppUrl("My Service", "home.lan/apps/", "path", 9999)).toBe(
|
||||
"http://home.lan/apps/my-service",
|
||||
);
|
||||
expect(buildAppUrl("My Service", "home.lan/apps/", "path", 9999)).toBe("http://home.lan/apps/my-service");
|
||||
});
|
||||
|
||||
it("replaces a supplied base port instead of producing a double port", () => {
|
||||
@@ -52,6 +50,12 @@ describe("buildIntegrationUrl", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("preserves an explicitly supplied default port for an app", () => {
|
||||
expect(buildAppUrl("My Service", "https://home.example.com:443/homarr", "hostPort")).toBe(
|
||||
"http://home.example.com:443",
|
||||
);
|
||||
});
|
||||
|
||||
it("formats IPv6 hosts safely in host-port mode", () => {
|
||||
expect(buildIntegrationUrl("sonarr", "https://[2001:db8::1]:8443/homarr", "hostPort")).toBe(
|
||||
"http://[2001:db8::1]:8989",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export { listDiscoveredContainersAsync } from "./list-discovered-containers";
|
||||
export { parseContainerLabels, type ParseContainerLabelsOptions } from "./parse-container-labels";
|
||||
export { createDockerSourceId, parseContainerLabels, type ParseContainerLabelsOptions } from "./parse-container-labels";
|
||||
export type { DiscoveredService, DockerDiscoveryHostResult, DockerDiscoveryResult } from "./types";
|
||||
@@ -51,7 +51,7 @@ describe("parseContainerLabels", () => {
|
||||
"remote:2375",
|
||||
),
|
||||
).toMatchObject({
|
||||
sourceId: "docker:remote:2375:container-1",
|
||||
sourceId: "docker:remote%3A2375:container-1",
|
||||
name: "Jellyfin",
|
||||
group: "Media",
|
||||
href: "http://jellyfin:8096",
|
||||
@@ -59,6 +59,21 @@ describe("parseContainerLabels", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps host and service identifiers unambiguous", () => {
|
||||
const first = parseContainerLabels(
|
||||
container({ "homarr.name": "Service", "homarr.href": "http://service", "homarr.id": "service" }),
|
||||
"remote:2375",
|
||||
);
|
||||
const second = parseContainerLabels(
|
||||
container({ "homarr.name": "Service", "homarr.href": "http://service", "homarr.id": "2375:service" }),
|
||||
"remote",
|
||||
);
|
||||
|
||||
expect(first?.sourceId).toBe("docker:remote%3A2375:service");
|
||||
expect(second?.sourceId).toBe("docker:remote:2375%3Aservice");
|
||||
expect(first?.sourceId).not.toBe(second?.sourceId);
|
||||
});
|
||||
|
||||
it("keeps a labeled service without a group for root placement", () => {
|
||||
expect(
|
||||
parseContainerLabels(
|
||||
|
||||
@@ -31,6 +31,9 @@ const parseIntegrationKind = (value: string | undefined): IntegrationKind | unde
|
||||
const parseWidgetKind = (value: string | undefined): WidgetKind | undefined =>
|
||||
value && widgetKindSet.has(value) ? (value as WidgetKind) : undefined;
|
||||
|
||||
export const createDockerSourceId = (host: string, externalId: string) =>
|
||||
`docker:${encodeURIComponent(host)}:${encodeURIComponent(externalId)}`;
|
||||
|
||||
export const parseContainerLabels = (
|
||||
container: Pick<ContainerInfo, "Id" | "Labels">,
|
||||
host: string,
|
||||
@@ -48,7 +51,7 @@ export const parseContainerLabels = (
|
||||
|
||||
const externalId = readLabel(labels, dockerLabels.id) ?? container.Id;
|
||||
return {
|
||||
sourceId: `docker:${host}:${externalId}`,
|
||||
sourceId: createDockerSourceId(host, externalId),
|
||||
containerId: container.Id,
|
||||
host,
|
||||
group,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { signIn } from "@homarr/auth/client";
|
||||
import { revalidatePathActionAsync } from "@homarr/common/client";
|
||||
import { useZodForm } from "@homarr/form";
|
||||
import { UserCreatePasswordFields } from "@homarr/forms-collection";
|
||||
import { showErrorNotification } from "@homarr/notifications";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { Link } from "@homarr/ui";
|
||||
import { groupCreateSchema } from "@homarr/validation/group";
|
||||
@@ -60,17 +61,24 @@ export const AccountSetup = ({ environment }: OnboardingStudioProps) => {
|
||||
const CredentialsSetup = () => {
|
||||
const t = useScopedI18n("init.studio.account");
|
||||
const [requiresSignIn, setRequiresSignIn] = useState(false);
|
||||
const [submitError, setSubmitError] = useState<string | null>(null);
|
||||
const recoveryActionRef = useRef<HTMLAnchorElement>(null);
|
||||
const mutation = clientApi.user.initUser.useMutation();
|
||||
const mutation = clientApi.user.initUser.useMutation({
|
||||
onError() {
|
||||
const message = t("unknownError");
|
||||
setSubmitError(message);
|
||||
showErrorNotification({ title: t("errorTitle"), message });
|
||||
},
|
||||
});
|
||||
const form = useZodForm(userInitSchema, {
|
||||
initialValues: { username: "", password: "", confirmPassword: "" },
|
||||
});
|
||||
|
||||
const submitAsync = async (values: z.infer<typeof userInitSchema>) => {
|
||||
setSubmitError(null);
|
||||
try {
|
||||
await mutation.mutateAsync(values);
|
||||
} catch (error) {
|
||||
form.setErrors({ username: error instanceof Error ? error.message : t("unknownError") });
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,9 +127,9 @@ const CredentialsSetup = () => {
|
||||
passwordInputProps={{ ...form.getInputProps("password"), autoComplete: "new-password" }}
|
||||
confirmPasswordInputProps={{ ...form.getInputProps("confirmPassword"), autoComplete: "new-password" }}
|
||||
/>
|
||||
{mutation.error ? (
|
||||
{submitError ? (
|
||||
<Alert color="red" title={t("errorTitle")}>
|
||||
{mutation.error.message}
|
||||
{submitError}
|
||||
</Alert>
|
||||
) : null}
|
||||
<Button type="submit" size="md" loading={mutation.isPending} rightSection={<IconArrowRight size={18} />}>
|
||||
@@ -135,16 +143,27 @@ const CredentialsSetup = () => {
|
||||
|
||||
const ExternalGroupSetup = () => {
|
||||
const t = useScopedI18n("init.studio.externalGroup");
|
||||
const [submitError, setSubmitError] = useState<string | null>(null);
|
||||
const mutation = clientApi.group.createInitialExternalGroup.useMutation({
|
||||
async onSuccess() {
|
||||
await revalidatePathActionAsync("/init");
|
||||
},
|
||||
onError() {
|
||||
const message = t("unknownError");
|
||||
setSubmitError(message);
|
||||
showErrorNotification({ title: t("errorTitle"), message });
|
||||
},
|
||||
});
|
||||
const form = useZodForm(groupCreateSchema, { initialValues: { name: "" } });
|
||||
|
||||
return (
|
||||
<AccountShell title={t("title")} description={t("description")}>
|
||||
<form onSubmit={form.onSubmit((values) => mutation.mutate(values))}>
|
||||
<form
|
||||
onSubmit={form.onSubmit((values) => {
|
||||
setSubmitError(null);
|
||||
mutation.mutate(values);
|
||||
})}
|
||||
>
|
||||
<Stack gap="md">
|
||||
<TextInput
|
||||
label={t("name")}
|
||||
@@ -153,9 +172,9 @@ const ExternalGroupSetup = () => {
|
||||
withAsterisk
|
||||
{...form.getInputProps("name")}
|
||||
/>
|
||||
{mutation.error ? (
|
||||
{submitError ? (
|
||||
<Alert color="red" title={t("errorTitle")}>
|
||||
{mutation.error.message}
|
||||
{submitError}
|
||||
</Alert>
|
||||
) : null}
|
||||
<Button type="submit" size="md" loading={mutation.isPending} rightSection={<IconArrowRight size={18} />}>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { isHttpUrl, resolveDiscoveredAppUrl, takeNewSourceIds } from "./discovery-selection";
|
||||
import { isHttpUrl, normalizeServiceUrl, resolveDiscoveredAppUrl, takeNewSourceIds } from "./discovery-selection";
|
||||
|
||||
describe("takeNewSourceIds", () => {
|
||||
it("keeps same-kind service instances independent and does not reselect them after refresh", () => {
|
||||
@@ -22,10 +22,12 @@ describe("takeNewSourceIds", () => {
|
||||
expect(resolveDiscoveredAppUrl(undefined, null, null)).toBe("");
|
||||
});
|
||||
|
||||
it("accepts only HTTP and HTTPS service addresses", () => {
|
||||
it("normalizes HTTP, HTTPS, and bare self-hosted service addresses", () => {
|
||||
expect(isHttpUrl("http://home.lan:8989")).toBe(true);
|
||||
expect(isHttpUrl("https://home.example/sonarr")).toBe(true);
|
||||
expect(isHttpUrl("home.lan:8989")).toBe(false);
|
||||
expect(normalizeServiceUrl("home.lan:8989")).toBe("http://home.lan:8989");
|
||||
expect(normalizeServiceUrl("0.0.0.0:8989")).toBe("http://0.0.0.0:8989");
|
||||
expect(isHttpUrl("javascript:alert(1)")).toBe(false);
|
||||
expect(isHttpUrl("file:///etc/passwd")).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -11,11 +11,15 @@ export const resolveDiscoveredAppUrl = (
|
||||
generatedUrl: string | null,
|
||||
) => override ?? suggestedUrl ?? generatedUrl ?? "";
|
||||
|
||||
export const isHttpUrl = (value: string) => {
|
||||
export const normalizeServiceUrl = (value: string) => {
|
||||
try {
|
||||
const protocol = new URL(value).protocol;
|
||||
return protocol === "http:" || protocol === "https:";
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) return null;
|
||||
const url = new URL(/^[a-z][a-z0-9+.-]*:\/\//iu.test(trimmed) ? trimmed : `http://${trimmed}`);
|
||||
return url.protocol === "http:" || url.protocol === "https:" ? url.toString().replace(/\/$/u, "") : null;
|
||||
} catch {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const isHttpUrl = (value: string) => normalizeServiceUrl(value) !== null;
|
||||
@@ -450,7 +450,7 @@
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,13 +35,21 @@ export const OnboardingStudio = (props: OnboardingStudioProps) => {
|
||||
setClaimState("ready");
|
||||
return;
|
||||
}
|
||||
const body = (await response.json().catch(() => null)) as { error?: string } | null;
|
||||
setClaimError(body?.error ?? t("errorDescription"));
|
||||
setClaimState(response.status === 423 ? "locked" : response.status === 403 ? "signIn" : "error");
|
||||
const body = (await response.json().catch(() => null)) as { code?: unknown } | null;
|
||||
if (body?.code === "locked") {
|
||||
setClaimState("locked");
|
||||
return;
|
||||
}
|
||||
if (body?.code === "administrator_required") {
|
||||
setClaimState("signIn");
|
||||
return;
|
||||
}
|
||||
setClaimError(t("errorDescription"));
|
||||
setClaimState("error");
|
||||
})
|
||||
.catch((error: unknown) => {
|
||||
.catch(() => {
|
||||
if (controller.signal.aborted) return;
|
||||
setClaimError(error instanceof Error ? error.message : t("errorDescription"));
|
||||
setClaimError(t("errorDescription"));
|
||||
setClaimState("error");
|
||||
});
|
||||
return () => controller.abort();
|
||||
|
||||
@@ -96,7 +96,7 @@ import { IntegrationAvatar, Link } from "@homarr/ui";
|
||||
import { IntegrationMultiSelectGrid } from "@homarr/ui/integration-select-grid";
|
||||
|
||||
import type { OnboardingStudioProps } from "./types";
|
||||
import { isHttpUrl, resolveDiscoveredAppUrl, takeNewSourceIds } from "./discovery-selection";
|
||||
import { isHttpUrl, normalizeServiceUrl, resolveDiscoveredAppUrl, takeNewSourceIds } from "./discovery-selection";
|
||||
import classes from "./onboarding-studio.module.css";
|
||||
|
||||
type StudioSection = "essentials" | "discover" | "connect" | "board" | "extend" | "review";
|
||||
@@ -150,8 +150,10 @@ export const SetupStudio = ({ environment }: OnboardingStudioProps) => {
|
||||
const [selectedAppIds, setSelectedAppIds] = useState<string[]>([]);
|
||||
const [appUrlOverrides, setAppUrlOverrides] = useState<Record<string, string>>({});
|
||||
const [appErrorSourceId, setAppErrorSourceId] = useState<string | null>(null);
|
||||
const [selectedBoardId, setSelectedBoardId] = useState<string | null>(environment.initialBoard?.id ?? null);
|
||||
const [boardName, setBoardName] = useState(environment.initialBoard?.name ?? "dashboard");
|
||||
const initialBoard =
|
||||
environment.initialBoard ?? (environment.availableBoards.length === 1 ? environment.availableBoards[0] : null);
|
||||
const [selectedBoardId, setSelectedBoardId] = useState<string | null>(initialBoard?.id ?? null);
|
||||
const [boardName, setBoardName] = useState(initialBoard?.name ?? "dashboard");
|
||||
const [primaryColor, setPrimaryColor] = useState("#fa5252");
|
||||
const [secondaryColor, setSecondaryColor] = useState("#fd7e14");
|
||||
const [itemRadius, setItemRadius] = useState<MantineSize>("lg");
|
||||
@@ -163,6 +165,7 @@ export const SetupStudio = ({ environment }: OnboardingStudioProps) => {
|
||||
const [applyError, setApplyError] = useState<string | null>(null);
|
||||
const [appError, setAppError] = useState<string | null>(null);
|
||||
const sectionHeadingRef = useRef<HTMLHeadingElement>(null);
|
||||
const sectionButtonRefs = useRef<(HTMLButtonElement | null)[]>([]);
|
||||
const initialSection = useRef(true);
|
||||
const focusSectionHeading = useRef(true);
|
||||
const seenIntegrationSourceIds = useRef(new Set<string>());
|
||||
@@ -177,7 +180,11 @@ export const SetupStudio = ({ environment }: OnboardingStudioProps) => {
|
||||
retry: false,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
const complete = clientApi.onboard.completeSetup.useMutation();
|
||||
const complete = clientApi.onboard.completeSetup.useMutation({
|
||||
onError(error) {
|
||||
showErrorNotification({ title: t("review.errorTitle"), message: error.message });
|
||||
},
|
||||
});
|
||||
const isApplying = complete.isPending;
|
||||
|
||||
const dockerData = docker.data;
|
||||
@@ -313,8 +320,7 @@ export const SetupStudio = ({ environment }: OnboardingStudioProps) => {
|
||||
if (!nextSection) return;
|
||||
focusSectionHeading.current = false;
|
||||
selectSection(nextSection.id);
|
||||
const nextButton = event.currentTarget.parentElement?.querySelectorAll("button").item(nextIndex);
|
||||
if (nextButton instanceof HTMLButtonElement) nextButton.focus();
|
||||
sectionButtonRefs.current[nextIndex]?.focus();
|
||||
};
|
||||
|
||||
const updateDraft = (id: string, patch: Partial<IntegrationDraft>) => {
|
||||
@@ -394,7 +400,7 @@ export const SetupStudio = ({ environment }: OnboardingStudioProps) => {
|
||||
return {
|
||||
sourceId: draft.sourceId ?? draft.id,
|
||||
name: draft.name,
|
||||
url: draft.url,
|
||||
url: normalizeServiceUrl(draft.url) ?? draft.url,
|
||||
kind: draft.kind,
|
||||
secrets: draft.secrets,
|
||||
iconUrl: discovered?.iconUrl ?? null,
|
||||
@@ -403,7 +409,7 @@ export const SetupStudio = ({ environment }: OnboardingStudioProps) => {
|
||||
};
|
||||
}),
|
||||
apps: appsToCreate.flatMap((app) => {
|
||||
const href = discoveredAppUrls[app.sourceId];
|
||||
const href = normalizeServiceUrl(discoveredAppUrls[app.sourceId] ?? "");
|
||||
return href
|
||||
? [
|
||||
{
|
||||
@@ -448,7 +454,7 @@ export const SetupStudio = ({ environment }: OnboardingStudioProps) => {
|
||||
if (dockerWarningCount > 0) {
|
||||
showWarningNotification({
|
||||
title: t("review.dockerWarningTitle"),
|
||||
message: t("review.dockerWarningDescription", { count: String(dockerWarningCount) }),
|
||||
message: t("review.dockerWarningDescription", { count: dockerWarningCount }),
|
||||
});
|
||||
}
|
||||
setApplyMessage(t("review.progress.done"));
|
||||
@@ -552,6 +558,9 @@ export const SetupStudio = ({ environment }: OnboardingStudioProps) => {
|
||||
return (
|
||||
<UnstyledButton
|
||||
key={section.id}
|
||||
ref={(node) => {
|
||||
sectionButtonRefs.current[index] = node;
|
||||
}}
|
||||
className={classes.railButton}
|
||||
data-active={active}
|
||||
onClick={() => selectSection(section.id)}
|
||||
@@ -1093,8 +1102,7 @@ const Connections = (props: StudioSectionProps) => {
|
||||
value={props.discoveredAppUrls[app.sourceId] ?? ""}
|
||||
onChange={(event) => props.setDiscoveredAppUrl(app.sourceId, event.currentTarget.value)}
|
||||
error={props.appErrorSourceId === app.sourceId ? props.appError : undefined}
|
||||
placeholder="https://service.example"
|
||||
type="url"
|
||||
placeholder="service.local:8080"
|
||||
required
|
||||
/>
|
||||
) : null}
|
||||
@@ -1253,7 +1261,7 @@ const BoardBuilder = (props: StudioSectionProps) => {
|
||||
allowDeselect={false}
|
||||
searchable
|
||||
withAsterisk
|
||||
error={props.selectedBoardId ? undefined : t("targetRequired")}
|
||||
error={!props.selectedBoardId && props.applyProgress > 0 ? t("targetRequired") : undefined}
|
||||
/>
|
||||
) : null}
|
||||
<TextInput
|
||||
@@ -1509,6 +1517,7 @@ const Extensions = (props: StudioSectionProps) => {
|
||||
|
||||
const AssistantSetup = ({ environment }: { environment: StudioSectionProps["environment"] }) => {
|
||||
const t = useScopedI18n("init.studio.extend.assistantSetup");
|
||||
const assistantSettingsT = useScopedI18n("management.page.settings.section.assistant");
|
||||
const reduceMotion = useReducedMotion();
|
||||
const [provider, setProvider] = useState<AssistantProvider>("homarr");
|
||||
const [baseUrl, setBaseUrl] = useState<string>(assistantProviderPresets.homarr.baseUrl);
|
||||
@@ -1532,6 +1541,9 @@ const AssistantSetup = ({ environment }: { environment: StudioSectionProps["envi
|
||||
await configuration.refetch();
|
||||
await models.refetch();
|
||||
},
|
||||
onError(error) {
|
||||
showErrorNotification({ title: t("errorTitle"), message: error.message });
|
||||
},
|
||||
});
|
||||
const updateConfiguration = clientApi.assistant.updateConfiguration.useMutation({
|
||||
onSuccess() {
|
||||
@@ -1616,7 +1628,10 @@ const AssistantSetup = ({ environment }: { environment: StudioSectionProps["envi
|
||||
label={t("provider")}
|
||||
value={provider}
|
||||
onChange={selectProvider}
|
||||
data={assistantProviderIds.map((value) => ({ value, label: value.replaceAll("-", " ") }))}
|
||||
data={assistantProviderIds.map((value) => ({
|
||||
value,
|
||||
label: assistantSettingsT(`provider.options.${value}.label`),
|
||||
}))}
|
||||
allowDeselect={false}
|
||||
/>
|
||||
<TextInput
|
||||
@@ -1768,6 +1783,9 @@ const McpSetup = ({ environment }: { environment: StudioSectionProps["environmen
|
||||
onSuccess(data) {
|
||||
setApiKey(data.apiKey);
|
||||
},
|
||||
onError(error) {
|
||||
showErrorNotification({ title: t("errorTitle"), message: error.message });
|
||||
},
|
||||
});
|
||||
const config = JSON.stringify(
|
||||
{
|
||||
@@ -1957,6 +1975,6 @@ const createDraft = ({
|
||||
url,
|
||||
source,
|
||||
secretOption: 0,
|
||||
secrets: getAllSecretKindOptions(kind)[0].map((secretKind) => ({ kind: secretKind, value: "" })),
|
||||
secrets: (getAllSecretKindOptions(kind)[0] ?? []).map((secretKind) => ({ kind: secretKind, value: "" })),
|
||||
error: null,
|
||||
});
|
||||
@@ -7,6 +7,7 @@ import { motion, useReducedMotion } from "motion/react";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { revalidatePathActionAsync } from "@homarr/common/client";
|
||||
import { showErrorNotification } from "@homarr/notifications";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { OnboardingStudioProps } from "./types";
|
||||
@@ -14,6 +15,7 @@ import classes from "./onboarding-studio.module.css";
|
||||
|
||||
export const Welcome = ({ environment, sqliteRestore }: OnboardingStudioProps) => {
|
||||
const t = useScopedI18n("init.studio.welcome");
|
||||
const claimT = useScopedI18n("init.studio.claim");
|
||||
const reduceMotion = useReducedMotion();
|
||||
const [showRestore, setShowRestore] = useState(false);
|
||||
const [claimPending, setClaimPending] = useState(false);
|
||||
@@ -22,16 +24,34 @@ export const Welcome = ({ environment, sqliteRestore }: OnboardingStudioProps) =
|
||||
async onSuccess() {
|
||||
await revalidatePathActionAsync("/init");
|
||||
},
|
||||
onError() {
|
||||
showErrorNotification({ title: t("errorTitle"), message: t("errorDescription") });
|
||||
},
|
||||
});
|
||||
|
||||
const getClaimError = (code: unknown) => {
|
||||
switch (code) {
|
||||
case "finished":
|
||||
case "unavailable":
|
||||
case "cross_site":
|
||||
return claimT("errorDescription");
|
||||
case "administrator_required":
|
||||
return claimT("signInDescription");
|
||||
case "locked":
|
||||
return claimT("lockedDescription");
|
||||
default:
|
||||
return t("errorDescription");
|
||||
}
|
||||
};
|
||||
|
||||
const claimOnboardingAsync = async () => {
|
||||
setClaimPending(true);
|
||||
setClaimError(null);
|
||||
try {
|
||||
const response = await fetch("/api/onboarding/claim", { method: "POST" });
|
||||
if (!response.ok) {
|
||||
const body = (await response.json().catch(() => null)) as { error?: string } | null;
|
||||
throw new Error(body?.error ?? t("errorTitle"));
|
||||
const body = (await response.json().catch(() => null)) as { code?: unknown } | null;
|
||||
throw new Error(getClaimError(body?.code));
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
@@ -128,7 +148,7 @@ export const Welcome = ({ environment, sqliteRestore }: OnboardingStudioProps) =
|
||||
|
||||
{claimError || start.error ? (
|
||||
<Alert color="red" title={t("errorTitle")} maw="38rem">
|
||||
{claimError ?? start.error?.message}
|
||||
{claimError ?? t("errorDescription")}
|
||||
</Alert>
|
||||
) : null}
|
||||
</Stack>
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Us donem la benvinguda a Homarr",
|
||||
"subtitle": "Comencem configurant la vostra instància de Homarr.",
|
||||
"description": "Per començar, seleccioneu com voleu configurar la vostra instància de Homarr.",
|
||||
"action": {
|
||||
"scratch": "Comença des de zero",
|
||||
"importOldmarr": "Importa des d'una versió de Homarr anterior a 1.0",
|
||||
"restoreSqlite": "",
|
||||
"restoreSqliteDescription": "",
|
||||
"backToOptions": ""
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importa dades",
|
||||
"subtitle": "Pot importar dades des d'una instància de Homarr existent.",
|
||||
"dropzone": {
|
||||
"title": "Arrossegueu el fitxer zip aquí o feu clic per navegar",
|
||||
"description": "El fitxer zip carregat es processarà i podreu seleccionar què voleu importar"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Canvia el fitzer"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importa la configuració",
|
||||
"description": "Configura el comportament d'importació"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "S'han trobat {count} taulers",
|
||||
"description": "Escolliu tots els taulers amb la mida que voleu importar",
|
||||
"action": {
|
||||
"selectAll": "Seleccionar-ho tot",
|
||||
"unselectAll": "Anul·la la selecció"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Resum de la importació",
|
||||
"description": "En el resum següent podeu veure el que s'importarà",
|
||||
"action": {
|
||||
"import": "Confirma la importació i continua"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Aplicacions",
|
||||
"boards": "Tauler",
|
||||
"integrations": "Integracions",
|
||||
"credentialUsers": "Credencials d'usuari"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Introduïu el token d'importació",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Introduïu el token d'importació mostrat a la instància prèvia de Homarr"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Token invàlid",
|
||||
"message": "El token que heu introduït no és vàlid"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Usuari administrador",
|
||||
"subtitle": "Especifiqueu les credencials del vostre usuari administrador.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "S'ha creat l'usuari",
|
||||
"message": "L'usuari s'ha creat correctament"
|
||||
},
|
||||
"error": {
|
||||
"title": "S'ha produït un error al crear l'usuari"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Grup extern",
|
||||
"subtitle": "Especifiqueu el grup que s'ha d'utilitzar per als usuaris externs.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nom del grup",
|
||||
"description": "El nom ha de coincidir amb el grup d'Administradors del proveïdor extern"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Configuració",
|
||||
"subtitle": "Configureu els paràmetres del servidor."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"continue": "",
|
||||
"skip": ""
|
||||
},
|
||||
"configure": {
|
||||
"progress": "",
|
||||
"skip": "",
|
||||
"finishing": "",
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "",
|
||||
"placeholder": "",
|
||||
"hint": "",
|
||||
"warning": "",
|
||||
"preview": "",
|
||||
"mode": {
|
||||
"subdomain": "",
|
||||
"hostPort": ""
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "",
|
||||
"detectedBreakdown": "",
|
||||
"summary": "",
|
||||
"appBadge": "",
|
||||
"appSectionLabel": "",
|
||||
"scanning": "",
|
||||
"scanningDescription": ""
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Finalitza la configuració",
|
||||
"subtitle": "Ja està tot llest!",
|
||||
"description": "El procés de configuració s'ha completat correctament. Podeu començar a utilitzar Homarr. Escolliu la vostra propera acció:",
|
||||
"action": {
|
||||
"goToBoard": "Ves al tauler {name}",
|
||||
"createBoard": "Creeu el vostre primer tauler",
|
||||
"inviteUser": "Convideu altres usuaris",
|
||||
"docs": "Llegiu la documentació"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Torna a l'inici"
|
||||
},
|
||||
"user": {
|
||||
"title": "Usuaris",
|
||||
"name": "Usuari",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Teniu canvis sense desar, esteu segur que voleu sortir?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importa des d'Homarr anterior a la versió 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Importació correcta",
|
||||
"message": "El tauler s'ha importat correctament"
|
||||
},
|
||||
"error": {
|
||||
"title": "Importació fallida",
|
||||
"message": "No s'ha pogut importar el tauler, comproveu els registres per a més detalls"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Selecciona un fitxer JSON",
|
||||
"invalidError": "Fitxer de configuració no vàlid"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Aplicacions",
|
||||
"avoidDuplicates": {
|
||||
"label": "Evita duplicats",
|
||||
"description": "Ignora les aplicacions on ja existeix una aplicació amb el mateix href"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Importa només les aplicacions",
|
||||
"description": "Només afegeix les aplicacions, el tauler s'ha de tornar a crear manualment"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Nom del tauler"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Mida de la pantalla",
|
||||
"description": "En versions anteriors a la 1.0 existien tres modes diferents, de manera que podíeu triar la quantitat de columnes per a cada mida de pantalla.",
|
||||
"option": {
|
||||
"sm": "Petita",
|
||||
"md": "Mitjana",
|
||||
"lg": "Gran"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Comportament de la barra lateral",
|
||||
"description": "Les barres laterals es van eliminar a la versió 1.0, podeu seleccionar què ha de passar amb els elements que contenen.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Última secció",
|
||||
"description": "La barra lateral es mostrarà sota l'última secció"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Elimina els elements",
|
||||
"description": "Els elements continguts a la barra lateral s'eliminaran"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Crear aplicació al vol",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Crea un tauler nou"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Importa un tauler"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Crea una aplicació nova"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "欢迎使用 Homarr",
|
||||
"subtitle": "让我们开始设置您的 Homarr 实例。",
|
||||
"description": "首先,请选择您想要如何设置您的 Homarr 实例。",
|
||||
"action": {
|
||||
"scratch": "从零开始",
|
||||
"importOldmarr": "从 1.0 之前的 Homarr 导入",
|
||||
"restoreSqlite": "从 SQLite 备份恢复",
|
||||
"restoreSqliteDescription": "上传之前 Homarr 实例的完整 SQLite 数据库备份。这将恢复所有面板、用户、应用、集成和设置。",
|
||||
"backToOptions": "← 返回设置选项"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "导入数据",
|
||||
"subtitle": "您可以从已有的 Homarr 实例导入数据。",
|
||||
"dropzone": {
|
||||
"title": "将 zip 文件拖到此处或单击浏览",
|
||||
"description": "上传的压缩包将被处理,您可以选择要导入的内容"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "更改文件"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "导入设置",
|
||||
"description": "配置导入方式"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "找到 {count} 个面板",
|
||||
"description": "选择您想要导入的所有面板",
|
||||
"action": {
|
||||
"selectAll": "选择全部",
|
||||
"unselectAll": "取消全选"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "导入概况",
|
||||
"description": "在下面的概况中,您可以看到将要导入的内容",
|
||||
"action": {
|
||||
"import": "确认导入并继续"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "应用",
|
||||
"boards": "面板",
|
||||
"integrations": "集成",
|
||||
"credentialUsers": "用户凭证"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "输入导入密钥",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "秘钥",
|
||||
"description": "输入您之前的 homarr 实例中显示的导入秘钥"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "无效秘钥",
|
||||
"message": "您输入的秘钥无效"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "管理员用户",
|
||||
"subtitle": "指定您的管理员用户的凭证。",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "创建用户",
|
||||
"message": "用户已成功创建"
|
||||
},
|
||||
"error": {
|
||||
"title": "用户创建失败"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "外部用户组",
|
||||
"subtitle": "指定应该用于外部用户的用户组。",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "用户组名称",
|
||||
"description": "名称必须与外部提供商的管理组匹配"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "设置",
|
||||
"subtitle": "配置服务器的设置"
|
||||
},
|
||||
"integrations": {
|
||||
"title": "集成",
|
||||
"subtitle": "选择您使用的服务。",
|
||||
"description": "选择您要连接的集成。我们将自动为您设置带有匹配小部件的面板。",
|
||||
"action": {
|
||||
"continue": "继续",
|
||||
"skip": "暂时跳过"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} / {total}",
|
||||
"skip": "跳过此集成",
|
||||
"finishing": "正在设置您的面板……",
|
||||
"error": {
|
||||
"title": "设置失败",
|
||||
"message": "设置面板时出现问题。请重试。"
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL 帮助程序",
|
||||
"description": "这些帮助程序尝试猜测服务的 URL。如果无效,只需手动输入地址。"
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Base URL",
|
||||
"placeholder": "homelab.local 或 192.168.1.1",
|
||||
"hint": "输入您的基础域或 IP 以自动填充集成 URL",
|
||||
"warning": "现在设置基础 URL,将自动填充所有集成的 URL,在配置过程中为您节省时间",
|
||||
"preview": "例如 {example}",
|
||||
"mode": {
|
||||
"subdomain": "子域名",
|
||||
"hostPort": "主机:端口"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker 检测到 {count} 个服务",
|
||||
"detectedBreakdown": "{integrations} 个集成 · {apps} 个应用",
|
||||
"summary": "Homarr 检测到 {apps} 个应用,其中 {integrations} 个具有内置集成",
|
||||
"appBadge": "应用",
|
||||
"appSectionLabel": "要添加到面板的应用(已选择 {count} 个)",
|
||||
"scanning": "正在扫描 Docker……",
|
||||
"scanningDescription": "正在查找系统上运行的容器"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "完成设置",
|
||||
"subtitle": "你已设置完成!",
|
||||
"description": "您已成功完成设置过程。现在您可以开始使用 Homarr 了。选择下一步操作:",
|
||||
"action": {
|
||||
"goToBoard": "转到 {name} 面板",
|
||||
"createBoard": "创建您的第一个面板",
|
||||
"inviteUser": "邀请其他用户",
|
||||
"docs": "阅读文档"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "返回起点"
|
||||
},
|
||||
"user": {
|
||||
"title": "用户",
|
||||
"name": "用户",
|
||||
@@ -4065,6 +4214,62 @@
|
||||
"message": "您有尚未保存的更改。您确定要离开吗?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "从 1.0.0 之前的 Homarr 导入",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "导入成功",
|
||||
"message": "面板导入成功"
|
||||
},
|
||||
"error": {
|
||||
"title": "导入失败",
|
||||
"message": "无法导入面板,请检查日志以获取更多详情"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "选择 JSON 文件",
|
||||
"invalidError": "无效的配置文件"
|
||||
},
|
||||
"apps": {
|
||||
"label": "应用",
|
||||
"avoidDuplicates": {
|
||||
"label": "避免重复",
|
||||
"description": "忽略已经存在具有相同链接的应用"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "仅导入应用",
|
||||
"description": "只添加应用,面板需要手动重新创建"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "面板名称"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "屏幕大小",
|
||||
"description": "在1.0之前的版本中,有三种不同的模式,所以你可以根据屏幕大小选择列的数量。",
|
||||
"option": {
|
||||
"sm": "小号",
|
||||
"md": "中号",
|
||||
"lg": "大号"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "侧边栏行为",
|
||||
"description": "侧边栏在1.0中被删除了,您可以选择其中的项目应该发生什么。",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "最后部分",
|
||||
"description": "侧边栏将显示在最后一部分的下方"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "删除项目",
|
||||
"description": "侧边栏中包含的项目将被删除"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "在运行时创建应用",
|
||||
@@ -5684,6 +5889,9 @@
|
||||
"newBoard": {
|
||||
"label": "创建面板"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "导入面板"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "创建应用"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "crwdns2264:0crwdne2264:0",
|
||||
"subtitle": "crwdns2266:0crwdne2266:0",
|
||||
"description": "crwdns2268:0crwdne2268:0",
|
||||
"action": {
|
||||
"scratch": "crwdns2270:0crwdne2270:0",
|
||||
"importOldmarr": "crwdns2272:0crwdne2272:0",
|
||||
"restoreSqlite": "crwdns4601:0crwdne4601:0",
|
||||
"restoreSqliteDescription": "crwdns4603:0crwdne4603:0",
|
||||
"backToOptions": "crwdns4605:0crwdne4605:0"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "crwdns2274:0crwdne2274:0",
|
||||
"subtitle": "crwdns2276:0crwdne2276:0",
|
||||
"dropzone": {
|
||||
"title": "crwdns2278:0crwdne2278:0",
|
||||
"description": "crwdns2280:0crwdne2280:0"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "crwdns2282:0crwdne2282:0"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "crwdns2284:0crwdne2284:0",
|
||||
"description": "crwdns2286:0crwdne2286:0"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "crwdns2288:0{count}crwdne2288:0",
|
||||
"description": "crwdns2692:0crwdne2692:0",
|
||||
"action": {
|
||||
"selectAll": "crwdns2292:0crwdne2292:0",
|
||||
"unselectAll": "crwdns2294:0crwdne2294:0"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "crwdns2296:0crwdne2296:0",
|
||||
"description": "crwdns2298:0crwdne2298:0",
|
||||
"action": {
|
||||
"import": "crwdns2300:0crwdne2300:0"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "crwdns2302:0crwdne2302:0",
|
||||
"boards": "crwdns2304:0crwdne2304:0",
|
||||
"integrations": "crwdns2306:0crwdne2306:0",
|
||||
"credentialUsers": "crwdns2308:0crwdne2308:0"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "crwdns2310:0crwdne2310:0",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "crwdns2312:0crwdne2312:0",
|
||||
"description": "crwdns2314:0crwdne2314:0"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "crwdns2316:0crwdne2316:0",
|
||||
"message": "crwdns2318:0crwdne2318:0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "crwdns2320:0crwdne2320:0",
|
||||
"subtitle": "crwdns2322:0crwdne2322:0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "crwdns2324:0crwdne2324:0",
|
||||
"message": "crwdns2326:0crwdne2326:0"
|
||||
},
|
||||
"error": {
|
||||
"title": "crwdns2328:0crwdne2328:0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "crwdns2330:0crwdne2330:0",
|
||||
"subtitle": "crwdns2332:0crwdne2332:0",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "crwdns2334:0crwdne2334:0",
|
||||
"description": "crwdns2336:0crwdne2336:0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "crwdns2338:0crwdne2338:0",
|
||||
"subtitle": "crwdns2340:0crwdne2340:0"
|
||||
},
|
||||
"integrations": {
|
||||
"title": "crwdns4369:0crwdne4369:0",
|
||||
"subtitle": "crwdns4371:0crwdne4371:0",
|
||||
"description": "crwdns4373:0crwdne4373:0",
|
||||
"action": {
|
||||
"continue": "crwdns4375:0crwdne4375:0",
|
||||
"skip": "crwdns4377:0crwdne4377:0"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "crwdns4379:0{current}crwdnd4379:0{total}crwdne4379:0",
|
||||
"skip": "crwdns4381:0crwdne4381:0",
|
||||
"finishing": "crwdns4383:0crwdne4383:0",
|
||||
"error": {
|
||||
"title": "crwdns4385:0crwdne4385:0",
|
||||
"message": "crwdns4387:0crwdne4387:0"
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "crwdns4389:0crwdne4389:0",
|
||||
"description": "crwdns4391:0crwdne4391:0"
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "crwdns4393:0crwdne4393:0",
|
||||
"placeholder": "crwdns4395:0crwdne4395:0",
|
||||
"hint": "crwdns4397:0crwdne4397:0",
|
||||
"warning": "crwdns4399:0crwdne4399:0",
|
||||
"preview": "crwdns4401:0{example}crwdne4401:0",
|
||||
"mode": {
|
||||
"subdomain": "crwdns4403:0crwdne4403:0",
|
||||
"hostPort": "crwdns4405:0crwdne4405:0"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "crwdns4407:0{count}crwdne4407:0",
|
||||
"detectedBreakdown": "crwdns4409:0{integrations}crwdnd4409:0{apps}crwdne4409:0",
|
||||
"summary": "crwdns4411:0{apps}crwdnd4411:0{integrations}crwdne4411:0",
|
||||
"appBadge": "crwdns4413:0crwdne4413:0",
|
||||
"appSectionLabel": "crwdns4415:0{count}crwdne4415:0",
|
||||
"scanning": "crwdns4417:0crwdne4417:0",
|
||||
"scanningDescription": "crwdns4419:0crwdne4419:0"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "crwdns2342:0crwdne2342:0",
|
||||
"subtitle": "crwdns2344:0crwdne2344:0",
|
||||
"description": "crwdns2346:0crwdne2346:0",
|
||||
"action": {
|
||||
"goToBoard": "crwdns2348:0{name}crwdne2348:0",
|
||||
"createBoard": "crwdns2350:0crwdne2350:0",
|
||||
"inviteUser": "crwdns2352:0crwdne2352:0",
|
||||
"docs": "crwdns2354:0crwdne2354:0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "crwdns2356:0crwdne2356:0"
|
||||
},
|
||||
"user": {
|
||||
"title": "crwdns2:0crwdne2:0",
|
||||
"name": "crwdns4:0crwdne4:0",
|
||||
@@ -3909,6 +4058,62 @@
|
||||
"message": "crwdns1380:0crwdne1380:0"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "crwdns1382:0crwdne1382:0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "crwdns1384:0crwdne1384:0",
|
||||
"message": "crwdns1386:0crwdne1386:0"
|
||||
},
|
||||
"error": {
|
||||
"title": "crwdns1388:0crwdne1388:0",
|
||||
"message": "crwdns1390:0crwdne1390:0"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "crwdns1392:0crwdne1392:0",
|
||||
"invalidError": "crwdns1394:0crwdne1394:0"
|
||||
},
|
||||
"apps": {
|
||||
"label": "crwdns1396:0crwdne1396:0",
|
||||
"avoidDuplicates": {
|
||||
"label": "crwdns1398:0crwdne1398:0",
|
||||
"description": "crwdns1400:0crwdne1400:0"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "crwdns1402:0crwdne1402:0",
|
||||
"description": "crwdns1404:0crwdne1404:0"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "crwdns1406:0crwdne1406:0"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "crwdns1408:0crwdne1408:0",
|
||||
"description": "crwdns2368:0crwdne2368:0",
|
||||
"option": {
|
||||
"sm": "crwdns1410:0crwdne1410:0",
|
||||
"md": "crwdns1412:0crwdne1412:0",
|
||||
"lg": "crwdns1414:0crwdne1414:0"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "crwdns1416:0crwdne1416:0",
|
||||
"description": "crwdns1418:0crwdne1418:0",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "crwdns1420:0crwdne1420:0",
|
||||
"description": "crwdns1422:0crwdne1422:0"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "crwdns1424:0crwdne1424:0",
|
||||
"description": "crwdns1426:0crwdne1426:0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "crwdns2810:0crwdne2810:0",
|
||||
@@ -5532,6 +5737,9 @@
|
||||
"newBoard": {
|
||||
"label": "crwdns2082:0crwdne2082:0"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "crwdns2084:0crwdne2084:0"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "crwdns2086:0crwdne2086:0"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Vítejte v Homarru",
|
||||
"subtitle": "Pojďme začít nastavením instance Homarru.",
|
||||
"description": "Chcete-li začít, zvolte, jak chcete nastavit instanci Homarru.",
|
||||
"action": {
|
||||
"scratch": "Začít od začátku",
|
||||
"importOldmarr": "Import z Homarru před verzí 1.0",
|
||||
"restoreSqlite": "Obnovit ze zálohy SQLite",
|
||||
"restoreSqliteDescription": "Nahrajte kompletní zálohu SQLite databáze z předchozí instance Homarru. Tím se obnoví všechny plochy, uživatelé, aplikace, integrace a nastavení.",
|
||||
"backToOptions": "← Zpět na možnosti nastavení"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Import dat",
|
||||
"subtitle": "Můžete importovat data z existující instance Homarru.",
|
||||
"dropzone": {
|
||||
"title": "Přetáhněte zip soubor sem nebo klikněte pro procházení souborů",
|
||||
"description": "Nahraný zip soubor bude zpracován a budete si moci vybrat, co chcete importovat"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Změnit soubor"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importovat nastavení",
|
||||
"description": "Konfigurovat chování importu"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Nalezeno {count} ploch",
|
||||
"description": "Vyberte všechny plochy s velikostmi, které chcete importovat",
|
||||
"action": {
|
||||
"selectAll": "Vybrat vše",
|
||||
"unselectAll": "Zrušit vybraní všeho"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Přehled importu",
|
||||
"description": "V následujícím přehledu můžete vidět, co bude importováno",
|
||||
"action": {
|
||||
"import": "Potvrdit import a pokračovat"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Aplikace",
|
||||
"boards": "Plochy",
|
||||
"integrations": "Integrace",
|
||||
"credentialUsers": "Uživatelské oprávnění"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Zadejte token pro import",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Zadejte zobrazený importní token z předchozí instance homarr"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Neplatný token",
|
||||
"message": "Token, který jste zadali je neplatný"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Správce",
|
||||
"subtitle": "Zadejte přihlašovací údaje pro administrátora.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Uživatel byl vytvořen",
|
||||
"message": "Uživatel byl úspěšně vytvořen"
|
||||
},
|
||||
"error": {
|
||||
"title": "Vytvoření uživatele se nezdařilo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Externí skupina",
|
||||
"subtitle": "Zadejte skupinu, která by měla být použita pro externí uživatele.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Název skupiny",
|
||||
"description": "Název musí odpovídat skupině admin externího poskytovatele"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Nastavení",
|
||||
"subtitle": "Konfigurace nastavení serveru."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrace",
|
||||
"subtitle": "Vyberte služby, které používáte.",
|
||||
"description": "Vyberte integrace, které chcete připojit. Automaticky nastavíme vaši plochu s odpovídajícími widgety.",
|
||||
"action": {
|
||||
"continue": "Pokračovat",
|
||||
"skip": "Prozatím přeskočit"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} z {total}",
|
||||
"skip": "Přeskočit tuto integraci",
|
||||
"finishing": "Nastavování vaší plochy...",
|
||||
"error": {
|
||||
"title": "Nastavení se nezdařilo",
|
||||
"message": "Během nastavování vaší plochy se něco pokazilo. Zkuste to prosím znovu."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Pomocníci s URL",
|
||||
"description": "Tito pomocníci se pokusí uhodnout URL vašich služeb. Pokud to nefunguje, zadejte adresu ručně."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Základní URL",
|
||||
"placeholder": "homelab.local nebo 192.168.1.1",
|
||||
"hint": "Zadejte svou základní doménu nebo IP pro automatické vyplnění integračních URL",
|
||||
"warning": "Nastavením základní URL nyní se automaticky vyplní všechna integrační URL, což vám ušetří čas během nastavování",
|
||||
"preview": "např. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdoména",
|
||||
"hostPort": "Hostitel:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker detekoval {count} služeb",
|
||||
"detectedBreakdown": "{integrations} integrací · {apps} aplikací",
|
||||
"summary": "Homarr detekoval {apps} aplikací, {integrations} z nich má vestavěné integrace",
|
||||
"appBadge": "Aplikace",
|
||||
"appSectionLabel": "Aplikace k přidání na plochu ({count} vybráno)",
|
||||
"scanning": "Skenování Dockeru...",
|
||||
"scanningDescription": "Hledání běžících kontejnerů ve vašem systému"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Dokončit nastavení",
|
||||
"subtitle": "Jste připraveni začít!",
|
||||
"description": "Úspěšně jste dokončili proces nastavení. Nyní můžete začít používat Homarr. Vyberte další akci:",
|
||||
"action": {
|
||||
"goToBoard": "Přejít na plochu {name}",
|
||||
"createBoard": "Vytvořte svou první plochu",
|
||||
"inviteUser": "Pozvat ostatní uživatele",
|
||||
"docs": "Přečtěte si dokumentaci"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Zpět na začátek"
|
||||
},
|
||||
"user": {
|
||||
"title": "Uživatelé",
|
||||
"name": "Uživatel",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Máte neuložené změny, jste si jistí, že chcete odejít?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": "Plochu se nepodařilo importovat, zkontrolujte logy pro více informací"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "",
|
||||
"invalidError": ""
|
||||
},
|
||||
"apps": {
|
||||
"label": "Aplikace",
|
||||
"avoidDuplicates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": ""
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "Malé",
|
||||
"md": "Střední",
|
||||
"lg": "Velké"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Vytvořit novou plochu"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Velkommen til Homarr",
|
||||
"subtitle": "Lad os komme i gang med at konfigurere din Homarr instans.",
|
||||
"description": "For at komme i gang, skal du vælge, hvordan du vil konfigurere din Homarr instans.",
|
||||
"action": {
|
||||
"scratch": "Start fra bunden",
|
||||
"importOldmarr": "Importer fra Homarr før 1.0",
|
||||
"restoreSqlite": "Gendan fra SQLite backup",
|
||||
"restoreSqliteDescription": "Upload en fuld SQLite database backup fra en tidligere Homarr instans. Dette vil gendanne alle tavler, brugere, apps, integrationer og indstillinger.",
|
||||
"backToOptions": "← Tilbage til opsætningsmuligheder"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importer data",
|
||||
"subtitle": "Du kan importere data fra en eksisterende Homarr instans.",
|
||||
"dropzone": {
|
||||
"title": "Træk zip-filen her eller klik for at gennemse",
|
||||
"description": "Den uploadede zip vil blive behandlet, og du vil kunne vælge, hvad du vil importere"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Ændre fil"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importer indstillinger",
|
||||
"description": "Konfigurer importadfærden"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Fundet {count} tavler",
|
||||
"description": "Vælg alle tavler med den størrelse, du vil importere",
|
||||
"action": {
|
||||
"selectAll": "Vælg alle",
|
||||
"unselectAll": "Fravælg alle"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Importér sammendrag",
|
||||
"description": "I nedenstående oversigt kan du se hvad der vil blive importeret",
|
||||
"action": {
|
||||
"import": "Bekræft import og fortsæt"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Apps",
|
||||
"boards": "Tavler",
|
||||
"integrations": "Integrationer",
|
||||
"credentialUsers": "Brugere, der er legitimerede"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Angiv import token",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Indtast den viste import token fra din tidligere homarr instans"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Ugyldig token",
|
||||
"message": "Den indtastede token er ugyldig"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Admin bruger",
|
||||
"subtitle": "Angiv legitimationsoplysninger for din administrator bruger.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Bruger oprettet",
|
||||
"message": "Brugeren blev oprettet"
|
||||
},
|
||||
"error": {
|
||||
"title": "Brugeroprettelse mislykkedes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Ekstern gruppe",
|
||||
"subtitle": "Angiv den gruppe, der skal bruges til eksterne brugere.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Gruppenavn",
|
||||
"description": "Navn skal matche admin gruppe fra ekstern udbyder"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Indstillinger",
|
||||
"subtitle": "Konfigurer serverindstillinger."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrationer",
|
||||
"subtitle": "Vælg de tjenester, du bruger.",
|
||||
"description": "Vælg de integrationer, du gerne vil forbinde. Vi konfigurerer dit dashboard med matchende widgets automatisk.",
|
||||
"action": {
|
||||
"continue": "Forsæt",
|
||||
"skip": "Spring over for nu"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} af {total}",
|
||||
"skip": "Spring over denne integration",
|
||||
"finishing": "Sætter dit dashboard op...",
|
||||
"error": {
|
||||
"title": "Opsætning mislykkedes",
|
||||
"message": "Der opstod en fejl under opsætningen af dit dashboard. Prøv igen."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL-hjælpere",
|
||||
"description": "Disse hjælpere forsøger at gætte URL'en til dine tjenester. Hvis det ikke virker, skal du blot indtaste adressen manuelt."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Basis-URL",
|
||||
"placeholder": "homelab.local eller 192.168.1.1",
|
||||
"hint": "Indtast dit basisdomæne eller IP for automatisk at udfylde integrations-URL'er",
|
||||
"warning": "Hvis du indstiller din basis-URL nu, udfyldes alle integrations-URL'er automatisk, hvilket sparer dig tid under opsætningen",
|
||||
"preview": "f.eks. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdomæne",
|
||||
"hostPort": "Vært:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker opdagede {count} tjenester",
|
||||
"detectedBreakdown": "{integrations} integrationer · {apps} apps",
|
||||
"summary": "Homarr opdagede {apps} apps, {integrations} heraf har indbyggede integrationer",
|
||||
"appBadge": "App",
|
||||
"appSectionLabel": "Apps der skal tilføjes til dashboard ({count} valgt)",
|
||||
"scanning": "Scanner Docker...",
|
||||
"scanningDescription": "Leder efter kørende containere på dit system"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Afslut opsætningen",
|
||||
"subtitle": "Du er klar!",
|
||||
"description": "Du har fuldført opsætningsprocessen. Du kan nu begynde at bruge Homarr. Vælg din næste handling:",
|
||||
"action": {
|
||||
"goToBoard": "Gå til {name} tavle",
|
||||
"createBoard": "Opret din første tavle",
|
||||
"inviteUser": "Inviter andre brugere",
|
||||
"docs": "Læs dokumentationen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Tilbage til start"
|
||||
},
|
||||
"user": {
|
||||
"title": "Brugere",
|
||||
"name": "Bruger",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Du har ændringer, der ikke er gemt. Er du sikker på, at du vil forlade siden?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importer fra homarr før 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Import udført",
|
||||
"message": "Tavlen blev importeret"
|
||||
},
|
||||
"error": {
|
||||
"title": "Import mislykkedes",
|
||||
"message": "Tavlen kunne ikke importeres, tjek logfilerne for yderligere detaljer"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Vælg JSON fil",
|
||||
"invalidError": "Ugyldig konfigurationsfil"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Apps",
|
||||
"avoidDuplicates": {
|
||||
"label": "Undgå dubletter",
|
||||
"description": "Ignorerer apps, hvor en app med samme href allerede findes"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Importér kun apps",
|
||||
"description": "Kun tilføjer apps, tavlen skal genskabes manuelt"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Navn på tavle"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Skærmstørrelse",
|
||||
"description": "I versioner før 1.0 tre forskellige tilstande eksisterede, så du var i stand til at vælge mængden af kolonner for hver skærmstørrelse.",
|
||||
"option": {
|
||||
"sm": "Lille",
|
||||
"md": "Mellem",
|
||||
"lg": "Stor"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Sidebar opførsel",
|
||||
"description": "Sidebars blev fjernet i 1.0, kan du vælge, hvad der skal ske med elementerne fra dem.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Sidste afsnit",
|
||||
"description": "Sidebjælken vil blive vist under sidste sektion"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Fjern elementer",
|
||||
"description": "Elementer i sidepanelet vil blive fjernet"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Opret app i farten",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Opret en ny tavle"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Importer en tavle"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Oprette en ny app"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Willkomme zu Homarr",
|
||||
"subtitle": "Lass uns mit der Einrichtung deiner Homarr-Instanz beginnen.",
|
||||
"description": "Um loszulegen, wähle bitte wie du deine Homarr Instanz einrichten möchtest.",
|
||||
"action": {
|
||||
"scratch": "Vo vorne starte",
|
||||
"importOldmarr": "Importiärä us Homarr vor 1.0",
|
||||
"restoreSqlite": "",
|
||||
"restoreSqliteDescription": "",
|
||||
"backToOptions": ""
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Date importiärä",
|
||||
"subtitle": "Du casch date us ere existierende Homarr Instanz importiere.",
|
||||
"dropzone": {
|
||||
"title": "Zieh e ZIP-Datei hiä ane oder klick druf um z durchsueche",
|
||||
"description": "Die uechegladeni ZIP Datei wird verarbeitet und du wirsch chönnä uswähle, was importiere wotsch"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Datei ändere"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Istellige importiere",
|
||||
"description": "Import verhalte konfiguriere"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "{count} boards gfunge",
|
||||
"description": "Wähl alli boards, mit dr grössi wo de wotsch importiere, us",
|
||||
"action": {
|
||||
"selectAll": "Alli uswähle",
|
||||
"unselectAll": "Gesamte Auswahl aufheben"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Import zämäfassig",
|
||||
"description": "Ir zämäfassig unge gsehsch, was importier wird",
|
||||
"action": {
|
||||
"import": "Bestätige und witer"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Apps",
|
||||
"boards": "Boads",
|
||||
"integrations": "Integratione",
|
||||
"credentialUsers": "Benutzer mit Zugangsdaten"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Import token igäh",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Gib z import token vo dire vorherige Homarr Instanz ah"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Invalids token",
|
||||
"message": "Z token wo de hesch agäh isch invalid"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Administrator benutzer",
|
||||
"subtitle": "Gib z Zugangsdate für di Administrator benutzer ah.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Benutzer ersteut",
|
||||
"message": "Dr Benutzer isch erfougrich ersteut worde"
|
||||
},
|
||||
"error": {
|
||||
"title": "Benutzerersteuig isch fehlgschlagge"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Externi Gruppe",
|
||||
"subtitle": "Gib d gruppe ah wo für externi Benutzer verwendet werde söu",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Guppename",
|
||||
"description": "Name muss mit der Admin-Gruppe des externen Anbieters übereinstimmen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Istellige",
|
||||
"subtitle": "Serveristellige apasse."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"continue": "",
|
||||
"skip": ""
|
||||
},
|
||||
"configure": {
|
||||
"progress": "",
|
||||
"skip": "",
|
||||
"finishing": "",
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "",
|
||||
"placeholder": "",
|
||||
"hint": "",
|
||||
"warning": "",
|
||||
"preview": "",
|
||||
"mode": {
|
||||
"subdomain": "",
|
||||
"hostPort": ""
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "",
|
||||
"detectedBreakdown": "",
|
||||
"summary": "",
|
||||
"appBadge": "",
|
||||
"appSectionLabel": "",
|
||||
"scanning": "",
|
||||
"scanningDescription": ""
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Irichtig abschliesse",
|
||||
"subtitle": "Du bisch startklar!",
|
||||
"description": "Du hast die Einrichtung erfolgreich abgeschlossen. Du kannst jetzt mit der Nutzung von Homarr beginnen. Wähle deine nächste Aktion:",
|
||||
"action": {
|
||||
"goToBoard": "Gehe zu {name} Board",
|
||||
"createBoard": "Erstelle dein erstes Board",
|
||||
"inviteUser": "Andere Benutzer einladen",
|
||||
"docs": "Lese die Dokumentation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Zurück zum Anfang"
|
||||
},
|
||||
"user": {
|
||||
"title": "Benutzer",
|
||||
"name": "Benutzer",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Sie haben ungespeicherte Änderungen, sind sie sicher dass sie abbrechen möchten?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Import von Homarr vor Version 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Import erfolgreich",
|
||||
"message": "Das Board wurde erfolgreich importiert"
|
||||
},
|
||||
"error": {
|
||||
"title": "Import fehlgeschlagen",
|
||||
"message": "Das Board konnte nicht importiert werden, überprüfen Sie die Protokolle für weitere Details"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Wähle eine JSON-Datei",
|
||||
"invalidError": "Ungültige Konfigurationsdatei"
|
||||
},
|
||||
"apps": {
|
||||
"label": "",
|
||||
"avoidDuplicates": {
|
||||
"label": "Duplikate vermeiden",
|
||||
"description": "Ignoriert Apps, bei denen eine App mit dem gleichen href bereits existiert"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Nur Apps importieren",
|
||||
"description": "Fügt nur die Apps hinzu, das Board muss manuell neu erstellt werden"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Board Name"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Bildschirmgröße",
|
||||
"description": "In Versionen vor 1.0 gab es drei verschiedene Modi, so dass Sie die Anzahl der Spalten für jede Bildschirmgröße festlegen konnten.",
|
||||
"option": {
|
||||
"sm": "Klein",
|
||||
"md": "Mittel",
|
||||
"lg": "Groß"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Verhalten der Seitenleiste",
|
||||
"description": "Seitenleisten wurden in 1.0 entfernt, Sie können wählen, was mit den Elementen in ihnen passieren soll.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Letzter Abschnitt",
|
||||
"description": "Seitenleiste wird unterhalb des letzten Abschnitts angezeigt"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Elemente entfernen",
|
||||
"description": "Elemente in der Seitenleiste werden entfernt"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Jetzt eine App erstellen",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Erstellen Sie ein neues Board"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Ein Board importieren"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Neue App erstellen"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Willkommen bei Homarr",
|
||||
"subtitle": "Lass uns mit der Einrichtung deiner Homarr-Instanz beginnen.",
|
||||
"description": "Um loszulegen, wähle bitte wie du deine Homarr Instanz einrichten möchtest.",
|
||||
"action": {
|
||||
"scratch": "Von vorne beginnen",
|
||||
"importOldmarr": "Import von Homarr vor 1.0",
|
||||
"restoreSqlite": "Aus SQLite-Backup wiederherstellen",
|
||||
"restoreSqliteDescription": "Laden Sie eine vollständige SQLite-Datenbanksicherung von einer vorherigen Homarr-Instanz hoch. Dies wird alle Boards, Benutzer, Apps, Integrationen und Einstellungen wiederherstellen.",
|
||||
"backToOptions": "← Zurück zu Setup Optionen"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Daten importieren",
|
||||
"subtitle": "Sie können Daten aus einer bestehenden Homarr-Instanz importieren.",
|
||||
"dropzone": {
|
||||
"title": "Ziehen Sie die Zip-Datei hierher oder klicken Sie zum Durchsuchen",
|
||||
"description": "Die hochgeladene Zip-Datei wird bearbeitet und Sie können wählen, was Sie importieren möchten"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Datei ändern"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Einstellungen Importieren",
|
||||
"description": "Importverhalten konfigurieren"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "{count} Boards gefunden",
|
||||
"description": "Wählen Sie alle Boards mit der Größe aus, die Sie importieren möchten",
|
||||
"action": {
|
||||
"selectAll": "Alles auswählen",
|
||||
"unselectAll": "Gesamte Auswahl aufheben"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Zusammenfassung des Imports",
|
||||
"description": "In der folgenden Zusammenfassung sehen Sie, was importiert wird",
|
||||
"action": {
|
||||
"import": "Import bestätigen und fortfahren"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Applikationen",
|
||||
"boards": "Boards",
|
||||
"integrations": "Integrationen",
|
||||
"credentialUsers": "Benutzer mit Zugangsdaten"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Importschlüssel eingeben",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Schlüssel",
|
||||
"description": "Gib den angezeigten Importschlüssel von der vorherigen Homarr-Instanz ein"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Ungültiger Schlüssel",
|
||||
"message": "Der eingegebene Schlüssel ist ungültig"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Administrator",
|
||||
"subtitle": "Geben Sie die Zugangsdaten für Ihren Administrator-Benutzer an.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Benutzer erstellt",
|
||||
"message": "Der Benutzer wurde erfolgreich erstellt"
|
||||
},
|
||||
"error": {
|
||||
"title": "Erstellung des Benutzers fehlgeschlagen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Externe Gruppe",
|
||||
"subtitle": "Gebe die Gruppe an, welche für externe Benutzer verwendet werden soll.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Gruppenname",
|
||||
"description": "Name muss mit der Admin-Gruppe des externen Anbieters übereinstimmen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Einstellungen",
|
||||
"subtitle": "Server-Einstellungen konfigurieren."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrationen",
|
||||
"subtitle": "Wählen Sie die von Ihnen verwendeten Dienste aus.",
|
||||
"description": "Wählen Sie die Integrationen, die Sie verbinden möchten. Ihr Dashboard wird automatisch mit passenden Widgets eingerichtet.",
|
||||
"action": {
|
||||
"continue": "Weiter",
|
||||
"skip": "Vorerst überspringen"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} von {total}",
|
||||
"skip": "Diese Integration überspringen",
|
||||
"finishing": "Dashboard wird eingerichtet...",
|
||||
"error": {
|
||||
"title": "Einrichtung fehlgeschlagen",
|
||||
"message": "Beim Einrichten des Dashboards ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL Helfer",
|
||||
"description": "Diese Helfer versuchen die URL für deine Dienste zu erraten. Wenn dies nicht funktioniert, gib einfach die Adresse manuell ein."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Basis URL",
|
||||
"placeholder": "homelab.local oder 192.168.1.1",
|
||||
"hint": "Geben Sie Ihre Basis-Domain oder IP ein, um die Integrations-URLs automatisch auszufüllen",
|
||||
"warning": "Wenn Sie jetzt Ihre Basis-URL einstellen, werden alle Integration-URLs automatisch ausgefüllt, was Ihnen Zeit während des Setups spart",
|
||||
"preview": "z.B. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Sub-Domain",
|
||||
"hostPort": "Host:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker erkannte {count} Dienste",
|
||||
"detectedBreakdown": "{integrations} Integrationen · {apps} Anwendungen",
|
||||
"summary": "Homarr erkannte {apps} Anwendungen, {integrations} von denen Integrationen integriert sind",
|
||||
"appBadge": "Anwendung",
|
||||
"appSectionLabel": "Zum Dashboard hinzuzufügende Apps ({count} gewählt)",
|
||||
"scanning": "Durchsuche Docker...",
|
||||
"scanningDescription": "Suche nach laufenden Containern auf Ihrem System"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Einrichtung abschließen",
|
||||
"subtitle": "Es kann losgehen!",
|
||||
"description": "Du hast die Einrichtung erfolgreich abgeschlossen. Du kannst jetzt mit der Nutzung von Homarr beginnen. Wähle deine nächste Aktion:",
|
||||
"action": {
|
||||
"goToBoard": "Gehe zu {name} Board",
|
||||
"createBoard": "Erstelle dein erstes Board",
|
||||
"inviteUser": "Andere Benutzer einladen",
|
||||
"docs": "Lese die Dokumentation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Zurück zum Anfang"
|
||||
},
|
||||
"user": {
|
||||
"title": "Benutzer",
|
||||
"name": "Benutzer",
|
||||
@@ -3909,6 +4058,62 @@
|
||||
"message": "Sie haben ungespeicherte Änderungen, sind sie sicher dass sie abbrechen möchten?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Import von Homarr vor Version 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Import erfolgreich",
|
||||
"message": "Das Board wurde erfolgreich importiert"
|
||||
},
|
||||
"error": {
|
||||
"title": "Import fehlgeschlagen",
|
||||
"message": "Das Board konnte nicht importiert werden, überprüfen Sie die Protokolle für weitere Details"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Wähle eine JSON-Datei",
|
||||
"invalidError": "Ungültige Konfigurationsdatei"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Apps",
|
||||
"avoidDuplicates": {
|
||||
"label": "Duplikate vermeiden",
|
||||
"description": "Ignoriert Apps, bei denen eine App mit dem gleichen href bereits existiert"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Nur Apps importieren",
|
||||
"description": "Fügt nur die Apps hinzu. Das Board selbst muss manuell neu erstellt werden"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Board Name"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Bildschirmgröße",
|
||||
"description": "In Versionen vor 1.0 gab es drei verschiedene Modi, so dass Sie die Anzahl der Spalten für jede Bildschirmgröße festlegen konnten.",
|
||||
"option": {
|
||||
"sm": "Klein",
|
||||
"md": "Mittel",
|
||||
"lg": "Groß"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Verhalten der Seitenleiste",
|
||||
"description": "Seitenleisten wurden in 1.0 entfernt, Sie können wählen, was mit den Elementen in ihnen passieren soll.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Letzter Abschnitt",
|
||||
"description": "Seitenleiste wird unterhalb des letzten Abschnitts angezeigt"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Elemente entfernen",
|
||||
"description": "Elemente in der Seitenleiste werden entfernt"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Jetzt eine App erstellen",
|
||||
@@ -5528,6 +5733,9 @@
|
||||
"newBoard": {
|
||||
"label": "Erstellen Sie ein neues Board"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Ein Board importieren"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Neue App erstellen"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Καλώς ήρθατε στο Homarr",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"scratch": "",
|
||||
"importOldmarr": "",
|
||||
"restoreSqlite": "Επαναφορά από αντίγραφο ασφαλείας SQLite",
|
||||
"restoreSqliteDescription": "Μεταφορτώστε ένα πλήρες αντίγραφο ασφαλείας βάσης δεδομένων SQLite από προηγούμενη εγκατάσταση Homarr. Αυτό θα επαναφέρει όλους τους πίνακες, χρήστες, εφαρμογές, ενσωματώσεις και ρυθμίσεις.",
|
||||
"backToOptions": "← Επιστροφή στις επιλογές ρύθμισης"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Εισαγωγή δεδομένων",
|
||||
"subtitle": "",
|
||||
"dropzone": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": ""
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Εισαγωγή ρυθμίσεων",
|
||||
"description": ""
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"selectAll": "Επιλογή όλων",
|
||||
"unselectAll": "Αποεπιλογή όλων"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"import": ""
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Εφαρμογές",
|
||||
"boards": "Πίνακες",
|
||||
"integrations": "",
|
||||
"credentialUsers": ""
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Διαχειριστής",
|
||||
"subtitle": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Ο Χρήστης δημιουργήθηκε",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Εξωτερική ομάδα",
|
||||
"subtitle": "",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Όνομα ομάδας",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Ρυθμίσεις",
|
||||
"subtitle": "Διαμόρφωση ρυθμίσεων διακομιστή."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Ενσωματώσεις",
|
||||
"subtitle": "Επιλέξτε τις υπηρεσίες που χρησιμοποιείτε.",
|
||||
"description": "Επιλέξτε τις ενσωματώσεις που θέλετε να συνδέσετε. Θα ρυθμίσουμε τον πίνακα σας με αντίστοιχα widgets αυτόματα.",
|
||||
"action": {
|
||||
"continue": "Συνέχεια",
|
||||
"skip": "Παράλειψη για τώρα"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} από {total}",
|
||||
"skip": "Παράλειψη αυτής της ενσωμάτωσης",
|
||||
"finishing": "Ρύθμιση του πίνακα σας...",
|
||||
"error": {
|
||||
"title": "Αποτυχία ρύθμισης",
|
||||
"message": "Κάτι πήγε στραβά κατά τη ρύθμιση του πίνακα σας. Παρακαλώ προσπαθήστε ξανά."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Βοηθοί URL",
|
||||
"description": "Αυτοί οι βοηθοί προσπαθούν να μαντέψουν το URL για τις υπηρεσίες σας. Αν δεν λειτουργήσει, απλά πληκτρολογήστε τη διεύθυνση χειροκίνητα."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Βασικό URL",
|
||||
"placeholder": "homelab.local ή 192.168.1.1",
|
||||
"hint": "Εισαγάγετε το βασικό domain ή IP σας για αυτόματη συμπλήρωση των URL ενσωμάτωσης",
|
||||
"warning": "Η ρύθμιση του βασικού URL τώρα θα συμπληρώσει αυτόματα όλα τα URL ενσωμάτωσης, εξοικονομώντας χρόνο κατά τη ρύθμιση",
|
||||
"preview": "π.χ. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Υποτομέας",
|
||||
"hostPort": "Διακομιστής:Θύρα"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Ο Docker εντόπισε {count} υπηρεσίες",
|
||||
"detectedBreakdown": "{integrations} ενσωματώσεις · {apps} εφαρμογές",
|
||||
"summary": "Το Homarr εντόπισε {apps} εφαρμογές, {integrations} από τις οποίες έχουν ενσωματωμένες ενσωματώσεις",
|
||||
"appBadge": "Εφαρμογή",
|
||||
"appSectionLabel": "Εφαρμογές προς προσθήκη στον πίνακα ({count} επιλεγμένες)",
|
||||
"scanning": "Σάρωση Docker...",
|
||||
"scanningDescription": "Αναζήτηση εκτελούμενων containers στο σύστημά σας"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"goToBoard": "",
|
||||
"createBoard": "",
|
||||
"inviteUser": "",
|
||||
"docs": "Διαβάστε την τεκμηρίωση"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": ""
|
||||
},
|
||||
"user": {
|
||||
"title": "Χρήστες",
|
||||
"name": "Χρήστης",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "",
|
||||
"invalidError": ""
|
||||
},
|
||||
"apps": {
|
||||
"label": "Εφαρμογές",
|
||||
"avoidDuplicates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": ""
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "Μικρό",
|
||||
"md": "Μεσαίο",
|
||||
"lg": "Μεγάλο"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Welcome to Homarr",
|
||||
"subtitle": "Let's start setting your Homarr instance up.",
|
||||
"description": "To get started, please select how you want to continue.",
|
||||
"action": {
|
||||
"scratch": "Start from scratch",
|
||||
"importOldmarr": "Import from a Homarr version before v1.0",
|
||||
"restoreSqlite": "Restore from SQLite backup",
|
||||
"restoreSqliteDescription": "Upload a full SQLite database backup from a previous Homarr instance. This will restore all boards, users, apps, integrations, and settings.",
|
||||
"backToOptions": "← Back to setup options"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Import data",
|
||||
"subtitle": "You can import data from an existing Homarr instance.",
|
||||
"dropzone": {
|
||||
"title": "Drag your ZIP file here or click to browse your files",
|
||||
"description": "The ZIP file you uploaded will be processed and you will be able to select what you would like to import"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Change file"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Import settings",
|
||||
"description": "Configure the import behaviour"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Found {count} boards",
|
||||
"description": "Choose all the boards with the size you want to import",
|
||||
"action": {
|
||||
"selectAll": "Select all",
|
||||
"unselectAll": "Deselect all"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Import summary",
|
||||
"description": "In the summary below, you can see what will be imported",
|
||||
"action": {
|
||||
"import": "Please confirm import and continue"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Applications",
|
||||
"boards": "Boards",
|
||||
"integrations": "Integrations",
|
||||
"credentialUsers": "Credential users"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Enter import token",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Enter the import token shown in your previous Homarr instance"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Invalid Token",
|
||||
"message": "Sorry, but the token you entered is invalid"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Administrative user",
|
||||
"subtitle": "Please specify the credentials for your administrator user.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "User created",
|
||||
"message": "The user has been created successfully"
|
||||
},
|
||||
"error": {
|
||||
"title": "User creation failed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "External group",
|
||||
"subtitle": "Please specify the group which should be used for external users.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Group name",
|
||||
"description": "The name needs to match the admin group of your external provider"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"subtitle": "Configure server settings"
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrations",
|
||||
"subtitle": "Select the services you use.",
|
||||
"description": "Choose the integrations you'd like to connect. We'll set up your dashboard with matching widgets automatically.",
|
||||
"action": {
|
||||
"continue": "Continue",
|
||||
"skip": "Skip for now"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} of {total}",
|
||||
"skip": "Skip this integration",
|
||||
"finishing": "Setting up your dashboard...",
|
||||
"error": {
|
||||
"title": "Setup failed",
|
||||
"message": "Something went wrong while setting up your dashboard. Please try again."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL helpers",
|
||||
"description": "These helpers try to guess the URL for your services. If it doesn't work, just type the address manually."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Base URL",
|
||||
"placeholder": "homelab.local or 192.168.1.1",
|
||||
"hint": "Enter your base domain or IP to auto-fill integration URLs",
|
||||
"warning": "Setting your base URL now will auto-fill all integration URLs, saving you time during setup",
|
||||
"preview": "e.g. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdomain",
|
||||
"hostPort": "Host:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker detected {count} services",
|
||||
"detectedBreakdown": "{integrations} integrations · {apps} apps",
|
||||
"summary": "Homarr detected {apps} apps, {integrations} of which have integrations built-in",
|
||||
"appBadge": "App",
|
||||
"appSectionLabel": "Apps to add to dashboard ({count} selected)",
|
||||
"scanning": "Scanning Docker...",
|
||||
"scanningDescription": "Looking for running containers on your system"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Finish set-up",
|
||||
"subtitle": "Congratulations, you are ready to go!",
|
||||
"description": "You have successfully finished the setup process. You can now start using Homarr. Please select your next action:",
|
||||
"action": {
|
||||
"goToBoard": "Go to {name} board",
|
||||
"createBoard": "Create your first board",
|
||||
"inviteUser": "Invite other users",
|
||||
"docs": "Read the documentation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Go back to the start"
|
||||
},
|
||||
"user": {
|
||||
"title": "Users",
|
||||
"name": "User",
|
||||
@@ -3865,6 +4014,62 @@
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "",
|
||||
"invalidError": ""
|
||||
},
|
||||
"apps": {
|
||||
"label": "",
|
||||
"avoidDuplicates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": ""
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "",
|
||||
"md": "",
|
||||
"lg": ""
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5475,6 +5680,9 @@
|
||||
"newBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
},
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"restoreTitle": "Restore this Homarr",
|
||||
"restoreDescription": "A full SQLite backup restores boards, people, apps, integrations, and settings. Homarr validates it before replacing anything.",
|
||||
"errorTitle": "Setup could not start",
|
||||
"errorDescription": "Your setup choices are still here. Try again, or reload the page if this continues.",
|
||||
"ready": "Ready to configure",
|
||||
"panelTitle": "From services to a useful board",
|
||||
"panelDescription": "Discovery, secure connections, layouts, widgets, Assistant, Workshop, and MCP stay connected in one flow.",
|
||||
@@ -64,7 +65,8 @@
|
||||
"name": "External administrator group",
|
||||
"nameDescription": "This is case-sensitive and must match your identity provider.",
|
||||
"continue": "Save group and continue",
|
||||
"errorTitle": "Group could not be saved"
|
||||
"errorTitle": "Group could not be saved",
|
||||
"unknownError": "The administrator group could not be saved."
|
||||
},
|
||||
"essentials": {
|
||||
"title": "Start with familiar defaults",
|
||||
@@ -117,9 +119,6 @@
|
||||
"connect": {
|
||||
"title": "Connect what makes the board useful",
|
||||
"description": "Select several services at once. Docker labels take priority, image matching fills gaps, and every URL and credential stays reviewable.",
|
||||
"search": "Search integrations",
|
||||
"widgets": "{count} widgets",
|
||||
"detected": "Detected",
|
||||
"discoveredIntegrations": "Detected integration instances ({count})",
|
||||
"detectedIntegrationLabel": "Import {name}, detected as {kind}",
|
||||
"detectedAppLabel": "Import detected app {name}",
|
||||
@@ -222,6 +221,7 @@
|
||||
"keyDescription": "For security, Homarr cannot show this API key again.",
|
||||
"copyKey": "Copy API key",
|
||||
"createKey": "Create an MCP API key",
|
||||
"errorTitle": "MCP API key could not be created",
|
||||
"loginRequired": "Sign in as an administrator after setup to create an API key.",
|
||||
"configuration": "Client configuration",
|
||||
"copy": "Copy configuration",
|
||||
@@ -6068,7 +6068,8 @@
|
||||
"private": "This board is private"
|
||||
},
|
||||
"preview": {
|
||||
"label": "Layout preview for {name}, with {count} items"
|
||||
"label": "Layout preview for {name}, with {count} items",
|
||||
"unknownCreator": "Unknown creator"
|
||||
},
|
||||
"noResults": {
|
||||
"title": "No boards yet",
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Bienvenido a Homarr",
|
||||
"subtitle": "Comencemos con la configuración de tu instancia de Homarr.",
|
||||
"description": "Para empezar, por favor, selecciona cómo deseas configurar tu instancia de Homarr.",
|
||||
"action": {
|
||||
"scratch": "Empezar de cero",
|
||||
"importOldmarr": "Importar desde una versión anterior a Homarr 1.0",
|
||||
"restoreSqlite": "",
|
||||
"restoreSqliteDescription": "",
|
||||
"backToOptions": ""
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importar datos",
|
||||
"subtitle": "Puedes importar datos desde una instancia de Homarr existente.",
|
||||
"dropzone": {
|
||||
"title": "Arrastre el archivo ZIP aquí o haga clic para navegar",
|
||||
"description": "El archivo ZIP subido será procesado y podrás seleccionar lo que quieres importar"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Modificar el archivo"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importar ajustes",
|
||||
"description": "Configurar el comportamiento de la importación"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Se encontraron {count} tableros",
|
||||
"description": "Elige todos los tableros con el tamaño que deseas para importar",
|
||||
"action": {
|
||||
"selectAll": "Seleccionar todo",
|
||||
"unselectAll": "Deshacer selección"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Resumen de la importación",
|
||||
"description": "En el resumen que se muestra a continuación puedes ver qué se importará",
|
||||
"action": {
|
||||
"import": "Confirmar la importación y continuar"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Aplicaciones",
|
||||
"boards": "Tableros",
|
||||
"integrations": "Integraciones",
|
||||
"credentialUsers": "Credenciales de usuarios"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Introducir token de importación",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Introduzca el token de importación mostrado de su anterior instancia de Homarr"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Token no válido",
|
||||
"message": "El token que has introducido no es válido"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Usuario administrador",
|
||||
"subtitle": "Especifica las credenciales para tu usuario administrador.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Usuario creado",
|
||||
"message": "El usuario se creó con éxito"
|
||||
},
|
||||
"error": {
|
||||
"title": "Error al crear el usuario"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Grupo externo",
|
||||
"subtitle": "Especifique el grupo que debe ser usado para usuarios externos.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nombre del grupo",
|
||||
"description": "El nombre debe coincidir con el grupo de administración del proveedor externo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Ajustes",
|
||||
"subtitle": "Configurar ajustes del servidor."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"continue": "",
|
||||
"skip": ""
|
||||
},
|
||||
"configure": {
|
||||
"progress": "",
|
||||
"skip": "",
|
||||
"finishing": "",
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "",
|
||||
"placeholder": "",
|
||||
"hint": "",
|
||||
"warning": "",
|
||||
"preview": "",
|
||||
"mode": {
|
||||
"subdomain": "",
|
||||
"hostPort": ""
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "",
|
||||
"detectedBreakdown": "",
|
||||
"summary": "",
|
||||
"appBadge": "",
|
||||
"appSectionLabel": "",
|
||||
"scanning": "",
|
||||
"scanningDescription": ""
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Finalizar la configuración",
|
||||
"subtitle": "¡Estás listo para empezar!",
|
||||
"description": "Has completado el proceso de configuración inicial con éxito. Puedes empezar a utilizar Homarr. Selecciona tu próxima tarea:",
|
||||
"action": {
|
||||
"goToBoard": "Ir al tablero {name}",
|
||||
"createBoard": "Crea tu primer tablero",
|
||||
"inviteUser": "Invita a otros usuarios",
|
||||
"docs": "Consulta la documentación"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Volver al inicio"
|
||||
},
|
||||
"user": {
|
||||
"title": "Usuarios",
|
||||
"name": "Usuario",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Tienes cambios sin guardar, ¿estás seguro de que quieres salir?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importar desde una versión anterior a Homarr 1.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Importación con éxito",
|
||||
"message": "El tablero fue importado con éxito"
|
||||
},
|
||||
"error": {
|
||||
"title": "Error de importación",
|
||||
"message": "El tablero no pudo ser importado, compruebe los registros para más detalles"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Seleccionar archivo JSON",
|
||||
"invalidError": "Archivo de configuración no válido"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Aplicaciones",
|
||||
"avoidDuplicates": {
|
||||
"label": "Evitar duplicados",
|
||||
"description": "Ignora aplicaciones donde ya existe una aplicación con el mismo href"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Importar solo aplicaciones",
|
||||
"description": "Sólo añade las aplicaciones, el tablero debe ser recreado manualmente"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Nombre del tablero"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Tamaño de pantalla",
|
||||
"description": "En versiones anteriores a la 1.0 existían tres modos diferentes, por lo que podías elegir la cantidad de columnas para cada tamaño de pantalla.",
|
||||
"option": {
|
||||
"sm": "Pequeño",
|
||||
"md": "Mediano",
|
||||
"lg": "Grande"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Comportamiento de la barra lateral",
|
||||
"description": "Las barras laterales fueron eliminadas en la versión 1.0, puedes seleccionar lo que debería pasar con los elementos dentro de ellas.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Última sección",
|
||||
"description": "La barra lateral se mostrará debajo de la última sección"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Eliminar los elementos",
|
||||
"description": "Los elementos contenidos en la barra lateral serán eliminados"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Crear aplicación en el momento",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Crear un nuevo tablero"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Importar un tablero"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Crear una nueva aplicación"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"scratch": "",
|
||||
"importOldmarr": "",
|
||||
"restoreSqlite": "",
|
||||
"restoreSqliteDescription": "",
|
||||
"backToOptions": ""
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"dropzone": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": ""
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"selectAll": "",
|
||||
"unselectAll": ""
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"import": ""
|
||||
},
|
||||
"entities": {
|
||||
"apps": "",
|
||||
"boards": "",
|
||||
"integrations": "",
|
||||
"credentialUsers": ""
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "",
|
||||
"subtitle": ""
|
||||
},
|
||||
"integrations": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"continue": "",
|
||||
"skip": ""
|
||||
},
|
||||
"configure": {
|
||||
"progress": "",
|
||||
"skip": "",
|
||||
"finishing": "",
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "",
|
||||
"placeholder": "",
|
||||
"hint": "",
|
||||
"warning": "",
|
||||
"preview": "",
|
||||
"mode": {
|
||||
"subdomain": "",
|
||||
"hostPort": ""
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "",
|
||||
"detectedBreakdown": "",
|
||||
"summary": "",
|
||||
"appBadge": "",
|
||||
"appSectionLabel": "",
|
||||
"scanning": "",
|
||||
"scanningDescription": ""
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"goToBoard": "",
|
||||
"createBoard": "",
|
||||
"inviteUser": "",
|
||||
"docs": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": ""
|
||||
},
|
||||
"user": {
|
||||
"title": "Kasutajad",
|
||||
"name": "Kasutaja",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Teil on salvestamata muudatusi, kas olete kindel, et soovite lahkuda?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Impordi Homarr'ist enne 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Importimine õnnestus",
|
||||
"message": "Töölaud imporditi edukalt"
|
||||
},
|
||||
"error": {
|
||||
"title": "Importimine ebaõnnestus",
|
||||
"message": "Töölauda ei saanud importida, vaadake logisid täpsema teabe saamiseks"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Vali JSON fail",
|
||||
"invalidError": "Vigane seadistusfail"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Rakendused",
|
||||
"avoidDuplicates": {
|
||||
"label": "Väldi duplikaate",
|
||||
"description": "Ignoreerib rakendusi, kui sama href'iga rakendus on juba olemas"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Impordi ainult rakendusi",
|
||||
"description": "Lisab ainult rakendused, töölaud tuleb käsitsi uuesti luua"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Töölaua nimi"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Ekraani suurus",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "Väike",
|
||||
"md": "Keskmine",
|
||||
"lg": "Suur"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Külgriba käitumine",
|
||||
"description": "Külgribad eemaldati versioonis 1.0, saate valida, mis peaks juhtuma neis olevate üksustega.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Viimane jaotis",
|
||||
"description": "Külgriba kuvatakse viimase jaotise all"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Eemalda üksused",
|
||||
"description": "Külgribal olevad üksused eemaldatakse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Tervetuloa Homarriin",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"scratch": "",
|
||||
"importOldmarr": "",
|
||||
"restoreSqlite": "Palauta SQLite-varmuuskopiosta",
|
||||
"restoreSqliteDescription": "Lataa täysi SQLite-tietokantavarmuuskopio aiemmasta Homarr-instanssista. Tämä palauttaa kaikki paneelit, käyttäjät, sovellukset, integraatiot ja asetukset.",
|
||||
"backToOptions": "← Takaisin asennusvaihtoehtoihin"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"dropzone": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": ""
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"selectAll": "Valitse kaikki",
|
||||
"unselectAll": "Tyhjennä valinnat"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"import": ""
|
||||
},
|
||||
"entities": {
|
||||
"apps": "",
|
||||
"boards": "",
|
||||
"integrations": "Integraatiot",
|
||||
"credentialUsers": ""
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Pääkäyttäjä",
|
||||
"subtitle": "Määritä pääkäyttäjäsi kirjautumistiedot.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": "Käyttäjän luonti epäonnistui"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Ulkoinen ryhmä",
|
||||
"subtitle": "Määritä ulkoisille käyttäjille käytettävä ryhmä.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Ryhmän nimi",
|
||||
"description": "Nimen tulee vastata ulkoisen palveluntarjoajan pääkäyttäjäryhmää"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Asetukset",
|
||||
"subtitle": "Määritä palvelinasetukset."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integraatiot",
|
||||
"subtitle": "Valitse käyttämäsi palvelut.",
|
||||
"description": "Valitse integraatiot, jotka haluat yhdistää. Kojelaudallaesi lisätään automaattisesti yhteensopivia widgettejä.",
|
||||
"action": {
|
||||
"continue": "Jatka",
|
||||
"skip": "Ohita toistaiseksi"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current}/{total}",
|
||||
"skip": "Ohita tämä integraatio",
|
||||
"finishing": "Kojelautaasi määritetään...",
|
||||
"error": {
|
||||
"title": "Määritys epäonnistui",
|
||||
"message": "Jotain meni pieleen kojelautaasi määritettäessä. Yritä uudelleen."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL-apurit",
|
||||
"description": "Nämä apurit pyrkivät arvaamaan palveluidesi URL-osoitteet. Jos tämä ei toimi, kirjoita osoite manuaalisesti."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Perus-URL",
|
||||
"placeholder": "homelab.local tai 192.168.1.1",
|
||||
"hint": "Syötä perusverkkotunnuksesi tai IP-osoite täyttääksesi integraation URL-osoitteet automaattisesti",
|
||||
"warning": "Asettamalla perusosoitteen nyt, voidaan integraatioiden URL-osoitteet täyttää automaattisesti, joka nopeuttaa käyttöönottoa",
|
||||
"preview": "esim. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Aliverkkotunnus",
|
||||
"hostPort": "Isäntä:Portti"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker löysi {count} palvelua",
|
||||
"detectedBreakdown": "{integrations} integraatiota · {apps} sovellusta",
|
||||
"summary": "Homarr havaitse {apps} sovellusta, joista {integrations} löytyy sisäänrakennettu integraatio",
|
||||
"appBadge": "Sovellus",
|
||||
"appSectionLabel": "Ohjauspaneeliin lisättävät sovellukset ({count} valittu)",
|
||||
"scanning": "Dockeria tutkitaan...",
|
||||
"scanningDescription": "Tunnistetaan järjestelmässäsi suoritettavia kontteja"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Viimeistele määritys",
|
||||
"subtitle": "Olet valmis aloittamaan!",
|
||||
"description": "Olet suorittanut käyttöönoton onnistuneesti ja voit nyt aloittaa Homarrin käytön. Valitse seuraava toimenpiteesi:",
|
||||
"action": {
|
||||
"goToBoard": "Avaa paneeli {name}",
|
||||
"createBoard": "Luo ensimmäinen paneelisi",
|
||||
"inviteUser": "Kutsu muita käyttäjiä",
|
||||
"docs": "Lue ohjeita"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Palaa alkuun"
|
||||
},
|
||||
"user": {
|
||||
"title": "Käyttäjät",
|
||||
"name": "Käyttäjä",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Muutoksia ei ole tallennettu. Haluatko varmasti poistua?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Tuo Homarr-versiota 1.0.0 vanhemmasta",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "",
|
||||
"invalidError": ""
|
||||
},
|
||||
"apps": {
|
||||
"label": "",
|
||||
"avoidDuplicates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": ""
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "",
|
||||
"md": "",
|
||||
"lg": ""
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Luo sovellus lennossa",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Luo uusi paneeli"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Tuo paneeli"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Luo uusi sovellus"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Bienvenue sur Homarr",
|
||||
"subtitle": "Commençons par configurer votre instance Homarr.",
|
||||
"description": "Pour commencer, veuillez selectionner comment vous souhaitez configurer votre instance Homarr.",
|
||||
"action": {
|
||||
"scratch": "Partir de zéro",
|
||||
"importOldmarr": "Importer depuis Homarr avant la 1.0",
|
||||
"restoreSqlite": "Restaurer depuis une sauvegarde SQLite",
|
||||
"restoreSqliteDescription": "Téléchargez une sauvegarde complète de la base de données SQLite depuis une instance Homarr précédente. Cela restaurera tous les tableaux, utilisateurs, applications, intégrations et paramètres.",
|
||||
"backToOptions": "← Retour aux options de configuration"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importer des données",
|
||||
"subtitle": "Vous pouvez importer des données depuis une instance Homarr existante.",
|
||||
"dropzone": {
|
||||
"title": "Déposez le fichier zip ici ou cliquez pour naviguer",
|
||||
"description": "Le zip téléchargé sera traité et vous pourrez sélectionner ce que vous voulez importer"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Changer le fichier"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importer des paramètres",
|
||||
"description": "Configurer le comportement d'importation"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "{count} tableaux trouvés",
|
||||
"description": "Choisissez tous les tableaux avec la taille que vous souhaitez importer",
|
||||
"action": {
|
||||
"selectAll": "Tout sélectionner",
|
||||
"unselectAll": "Tout désélectionner"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Résumé de l'importation",
|
||||
"description": "Dans le résumé ci-dessous vous pouvez voir ce qui va être importé",
|
||||
"action": {
|
||||
"import": "Confirmer l'importation et continuer"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Applications",
|
||||
"boards": "Tableaux de bord",
|
||||
"integrations": "Intégrations",
|
||||
"credentialUsers": "Utilisateurs identifiés"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Saisir le jeton d'importation",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Jeton",
|
||||
"description": "Entrez le jeton d'importation de votre instance précédente"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Jeton non valide",
|
||||
"message": "Le jeton que vous avez saisi est invalide"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Administrateur",
|
||||
"subtitle": "Spécifiez les informations d'identification pour votre compte d'administrateur.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Utilisateur créé",
|
||||
"message": "L’utilisateur a été créé avec succès"
|
||||
},
|
||||
"error": {
|
||||
"title": "La création de l'utilisateur a échoué"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Groupe externe",
|
||||
"subtitle": "Spécifie le groupe à utiliser pour les utilisateurs externes.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nom du groupe",
|
||||
"description": "Le nom doit correspondre au groupe administrateur du fournisseur externe"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Paramètres",
|
||||
"subtitle": "Configurer les paramètres du serveur."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Intégrations",
|
||||
"subtitle": "Sélectionnez les services que vous utilisez.",
|
||||
"description": "Choisissez les intégrations que vous souhaitez connecter. Nous allons configurer votre tableau de bord avec les widgets correspondants automatiquement.",
|
||||
"action": {
|
||||
"continue": "Continuer",
|
||||
"skip": "Ignorer pour le moment"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} sur {total}",
|
||||
"skip": "Ignorer cette intégration",
|
||||
"finishing": "Configuration de votre tableau de bord...",
|
||||
"error": {
|
||||
"title": "Échec de la configuration",
|
||||
"message": "Une erreur s'est produite lors de la configuration de votre tableau de bord. Veuillez réessayer."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Aides pour les URL",
|
||||
"description": "Ces aides essaient de deviner l'URL de vos services. Si cela ne fonctionne pas, tapez simplement l'adresse manuellement."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "URL de base",
|
||||
"placeholder": "homelab.local ou 192.168.1.1",
|
||||
"hint": "Entrez votre domaine de base ou votre IP pour le remplissage automatique des URL d'intégration",
|
||||
"warning": "Définir votre URL de base maintenant remplira automatiquement toutes les URL d'intégration, ce qui vous fera gagner du temps lors de la configuration",
|
||||
"preview": "ex. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Sous-domaine",
|
||||
"hostPort": "Hôte:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker a détecté {count} services",
|
||||
"detectedBreakdown": "Intégrations {integrations} · Applications {apps}",
|
||||
"summary": "Les applications {apps} ont été détectées par Homarr, dont {integrations} ont des intégrations intégrées",
|
||||
"appBadge": "App",
|
||||
"appSectionLabel": "Applications à ajouter au tableau de bord ({count} sélectionné)",
|
||||
"scanning": "Analyse de Docker...",
|
||||
"scanningDescription": "Recherche de conteneurs en cours d'exécution sur votre système"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Terminer la configuration",
|
||||
"subtitle": "Vous êtes prêt !",
|
||||
"description": "Vous avez terminé avec succès le processus d'installation. Vous pouvez maintenant commencer à utiliser Homarr. Sélectionnez votre prochaine action :",
|
||||
"action": {
|
||||
"goToBoard": "Accéder au tableau {name}",
|
||||
"createBoard": "Créez votre premier tableau",
|
||||
"inviteUser": "Inviter d'autres utilisateurs",
|
||||
"docs": "Lire la documentation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Retour au début"
|
||||
},
|
||||
"user": {
|
||||
"title": "Utilisateurs",
|
||||
"name": "Utilisateur",
|
||||
@@ -3893,6 +4042,62 @@
|
||||
"message": "Vous avez des modifications non enregistrées, êtes-vous sûr(e) de vouloir quitter ?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importer depuis homarr avant la version 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Importation réussie",
|
||||
"message": "Le tableau a été importé avec succès"
|
||||
},
|
||||
"error": {
|
||||
"title": "Échec de l'importation",
|
||||
"message": "Le tableau n'a pas pu être importé, vérifiez les logs pour plus de détails"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Sélectionnez un fichier JSON",
|
||||
"invalidError": "Fichier de configuration invalide"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Applications",
|
||||
"avoidDuplicates": {
|
||||
"label": "Éviter les doublons",
|
||||
"description": "Ignore les applications où une application avec le même href existe déjà"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Importer uniquement les applications",
|
||||
"description": "Ajoute uniquement les applications, le tableau doit être recréé manuellement"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Nom du tableau"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Taille de l'écran",
|
||||
"description": "Dans les versions antérieures à 1,0 il existait trois modes différents, de sorte que vous pouviez choisir le nombre de colonnes pour chaque taille d'écran.",
|
||||
"option": {
|
||||
"sm": "Petite",
|
||||
"md": "Moyenne",
|
||||
"lg": "Grande"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Comportement de la barre latérale",
|
||||
"description": "Les barres latérales ont été enlevées en 1.0, vous pouvez sélectionner ce qui doit se passer avec les éléments à l'intérieur.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Dernière section",
|
||||
"description": "La barre latérale sera affichée sous la dernière section"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Retirer des éléments",
|
||||
"description": "Les éléments contenus dans la barre latérale seront supprimés"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Créer une application à la volée",
|
||||
@@ -5503,6 +5708,9 @@
|
||||
"newBoard": {
|
||||
"label": "Créer un nouveau tableau"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Importer un tableau"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Créer une nouvelle application"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "ברוכים הבאים ל- Homarr",
|
||||
"subtitle": "בוא נתחיל בהגדרת ה-Homarr שלך.",
|
||||
"description": "כדי להתחיל, בחר כיצד ברצונך להגדיר את ה-Homarr שלך.",
|
||||
"action": {
|
||||
"scratch": "התחל מאפס",
|
||||
"importOldmarr": "יבוא מ-Homarr לפני 1.0",
|
||||
"restoreSqlite": "",
|
||||
"restoreSqliteDescription": "",
|
||||
"backToOptions": ""
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "ייבוא נתונים",
|
||||
"subtitle": "אתה יכול לייבא נתונים מ- Homarr קיים.",
|
||||
"dropzone": {
|
||||
"title": "גרור את קובץ ה-zip לכאן או לחץ כדי לחפש",
|
||||
"description": "ה-zip שהועלה יעובד ותוכל לבחור מה אתה רוצה לייבא"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "שנה קובץ"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "הגדרות ייבוא",
|
||||
"description": "הגדר את התנהגות הייבוא"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "נמצאו {count} לוחות",
|
||||
"description": "בחר את כל הלוחות עם הגודל שברצונך לייבא",
|
||||
"action": {
|
||||
"selectAll": "בחר הכל",
|
||||
"unselectAll": "בטל את הבחירה בכולם"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "סיכום ייבוא",
|
||||
"description": "בסיכום למטה תוכלו לראות מה ייבא",
|
||||
"action": {
|
||||
"import": "אשר את הייבוא והמשך"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "אפליקציות",
|
||||
"boards": "לוחות",
|
||||
"integrations": "אינטגרציות",
|
||||
"credentialUsers": "משתמשים מאושרים"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "הזן אסימון ייבוא",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "טוקן",
|
||||
"description": "הזן את אסימון הייבוא המוצג ב- Homarr הקודם שלך"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "אסימון לא חוקי",
|
||||
"message": "האסימון שהזנת אינו חוקי"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "משתמש מנהל",
|
||||
"subtitle": "ציין את האישורים עבור משתמש המנהל שלך.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "המשתמש נוצר",
|
||||
"message": "המשתמש נוצר בהצלחה"
|
||||
},
|
||||
"error": {
|
||||
"title": "יצירת המשתמש נכשלה"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "קבוצה חיצונית",
|
||||
"subtitle": "ציין את הקבוצה שבה יש להשתמש עבור משתמשים חיצוניים.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "שם הקבוצה",
|
||||
"description": "השם צריך להתאים לקבוצת הניהול של הספק החיצוני"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "הגדרות",
|
||||
"subtitle": "קבע את הגדרות השרת."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"continue": "",
|
||||
"skip": ""
|
||||
},
|
||||
"configure": {
|
||||
"progress": "",
|
||||
"skip": "",
|
||||
"finishing": "",
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "",
|
||||
"placeholder": "",
|
||||
"hint": "",
|
||||
"warning": "",
|
||||
"preview": "",
|
||||
"mode": {
|
||||
"subdomain": "",
|
||||
"hostPort": ""
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "",
|
||||
"detectedBreakdown": "",
|
||||
"summary": "",
|
||||
"appBadge": "",
|
||||
"appSectionLabel": "",
|
||||
"scanning": "",
|
||||
"scanningDescription": ""
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "סיים את ההגדרה",
|
||||
"subtitle": "המערכת מוכנה לפעולה!",
|
||||
"description": "השלמת בהצלחה את תהליך ההגדרה. כעת תוכל להתחיל להשתמש ב-Homarr. בחר את הפעולה הבאה שלך:",
|
||||
"action": {
|
||||
"goToBoard": "עבור ללוח {name}",
|
||||
"createBoard": "צור את הלוח הראשון שלך",
|
||||
"inviteUser": "הזמן משתמשים אחרים",
|
||||
"docs": "קרא את הדוקומנטציה"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "חזרה להתחלה"
|
||||
},
|
||||
"user": {
|
||||
"title": "משתמשים",
|
||||
"name": "משתמש",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "יש לך שינויים שלא נשמרו, האם אתה בטוח שברצונך לעזוב?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "יבוא מ- homarr לפני 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "הייבוא הצליח",
|
||||
"message": "הלוח יובא בהצלחה"
|
||||
},
|
||||
"error": {
|
||||
"title": "הייבוא נכשל",
|
||||
"message": "לא ניתן לייבא את הלוח, בדוק את לוגים לפרטים נוספים"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "בחר קובץ JSON",
|
||||
"invalidError": "קובץ תצורה לא חוקי"
|
||||
},
|
||||
"apps": {
|
||||
"label": "אפליקציות",
|
||||
"avoidDuplicates": {
|
||||
"label": "הימנע מכפילויות",
|
||||
"description": "מתעלם מאפליקציות שבהן כבר קיימת אפליקציה עם אותה כתובת רשת"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "ייבוא רק אפליקציות",
|
||||
"description": "רק מוסיף את האפליקציות, יש ליצור מחדש את הלוח באופן ידני"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "שם הלוח"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "גודל מסך",
|
||||
"description": "בגרסאות שלפני 1.0 היו קיימים שלושה מצבים שונים, כך שניתן היה לבחור את כמות העמודות עבור כל גודל מסך.",
|
||||
"option": {
|
||||
"sm": "קטן",
|
||||
"md": "בינוני",
|
||||
"lg": "גדול"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "התנהגות סרגל הצד",
|
||||
"description": "סרגלי צד הוסרו ב- 1.0, אתה יכול לבחור מה צריך לקרות עם הפריטים שבתוכם.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "החלק האחרון",
|
||||
"description": "סרגל צד יוצג מתחת לקטע האחרון"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "הסרת פריטים",
|
||||
"description": "פריטים הכלולים בסרגל הצד יוסרו"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "צור אפליקציה תוך כדי תנועה",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "יצירת לוח חדש"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "ייבוא לוח"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "יצירת אפליקציה חדשה"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"scratch": "",
|
||||
"importOldmarr": "",
|
||||
"restoreSqlite": "Vrati iz SQLite sigurnosne kopije",
|
||||
"restoreSqliteDescription": "Prenesite cjelovitu SQLite sigurnosnu kopiju baze podataka iz prethodne Homarr instance. To će vratiti sve ploče, korisnike, aplikacije, integracije i postavke.",
|
||||
"backToOptions": "← Natrag na opcije postavljanja"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"dropzone": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": ""
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"selectAll": "",
|
||||
"unselectAll": ""
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"import": ""
|
||||
},
|
||||
"entities": {
|
||||
"apps": "aplikacije",
|
||||
"boards": "Daske",
|
||||
"integrations": "",
|
||||
"credentialUsers": ""
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Znak",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Postavke",
|
||||
"subtitle": ""
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integracije",
|
||||
"subtitle": "Odaberite usluge koje koristite.",
|
||||
"description": "Odaberite integracije koje želite povezati. Automatski ćemo postaviti vašu ploču s odgovarajućim widgetima.",
|
||||
"action": {
|
||||
"continue": "Nastavi",
|
||||
"skip": "Preskoči za sada"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} od {total}",
|
||||
"skip": "Preskoči ovu integraciju",
|
||||
"finishing": "Postavljanje vaše ploče...",
|
||||
"error": {
|
||||
"title": "Postavljanje nije uspjelo",
|
||||
"message": "Nešto je pošlo po zlu prilikom postavljanja vaše ploče. Pokušajte ponovno."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Pomagači URL-a",
|
||||
"description": "Ovi pomagači pokušavaju pogoditi URL za vaše usluge. Ako ne radi, samo ručno upišite adresu."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Osnovni URL",
|
||||
"placeholder": "homelab.local ili 192.168.1.1",
|
||||
"hint": "Unesite svoju osnovnu domenu ili IP za automatsko popunjavanje URL-ova integracija",
|
||||
"warning": "Postavljanjem osnovnog URL-a sada automatski će ispuniti sve URL-ove integracija, uštedjet ćete vrijeme tijekom postavljanja",
|
||||
"preview": "npr. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Poddomena",
|
||||
"hostPort": "Računalo:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker je otkrio {count} usluga",
|
||||
"detectedBreakdown": "{integrations} integracija · {apps} aplikacija",
|
||||
"summary": "Homarr je otkrio {apps} aplikacija, {integrations} od kojih imaju ugrađene integracije",
|
||||
"appBadge": "Aplikacija",
|
||||
"appSectionLabel": "Aplikacije za dodavanje na ploču ({count} odabrano)",
|
||||
"scanning": "Skeniranje Dockera...",
|
||||
"scanningDescription": "Traženje pokrenutih kontejnera na vašem sustavu"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"goToBoard": "",
|
||||
"createBoard": "",
|
||||
"inviteUser": "",
|
||||
"docs": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": ""
|
||||
},
|
||||
"user": {
|
||||
"title": "Korisnici",
|
||||
"name": "Korisnik",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Imate nespremljene promjene, jeste li sigurni da želite otići?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Uvoz iz homarr prije 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Uvoz uspješan",
|
||||
"message": "Ploča je uspješno uvezena"
|
||||
},
|
||||
"error": {
|
||||
"title": "Uvoz nije uspio",
|
||||
"message": "Ploču nije bilo moguće uvesti, provjerite zapise za više detalja"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Odaberite JSON datoteku",
|
||||
"invalidError": "Nevažeća konfiguracijska datoteka"
|
||||
},
|
||||
"apps": {
|
||||
"label": "aplikacije",
|
||||
"avoidDuplicates": {
|
||||
"label": "Izbjegni duplikate",
|
||||
"description": "Zanemaruje aplikacije kod kojih već postoji aplikacija s istim href-om"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Uvezi samo aplikacije",
|
||||
"description": "Dodaje samo aplikacije, ploču treba ručno rekreirati"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Naziv ploče"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Veličina zaslona",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "Mali",
|
||||
"md": "Srednji",
|
||||
"lg": "velika"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Ponašanje bočne trake",
|
||||
"description": "Bočne trake su uklonjene u 1.0, možete odabrati što bi se trebalo dogoditi sa stavkama unutar njih.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Posljednji odjeljak",
|
||||
"description": "Bočna traka će biti prikazana ispod posljednjeg odjeljka"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Ukloni stavke",
|
||||
"description": "Stavke unutar bočne trake bit će uklonjene"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Stvori novu ploču"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Uvezi ploču"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Stvori novu aplikaciju"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Üdvözöljük a Homarrban",
|
||||
"subtitle": "Kezdjük el a Homarr-példány beállítását.",
|
||||
"description": "A kezdéshez válassza ki, hogyan szeretné beállítani a Homarr-példányt.",
|
||||
"action": {
|
||||
"scratch": "Kezdjük a legelejétől",
|
||||
"importOldmarr": "Importálás Homarr 1.0 előtti verzióból",
|
||||
"restoreSqlite": "Visszaállítás SQLite-mentésből",
|
||||
"restoreSqliteDescription": "Tölts fel egy teljes SQLite adatbázis biztonsági mentést egy korábbi Homarr példányból. Ez visszaállítja az összes táblát, felhasználót, alkalmazást, integrációt és beállítást.",
|
||||
"backToOptions": "← Vissza a beállítási lehetőségekhez"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importálás",
|
||||
"subtitle": "Importálhat adatokat egy meglévő Homarr-példányból.",
|
||||
"dropzone": {
|
||||
"title": "Húzza ide a zip fájlt, vagy kattintson a böngészéshez",
|
||||
"description": "A feltöltött zip fájlt feldolgozzuk, és kiválaszthatja, hogy mit szeretne importálni"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Fájl módosítása"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Beállítások importálása",
|
||||
"description": "Az importálási viselkedés konfigurálása"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Talált {count} táblák",
|
||||
"description": "Válassza ki az összes olyan méretű táblát, amelyet importálni szeretne",
|
||||
"action": {
|
||||
"selectAll": "Összes kijelölése",
|
||||
"unselectAll": "Kijelölés megszüntetése"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Import összefoglaló",
|
||||
"description": "Az alábbi összefoglalóban láthatja, hogy mi lesz importálva",
|
||||
"action": {
|
||||
"import": "Importálás megerősítése és folytatás"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Alkalmazások",
|
||||
"boards": "Táblák",
|
||||
"integrations": "Integrációk",
|
||||
"credentialUsers": "Hitelesített felhasználók"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Import token megadása",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Írja be a megjelenített import tokent az előző homarr példányból"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Érvénytelen token",
|
||||
"message": "A megadott token érvénytelen"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Admin felhasználó",
|
||||
"subtitle": "Adja meg a rendszergazda felhasználó hitelesítő adatait.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Létrejött a felhasználó",
|
||||
"message": "A felhasználót sikeresen létrehoztuk"
|
||||
},
|
||||
"error": {
|
||||
"title": "A felhasználó létrehozása sikertelen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Külső csoport",
|
||||
"subtitle": "Adja meg a külső felhasználók számára használandó csoportot.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Csoportnév",
|
||||
"description": "A névnek meg kell egyeznie a külső szolgáltató admin csoportjával"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Beállítások",
|
||||
"subtitle": "Szerver beállítások konfigurálása."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrációk",
|
||||
"subtitle": "Válaszd ki a használt szolgáltatásokat.",
|
||||
"description": "Válaszd ki a csatlakoztatni kívánt integrációkat. Automatikusan beállítjuk az irányítópultot a megfelelő widgetekkel.",
|
||||
"action": {
|
||||
"continue": "Folytatás",
|
||||
"skip": "Kihagyás most"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} / {total}",
|
||||
"skip": "Integráció kihagyása",
|
||||
"finishing": "Irányítópult beállítása...",
|
||||
"error": {
|
||||
"title": "A beállítás sikertelen",
|
||||
"message": "Hiba történt az irányítópult beállítása közben. Próbáld újra."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL segítők",
|
||||
"description": "Ezek a segítők megpróbálják kitalálni a szolgáltatásaid URL-jét. Ha nem működik, írd be manuálisan a címet."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Alap URL",
|
||||
"placeholder": "homelab.local vagy 192.168.1.1",
|
||||
"hint": "Add meg az alap domain-t vagy IP-t az integrációs URL-ek automatikus kitöltéséhez",
|
||||
"warning": "Az alap URL megadásával most automatikusan kitöltődik az összes integrációs URL, időt takarítva meg a beállítás során",
|
||||
"preview": "pl. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Aldomain",
|
||||
"hostPort": "Hoszt:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "A Docker {count} szolgáltatást észlelt",
|
||||
"detectedBreakdown": "{integrations} integráció · {apps} alkalmazás",
|
||||
"summary": "A Homarr {apps} alkalmazást észlelt, ebből {integrations} beépített integrációval rendelkezik",
|
||||
"appBadge": "Alkalmazás",
|
||||
"appSectionLabel": "Irányítópultra adandó alkalmazások ({count} kiválasztva)",
|
||||
"scanning": "Docker szkennelése...",
|
||||
"scanningDescription": "Futó konténerek keresése a rendszeren"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Beállítás befejezése",
|
||||
"subtitle": "Készen állsz!",
|
||||
"description": "Sikeresen befejezte a beállítási folyamatot. Most már használhatja a Homarr-t. Válassza ki a következő műveletet:",
|
||||
"action": {
|
||||
"goToBoard": "Tovább a {name} oldalra",
|
||||
"createBoard": "Az első tábla létrehozása",
|
||||
"inviteUser": "Más felhasználók meghívása",
|
||||
"docs": "Olvassa el a dokumentációt"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Vissza a starthoz"
|
||||
},
|
||||
"user": {
|
||||
"title": "Felhasználók",
|
||||
"name": "Felhasználó",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Nem mentett változtatásai vannak, biztosan el akarja hagyni az oldalt?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importálás a homarr 1.0.0 előtti verzióból",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Sikeres importálás",
|
||||
"message": "A tábla sikeresen importálva"
|
||||
},
|
||||
"error": {
|
||||
"title": "Importálás nem sikerült",
|
||||
"message": "Táblát nem sikerült importálni; további részletekért nézd meg a naplófájlokat"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "JSON fájl kiválasztása",
|
||||
"invalidError": "Érvénytelen konfigurációs fájl"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Alkalmazások",
|
||||
"avoidDuplicates": {
|
||||
"label": "Kerülje az ismétlődéseket",
|
||||
"description": "Nem veszi figyelembe azokat az alkalmazásokat, amelyeknél már létezik azonos href-vel rendelkező alkalmazás"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Csak alkalmazások importálása",
|
||||
"description": "Csak az alkalmazásokat adja hozzá, a táblát manuálisan kell újra létrehozni"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Tábla neve"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Képernyő méret",
|
||||
"description": "Az 1.0 előtti verziókban három különböző mód létezett, így minden képernyőmérethez be tudtad állítani az oszlopok számát.",
|
||||
"option": {
|
||||
"sm": "Kicsi",
|
||||
"md": "Közepes",
|
||||
"lg": "Nagy"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Oldalsáv viselkedés",
|
||||
"description": "Az 1.0 verzióban az oldalsávok el lettek távolítva, kiválaszthatod, mi történjen a bennük lévő elemekkel.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Utolsó szakasz",
|
||||
"description": "Az oldalsáv az utolsó szakasz alatt jelenik meg"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Elemek eltávolítása",
|
||||
"description": "Az oldalsávban lévő elemek el lesznek távolítva"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Alkalmazás létrehozása rögtön",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Új tábla létrehozása"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Tábla importálása"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Új alkalmazás létrehozása"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Ti diamo il benvenuto su Homarr",
|
||||
"subtitle": "Iniziamo con la creazione della tua istanza di Homarr.",
|
||||
"description": "Per iniziare, seleziona come vuoi configurare la tua istanza di Homarr.",
|
||||
"action": {
|
||||
"scratch": "Inizia da zero",
|
||||
"importOldmarr": "Importa da Homarr prima della 1.0",
|
||||
"restoreSqlite": "Ripristina da backup SQLite",
|
||||
"restoreSqliteDescription": "Carica un backup completo del database SQLite da una precedente istanza di Homarr. Questo ripristinerà tutte le board, gli utenti, le app, le integrazioni e le impostazioni.",
|
||||
"backToOptions": "← Torna alle opzioni di configurazione"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importa dati",
|
||||
"subtitle": "Puoi importare dati da un'istanza Homarr esistente.",
|
||||
"dropzone": {
|
||||
"title": "Trascina il file zip qui o fai clic per sfogliare",
|
||||
"description": "Lo zip caricato sarà elaborato e sarai in grado di selezionare quello che vuoi importare"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Cambia file"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importa impostazioni",
|
||||
"description": "Configura le azioni d'importazione"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Trovate {count} board",
|
||||
"description": "Scegli tutte le board con la dimensione che vuoi importare",
|
||||
"action": {
|
||||
"selectAll": "Seleziona tutto",
|
||||
"unselectAll": "Deseleziona tutto"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Riepilogo",
|
||||
"description": "Nel riepilogo sottostante puoi vedere cosa verrà importato",
|
||||
"action": {
|
||||
"import": "Conferma importazione e continua"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Applicazioni",
|
||||
"boards": "Board",
|
||||
"integrations": "Integrazioni",
|
||||
"credentialUsers": "Credential users"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Inserisci il token d'importazione",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Inserisci il token d'importazione mostrato dalla tua precedente istanza homarr"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Token non valido",
|
||||
"message": "Token inserito non valido"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Amministratore",
|
||||
"subtitle": "Specifica le credenziali per l'amministratore.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Utente creato",
|
||||
"message": "L'utente è stato creato correttamente"
|
||||
},
|
||||
"error": {
|
||||
"title": "Creazione dell'utente non riuscita"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Gruppo esterno",
|
||||
"subtitle": "Specifica il gruppo da utilizzare per gli utenti esterni.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nome gruppo",
|
||||
"description": "Il nome deve corrispondere al gruppo admin del provider esterno"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Impostazioni",
|
||||
"subtitle": "Configura le impostazioni del server."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrazioni",
|
||||
"subtitle": "Seleziona i servizi che utilizzi.",
|
||||
"description": "Scegli le integrazioni che desideri connettere. Configureremo automaticamente la tua dashboard con i widget corrispondenti.",
|
||||
"action": {
|
||||
"continue": "Continua",
|
||||
"skip": "Salta per ora"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} di {total}",
|
||||
"skip": "Salta questa integrazione",
|
||||
"finishing": "Configurazione della tua dashboard in corso...",
|
||||
"error": {
|
||||
"title": "Configurazione non riuscita",
|
||||
"message": "Qualcosa è andato storto durante la configurazione della tua dashboard. Riprova."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Helper URL",
|
||||
"description": "Questi helper cercano di indovinare l'URL dei tuoi servizi. Se non funziona, inserisci l'indirizzo manualmente."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Url di base",
|
||||
"placeholder": "homelab.local o 192.168.1.1",
|
||||
"hint": "Inserisci il tuo dominio di base o IP per compilare automaticamente gli URL delle integrazioni",
|
||||
"warning": "Impostando ora il tuo URL di base verrai aiutato a compilare automaticamente tutti gli URL delle integrazioni, risparmiando tempo durante la configurazione",
|
||||
"preview": "es. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Sottodominio",
|
||||
"hostPort": "Host:Porta"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker ha rilevato {count} servizi",
|
||||
"detectedBreakdown": "{integrations} integrazioni · {apps} app",
|
||||
"summary": "Homarr ha rilevato {apps} app, {integrations} delle quali hanno integrazioni integrate",
|
||||
"appBadge": "App",
|
||||
"appSectionLabel": "App da aggiungere alla dashboard ({count} selezionate)",
|
||||
"scanning": "Scansione Docker...",
|
||||
"scanningDescription": "Ricerca di container in esecuzione sul sistema in corso"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Termina configurazione",
|
||||
"subtitle": "È tutto pronto per iniziare!",
|
||||
"description": "Hai completato con successo la configurazione. Ora puoi iniziare a usare Homarr. Seleziona la prossima azione:",
|
||||
"action": {
|
||||
"goToBoard": "Vai alla board: {name}",
|
||||
"createBoard": "Crea la tua prima board",
|
||||
"inviteUser": "Invita altri utenti",
|
||||
"docs": "Leggi la documentazione"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Torna all'inizio"
|
||||
},
|
||||
"user": {
|
||||
"title": "Utenti",
|
||||
"name": "Utente",
|
||||
@@ -3909,6 +4058,62 @@
|
||||
"message": "Ci sono modifiche non salvate. Vuoi davvero uscire?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importa da homarr prima della versione 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Importazione conclusa con successo",
|
||||
"message": "La board è stata importata con successo"
|
||||
},
|
||||
"error": {
|
||||
"title": "Impossibile importare",
|
||||
"message": "La board non può essere importata, controlla i log per ulteriori dettagli"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Seleziona file JSON",
|
||||
"invalidError": "File di configurazione non valido"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Applicazioni",
|
||||
"avoidDuplicates": {
|
||||
"label": "Evita i duplicati",
|
||||
"description": "Ignora le app in cui esiste già un'app con lo stesso href"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Importa solo app",
|
||||
"description": "Aggiunge solo le app, il board deve essere ricreato manualmente"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Nome della board"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Dimensione dello schermo",
|
||||
"description": "Nelle versioni precedenti alla 1.0 esistevano tre modalità diverse, per cui era possibile scegliere il numero di colonne per ogni dimensione dello schermo.",
|
||||
"option": {
|
||||
"sm": "Piccolo",
|
||||
"md": "Medio",
|
||||
"lg": "Grande"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Comportamento barra laterale",
|
||||
"description": "Le barre laterali sono state rimosse nella versione 1.0, ora è possibile selezionare cosa fare con gli elementi al loro interno.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Ultima sezione",
|
||||
"description": "La barra laterale verrà visualizzata sotto l'ultima sezione"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Rimuovi elementi",
|
||||
"description": "Gli elementi contenuti nella barra laterale verranno rimossi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Crea app al volo",
|
||||
@@ -5532,6 +5737,9 @@
|
||||
"newBoard": {
|
||||
"label": "Crea una nuova board"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Importa una board"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Crea una nuova app"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Homarrへようこそ",
|
||||
"subtitle": "Homarrインスタンスの設定を始めましょう。",
|
||||
"description": "始めるには、Homarrインスタンスの設定方法を選択してください。",
|
||||
"action": {
|
||||
"scratch": "自分でゼロから作成",
|
||||
"importOldmarr": "1.0 より前の Homarr からインポート",
|
||||
"restoreSqlite": "",
|
||||
"restoreSqliteDescription": "",
|
||||
"backToOptions": ""
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "データのインポート",
|
||||
"subtitle": "既存のHomarrインスタンスからデータをインポートできます。",
|
||||
"dropzone": {
|
||||
"title": "ここにzipファイルをドラッグするか、クリックして参照してください",
|
||||
"description": "アップロードされたzipファイルは処理され、インポートするものを選択することができます"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "ファイルを変更する"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "設定をインポート",
|
||||
"description": "インポートの動作を設定"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "{count} 個のボードを見つけました",
|
||||
"description": "インポートしたいサイズのボードをすべて選択してください",
|
||||
"action": {
|
||||
"selectAll": "すべてを選択",
|
||||
"unselectAll": "すべて選択解除"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "インポート結果",
|
||||
"description": "以下のサマリーで、インポートする内容を確認できます",
|
||||
"action": {
|
||||
"import": "インポートを確認して続ける"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "アプリ",
|
||||
"boards": "ボード",
|
||||
"integrations": "連携機能",
|
||||
"credentialUsers": "認証情報ユーザー"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "インポートトークンを入力してください",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "トークン",
|
||||
"description": "以前のhomarrインスタンスから表示されたインポートトークンを入力してください"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "無効なトークン",
|
||||
"message": "入力されたトークンは無効です"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "管理者ユーザー",
|
||||
"subtitle": "管理者ユーザーの認証情報を指定します。",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "ユーザーが作成されました",
|
||||
"message": "ユーザーが正常に作成されました"
|
||||
},
|
||||
"error": {
|
||||
"title": "ユーザーの作成に失敗しました"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "外部グループ",
|
||||
"subtitle": "外部ユーザーに使用するグループを指定します。",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "グループ名",
|
||||
"description": "名前は外部プロバイダの管理者グループと一致する必要があります"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "設定",
|
||||
"subtitle": "サーバーの設定。"
|
||||
},
|
||||
"integrations": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"continue": "",
|
||||
"skip": ""
|
||||
},
|
||||
"configure": {
|
||||
"progress": "",
|
||||
"skip": "",
|
||||
"finishing": "",
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "",
|
||||
"placeholder": "",
|
||||
"hint": "",
|
||||
"warning": "",
|
||||
"preview": "",
|
||||
"mode": {
|
||||
"subdomain": "",
|
||||
"hostPort": ""
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "",
|
||||
"detectedBreakdown": "",
|
||||
"summary": "",
|
||||
"appBadge": "",
|
||||
"appSectionLabel": "",
|
||||
"scanning": "",
|
||||
"scanningDescription": ""
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "設定終了",
|
||||
"subtitle": "準備ができています!",
|
||||
"description": "セットアッププロセスが正常に完了しました。今すぐHomarrの使用を開始できます。次のアクションを選択してください:",
|
||||
"action": {
|
||||
"goToBoard": "{name} ボードへ移動",
|
||||
"createBoard": "あなたの最初のボードを作成する",
|
||||
"inviteUser": "他のユーザーを招待する",
|
||||
"docs": "ドキュメントを読む"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "最初に戻る"
|
||||
},
|
||||
"user": {
|
||||
"title": "ユーザー",
|
||||
"name": "ユーザー",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "保存されていない変更があります。このページから移動してもいいですか?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "1.0.0 より前の Homarr からインポート",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "インポート成功",
|
||||
"message": "ボードは、正常にインポートされました"
|
||||
},
|
||||
"error": {
|
||||
"title": "インポート失敗",
|
||||
"message": "ボードをインポートできませんでした。詳細はログを確認してください"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "JSON ファイルを選択",
|
||||
"invalidError": "無効な設定ファイルです"
|
||||
},
|
||||
"apps": {
|
||||
"label": "アプリ",
|
||||
"avoidDuplicates": {
|
||||
"label": "重複の回避",
|
||||
"description": "同じ href を持つアプリが既に存在するアプリを無視します"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "アプリのみインポート",
|
||||
"description": "アプリのみを追加します。ボードを手動で再作成する必要があります"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "ボード名"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "画面サイズ",
|
||||
"description": "1.0 以前のバージョンでは、3種類のモードが存在するため、画面サイズごとに列数を選択することができました。",
|
||||
"option": {
|
||||
"sm": "小",
|
||||
"md": "中",
|
||||
"lg": "大"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "サイドバーの動作",
|
||||
"description": "サイドバーは 1.0 で削除され、内部のアイテムで何が起こるかを選択できます。",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "最後のセクション",
|
||||
"description": "最後のセクションの下に、サイドバーが表示されます"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "アイテムを削除",
|
||||
"description": "サイドバーに含まれるアイテムは、削除されます"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "即座にアプリを作成",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "新しいボードを作成する"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "ボードをインポート"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "新しいアプリを作成する"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Homarr에 오신 것을 환영합니다",
|
||||
"subtitle": "Homarr 인스턴스 설정을 시작합니다.",
|
||||
"description": "시작하기 전에, Homarr 인스턴스를 어떻게 설정할지 선택해주세요.",
|
||||
"action": {
|
||||
"scratch": "처음부터 시작하기",
|
||||
"importOldmarr": "1.0 이전의 Homarr에서 불러오기",
|
||||
"restoreSqlite": "SQLite 백업 복원",
|
||||
"restoreSqliteDescription": "이전 Homarr 인스턴스로부터 전체 SQLite 데이터베이스 백업을 업로드합니다. 모든 보드, 사용자, 앱, 통합 및 설정이 복원됩니다.",
|
||||
"backToOptions": "← 설정 옵션으로 돌아가기"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "데이터 불러오기",
|
||||
"subtitle": "기존 Homarr 인스턴스에서 데이터를 불러올 수 있습니다.",
|
||||
"dropzone": {
|
||||
"title": "zip 파일 드롭 또는 클릭해서 찾아보기",
|
||||
"description": "업로드된 zip이 처리되어 가져올 항목을 선택할 수 있습니다"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "파일 변경"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "설정 불러오기",
|
||||
"description": "가져오기 동작 설정"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "{count}개의 보드 찾음",
|
||||
"description": "가져올 보드의 크기를 모두 선택",
|
||||
"action": {
|
||||
"selectAll": "모두 선택",
|
||||
"unselectAll": "모두 선택 해제"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "불러오기 요약",
|
||||
"description": "아래 요약에서 가져올 항목을 확인할 수 있습니다",
|
||||
"action": {
|
||||
"import": "가져오기 확인 및 계속 진행"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "앱",
|
||||
"boards": "보드",
|
||||
"integrations": "통합",
|
||||
"credentialUsers": "자격 증명 사용자"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "가져오기 토큰 입력",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "토큰",
|
||||
"description": "이전 Homarr 인스턴스에서 표시된 가져오기 토큰 입력"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "유효하지 않은 토큰",
|
||||
"message": "입력한 토큰이 유효하지 않습니다"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "관리자",
|
||||
"subtitle": "관리자의 계정 정보를 설정해주세요.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "계정 생성됨",
|
||||
"message": "계정이 성공적으로 생성되었습니다"
|
||||
},
|
||||
"error": {
|
||||
"title": "계정 생성 실패"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "외부 그룹",
|
||||
"subtitle": "외부 사용자가 사용할 그룹을 지정합니다.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "그룹 이름",
|
||||
"description": "이름은 외부 제공자의 관리자 그룹과 일치해야 합니다"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "설정",
|
||||
"subtitle": "서버 설정하기."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "통합",
|
||||
"subtitle": "사용할 서비스를 선택합니다.",
|
||||
"description": "연결하려는 통합을 선택하십시오. 일치하는 위젯으로 대시보드를 자동 설정합니다.",
|
||||
"action": {
|
||||
"continue": "계속",
|
||||
"skip": "지금은 건너뛰기"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{total}개 중 {current}개",
|
||||
"skip": "이 통합 건너뛰기",
|
||||
"finishing": "대시보드 설정 중...",
|
||||
"error": {
|
||||
"title": "설치 실패",
|
||||
"message": "대시보드를 설정하는 중 문제가 발생했습니다. 다시 시도해 주십시오."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL 도우미",
|
||||
"description": "서비스 URL을 추측합니다. 작동하지 않을 경우, 주소를 직접 입력해 주십시오."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "기본 URL",
|
||||
"placeholder": "homelab.local 또는 192.168.1.1",
|
||||
"hint": "기본 도메인 또는 IP를 입력하여 통합 URL 자동 채우기",
|
||||
"warning": "지금 기본 URL을 설정하면 모든 통합 URL이 자동으로 채워져 설정 시간을 아낄 수 있습니다",
|
||||
"preview": "예) {example}",
|
||||
"mode": {
|
||||
"subdomain": "서브도메인",
|
||||
"hostPort": "호스트:포트"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "{count}개 docker 서비스 감지",
|
||||
"detectedBreakdown": "통합 {integrations}개, 앱 {apps}개",
|
||||
"summary": "Homarr가 {apps}개 앱을 감지했으며, 그 중 {integrations}개는 통합 기능이 내장되어 있습니다",
|
||||
"appBadge": "앱",
|
||||
"appSectionLabel": "대시보드에 추가할 앱 ({count}개 선택)",
|
||||
"scanning": "Docker 스캔 중...",
|
||||
"scanningDescription": "시스템에서 실행 중인 컨테이너 찾기"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "설정 완료",
|
||||
"subtitle": "모든 준비가 끝났습니다!",
|
||||
"description": "설정 과정을 성공적으로 완료했습니다. 이제 Homarr을 사용할 수 있습니다. 다음 작업을 선택해주세요:",
|
||||
"action": {
|
||||
"goToBoard": "{name} 보드로 가기",
|
||||
"createBoard": "첫 번째 보드 만들기",
|
||||
"inviteUser": "다른 사용자 초대하기",
|
||||
"docs": "문서 읽기"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "시작으로 돌아가기"
|
||||
},
|
||||
"user": {
|
||||
"title": "사용자",
|
||||
"name": "사용자",
|
||||
@@ -3894,6 +4043,62 @@
|
||||
"message": "저장되지 않은 변경 사항이 있습니다. 나가시겠습니까?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "1.0.0 이전의 Homarr에서 가져오기",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "가져오기 완료",
|
||||
"message": "보드 가져오기가 완료되었습니다"
|
||||
},
|
||||
"error": {
|
||||
"title": "가져오기 실패",
|
||||
"message": "보드를 가져올 수 없었습니다, 상세 내용은 로그를 확인해 주십시오"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "JSON 파일 선택",
|
||||
"invalidError": "올바르지 않은 설정 파일"
|
||||
},
|
||||
"apps": {
|
||||
"label": "앱",
|
||||
"avoidDuplicates": {
|
||||
"label": "중복 방지",
|
||||
"description": "동일한 href를 가진 앱에서는 가져오기 내용을 무시합니다"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "앱만 가져오기",
|
||||
"description": "앱만 추가합니다. 보드는 수동으로 다시 생성해야 합니다"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "보드 이름"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "화면 크기",
|
||||
"description": "1.0 이전 버전에서는 세 가지의 다른 모드가 존재했으므로 각 화면 크기에 맞는 열 수를 선택할 수 있었습니다.",
|
||||
"option": {
|
||||
"sm": "작음",
|
||||
"md": "중간",
|
||||
"lg": "큼"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "사이드바 행동",
|
||||
"description": "사이드바는 1.0에서 제거되었으며, 그 안에 있던 항목을 어떻게 처리할지 선택할 수 있습니다.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "마지막 섹션",
|
||||
"description": "마지막 섹션 아래에 사이드바를 표시합니다"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "항목 제거",
|
||||
"description": "사이드바 내에 있는 항목을 제거합니다"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "즉석 앱 생성",
|
||||
@@ -5516,6 +5721,9 @@
|
||||
"newBoard": {
|
||||
"label": "새 보드 생성"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "보드 가져오기"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "새 앱 생성"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"scratch": "",
|
||||
"importOldmarr": "",
|
||||
"restoreSqlite": "Atkurti iš SQLite atsarginės kopijos",
|
||||
"restoreSqliteDescription": "Įkelkite pilną SQLite duomenų bazės atsarginę kopiją iš ankstesnio Homarr egzemplioriaus. Tai atkurs visas lentas, naudotojus, programėles, integracijas ir nustatymus.",
|
||||
"backToOptions": "← Atgal į sąrankos parinktis"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"dropzone": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Pakeisti failą"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"selectAll": "",
|
||||
"unselectAll": ""
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"import": ""
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Programėlės",
|
||||
"boards": "Lentos",
|
||||
"integrations": "",
|
||||
"credentialUsers": ""
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Žetonas",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Nustatymai",
|
||||
"subtitle": ""
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integracijos",
|
||||
"subtitle": "Pasirinkite naudojamas paslaugas.",
|
||||
"description": "Pasirinkite integracijas, kurias norite prijungti. Automatiškai sukonfigūruosime jūsų valdymo skydelį su atitinkamais valdikliais.",
|
||||
"action": {
|
||||
"continue": "Tęsti",
|
||||
"skip": "Kol kas praleisti"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} iš {total}",
|
||||
"skip": "Praleisti šią integraciją",
|
||||
"finishing": "Konfigūruojamas valdymo skydelis...",
|
||||
"error": {
|
||||
"title": "Sąranka nepavyko",
|
||||
"message": "Kažkas nepavyko konfigūruojant valdymo skydelį. Bandykite dar kartą."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL pagalbininkai",
|
||||
"description": "Šie pagalbininkai bando atspėti jūsų paslaugų URL. Jei nepavyksta, tiesiog įveskite adresą rankiniu būdu."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Bazinis URL",
|
||||
"placeholder": "homelab.local arba 192.168.1.1",
|
||||
"hint": "Įveskite pagrindinį domeną ar IP, kad automatiškai užpildytumėte integracijų URL",
|
||||
"warning": "Nustatę bazinį URL dabar, automatiškai užpildysite visus integracijų URL, taip sutaupydami laiko diegimo metu",
|
||||
"preview": "pvz., {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdomenas",
|
||||
"hostPort": "Mazgas:Prievadas"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker aptiko {count} paslaugas",
|
||||
"detectedBreakdown": "{integrations} integracijų · {apps} programėlių",
|
||||
"summary": "Homarr aptiko {apps} programėlių, iš kurių {integrations} turi integracijas",
|
||||
"appBadge": "Programėlė",
|
||||
"appSectionLabel": "Programėlės, pridedamos į valdymo skydelį (pasirinkta {count})",
|
||||
"scanning": "Nuskaitomas Docker...",
|
||||
"scanningDescription": "Ieškoma veikiančių konteinerių jūsų sistemoje"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"goToBoard": "",
|
||||
"createBoard": "",
|
||||
"inviteUser": "",
|
||||
"docs": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": ""
|
||||
},
|
||||
"user": {
|
||||
"title": "Vartotojai",
|
||||
"name": "Vartotojas",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Turite neišsaugotų pakeitimų, ar tikrai norite išeiti?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importuoti iš homarr prieš 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Importavimas sėkmingas",
|
||||
"message": "Lenta sėkmingai importuota"
|
||||
},
|
||||
"error": {
|
||||
"title": "Importavimas nepavyko",
|
||||
"message": "Lentos importuoti nepavyko, patikrinkite žurnalus dėl išsamesnės informacijos"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Pasirinkite JSON failą",
|
||||
"invalidError": "Netinkamas konfigūracijos failas"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Programėlės",
|
||||
"avoidDuplicates": {
|
||||
"label": "Vengti dublikatų",
|
||||
"description": "Nepaiso programėlių, kai jau yra programėlė su tokiu pat href"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Importuoti tik programėles",
|
||||
"description": "Prideda tik programėles, lentą reikia perkurti rankiniu būdu"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Lentos pavadinimas"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Ekrano dydis",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "Mažas",
|
||||
"md": "Vidutinis",
|
||||
"lg": "Didelis"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Šoninės juostos elgsena",
|
||||
"description": "Šoninės juostos buvo pašalintos 1.0, galite pasirinkti, kas turėtų nutikti su jose esančiais elementais.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Paskutinė sekcija",
|
||||
"description": "Šoninė juosta bus rodoma po paskutine sekcija"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Pašalinti elementus",
|
||||
"description": "Elementai, esantys šoninėje juostoje, bus pašalinti"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"scratch": "Sākt no jauna",
|
||||
"importOldmarr": "",
|
||||
"restoreSqlite": "SQLite rezerves kopija",
|
||||
"restoreSqliteDescription": "Augšupielādējiet pilnu SQLite datu bāzes dublējumu no iepriekšējās Homarr instances. Tas atjaunos visus dēļus, lietotājus, lietotnes, integrācijas un iestatījumus.",
|
||||
"backToOptions": "← Atpakaļ uz iestatīšanas opcijām"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importēt datus",
|
||||
"subtitle": "",
|
||||
"dropzone": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": ""
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importēt iestatījumus",
|
||||
"description": ""
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"selectAll": "Atzīmēt visu",
|
||||
"unselectAll": ""
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Importēšanas kopsavilkums",
|
||||
"description": "",
|
||||
"action": {
|
||||
"import": ""
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Lietotnes",
|
||||
"boards": "Dēļi",
|
||||
"integrations": "Integrācijas",
|
||||
"credentialUsers": ""
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Atslēga",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Administratora lietotājs",
|
||||
"subtitle": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Lietotājs izveidots",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": "Lietotāja izveide neizdevās"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Iestatījumi",
|
||||
"subtitle": ""
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrācijas",
|
||||
"subtitle": "Atlasiet pakalpojumus, ko izmantojat.",
|
||||
"description": "Izvēlieties integrācijas, ko vēlaties savienot. Mēs automātiski iestatīsim jūsu informācijas paneli ar atbilstošiem logrīkiem.",
|
||||
"action": {
|
||||
"continue": "Turpināt",
|
||||
"skip": "Pagaidām izlaist šo soli"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} no {total}",
|
||||
"skip": "Izlaist šo integrāciju",
|
||||
"finishing": "Notiek informācijas paneļa iestatīšana...",
|
||||
"error": {
|
||||
"title": "Neizdevās iestatīt!",
|
||||
"message": "Radās kļūda, iestatot jūsu informācijas paneli. Lūdzu, mēģiniet vēlreiz."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL palīgrīki",
|
||||
"description": "Šie palīgrīki mēģina uzminēt jūsu pakalpojumu URL. Ja tas nedarbojas, vienkārši ievadiet adresi manuāli."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Bāzes URL",
|
||||
"placeholder": "homelab.local vai 192.168.1.1",
|
||||
"hint": "Ievadiet savu bāzes domēnu vai IP, lai automātiski aizpildītu integrāciju URL",
|
||||
"warning": "Bāzes URL iestatīšana tagad automātiski aizpildīs visus integrāciju URL, ietaupot laiku iestatīšanas laikā",
|
||||
"preview": "piem., {example}",
|
||||
"mode": {
|
||||
"subdomain": "Apakšdomēns",
|
||||
"hostPort": "Resursdators:Ports"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker atklāja {count} pakalpojumus",
|
||||
"detectedBreakdown": "{integrations} integrācijas · {apps} lietotnes",
|
||||
"summary": "Homarr atklāja {apps} lietotnes, {integrations} no tām ir iebūvētas integrācijas",
|
||||
"appBadge": "Lietotne",
|
||||
"appSectionLabel": "Pievienojamās lietotnes informācijas panelim ({count} atlasītas)",
|
||||
"scanning": "Notiek Docker skenēšana...",
|
||||
"scanningDescription": "Meklē darbojošos konteinerus jūsu sistēmā"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Pabeigt Iestatīšanu",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"goToBoard": "",
|
||||
"createBoard": "",
|
||||
"inviteUser": "Ielūgt citus lietotājus",
|
||||
"docs": "Lasīt dokumentāciju"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": ""
|
||||
},
|
||||
"user": {
|
||||
"title": "Lietotāji",
|
||||
"name": "Lietotājs",
|
||||
@@ -3850,6 +3999,62 @@
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "",
|
||||
"invalidError": ""
|
||||
},
|
||||
"apps": {
|
||||
"label": "Lietotnes",
|
||||
"avoidDuplicates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": ""
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "Mazs",
|
||||
"md": "Vidējs",
|
||||
"lg": "Liels"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5460,6 +5665,9 @@
|
||||
"newBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Welkom bij Homarr",
|
||||
"subtitle": "Laten we beginnen met het opzetten van je Homarr instantie.",
|
||||
"description": "Selecteer om te beginnen hoe je je Homarr instantie wilt instellen.",
|
||||
"action": {
|
||||
"scratch": "Vanaf nul beginnen",
|
||||
"importOldmarr": "Importeren uit Homarr vóór 1.0",
|
||||
"restoreSqlite": "Herstellen vanuit SQLite-back-up",
|
||||
"restoreSqliteDescription": "Upload een volledige SQLite-databaseback-up van een vorige Homarr-instantie. Dit zal alle borden, gebruikers, apps, integraties en instellingen herstellen.",
|
||||
"backToOptions": "← Terug naar installatie-opties"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Gegevens importeren",
|
||||
"subtitle": "Je kunt gegevens importeren uit een bestaande Homarr instantie.",
|
||||
"dropzone": {
|
||||
"title": "Sleep het ZIP-bestand hierheen of klik om te bladeren",
|
||||
"description": "De geüploade ZIP wordt verwerkt en je kunt selecteren wat je wilt importeren"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Bestand veranderen"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Instellingen importeren",
|
||||
"description": "Het importgedrag configureren"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "{count} borden gevonden",
|
||||
"description": "Kies alle borden met hun grootte die je wilt importeren",
|
||||
"action": {
|
||||
"selectAll": "Alles selecteren",
|
||||
"unselectAll": "Alles deselecteren"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Overzicht importeren",
|
||||
"description": "In het onderstaande overzicht kun je zien wat er wordt geïmporteerd",
|
||||
"action": {
|
||||
"import": "Import bevestigen en doorgaan"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Apps",
|
||||
"boards": "Borden",
|
||||
"integrations": "Integraties",
|
||||
"credentialUsers": "Inloggegevens gebruikers"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Importeertoken invoeren",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Penning",
|
||||
"description": "Voer het getoonde importeertoken van je vorige Homarr instantie in"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Ongeldig token",
|
||||
"message": "Het ingevoerde token is ongeldig"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Beheerder gebruiker",
|
||||
"subtitle": "Geef de inloggegevens op voor de administrator gebruiker.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Gebruiker aangemaakt",
|
||||
"message": "De gebruiker is succesvol aangemaakt"
|
||||
},
|
||||
"error": {
|
||||
"title": "Gebruiker aanmaken mislukt"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Externe groep",
|
||||
"subtitle": "Geef de groep op die moet worden gebruikt voor externe gebruikers.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Groepsnaam",
|
||||
"description": "De naam moet overeenkomen met de beheerdersgroep van de externe provider"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Instellingen",
|
||||
"subtitle": "Serverinstellingen configureren."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integraties",
|
||||
"subtitle": "Selecteer de services die je gebruikt.",
|
||||
"description": "Kies de integraties die je wilt verbinden. We stellen je dashboard in met bijbehorende widgets.",
|
||||
"action": {
|
||||
"continue": "Doorgaan",
|
||||
"skip": "Overslaan voor nu"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} van {total}",
|
||||
"skip": "Deze integratie overslaan",
|
||||
"finishing": "Je dashboard instellen...",
|
||||
"error": {
|
||||
"title": "Instellen mislukt",
|
||||
"message": "Er is iets misgegaan bij het instellen van je dashboard. Probeer het opnieuw."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL-helpers",
|
||||
"description": "Deze helpers proberen de URL voor je services te raden. Als het niet werkt, typ dan handmatig het adres."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Basis-URL",
|
||||
"placeholder": "homelab.local of 192.168.1.1",
|
||||
"hint": "Voer je basisdomein of IP in om integratie-URL's automatisch in te vullen",
|
||||
"warning": "Door nu je basis-URL in te stellen worden alle integratie-URL's automatisch ingevuld, wat je tijd bespaart tijdens de installatie",
|
||||
"preview": "bijv. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdomein",
|
||||
"hostPort": "Host:Poort"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker heeft {count} services gedetecteerd",
|
||||
"detectedBreakdown": "{integrations} integraties · {apps} apps",
|
||||
"summary": "Homarr heeft {apps} apps gedetecteerd, waarvan {integrations} ingebouwde integraties hebben",
|
||||
"appBadge": "App",
|
||||
"appSectionLabel": "Apps om aan dashboard toe te voegen ({count} geselecteerd)",
|
||||
"scanning": "Docker scannen...",
|
||||
"scanningDescription": "Zoeken naar actieve containers op je systeem"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Instellen voltooien",
|
||||
"subtitle": "Je bent er klaar voor!",
|
||||
"description": "Je hebt het installatieproces succesvol afgerond. Je kunt Homarr nu gaan gebruiken. Selecteer je volgende actie:",
|
||||
"action": {
|
||||
"goToBoard": "Ga naar {name} bord",
|
||||
"createBoard": "Je eerste bord aanmaken",
|
||||
"inviteUser": "Andere gebruikers uitnodigen",
|
||||
"docs": "Lees de documentatie"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Terug naar start"
|
||||
},
|
||||
"user": {
|
||||
"title": "Gebruikers",
|
||||
"name": "Gebruiker",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Je hebt niet-opgeslagen wijzigingen, weet je zeker dat je weg wilt?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importeren uit Homarr vóór 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Succesvol geimporteerd",
|
||||
"message": "Het bord is succesvol geïmporteerd"
|
||||
},
|
||||
"error": {
|
||||
"title": "Importeren mislukt",
|
||||
"message": "Het bord kon niet worden geïmporteerd, controleer de logs voor meer informatie"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "JSON-bestand selecteren",
|
||||
"invalidError": "Ongeldig configuratiebestand"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Apps",
|
||||
"avoidDuplicates": {
|
||||
"label": "Duplicaten vermijden",
|
||||
"description": "Negeert apps waar al een app met dezelfde href bestaat"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Alleen apps importeren",
|
||||
"description": "Voegt alleen de apps toe, het bord moet handmatig opnieuw worden aangemaakt"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Bord naam"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Schermgrootte",
|
||||
"description": "In versies vóór 1.0 bestonden drie verschillende modi, zodat je het aantal kolommen voor elke schermgrootte kon kiezen.",
|
||||
"option": {
|
||||
"sm": "Klein",
|
||||
"md": "Gemiddeld",
|
||||
"lg": "Groot"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Zijbalk-gedrag",
|
||||
"description": "Zijbalken zijn verwijderd in 1.0, je kunt kiezen wat er moet gebeuren met de items erin.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Laatste sectie",
|
||||
"description": "De zijbalk wordt onder de laatste sectie weergegeven"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Items verwijderen",
|
||||
"description": "Items in de zijbalk worden verwijderd"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "App onmiddellijk maken",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Een nieuw bord aanmaken"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Een bord importeren"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Een nieuwe app aanmaken"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Velkommen til Homarr",
|
||||
"subtitle": "La oss begynne med å sette opp Homarr-forekomsten din.",
|
||||
"description": "For å komme i gang, velg hvordan du vil sette opp din Homarr forekomst.",
|
||||
"action": {
|
||||
"scratch": "Start fra begynnelsen",
|
||||
"importOldmarr": "Importer fra Homarr før 1.0",
|
||||
"restoreSqlite": "Gjenopprett fra SQLite sikkerhetskopi",
|
||||
"restoreSqliteDescription": "Last opp en full SQLite database sikkerhetskopi fra en tidligere Homarr instans. Dette vil gjenopprette alle tavler, brukere, apper, integrasjoner og innstillinger.",
|
||||
"backToOptions": ""
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importer data",
|
||||
"subtitle": "Du kan importere data fra en eksisterende Homarr-forekomst.",
|
||||
"dropzone": {
|
||||
"title": "Dra zip-filen hit eller klikk for å bla gjennom",
|
||||
"description": "Den opplastede zip-filen vil bli behandlet og du kan velge hva du ønsker å importere"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Endre fil"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importinnstillinger",
|
||||
"description": "Konfigurer import oppførsel"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Fant {count} tavler",
|
||||
"description": "Velg alle tavler med størrelse du vil importere",
|
||||
"action": {
|
||||
"selectAll": "Velg alle",
|
||||
"unselectAll": "Velg bort alle"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Importoversikt",
|
||||
"description": "I oversikten nedenfor kan du se hva som vil bli importert",
|
||||
"action": {
|
||||
"import": "Bekreft import og fortsett"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Apper",
|
||||
"boards": "Tavler",
|
||||
"integrations": "Integrasjoner",
|
||||
"credentialUsers": "Påloggings-brukere"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Angi import-token",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Angi vist import-token for din forrige Homarr forekomst"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Ugyldig token",
|
||||
"message": "Token du anga er ugyldig"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Admin-bruker",
|
||||
"subtitle": "Angi innloggingsdetaljene for administratorbrukeren din.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Bruker opprettet",
|
||||
"message": "Bruker opprettet"
|
||||
},
|
||||
"error": {
|
||||
"title": "Brukeropprettelse feilet"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Ekstern gruppe",
|
||||
"subtitle": "Angi gruppen som skal brukes for eksterne brukere.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Gruppenavn",
|
||||
"description": "Navnet må stemme med administratorgruppe av ekstern leverandør"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Innstillinger",
|
||||
"subtitle": "Konfigurer serverinnstillinger."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"continue": "",
|
||||
"skip": ""
|
||||
},
|
||||
"configure": {
|
||||
"progress": "",
|
||||
"skip": "",
|
||||
"finishing": "",
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "",
|
||||
"placeholder": "",
|
||||
"hint": "",
|
||||
"warning": "",
|
||||
"preview": "",
|
||||
"mode": {
|
||||
"subdomain": "",
|
||||
"hostPort": ""
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "",
|
||||
"detectedBreakdown": "",
|
||||
"summary": "",
|
||||
"appBadge": "",
|
||||
"appSectionLabel": "",
|
||||
"scanning": "",
|
||||
"scanningDescription": ""
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Fullfør oppsett",
|
||||
"subtitle": "Alt er klart!",
|
||||
"description": "Du har fullført installasjonsprosessen. Du kan nå bruke Homarr. Velg din neste handling:",
|
||||
"action": {
|
||||
"goToBoard": "Gå til {name} tavlen",
|
||||
"createBoard": "Opprett din første tavle",
|
||||
"inviteUser": "Inviter andre brukere",
|
||||
"docs": "Les dokumentasjonen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Tilbake til start"
|
||||
},
|
||||
"user": {
|
||||
"title": "Brukere",
|
||||
"name": "Bruker",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Du har ulagrede endringer, er du sikker på at du vil avslutte?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importer fra homarr før 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Importen var vellykket",
|
||||
"message": "Tavlen ble importert"
|
||||
},
|
||||
"error": {
|
||||
"title": "Import feilet",
|
||||
"message": "Tavlen kunne ikke importeres, sjekk loggene for ytterligere detaljer"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Velg JSON-fil",
|
||||
"invalidError": "Ugyldig konfigurasjonsfil"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Apper",
|
||||
"avoidDuplicates": {
|
||||
"label": "Unngå duplikater",
|
||||
"description": "Ignorerer apper der en app med samme href allerede eksisterer"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Bare importer apper",
|
||||
"description": "Bare legge til appene, tavlen må gjenskapes manuelt"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Navn på tavle"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Skjerm størrelse",
|
||||
"description": "I versjoner før 1.0 fantes tre forskjellige moduser, slik at du kunne velge antall kolonner for hver skjermstørrelse.",
|
||||
"option": {
|
||||
"sm": "Liten",
|
||||
"md": "Medium",
|
||||
"lg": "Stor"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Oppførsel for sidepanelet",
|
||||
"description": "Sidestolper ble fjernet i 1.0, du kan velge hva som skal skje med elementene inne i dem.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Siste seksjon",
|
||||
"description": "Sidepanelet vil bli vist under den siste seksjonen"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Slett elementer",
|
||||
"description": "Elementer som finnes i sidepanelet vil bli fjernet"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Opprett app direkte",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Opprett en ny tavle"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Importer en tavle"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Opprett en ny app"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Witaj w Homarr",
|
||||
"subtitle": "Zacznijmy od konfiguracji Twojej instancji Homarr.",
|
||||
"description": "Aby rozpocząć, wybierz jak chcesz skonfigurować instancję Homarr.",
|
||||
"action": {
|
||||
"scratch": "Zacznij od zera",
|
||||
"importOldmarr": "Importuj z Homarr przed 1.0",
|
||||
"restoreSqlite": "Przywróć z kopii zapasowej SQLite",
|
||||
"restoreSqliteDescription": "Prześlij pełną kopię zapasową bazy danych SQLite z poprzedniej instancji Homarr. Spowoduje to przywrócenie wszystkich tablic, użytkowników, aplikacji, integracji i ustawień.",
|
||||
"backToOptions": "← Wróć do opcji konfiguracji"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importuj dane",
|
||||
"subtitle": "Możesz zaimportować dane z istniejącej instancji Homarra.",
|
||||
"dropzone": {
|
||||
"title": "Przeciągnij tutaj plik zip lub kliknij, aby przeglądać",
|
||||
"description": "Przesłany zip zostanie przetworzony i będziesz mógł wybrać co chcesz zaimportować"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Zmień plik"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importuj ustawienia",
|
||||
"description": "Skonfiguruj zachowanie importu"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Znaleziono {count} tablic",
|
||||
"description": "Wybierz wszystkie tablice o rozmiarze do zaimportowania",
|
||||
"action": {
|
||||
"selectAll": "Zaznacz wszystkie",
|
||||
"unselectAll": "Odznacz wszystkie"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Podsumowanie importu",
|
||||
"description": "W poniższym podsumowaniu możesz zobaczyć, co zostanie zaimportowane",
|
||||
"action": {
|
||||
"import": "Potwierdź import i kontynuuj"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Aplikacje",
|
||||
"boards": "Tablice",
|
||||
"integrations": "Integracje",
|
||||
"credentialUsers": "Dane użytkowników"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Wpisz token importu",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Wprowadź token importu z poprzedniej instancji homarr"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Nieprawidłowy token",
|
||||
"message": "Wprowadzony token jest nieprawidłowy"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Administrator",
|
||||
"subtitle": "Określ dane uwierzytelniające dla administratora",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Użytkownik został utworzony",
|
||||
"message": "Użytkownik został pomyślnie utworzony"
|
||||
},
|
||||
"error": {
|
||||
"title": "Błąd podczas tworzenia użytkownika"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Zewnętrzna grupa",
|
||||
"subtitle": "Określ grupę, która powinna być używana przez użytkowników zewnętrznych.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nazwa grupy",
|
||||
"description": "Nazwa musi być zgodna z grupą administratora zewnętrznego dostawcy"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Ustawienia",
|
||||
"subtitle": "Konfiguruj ustawienia serwera"
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integracje",
|
||||
"subtitle": "Wybierz usługi, których używasz.",
|
||||
"description": "Wybierz integracje, które chcesz połączyć. Skonfigurujemy Twoją tablicę z pasującymi widgetami automatycznie.",
|
||||
"action": {
|
||||
"continue": "Kontynuuj",
|
||||
"skip": "Pomiń na razie"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} z {total}",
|
||||
"skip": "Pomiń tę integrację",
|
||||
"finishing": "Konfigurowanie twojej tablicy...",
|
||||
"error": {
|
||||
"title": "Konfiguracja nie powiodła się",
|
||||
"message": "Coś poszło nie tak podczas konfiguracji twojej tablicy. Spróbuj ponownie później."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL helpers",
|
||||
"description": "URL helpers spróbują odgadnąć URL twoich serwisów. Jeżeli to nie zadziała, po prostu wpisz adres ręcznie."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Base URL",
|
||||
"placeholder": "homelab.local lub 192.168.1.1",
|
||||
"hint": "Wprowadź swoją podstawową domenę lub adres IP, aby automatycznie wypełniać adresy URL integracji",
|
||||
"warning": "Ustawienie Base URL spowoduje automatyczne wypełnienie wszystkich adresów URL integracji, oszczędzając czas podczas konfiguracji",
|
||||
"preview": "np. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdomena",
|
||||
"hostPort": "Host:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Doker wykrył {count} usług",
|
||||
"detectedBreakdown": "Integracje {integrations} · {apps} aplikacje",
|
||||
"summary": "Homarr wykrył {apps} aplikacji, z których {integrations} ma wbudowane integracje",
|
||||
"appBadge": "Aplikacja",
|
||||
"appSectionLabel": "Aplikacje do dodania do tablicy (wybrano {count})",
|
||||
"scanning": "Skanowanie Dockera...",
|
||||
"scanningDescription": "Szukanie uruchomionych kontenerów w systemie"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Zakończ konfigurację",
|
||||
"subtitle": "Gotowe!",
|
||||
"description": "Pomyślnie zakończyłeś proces konfiguracji. Teraz możesz zacząć używać Homarr. Wybierz następną akcję:",
|
||||
"action": {
|
||||
"goToBoard": "Idź do tablicy {name}",
|
||||
"createBoard": "Stwórz swoją pierwszą tablicę",
|
||||
"inviteUser": "Zaproś innych użytkowników",
|
||||
"docs": "Przeczytaj dokumentację"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Powrót do początku"
|
||||
},
|
||||
"user": {
|
||||
"title": "Użytkownicy",
|
||||
"name": "Użytkownik",
|
||||
@@ -3909,6 +4058,62 @@
|
||||
"message": "Masz niezapisane zmiany, czy na pewno chcesz wyjść?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Import z Homarr sprzed wersji 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Import zakończony pomyślnie",
|
||||
"message": "Tablica została pomyślnie zaimportowana"
|
||||
},
|
||||
"error": {
|
||||
"title": "Import nie powiódł się",
|
||||
"message": "Nie udało się zaimportować tablicy. Sprawdź logi, aby uzyskać więcej informacji."
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Wybierz plik JSON",
|
||||
"invalidError": "Nieprawidłowy plik konfiguracji"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Aplikacje",
|
||||
"avoidDuplicates": {
|
||||
"label": "Unikaj duplikatów",
|
||||
"description": "Ignoruje aplikacje, dla których już istnieje aplikacja z tym samym adresem href."
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Import tylko aplikacje",
|
||||
"description": "Dodaje tylko aplikacje, tablica musi zostać odtworzona ręcznie."
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Nazwa tablicy"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Rozmiar ekranu",
|
||||
"description": "W wersjach przed 1.0 istniały trzy różne tryby, dzięki czemu można było wybrać liczbę kolumn dla każdego rozmiaru ekranu.",
|
||||
"option": {
|
||||
"sm": "Mały",
|
||||
"md": "Średni",
|
||||
"lg": "Duży"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Zachowanie paska bocznego",
|
||||
"description": "Paski boczne zostały usunięte w wersji 1.0, możesz wybrać, co ma się stać z elementami, które się w nich znajdowały.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Ostatnia sekcja",
|
||||
"description": "Pasek boczny będzie wyświetlany poniżej ostatniej sekcji"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Usuń elementy",
|
||||
"description": "Elementy znajdujące się w pasku bocznym zostaną usunięte"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Utwórz aplikację w locie",
|
||||
@@ -5532,6 +5737,9 @@
|
||||
"newBoard": {
|
||||
"label": "Utwórz nową tablicę"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Importuj tablicę"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Utwórz nową aplikację"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Bem-vindo ao Homarr",
|
||||
"subtitle": "Vamos começar configurando a sua instância Homarr.",
|
||||
"description": "Para começar, por favor selecione como você deseja configurar sua instância Homarr.",
|
||||
"action": {
|
||||
"scratch": "Começar do zero",
|
||||
"importOldmarr": "Importe de uma instância do Homarr anterior a 1.0",
|
||||
"restoreSqlite": "Restaurar do backup SQLite",
|
||||
"restoreSqliteDescription": "Fazer o upload de um backup completo do banco de dados SQLite de uma instância anterior da Homarr. Isso restaurará todos os painéis, usuários, apps, integrações e configurações.",
|
||||
"backToOptions": "← Retorna às opções de instalação"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importar dados",
|
||||
"subtitle": "Você pode importar dados de uma instância existente do Homarr.",
|
||||
"dropzone": {
|
||||
"title": "Arraste o arquivo ZIP aqui ou clique para procurar",
|
||||
"description": "O arquivo ZIP enviado será processado e você poderá selecionar o que deseja importar"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Alterar arquivo"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importar configurações",
|
||||
"description": "Configure o comportamento da importação"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "{count} painéis encontrados",
|
||||
"description": "Escolha todos os painéis com o tamanho que você deseja importar",
|
||||
"action": {
|
||||
"selectAll": "Selecionar todos",
|
||||
"unselectAll": "Desmarcar Todos"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Resumo da importação",
|
||||
"description": "No resumo abaixo você pode ver o que será importado",
|
||||
"action": {
|
||||
"import": "Confirmar a importação e continuar"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Aplicativos",
|
||||
"boards": "Painéis",
|
||||
"integrations": "Integrações",
|
||||
"credentialUsers": "Usuários credenciados"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Insira o token de importação",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Insira o token de importação mostrado em sua instância homarr anterior"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Token inválido",
|
||||
"message": "O token que você inseriu é inválido"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Usuário Administrador",
|
||||
"subtitle": "Especifique as credenciais para seu usuário administrador.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Usuário criado",
|
||||
"message": "O usuário foi criado com sucesso"
|
||||
},
|
||||
"error": {
|
||||
"title": "Falha ao criar usuário"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Grupo externo",
|
||||
"subtitle": "Especifique o grupo que deve ser usado para usuários externos.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nome do grupo",
|
||||
"description": "O nome tem que coincidir com o grupo administrador do provedor externo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Configurações",
|
||||
"subtitle": "Definir as configurações do servidor."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrações",
|
||||
"subtitle": "Selecione os serviços que você usa.",
|
||||
"description": "Escolha as integrações que deseja conectar. Vamos configurar seu painel com os widgets correspondentes automaticamente.",
|
||||
"action": {
|
||||
"continue": "Continuar",
|
||||
"skip": "Pular por enquanto"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} de {total}",
|
||||
"skip": "Pular esta integração",
|
||||
"finishing": "Configurando seu painel...",
|
||||
"error": {
|
||||
"title": "Falha na configuração",
|
||||
"message": "Algo deu errado ao configurar seu painel. Por favor, tente novamente."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Auxiliares de URL",
|
||||
"description": "Esses auxiliares tentam adivinhar a URL dos seus serviços. Se não funcionar, digite o endereço manualmente."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "URL base",
|
||||
"placeholder": "homelab.local ou 192.168.1.1",
|
||||
"hint": "Digite seu domínio base ou IP para preencher automaticamente as URLs das integrações",
|
||||
"warning": "Definir sua URL base agora preencherá automaticamente todas as URLs das integrações, economizando tempo durante a configuração",
|
||||
"preview": "ex.: {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdomínio",
|
||||
"hostPort": "Host:Porta"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker detectou {count} serviços",
|
||||
"detectedBreakdown": "{integrations} integrações · {apps} apps",
|
||||
"summary": "O Homarr detectou {apps} apps, dos quais {integrations} possuem integrações nativas",
|
||||
"appBadge": "App",
|
||||
"appSectionLabel": "Apps para adicionar ao painel ({count} selecionados)",
|
||||
"scanning": "Verificando Docker...",
|
||||
"scanningDescription": "Procurando contêineres em execução no seu sistema"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Concluir configuração",
|
||||
"subtitle": "Você está pronto para começar!",
|
||||
"description": "Você concluiu com sucesso o processo de configuração. Agora você pode começar a usar o Homarr. Selecione sua próxima ação:",
|
||||
"action": {
|
||||
"goToBoard": "Ir para o painel {name}",
|
||||
"createBoard": "Crie seu primeiro painel",
|
||||
"inviteUser": "Convidar outros usuários",
|
||||
"docs": "Ler a documentação"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Voltar ao início"
|
||||
},
|
||||
"user": {
|
||||
"title": "Usuários",
|
||||
"name": "Usuário",
|
||||
@@ -3892,6 +4041,62 @@
|
||||
"message": "Você tem alterações não salvas, tem certeza de que deseja sair?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importar do Homarr anterior à versão 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Importação bem-sucedida",
|
||||
"message": "O painel foi importado com sucesso"
|
||||
},
|
||||
"error": {
|
||||
"title": "Falha na importação",
|
||||
"message": "O painel não pôde ser importado, verifique os logs para mais detalhes"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Selecionar arquivo JSON",
|
||||
"invalidError": "Arquivo de configuração inválido"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Aplicativos",
|
||||
"avoidDuplicates": {
|
||||
"label": "Evitar duplicatas",
|
||||
"description": "Ignora aplicativos onde já existe um aplicativo com o mesmo href"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Importar apenas aplicativos",
|
||||
"description": "Só adiciona os aplicativos, o painel precisa ser recriado manualmente"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Nome do painel"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Tamanho da tela",
|
||||
"description": "Nas versões anteriores à 1.0 existiam três modos diferentes, então você podia escolher a quantidade de colunas para cada tamanho de tela.",
|
||||
"option": {
|
||||
"sm": "Pequeno",
|
||||
"md": "Médio",
|
||||
"lg": "Grande"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Comportamento da barra lateral",
|
||||
"description": "As barras laterais foram removidas na versão 1.0. Você pode selecionar o que deve acontecer com os itens dentro delas.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Última seção",
|
||||
"description": "A barra lateral será exibida abaixo da última seção"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Remover itens",
|
||||
"description": "Os itens presentes na barra lateral serão removidos"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Criar aplicativo em tempo real",
|
||||
@@ -5502,6 +5707,9 @@
|
||||
"newBoard": {
|
||||
"label": "Criar um novo quadro"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Importe um quadro"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Criar aplicativo"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"scratch": "",
|
||||
"importOldmarr": "",
|
||||
"restoreSqlite": "Restaurar do backup SQLite",
|
||||
"restoreSqliteDescription": "Carregar um backup completo do banco de dados SQLite de uma instância anterior do Homarr. Isso restaurará todos os painéis, usuários, aplicativos, integrações e configurações.",
|
||||
"backToOptions": "← Voltar para opções de configuração"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"dropzone": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": ""
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"selectAll": "",
|
||||
"unselectAll": ""
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"import": ""
|
||||
},
|
||||
"entities": {
|
||||
"apps": "",
|
||||
"boards": "",
|
||||
"integrations": "",
|
||||
"credentialUsers": ""
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "",
|
||||
"subtitle": ""
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrações",
|
||||
"subtitle": "Selecione os serviços que você usa.",
|
||||
"description": "Escolha as integrações que você gostaria de conectar. Vamos configurar seu painel com widgets correspondentes automaticamente.",
|
||||
"action": {
|
||||
"continue": "Continuar",
|
||||
"skip": "Pular por enquanto"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} de {total}",
|
||||
"skip": "Pular esta integração",
|
||||
"finishing": "Configurando seu painel...",
|
||||
"error": {
|
||||
"title": "Falha na configuração",
|
||||
"message": "Algo deu errado ao configurar seu painel. Por favor, tente novamente."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Ajudantes de URL",
|
||||
"description": "Esses ajudantes tentam adivinhar a URL para seus serviços. Se não funcionar, basta digitar o endereço manualmente."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "URL base",
|
||||
"placeholder": "homelab.local ou 192.168.1.1",
|
||||
"hint": "Digite seu domínio base ou IP para preencher automaticamente as URLs de integração",
|
||||
"warning": "Definir sua URL base agora preencherá automaticamente todas as URLs de integração, economizando tempo durante a configuração",
|
||||
"preview": "ex.: {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdomínio",
|
||||
"hostPort": "Host:Porta"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker detectou {count} serviços",
|
||||
"detectedBreakdown": "{integrations} integrações · {apps} apps",
|
||||
"summary": "Homarr detectou {apps} aplicativos, {integrations} dos quais têm integrações integradas",
|
||||
"appBadge": "Aplicativo",
|
||||
"appSectionLabel": "Apps para adicionar ao painel ({count} selecionados)",
|
||||
"scanning": "Escaneando Docker...",
|
||||
"scanningDescription": "Procurando contêineres em execução no seu sistema"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"goToBoard": "",
|
||||
"createBoard": "",
|
||||
"inviteUser": "",
|
||||
"docs": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": ""
|
||||
},
|
||||
"user": {
|
||||
"title": "Usuários",
|
||||
"name": "Usuário",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Você tem alterações não salvas, tem certeza de que deseja sair?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Importar do Homarr anterior à versão 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Importação bem-sucedida",
|
||||
"message": "O painel foi importado com sucesso"
|
||||
},
|
||||
"error": {
|
||||
"title": "Falha na importação",
|
||||
"message": "O painel não pôde ser importado, verifique os logs para mais detalhes"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Selecionar arquivo JSON",
|
||||
"invalidError": "Arquivo de configuração inválido"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Aplicativos",
|
||||
"avoidDuplicates": {
|
||||
"label": "Evitar duplicatas",
|
||||
"description": "Ignora aplicativos onde já existe um aplicativo com o mesmo href"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Importar apenas aplicativos",
|
||||
"description": "Apenas adiciona os aplicativos, o painel precisa ser recriado manualmente"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Nome do painel"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Tamanho da tela",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "Pequeno",
|
||||
"md": "Médio",
|
||||
"lg": "Grande"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Comportamento da barra lateral",
|
||||
"description": "As barras laterais foram removidas na versão 1.0. Você pode selecionar o que deve acontecer com os itens dentro delas.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Última seção",
|
||||
"description": "A barra lateral será exibida abaixo da última seção"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Remover itens",
|
||||
"description": "Os itens contidos na barra lateral serão removidos"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Bun venit",
|
||||
"subtitle": "Să începem cu configurarea Homarr.",
|
||||
"description": "Pentru a începe, selectează modul în care vrei să setezi Homarr.",
|
||||
"action": {
|
||||
"scratch": "Începe de la zero",
|
||||
"importOldmarr": "Importă din Homarr înainte de 1.0",
|
||||
"restoreSqlite": "Restaurează dintr-un backup SQLite",
|
||||
"restoreSqliteDescription": "Încarcă o copie completă a bazei de date SQLite dintr-o instalare anterioară a Homarr. Aceasta va restaura toate interfețele, utilizatorii, aplicaţiile, integrările şi setările.",
|
||||
"backToOptions": "← Înapoi la opțiunile de configurare"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importare date",
|
||||
"subtitle": "Puteți importa date dintr-o instalare Homarr existentă.",
|
||||
"dropzone": {
|
||||
"title": "Trage fişierul zip aici sau apasă pentru a-l căuta",
|
||||
"description": "Fișierul zip încărcat va fi procesat și vei putea selecta ceea ce dorești să imporți"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Schimbă fișierul"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importă Setări",
|
||||
"description": "Configurare comportamentul de importare"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "S-au găsit {count} secţiuni",
|
||||
"description": "Alege toate secțiunile cu dimensiunea pe care dorești să o imporți",
|
||||
"action": {
|
||||
"selectAll": "Selectează tot",
|
||||
"unselectAll": "Deselectează tot"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Rezumat importare",
|
||||
"description": "În rezumatul de mai jos poți vedea ce va fi importat",
|
||||
"action": {
|
||||
"import": "Confirmă importul şi continuă"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Aplicații",
|
||||
"boards": "Planșe",
|
||||
"integrations": "Integrări",
|
||||
"credentialUsers": "Utilizatori acreditați"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Introdu token-ul de import",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token-ul",
|
||||
"description": "Introdu token-ul de import afișat în instalarea de homarr anterioară"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Token invalid",
|
||||
"message": "Token-ul introdus e invalid"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Utilizator Administrator",
|
||||
"subtitle": "Specifică credențialele pentru utilizatorul administrator.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Utilizator creat",
|
||||
"message": "Utilizatorul a fost creat cu succes"
|
||||
},
|
||||
"error": {
|
||||
"title": "Crearea utilizatorului a eșuat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Grup extern",
|
||||
"subtitle": "Specifică grupul care ar trebui să fie utilizat pentru utilizatori externi.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nume grup",
|
||||
"description": "Numele trebuie să corespundă grupului de administratori al furnizorului extern"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Setări",
|
||||
"subtitle": "Configurare setări server."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrări",
|
||||
"subtitle": "Selectează serviciile pe care le folosești.",
|
||||
"description": "Alegeți integrările pe care doriți să le conectați. Vă vom configura tabloul de bord cu widget-uri care se potrivesc automat.",
|
||||
"action": {
|
||||
"continue": "Continuă",
|
||||
"skip": "Omite pentru moment"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} din {total}",
|
||||
"skip": "Omite această integrare",
|
||||
"finishing": "Se configurează tabloul de bord...",
|
||||
"error": {
|
||||
"title": "Configurarea a eșuat",
|
||||
"message": "Ceva nu a mers bine în timpul configurării tabloului de bord. Te rugăm să încerci din nou."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Helperi URL",
|
||||
"description": "Acești helperi încearcă să ghicească URL-ul serviciilor tale. Dacă nu funcționează, introdu adresa manual."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "URL de bază",
|
||||
"placeholder": "homelab.local sau 192.168.1.1",
|
||||
"hint": "Introdu domeniul de bază sau IP-ul pentru a completa automat adresele URL ale integrărilor",
|
||||
"warning": "Setarea adresei URL de bază acum va completa automat toate URL-urile integrărilor, scurtând timpul necesar configurării",
|
||||
"preview": "de ex. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdomeniu",
|
||||
"hostPort": "Gazdă:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker a detectat {count} servicii",
|
||||
"detectedBreakdown": "{integrations} integrări · {apps} aplicații",
|
||||
"summary": "Homarr a detectat {apps} aplicații, dintre care {integrations} au integrări încorporate",
|
||||
"appBadge": "Aplicație",
|
||||
"appSectionLabel": "Aplicații de adăugat la tabloul de bord ({count} selectate)",
|
||||
"scanning": "Scanare Docker...",
|
||||
"scanningDescription": "Căutare containere care rulează pe sistem"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Finalizează configurarea",
|
||||
"subtitle": "Ești gata să începi!",
|
||||
"description": "Ai finalizat cu succes procesul de configurare. Acum poți începe să utilizezi Homarr. Selectează următoarea acțiune:",
|
||||
"action": {
|
||||
"goToBoard": "Mergi la panoul {name}",
|
||||
"createBoard": "Creează primul tău panou",
|
||||
"inviteUser": "Invită alți utilizatori",
|
||||
"docs": "Citește documentația"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Înapoi la început"
|
||||
},
|
||||
"user": {
|
||||
"title": "Utilizatori",
|
||||
"name": "Utilizator",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "",
|
||||
"invalidError": ""
|
||||
},
|
||||
"apps": {
|
||||
"label": "Aplicații",
|
||||
"avoidDuplicates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": ""
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "Mic",
|
||||
"md": "Mediu",
|
||||
"lg": "Mare"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Добро пожаловать в Homarr",
|
||||
"subtitle": "Давайте начнем настройку вашего экземпляра Homarr.",
|
||||
"description": "Для начала выберите, как вы хотите настроить ваш экземпляр Homarr.",
|
||||
"action": {
|
||||
"scratch": "Начать с нуля",
|
||||
"importOldmarr": "Импортировать из Homarr версии до 1.0",
|
||||
"restoreSqlite": "Восстановить из резервной копии SQLite",
|
||||
"restoreSqliteDescription": "Загрузите полную резервную копию базы данных SQLite из предыдущего экземпляра Homarr. Это восстановит все панели, пользователей, приложения, интеграции и настройки.",
|
||||
"backToOptions": "← Назад к вариантам настройки"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Импорт данных",
|
||||
"subtitle": "Вы можете импортировать данные из существующего экземпляра Homarr.",
|
||||
"dropzone": {
|
||||
"title": "Перетащите ZIP-файл сюда или нажмите для его выбора",
|
||||
"description": "Загруженный ZIP-файл будет обработан, и вы сможете выбрать, что хотите импортировать"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Изменить файл"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Настройки импорта",
|
||||
"description": "Настройте параметры импорта"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Найдено {count} панелей",
|
||||
"description": "Выберите все панели с их размерами, которые вы хотите импортировать",
|
||||
"action": {
|
||||
"selectAll": "Выбрать все",
|
||||
"unselectAll": "Снять выбор со всех"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Сводка по импорту",
|
||||
"description": "В приведенной ниже сводке вы можете увидеть, что будет импортировано",
|
||||
"action": {
|
||||
"import": "Подтвердить импорт и продолжить"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Приложения",
|
||||
"boards": "Панели",
|
||||
"integrations": "Интеграции",
|
||||
"credentialUsers": "Учетные данные пользователя"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Введите токен импорта",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Токен",
|
||||
"description": "Введите показанный токен импорта из вашего предыдущего экземпляра Homarr"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Недействительный токен",
|
||||
"message": "Введенный токен недействителен"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Администратор системы",
|
||||
"subtitle": "Укажите учетные данные для администратора системы.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Пользователь создан",
|
||||
"message": "Пользователь успешно создан"
|
||||
},
|
||||
"error": {
|
||||
"title": "Не удалось создать пользователя"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Внешняя группа",
|
||||
"subtitle": "Укажите группу, которая будет использоваться для внешних пользователей.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Название группы",
|
||||
"description": "Название должно соответствовать группе администраторов внешнего провайдера"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Настройки",
|
||||
"subtitle": "Настройте параметры сервера."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Интеграции",
|
||||
"subtitle": "Выберите используемые сервисы.",
|
||||
"description": "Выберите интеграции, которые хотите подключить. Мы автоматически настроим панель с соответствующими виджетами.",
|
||||
"action": {
|
||||
"continue": "Продолжить",
|
||||
"skip": "Пропустить"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} из {total}",
|
||||
"skip": "Пропустить эту интеграцию",
|
||||
"finishing": "Настройка панели...",
|
||||
"error": {
|
||||
"title": "Ошибка настройки",
|
||||
"message": "Что-то пошло не так при настройке панели. Пожалуйста, попробуйте снова."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Помощники URL",
|
||||
"description": "Эти помощники пытаются угадать URL ваших сервисов. Если не сработает, просто введите адрес вручную."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Базовый URL",
|
||||
"placeholder": "homelab.local или 192.168.1.1",
|
||||
"hint": "Введите базовый домен или IP для автозаполнения URL интеграций",
|
||||
"warning": "Установка базового URL сейчас автоматически заполнит все URL интеграций, сэкономив время при настройке",
|
||||
"preview": "например, {example}",
|
||||
"mode": {
|
||||
"subdomain": "Поддомен",
|
||||
"hostPort": "Хост:Порт"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker обнаружил {count} сервисов",
|
||||
"detectedBreakdown": "{integrations} интеграций · {apps} приложений",
|
||||
"summary": "Homarr обнаружил {apps} приложений, {integrations} из которых имеют встроенные интеграции",
|
||||
"appBadge": "Приложение",
|
||||
"appSectionLabel": "Приложения для добавления на панель (выбрано {count})",
|
||||
"scanning": "Сканирование Docker...",
|
||||
"scanningDescription": "Поиск запущенных контейнеров в системе"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Завершение настройки",
|
||||
"subtitle": "Всё готово к работе!",
|
||||
"description": "Вы успешно завершили процесс настройки. Теперь вы можете начать использовать Homarr. Выберите следующее действие:",
|
||||
"action": {
|
||||
"goToBoard": "Перейти к панели {name}",
|
||||
"createBoard": "Создать первую панель",
|
||||
"inviteUser": "Пригласить других пользователей",
|
||||
"docs": "Прочитать документацию"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Вернуться к началу"
|
||||
},
|
||||
"user": {
|
||||
"title": "Пользователи",
|
||||
"name": "Пользователь",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "У вас есть несохранённые изменения. Вы уверены, что хотите выйти?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Импорт из версии Homarr до 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Импорт успешно выполнен",
|
||||
"message": "Панель успешно импортирована"
|
||||
},
|
||||
"error": {
|
||||
"title": "Импорт не удался",
|
||||
"message": "Не удалось импортировать панель, проверьте логи для дополнительной информации"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Выберите JSON-файл",
|
||||
"invalidError": "Недействительный файл конфигурации"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Приложения",
|
||||
"avoidDuplicates": {
|
||||
"label": "Избегать дубликатов",
|
||||
"description": "Игнорирует приложения, для которых уже существует приложение с тем же URL-адресом"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Импортировать только приложения",
|
||||
"description": "Добавляет только приложения, панель нужно будет создать заново вручную"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Название панели"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Размер экрана",
|
||||
"description": "В версиях до 1.0 существовало три разных режима, поэтому вы могли выбрать количество столбцов для каждого размера экрана.",
|
||||
"option": {
|
||||
"sm": "Маленький",
|
||||
"md": "Средний",
|
||||
"lg": "Большой"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Поведение боковых панелей",
|
||||
"description": "Боковые панели были удалены в версии 1.0, вы можете выбрать, что должно произойти с элементами внутри них.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Последний раздел",
|
||||
"description": "Боковая панель будет отображаться под последним разделом"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Удалить элементы",
|
||||
"description": "Элементы, содержащиеся в боковой панели, будут удалены"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Быстрое создание приложения",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Создать новую панель"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Импортировать панель"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Создать новое приложение"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Víta Vás Homár",
|
||||
"subtitle": "Začnime s nastavením inštancie Homár.",
|
||||
"description": "Ak chcete začať, vyberte, ako chcete nastaviť inštanciu Homár.",
|
||||
"action": {
|
||||
"scratch": "Začať odznova",
|
||||
"importOldmarr": "Import z Homarr pred 1.0",
|
||||
"restoreSqlite": "Obnoviť zo zálohy SQLite",
|
||||
"restoreSqliteDescription": "Nahrajte úplnú zálohu databázy SQLite z predchádzajúcej inštancie Homarr. Tým sa obnovia všetky dosky, používatelia, aplikácie, integrácie a nastavenia.",
|
||||
"backToOptions": "← Späť na možnosti nastavenia"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importovať dáta",
|
||||
"subtitle": "Údaje môžete importovať z existujúcej inštancie aplikácie Homarr.",
|
||||
"dropzone": {
|
||||
"title": "Potiahnite súbor ZIP sem alebo kliknite na tlačidlo prehľadávania",
|
||||
"description": "Nahraný súbor zip sa spracuje a vy si budete môcť vybrať, čo chcete importovať."
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Zmeniť súbor"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Import nastavení",
|
||||
"description": "Nakonfigurujte správanie importu"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Nájdených {count} dosiek",
|
||||
"description": "Vyberte všetky dosky s veľkosťou, ktorú chcete importovať",
|
||||
"action": {
|
||||
"selectAll": "Vybrať všetko",
|
||||
"unselectAll": "Zrušiť výber"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Súhrn importu",
|
||||
"description": "V nasledujúcom prehľade môžete vidieť, čo sa bude importovať",
|
||||
"action": {
|
||||
"import": "Potvrďte import a pokračujte"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Aplikácie",
|
||||
"boards": "Dosky",
|
||||
"integrations": "Integrácie",
|
||||
"credentialUsers": "Používatelia poverení"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Zadajte token importu",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Zadajte zobrazený token importu z predchádzajúcej inštancie homarr"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Neplatný token",
|
||||
"message": "Zadaný token je neplatný"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Používateľ administrátora",
|
||||
"subtitle": "Zadajte poverenia pre používateľa správcu.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Používateľ vytvorený",
|
||||
"message": "Používateľ bol úspešne vytvorený"
|
||||
},
|
||||
"error": {
|
||||
"title": "Vytvorenie užívateľa zlyhalo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Externá skupina",
|
||||
"subtitle": "Zadajte skupinu, ktorá sa má použiť pre externých používateľov.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Názov skupiny",
|
||||
"description": "Názov sa musí zhodovať s administrátorskou skupinou externého poskytovateľa"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Nastavenia",
|
||||
"subtitle": "Nakonfigurujte nastavenia servera."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrácie",
|
||||
"subtitle": "Vyberte služby, ktoré používate.",
|
||||
"description": "Vyberte integrácie, ktoré chcete pripojiť. Automaticky nastavíme prístrojovú dosku so zodpovedajúcimi miniaplikáciami.",
|
||||
"action": {
|
||||
"continue": "Pokračovať",
|
||||
"skip": "Teraz preskočiť"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} z {total}",
|
||||
"skip": "Preskočiť túto integráciu",
|
||||
"finishing": "Nastavuje sa prístrojová doska...",
|
||||
"error": {
|
||||
"title": "Nastavenie zlyhalo",
|
||||
"message": "Pri nastavovaní prístrojovej dosky sa niečo pokazilo. Skúste to znova."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Pomocníci URL",
|
||||
"description": "Títo pomocníci sa snažia uhádnuť adresu URL pre vaše služby. Ak to nefunguje, jednoducho napíšte adresu ručne."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Základná adresa URL",
|
||||
"placeholder": "homelab.local alebo 192.168.1.1",
|
||||
"hint": "Zadajte svoju základnú doménu alebo IP, aby sa automaticky vyplnili adresy URL integrácií",
|
||||
"warning": "Nastavením základnej adresy URL teraz sa automaticky vyplnia všetky adresy URL integrácií, čím ušetríte čas počas nastavovania",
|
||||
"preview": "napr. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdoména",
|
||||
"hostPort": "Hostiteľ:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker rozpoznal {count} služieb",
|
||||
"detectedBreakdown": "{integrations} integrácií · {apps} aplikácií",
|
||||
"summary": "Homarr rozpoznal {apps} aplikácií, z ktorých {integrations} má vstavané integrácie",
|
||||
"appBadge": "Aplikácia",
|
||||
"appSectionLabel": "Aplikácie, ktoré sa pridajú na prístrojovú dosku ({count} vybratých)",
|
||||
"scanning": "Skenuje sa Docker...",
|
||||
"scanningDescription": "Hľadajú sa spustené kontajnery vo vašom systéme"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Dokončiť nastavenie",
|
||||
"subtitle": "Ste pripravení vyraziť!",
|
||||
"description": "Úspešne ste dokončili proces nastavenia. Teraz môžete začať používať Homarr. Vyberte ďalšiu akciu:",
|
||||
"action": {
|
||||
"goToBoard": "Prejdite na nástenku {name}",
|
||||
"createBoard": "Vytvorte si svoju prvú nástenku",
|
||||
"inviteUser": "Pozvite ďalších používateľov",
|
||||
"docs": "Prečítajte si dokumentáciu"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Späť na začiatok"
|
||||
},
|
||||
"user": {
|
||||
"title": "Používatelia",
|
||||
"name": "Používateľ",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Máte neuložené zmeny. Naozaj chcete odísť?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Import z homarru pred 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Import úspešný",
|
||||
"message": "Doska bola úspešne importovaná"
|
||||
},
|
||||
"error": {
|
||||
"title": "Import zlyhal.",
|
||||
"message": "Dosku sa nepodarilo importovať, ďalšie podrobnosti nájdete v záznamoch"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Vyberte súbor JSON",
|
||||
"invalidError": "Neplatný konfiguračný súbor"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Aplikácie",
|
||||
"avoidDuplicates": {
|
||||
"label": "Vyhnite sa duplikátom",
|
||||
"description": "Ignoruje aplikácie, v ktorých už existuje aplikácia s rovnakým href"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Importujte iba aplikácie",
|
||||
"description": "Pridá len aplikácie, dosku je potrebné vytvoriť znova ručne"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Názov dosky"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Veľkosť obrazovky",
|
||||
"description": "Vo verziách pred 1.0 existovali tri rôzne režimy, takže ste si mohli vybrať množstvo stĺpcov pre každú veľkosť obrazovky.",
|
||||
"option": {
|
||||
"sm": "Malé",
|
||||
"md": "Stredné",
|
||||
"lg": "Veľké"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Správanie bočného panela",
|
||||
"description": "Bočné panely boli odstránené vo verzii 1.0, môžete si vybrať, čo sa má stať s položkami v nich.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Posledná sekcia",
|
||||
"description": "Pod poslednou sekciou sa zobrazí bočný panel"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Odstrániť položky",
|
||||
"description": "Položky na bočnom paneli budú odstránené"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Vytvorte aplikáciu za chodu",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Vytvorte novú dosku"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Importujte dosku"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Vytvorte novú aplikáciu"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"scratch": "",
|
||||
"importOldmarr": "",
|
||||
"restoreSqlite": "Obnovi iz varnostne kopije SQLite",
|
||||
"restoreSqliteDescription": "Naložite celotno varnostno kopijo baze podatkov SQLite iz prejšnjega primerka Homarr. To bo obnovilo vse table, uporabnike, aplikacije, integracije in nastavitve.",
|
||||
"backToOptions": "← Nazaj na možnosti nastavitve"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"dropzone": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": ""
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"selectAll": "",
|
||||
"unselectAll": ""
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"import": ""
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Aplikacije",
|
||||
"boards": "Deske",
|
||||
"integrations": "",
|
||||
"credentialUsers": ""
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Žeton",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Nastavitve",
|
||||
"subtitle": ""
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integracije",
|
||||
"subtitle": "Izberite storitve, ki jih uporabljate.",
|
||||
"description": "Izberite integracije, ki jih želite povezati. Samodejno bomo nastavili vašo nadzorno ploščo z ustreznimi gradniki.",
|
||||
"action": {
|
||||
"continue": "Nadaljuj",
|
||||
"skip": "Zaenkrat preskoči"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} od {total}",
|
||||
"skip": "Preskoči to integracijo",
|
||||
"finishing": "Nastavljanje vaše nadzorne plošče ...",
|
||||
"error": {
|
||||
"title": "Nastavitev ni uspela",
|
||||
"message": "Pri nastavljanju vaše nadzorne plošče je prišlo do napake. Poskusite znova."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Pomočniki URL",
|
||||
"description": "Ti pomočniki poskušajo uganiti URL za vaše storitve. Če ne deluje, preprosto ročno vnesite naslov."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Osnovni URL",
|
||||
"placeholder": "homelab.local ali 192.168.1.1",
|
||||
"hint": "Vnesite svojo osnovno domeno ali IP za samodejno izpolnjevanje URL-jev integracij",
|
||||
"warning": "Če zdaj nastavite osnovni URL, bodo vsi URL-ji integracij samodejno izpolnjeni, kar vam prihrani čas med nastavljanjem",
|
||||
"preview": "npr. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Pod-domena",
|
||||
"hostPort": "Gostitelj:Vrata"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker zazna {count} storitev",
|
||||
"detectedBreakdown": "{integrations} integracij · {apps} aplikacij",
|
||||
"summary": "Homarr je zaznal {apps} aplikacij, od katerih ima {integrations} vgrajene integracije",
|
||||
"appBadge": "Aplikacija",
|
||||
"appSectionLabel": "Aplikacije za dodajanje na nadzorno ploščo ({count} izbranih)",
|
||||
"scanning": "Skeniranje Dockerja ...",
|
||||
"scanningDescription": "Iskanje tekočih vsebnikov v vašem sistemu"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"goToBoard": "",
|
||||
"createBoard": "",
|
||||
"inviteUser": "",
|
||||
"docs": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": ""
|
||||
},
|
||||
"user": {
|
||||
"title": "Uporabniki",
|
||||
"name": "Uporabnik",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Vsebina ni shranjena, želite nadaljevati?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "",
|
||||
"invalidError": ""
|
||||
},
|
||||
"apps": {
|
||||
"label": "Aplikacije",
|
||||
"avoidDuplicates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": ""
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "Majhna",
|
||||
"md": "Srednja",
|
||||
"lg": "Velika"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Välkommen till Homarr",
|
||||
"subtitle": "Låt oss komma igång med att sätta upp din installation av Homarr.",
|
||||
"description": "För att komma igång, välj hur du vill ställa in din Homarr-installation.",
|
||||
"action": {
|
||||
"scratch": "Börja från början",
|
||||
"importOldmarr": "Importera från Homarr äldre än version 1.0",
|
||||
"restoreSqlite": "Återställ från SQLite-säkerhetskopia",
|
||||
"restoreSqliteDescription": "Ladda upp en fullständig SQLite-databassäkerhetskopia från en tidigare Homarr-instans. Detta återställer alla tavlor, användare, appar, integrationer och inställningar.",
|
||||
"backToOptions": "← Tillbaka till installationsalternativ"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importera data",
|
||||
"subtitle": "Du kan importera data från en befintlig installation av Homarr.",
|
||||
"dropzone": {
|
||||
"title": "Dra ZIP-filen hit eller klicka för att bläddra",
|
||||
"description": "Den uppladdade ZIP-filen kommer att bearbetas och du kommer att kunna välja vad du vill importera"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Byt fil"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Importera inställningar",
|
||||
"description": "Konfigurera hur importen skall genomföras"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Hittade {count} tavlor",
|
||||
"description": "Välj alla tavlor med den storlek du vill importera",
|
||||
"action": {
|
||||
"selectAll": "Välj alla",
|
||||
"unselectAll": "Avmarkera alla"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Summering av importen",
|
||||
"description": "I sammanfattningen nedan kan du se vad som kommer att importeras",
|
||||
"action": {
|
||||
"import": "Bekräfta importen och fortsätt"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Applikationer",
|
||||
"boards": "Tavlor",
|
||||
"integrations": "Integrationer",
|
||||
"credentialUsers": "Användaruppgifter"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Ange 'Token' för importen",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token",
|
||||
"description": "Ange 'import-token' från din tidigare installation av Homarr"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Felaktig 'Token'",
|
||||
"message": "Den 'Token' som du angivit är felaktig"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Administratör",
|
||||
"subtitle": "Ange inloggningsuppgifter för administratören.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Användare har adderats",
|
||||
"message": "Användaren adderades"
|
||||
},
|
||||
"error": {
|
||||
"title": "Misslyckades med att addera användaren"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Extern grupp",
|
||||
"subtitle": "Ange vilken grupp som skall användas för externa användare.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Gruppens namn",
|
||||
"description": "Namnet måste matcha admin-grupp i extern tjänst"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Inställningar",
|
||||
"subtitle": "Konfigurera serverinställningar."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrationer",
|
||||
"subtitle": "Välj de tjänster du använder.",
|
||||
"description": "Välj de integrationer du vill ansluta. Vi konfigurerar automatiskt instrumentpanelen med matchande widgetar.",
|
||||
"action": {
|
||||
"continue": "Fortsätt",
|
||||
"skip": "Hoppa över för nu"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} av {total}",
|
||||
"skip": "Hoppa över denna integration",
|
||||
"finishing": "Konfigurerar instrumentpanelen...",
|
||||
"error": {
|
||||
"title": "Konfigurationen misslyckades",
|
||||
"message": "Något gick fel vid konfigurationen av instrumentpanelen. Försök igen."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL-hjälpare",
|
||||
"description": "Dessa hjälpare gissar URL: en för dina tjänster. Om det inte fungerar, ange adressen manuellt."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Bas-URL",
|
||||
"placeholder": "homelab.local eller 192.168.1.1",
|
||||
"hint": "Ange din basdomän eller IP för att automatiskt fylla i integrations-URL: er",
|
||||
"warning": "Om du anger din bas-URL nu fylls alla integrations-URL: er i automatiskt, vilket sparar tid under installationen",
|
||||
"preview": "t.ex. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Subdomän",
|
||||
"hostPort": "Värd:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker upptäckte {count} tjänster",
|
||||
"detectedBreakdown": "{integrations} integrationer · {apps} appar",
|
||||
"summary": "Homarr upptäckte {apps} appar, varav {integrations} har inbyggda integrationer",
|
||||
"appBadge": "Applikation",
|
||||
"appSectionLabel": "Appar att lägga till på instrumentpanelen ({count} valda)",
|
||||
"scanning": "Söker igenom Docker...",
|
||||
"scanningDescription": "Letar efter körande behållare på ditt system"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Slutför installationen",
|
||||
"subtitle": "Du är redo att sätta igång!",
|
||||
"description": "Du har slutfört installationen. Du kan nu börja använda Homarr. Välj din nästa åtgärd:",
|
||||
"action": {
|
||||
"goToBoard": "Gå till tavlan {name}",
|
||||
"createBoard": "Addera din första tavla",
|
||||
"inviteUser": "Bjud in andra användare",
|
||||
"docs": "Läs dokumentationen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Tillbaka till början"
|
||||
},
|
||||
"user": {
|
||||
"title": "Användare",
|
||||
"name": "Användare",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Du har ändringar som inte har sparats. Är du säker på att du vill fortsätta?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": "Tavlan har importerats"
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "",
|
||||
"invalidError": ""
|
||||
},
|
||||
"apps": {
|
||||
"label": "Applikationer",
|
||||
"avoidDuplicates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": ""
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "",
|
||||
"description": "I versioner äldre än version 1.0 fanns tre olika lägen, så du kunde välja antalet kolumner för varje skärmstorlek.",
|
||||
"option": {
|
||||
"sm": "Liten",
|
||||
"md": "Mellan",
|
||||
"lg": "Stor"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Ta bort objekt",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Addera en grupp"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Addera en ny applikation"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Homarr'a Hoş Geldiniz",
|
||||
"subtitle": "Homarr örneğinizi kurmaya başlayalım.",
|
||||
"description": "Başlamak için lütfen Homarr örneğinizi nasıl kurmak istediğinizi seçin.",
|
||||
"action": {
|
||||
"scratch": "Sıfırdan Başla",
|
||||
"importOldmarr": "Homarr 1.0'dan Önceki Yedeğinizi İçe Aktarın",
|
||||
"restoreSqlite": "SQLite yedeklemesinden geri yükle",
|
||||
"restoreSqliteDescription": "Önceki bir Homarr örneğinden tam SQLite veritabanı yedeklemesi yükleyin. Bu, tüm panoları, kullanıcıları, uygulamaları, entegrasyonları ve ayarları geri yükler.",
|
||||
"backToOptions": "← Kurulum seçeneklerine geri dön"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Verileri İçe Aktar",
|
||||
"subtitle": "Mevcut bir Homarr örneğinden veri içe aktarabilirsiniz.",
|
||||
"dropzone": {
|
||||
"title": "Zip dosyasını buraya sürükleyin veya göz atmak için tıklayın",
|
||||
"description": "Seçtiğiniz zip işlenecek ve içe aktarmak istediğiniz verileri seçebileceksiniz"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Dosyayı Değiştir"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "İçe Aktarma Ayarları",
|
||||
"description": "İçe Aktarma İşlevlerini Yapılandır"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "{count} Panel Bulundu",
|
||||
"description": "İçe Aktarılacak Tüm Panellerin Boyutlarını Seçin",
|
||||
"action": {
|
||||
"selectAll": "Tümünü Seç",
|
||||
"unselectAll": "Tüm Seçimi Kaldır"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "İçe Aktarma Özeti",
|
||||
"description": "Aşağıdaki Özeti Kontrol Ederek İçe Aktarılacak İşlevleri Görebilirsiniz",
|
||||
"action": {
|
||||
"import": "İçe Aktarmayı Onayla ve Devam Et"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Uygulamalar",
|
||||
"boards": "Paneller",
|
||||
"integrations": "Entegrasyonlar",
|
||||
"credentialUsers": "Kullanıcı Kimlik Bilgileri"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "İçe Aktarma Anahtarını Girin",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Token Anahtarı",
|
||||
"description": "Önceki Homarr Örneğinizden Aldığınız İçe Aktarma Anahtarı girin"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Token",
|
||||
"message": "Girdiğiniz Token Anahtarı Geçersiz"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Yönetici",
|
||||
"subtitle": "Yönetici kullanıcınız için kimlik bilgilerini girin.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Kullanıcı oluşturuldu",
|
||||
"message": "Kullanıcı başarıyla oluşturuldu"
|
||||
},
|
||||
"error": {
|
||||
"title": "Kullanıcı oluşturma başarısız"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Harici grup",
|
||||
"subtitle": "Harici kullanıcılar için kullanılacak grubu belirtin.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Grup adı",
|
||||
"description": "Ad, harici sağlayıcının yönetici grubuyla eşleşmelidir"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Ayarlar",
|
||||
"subtitle": "Sunucu ayarlarınızı yapılandırın."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Entegrasyonlar",
|
||||
"subtitle": "Kullandığınız hizmetleri seçin.",
|
||||
"description": "Bağlanmak istediğiniz entegrasyonları seçin. Panonuzu eşleşen widget'larla otomatik olarak kuracağız.",
|
||||
"action": {
|
||||
"continue": "Devam Et",
|
||||
"skip": "Şimdilik atla"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} / {total}",
|
||||
"skip": "Bu entegrasyonu atla",
|
||||
"finishing": "Panonuz kuruluyor...",
|
||||
"error": {
|
||||
"title": "Kurulum başarısız oldu",
|
||||
"message": "Panonuzu kurarken bir şeyler yanlış gitti. Lütfen tekrar deneyin."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL yardımcıları",
|
||||
"description": "Bu yardımcılar, hizmetlerinizin URL'sini tahmin etmeye çalışır. Çalışmazsa, adresi manuel olarak yazın."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Temel URL",
|
||||
"placeholder": "homelab.local veya 192.168.1.1",
|
||||
"hint": "Entegrasyon URL'lerini otomatik doldurmak için temel alan adınızı veya IP'nizi girin",
|
||||
"warning": "Temel URL'nizi şimdi ayarlamak, tüm entegrasyon URL'lerini otomatik olarak dolduracak ve kurulum sırasında zaman kazandıracak",
|
||||
"preview": "örn. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Alt alan adı",
|
||||
"hostPort": "Ana Bilgisayar:Port"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker {count} hizmet tespit etti",
|
||||
"detectedBreakdown": "{integrations} entegrasyon · {apps} uygulama",
|
||||
"summary": "Homarr {apps} uygulama tespit etti, bunların {integrations} tanesinde entegrasyon yerleşik",
|
||||
"appBadge": "Uygulama",
|
||||
"appSectionLabel": "Panoya eklenecek uygulamalar ({count} seçili)",
|
||||
"scanning": "Docker taranıyor...",
|
||||
"scanningDescription": "Sisteminizdeki çalışan konteynerler aranıyor"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Kurulumu Bitir",
|
||||
"subtitle": "Başlamaya Hazırsınız!",
|
||||
"description": "Kurulum sürecini başarıyla tamamladınız. Artık Homarr'ı kullanmaya başlayabilirsiniz. Sonraki eyleminizi seçin:",
|
||||
"action": {
|
||||
"goToBoard": "{name} Paneline Git",
|
||||
"createBoard": "İlk Panelinizi Oluşturun",
|
||||
"inviteUser": "Yeni Kullanıcı Davet Et",
|
||||
"docs": "Dokümanları Oku"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Başlangıca Geri Dön"
|
||||
},
|
||||
"user": {
|
||||
"title": "Kullanıcılar",
|
||||
"name": "Kullanıcı",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Kaydedilmemiş değişiklikleriniz var, çıkmak istediğinizden emin misiniz?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Homarr 1.0'dan önceki yedeğinizi içe aktarın",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "İçe aktarma başarılı",
|
||||
"message": "Panel başarıyla içe aktarıldı"
|
||||
},
|
||||
"error": {
|
||||
"title": "İçe aktarma başarısız oldu",
|
||||
"message": "Panel içe aktarılamadı, daha fazla ayrıntı için günlükleri kontrol edin"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "JSON Dosyası Seç",
|
||||
"invalidError": "Geçersiz yapılandırma dosyası"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Uygulamalar",
|
||||
"avoidDuplicates": {
|
||||
"label": "Tekrarlardan kaçının",
|
||||
"description": "Aynı href'e sahip bir uygulamanın zaten mevcut olduğu uygulamaları yok sayar"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Yalnızca uygulamaları içe aktar",
|
||||
"description": "Sadece uygulamaları ekler, panelin manuel olarak yeniden oluşturulması gerekir"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Panel adı"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Ekran boyutu",
|
||||
"description": "1.0'dan önceki sürümlerde üç farklı mod mevcuttu, yani her ekran boyutu için sütun miktarını seçebiliyordunuz.",
|
||||
"option": {
|
||||
"sm": "Küçük",
|
||||
"md": "Orta",
|
||||
"lg": "Büyük"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Kenar çubuğu davranışı",
|
||||
"description": "Kenar çubukları 1.0'da kaldırıldı, içlerindeki öğelere ne olacağını seçebilirsiniz.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Son bölüm",
|
||||
"description": "Kenar çubuğu son bölümün altında görüntülenecektir"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Öğeleri kaldır",
|
||||
"description": "Kenar çubuğunda bulunan öğeler kaldırılacak"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Anında uygulama oluştur",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "Yeni Panel Oluştur"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Bir paneli içe aktar"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Yeni Uygulama Oluştur"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Ласкаво просимо до Homarr",
|
||||
"subtitle": "Почнемо з налаштування вашого Homarr.",
|
||||
"description": "Щоб почати, будь ласка, виберіть спосіб налаштування Вашого Homarr.",
|
||||
"action": {
|
||||
"scratch": "Почати з нуля",
|
||||
"importOldmarr": "Імпорт з Homarr пре-1.0",
|
||||
"restoreSqlite": "Відновлення з резервної копії SQLite",
|
||||
"restoreSqliteDescription": "Завантажте повну резервну копію бази даних SQLite з попереднього екземпляра Homarr. Це відновить усі дошки, користувачів, програми, інтеграції та налаштування.",
|
||||
"backToOptions": "Назад до параметрів налаштування"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Імпорт даних",
|
||||
"subtitle": "Ви можете імпортувати дані з наявного екземпляра Homarr.",
|
||||
"dropzone": {
|
||||
"title": "Перетягніть zip-файл сюди або клікніть для пошуку",
|
||||
"description": "Завантажений zip буде оброблений і ви зможете вибрати що ви хочете імпортувати"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Змінити файл"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Імпортувати налаштування",
|
||||
"description": "Конфігурація імпорту"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Знайдено {count} дощок",
|
||||
"description": "Оберіть всі дошки з розміром які ви хочете імпортувати",
|
||||
"action": {
|
||||
"selectAll": "Вибрати все",
|
||||
"unselectAll": "Прибрати всі"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "Підсумок імпорту",
|
||||
"description": "У наведеному нижче розділі ви можете побачити, що буде імпортовано",
|
||||
"action": {
|
||||
"import": "Підтвердить імпорт та продовжуйте"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Додатки",
|
||||
"boards": "Дошки",
|
||||
"integrations": "Інтеграції",
|
||||
"credentialUsers": "Облікові записи"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Введіть токен імпорту",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Токен",
|
||||
"description": "Введіть показаний токен імпорту з вашого попереднього екземпляра homarr"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Невірний токен",
|
||||
"message": "Введений вами токен невірний"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Адміністратор",
|
||||
"subtitle": "Вкажіть облікові дані для вашого адміністратора.",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Користувача створено",
|
||||
"message": "Користувача успішно створено"
|
||||
},
|
||||
"error": {
|
||||
"title": "Не вдалося створити користувача"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "Зовнішня група",
|
||||
"subtitle": "Вкажіть групу, яку слід використовувати для зовнішніх користувачів.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Назва групи",
|
||||
"description": "Ім'я має відповідати групі адміністраторів зовнішнього провайдера"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Налаштування",
|
||||
"subtitle": "Налаштування сервера."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Інтеграції",
|
||||
"subtitle": "Виберіть сервіси, якими ви користуєтеся.",
|
||||
"description": "Виберіть інтеграції, які ви хочете під'єднати. Ми автоматично налаштуємо вашу інформаційну панель з відповідними віджетами.",
|
||||
"action": {
|
||||
"continue": "Продовжити",
|
||||
"skip": "Пропустити поки що"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} з {total}",
|
||||
"skip": "Пропустити цю інтеграцію",
|
||||
"finishing": "Налаштування панелі інструментів...",
|
||||
"error": {
|
||||
"title": "Не вдалося налаштувати",
|
||||
"message": "Під час налаштування вашої інформаційної панелі сталася помилка. Спробуйте ще раз."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Помічники URL-адрес",
|
||||
"description": "Ці помічники намагаються вгадати URL-адресу ваших послуг. Якщо це не працює, просто введіть адресу вручну."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "Базовий URL",
|
||||
"placeholder": "homelab.local або 192.168.1.1",
|
||||
"hint": "Введіть свій базовий домен або IP-адресу для автоматичного заповнення URL-адрес інтеграції",
|
||||
"warning": "Якщо встановити базову URL-адресу зараз, усі URL-адреси інтеграції будуть автоматично заповнені, що заощадить ваш час під час налаштування",
|
||||
"preview": "напр. {example}",
|
||||
"mode": {
|
||||
"subdomain": "Субдомен",
|
||||
"hostPort": "Хост:Порт"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker виявив {count} служб",
|
||||
"detectedBreakdown": "{integrations} інтеграцій - {apps} програм",
|
||||
"summary": "Homarr виявив {apps} програми, {integrations} з яких мають вбудовану інтеграцію",
|
||||
"appBadge": "Додаток",
|
||||
"appSectionLabel": "Додатки для додавання на інформаційну панель (вибрано {count})",
|
||||
"scanning": "Сканування Docker...",
|
||||
"scanningDescription": "Пошук запущених контейнерів у вашій системі"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Завершити налаштування",
|
||||
"subtitle": "Все готово!",
|
||||
"description": "Ви завершили процес налаштування. Тепер ви можете почати використовувати Homarr. Виберіть наступну дію:",
|
||||
"action": {
|
||||
"goToBoard": "Перейти на {name} дошку",
|
||||
"createBoard": "Створіть свою першу дошку",
|
||||
"inviteUser": "Запросити інших користувачів",
|
||||
"docs": "Ознайомитися з документацією"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "На початок"
|
||||
},
|
||||
"user": {
|
||||
"title": "Користувачі",
|
||||
"name": "Користувач",
|
||||
@@ -3850,6 +3999,62 @@
|
||||
"message": "У вас є незбережені зміни. Ви впевнені, що хочете вийти?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Імпорт з homarr до версії 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Успішно імпортовано",
|
||||
"message": "Дошка успішно імпортована"
|
||||
},
|
||||
"error": {
|
||||
"title": "Помилка імпорту",
|
||||
"message": "Дошка не може бути імпортована, перегляньте журнали для подальших деталей"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Обрати файл JSON",
|
||||
"invalidError": "Неправильний файл конфігурації"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Додатки",
|
||||
"avoidDuplicates": {
|
||||
"label": "Уникати дублікатів",
|
||||
"description": "Ігнорує додатки, якщо додаток з таким самим посиланням вже існує"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Імпортувати лише додатки",
|
||||
"description": "Додавати лише додатки, дошка повинна бути перестворена вручну"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Назва дошки"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Розмір екрану",
|
||||
"description": "У версіях до 1.0 існувало три різні режими, тому ви могли вибрати кількість стовпців для кожного розміру екрана.",
|
||||
"option": {
|
||||
"sm": "Малий",
|
||||
"md": "Середній",
|
||||
"lg": "Великий"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Налаштування бічної панелі",
|
||||
"description": "Бічні панелі видалені з версії 1.0, ви можете вибрати, що має статися з елементами всередині них.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Останній розділ",
|
||||
"description": "Бічна панель буде відображатися під останнім розділом"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Видалити елементи",
|
||||
"description": "Елементи, що містяться в бічній панелі, будуть видалені"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "Створити програму на льоту",
|
||||
@@ -5460,6 +5665,9 @@
|
||||
"newBoard": {
|
||||
"label": "Створити нову дошку"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "Імпортувати дошку"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "Створити новий додаток"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "Chào mừng đến với Homarr",
|
||||
"subtitle": "Hãy bắt đầu cài đặt ứng dụng Homarr của bạn.",
|
||||
"description": "Để bắt đầu, hãy chọn cách bạn muốn cài đặt ứng dụng Homarr của mình.",
|
||||
"action": {
|
||||
"scratch": "Bắt đầu từ đầu",
|
||||
"importOldmarr": "Nhập dữ liệu từ Homarr phiên bản trước 1.0",
|
||||
"restoreSqlite": "Khôi phục từ bản sao lưu SQLite",
|
||||
"restoreSqliteDescription": "Tải lên bản sao lưu cơ sở dữ liệu SQLite đầy đủ từ phiên bản Homarr trước. Thao tác này sẽ khôi phục tất cả bảng, người dùng, ứng dụng, tích hợp và cài đặt.",
|
||||
"backToOptions": "← Quay lại tùy chọn thiết lập"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Nhập dữ liệu",
|
||||
"subtitle": "Bạn có thể nhập dữ liệu từ một phiên bản Homarr có sẵn.",
|
||||
"dropzone": {
|
||||
"title": "Kéo tệp tin zip vào đây hoặc nhấp chuột để chọn",
|
||||
"description": "Tệp tin zip đã tải lên sẽ được xử lý và bạn sẽ có thể chọn những gì bạn muốn nhập"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "Thay đổi tập tin"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "Nhập cài đặt",
|
||||
"description": "Cấu hình hành vi nhập dữ liệu"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "Tìm thấy {count} bảng",
|
||||
"description": "Chọn tất cả các bảng với kích thước bạn muốn nhập",
|
||||
"action": {
|
||||
"selectAll": "Chọn tất cả",
|
||||
"unselectAll": "Bỏ chọn tất cả"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"action": {
|
||||
"import": "Xác nhận nhập và tiếp tục"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "Ứng dụng",
|
||||
"boards": "Bảng",
|
||||
"integrations": "Tích hợp",
|
||||
"credentialUsers": ""
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "Nhập token nhập",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "Mã thông báo",
|
||||
"description": "Nhập token nhập được hiển thị từ phiên bản homarr trước đó của bạn"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "Token không hợp lệ",
|
||||
"message": "Token bạn nhập không đúng"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "Người dùng quản trị",
|
||||
"subtitle": "",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Đã tạo người dùng",
|
||||
"message": "Người dùng đã được tạo thành công"
|
||||
},
|
||||
"error": {
|
||||
"title": "Tạo người dùng không thành công"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Tên nhóm",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Cài đặt",
|
||||
"subtitle": "Cấu hình cài đặt máy chủ."
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Tích hợp",
|
||||
"subtitle": "Chọn dịch vụ bạn dùng.",
|
||||
"description": "Chọn các tích hợp bạn muốn kết nối. Chúng tôi sẽ tự động thiết lập bảng với widget phù hợp.",
|
||||
"action": {
|
||||
"continue": "Tiếp tục",
|
||||
"skip": "Bỏ qua lúc này"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current} của {total}",
|
||||
"skip": "Bỏ qua tích hợp này",
|
||||
"finishing": "Đang thiết lập bảng của bạn...",
|
||||
"error": {
|
||||
"title": "Thiết lập thất bại",
|
||||
"message": "Đã xảy ra lỗi khi thiết lập bảng. Vui lòng thử lại."
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "Trợ giúp URL",
|
||||
"description": "Những trợ giúp này cố gắng đoán URL cho dịch vụ của bạn. Nếu không hiệu quả, hãy nhập địa chỉ thủ công."
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "URL cơ sở",
|
||||
"placeholder": "homelab.local hoặc 192.168.1.1",
|
||||
"hint": "Nhập tên miền cơ sở hoặc IP để tự động điền URL tích hợp",
|
||||
"warning": "Đặt URL cơ sở bây giờ sẽ tự động điền tất cả URL tích hợp, tiết kiệm thời gian thiết lập",
|
||||
"preview": "ví dụ: {example}",
|
||||
"mode": {
|
||||
"subdomain": "Tên miền phụ",
|
||||
"hostPort": "Máy:Cổng"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker phát hiện {count} dịch vụ",
|
||||
"detectedBreakdown": "{integrations} tích hợp · {apps} ứng dụng",
|
||||
"summary": "Homarr phát hiện {apps} ứng dụng, {integrations} trong đó có tích hợp sẵn",
|
||||
"appBadge": "Ứng dụng",
|
||||
"appSectionLabel": "Ứng dụng thêm vào bảng ({count} đã chọn)",
|
||||
"scanning": "Đang quét Docker...",
|
||||
"scanningDescription": "Đang tìm container đang chạy trên hệ thống của bạn"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "Hoàn tất cài đặt",
|
||||
"subtitle": "Bạn đã sẵn sàng để tiếp tục!",
|
||||
"description": "",
|
||||
"action": {
|
||||
"goToBoard": "",
|
||||
"createBoard": "",
|
||||
"inviteUser": "Mời người dùng khác",
|
||||
"docs": "Đọc tài liệu hướng dẫn"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "Trở lại từ đầu"
|
||||
},
|
||||
"user": {
|
||||
"title": "Người dùng",
|
||||
"name": "Người dùng",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "Bạn có thay đổi chưa lưu, bạn có chắc chắn muốn rời đi không?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "Nhập từ Homarr trước 1.0.0",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "Nhập thành công",
|
||||
"message": "Bảng đã được nhập thành công"
|
||||
},
|
||||
"error": {
|
||||
"title": "Nhập không thành công",
|
||||
"message": "Không thể nhập bảng, kiểm tra nhật ký để biết chi tiết"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "Chọn tệp JSON",
|
||||
"invalidError": "Tệp cấu hình không hợp lệ"
|
||||
},
|
||||
"apps": {
|
||||
"label": "Ứng dụng",
|
||||
"avoidDuplicates": {
|
||||
"label": "Tránh trùng lặp",
|
||||
"description": "Bỏ qua ứng dụng nếu đã có ứng dụng cùng href"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "Chỉ nhập ứng dụng",
|
||||
"description": "Chỉ thêm ứng dụng, cần tạo lại bảng thủ công"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Tên bảng"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "Kích thước màn hình",
|
||||
"description": "",
|
||||
"option": {
|
||||
"sm": "Bé nhỏ",
|
||||
"md": "Trung bình",
|
||||
"lg": "Lớn"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "Hành vi thanh bên",
|
||||
"description": "Thanh bên đã bị loại bỏ trong 1.0, bạn có thể chọn điều gì xảy ra với các mục bên trong.",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "Phần cuối cùng",
|
||||
"description": "Thanh bên sẽ hiển thị bên dưới phần cuối cùng"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "Xóa mục",
|
||||
"description": "Các mục trong thanh bên sẽ bị xóa"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
},
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
{
|
||||
"init": {},
|
||||
"init": {
|
||||
"step": {
|
||||
"start": {
|
||||
"title": "歡迎使用 Homarr",
|
||||
"subtitle": "讓我們開始設定 Homarr",
|
||||
"description": "請選擇設定 Homarr 方式",
|
||||
"action": {
|
||||
"scratch": "重新開始",
|
||||
"importOldmarr": "從 1.0 版本的 Homarr 匯入設定",
|
||||
"restoreSqlite": "從 SQLite 備份還原",
|
||||
"restoreSqliteDescription": "上傳先前 Homarr 執行個體的完整 SQLite 資料庫備份。這將還原所有面板、使用者、應用程式、整合和設定。",
|
||||
"backToOptions": "← 返回設定選項"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "匯入數據",
|
||||
"subtitle": "從現有的 Homarr 匯入數據",
|
||||
"dropzone": {
|
||||
"title": "將 ZIP 壓縮檔拖曳至此處或點擊瀏覽",
|
||||
"description": "上傳的壓縮檔將被處理,您可以選擇要匯入的內容"
|
||||
},
|
||||
"fileInfo": {
|
||||
"action": {
|
||||
"change": "更改檔案"
|
||||
}
|
||||
},
|
||||
"importSettings": {
|
||||
"title": "匯入設定",
|
||||
"description": "設定匯入方式"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "找到 {count} 個面板",
|
||||
"description": "選擇要匯入的面板",
|
||||
"action": {
|
||||
"selectAll": "選擇全部",
|
||||
"unselectAll": "取消全選"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"title": "匯入概況",
|
||||
"description": "於下方的概況中,可以看到即將匯入的內容",
|
||||
"action": {
|
||||
"import": "確認匯入並繼續"
|
||||
},
|
||||
"entities": {
|
||||
"apps": "應用程式",
|
||||
"boards": "面板",
|
||||
"integrations": "集成",
|
||||
"credentialUsers": "使用者憑證"
|
||||
}
|
||||
},
|
||||
"tokenModal": {
|
||||
"title": "輸入匯入密鑰",
|
||||
"field": {
|
||||
"token": {
|
||||
"label": "密鑰",
|
||||
"description": "輸入之前 Homarr 中顯示導入之密鑰匙"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"error": {
|
||||
"title": "無效密鑰",
|
||||
"message": "輸入的密鑰無效"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "管理員",
|
||||
"subtitle": "指定管理員的使用者憑證",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "創建使用者",
|
||||
"message": "使用者已成功創建"
|
||||
},
|
||||
"error": {
|
||||
"title": "使用者創建失敗"
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"title": "外部使用者",
|
||||
"subtitle": "指定用於外部使用者的用戶組",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "用戶組名稱",
|
||||
"description": "名稱必須與外部提供者的管理員匹配"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "設定",
|
||||
"subtitle": "設定伺服器的設定"
|
||||
},
|
||||
"integrations": {
|
||||
"title": "整合",
|
||||
"subtitle": "選取你使用的服務。",
|
||||
"description": "選擇你要連接的整合。我們將會自動為你的儀表板設定相符的小工具。",
|
||||
"action": {
|
||||
"continue": "繼續",
|
||||
"skip": "暫時略過"
|
||||
},
|
||||
"configure": {
|
||||
"progress": "{current}/{total}",
|
||||
"skip": "略過此整合",
|
||||
"finishing": "正在設定你的儀表板……",
|
||||
"error": {
|
||||
"title": "設定失敗",
|
||||
"message": "設定儀表板時發生錯誤。請再試一次。"
|
||||
},
|
||||
"helpers": {
|
||||
"tooltip": "URL 幫手",
|
||||
"description": "這些幫手會嘗試猜測你的服務 URL。如果無效,請手動輸入位址。"
|
||||
}
|
||||
},
|
||||
"urlTemplate": {
|
||||
"label": "基礎 URL",
|
||||
"placeholder": "homelab.local 或 192.168.1.1",
|
||||
"hint": "輸入你的基礎網域或 IP 以自動填寫整合 URL",
|
||||
"warning": "現在設定你的基礎 URL 將會自動填寫所有整合 URL,在設定過程中節省你的時間",
|
||||
"preview": "例如 {example}",
|
||||
"mode": {
|
||||
"subdomain": "子網域",
|
||||
"hostPort": "主機:連接埠"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"detected": "Docker 偵測到 {count} 個服務",
|
||||
"detectedBreakdown": "{integrations} 個整合 · {apps} 個應用程式",
|
||||
"summary": "Homarr 偵測到 {apps} 個應用程式,其中 {integrations} 個具有內建整合",
|
||||
"appBadge": "應用程式",
|
||||
"appSectionLabel": "要新增至儀表板的應用程式(已選取 {count} 個)",
|
||||
"scanning": "正在掃描 Docker……",
|
||||
"scanningDescription": "正在尋找系統上執行的容器"
|
||||
}
|
||||
},
|
||||
"finish": {
|
||||
"title": "設定完成",
|
||||
"subtitle": "已設定完成",
|
||||
"description": "已成功完成設定,開始使用 Homarr,請選擇下一步操作",
|
||||
"action": {
|
||||
"goToBoard": "進入 {name} 面板",
|
||||
"createBoard": "創建第一個面板",
|
||||
"inviteUser": "邀請其他使用者",
|
||||
"docs": "閱讀說明書"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backToStart": "返回起點"
|
||||
},
|
||||
"user": {
|
||||
"title": "使用者",
|
||||
"name": "使用者",
|
||||
@@ -3840,6 +3989,62 @@
|
||||
"message": "尚未保存編輯,確認要離開嗎?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
"label": "從 1.0.0 之前的 Homarr 匯入",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "匯入成功",
|
||||
"message": "面板匯入成功"
|
||||
},
|
||||
"error": {
|
||||
"title": "匯入失敗",
|
||||
"message": "無法匯入面板,請查閱 Logs 以取得更多詳情"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"file": {
|
||||
"label": "選擇 JSON 檔案",
|
||||
"invalidError": "無效的設定檔案"
|
||||
},
|
||||
"apps": {
|
||||
"label": "應用程式",
|
||||
"avoidDuplicates": {
|
||||
"label": "避免重複",
|
||||
"description": "忽略已存在具有相同鏈結的應用程式"
|
||||
},
|
||||
"onlyImportApps": {
|
||||
"label": "僅匯入應用程式",
|
||||
"description": "僅新增應用程式,面板需要手動重新創建"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "面板名稱"
|
||||
},
|
||||
"screenSize": {
|
||||
"label": "螢幕大小",
|
||||
"description": "在 1.0 之前的版本中,有三種不同的模式,因此可以根據螢幕大小選擇列的數量",
|
||||
"option": {
|
||||
"sm": "小號",
|
||||
"md": "中等",
|
||||
"lg": "大號"
|
||||
}
|
||||
},
|
||||
"sidebarBehavior": {
|
||||
"label": "側邊欄行為",
|
||||
"description": "側邊欄在 1.0 中被移除了,你可以選擇該怎麼處理其中的項目",
|
||||
"option": {
|
||||
"lastSection": {
|
||||
"label": "最後區段",
|
||||
"description": "側邊欄將顯示在最後區段的下方"
|
||||
},
|
||||
"removeItems": {
|
||||
"label": "移除項目",
|
||||
"description": "側邊欄中包含的項目將被移除"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickCreateApp": {
|
||||
"modal": {
|
||||
"title": "快速建立應用程式",
|
||||
@@ -5450,6 +5655,9 @@
|
||||
"newBoard": {
|
||||
"label": "創建新面板"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": "匯入面板"
|
||||
},
|
||||
"newApp": {
|
||||
"label": "創建新應用程式"
|
||||
},
|
||||
|
||||
@@ -15,8 +15,7 @@ interface SearchInputProps {
|
||||
}
|
||||
|
||||
export const SearchInput = ({ placeholder, ariaLabel, defaultValue, flexExpand = false }: SearchInputProps) => {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const { replace } = useRouter();
|
||||
const router = useRouter();
|
||||
const pathName = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -25,9 +24,9 @@ export const SearchInput = ({ placeholder, ariaLabel, defaultValue, flexExpand =
|
||||
setValue(defaultValue ?? "");
|
||||
setLoading(false);
|
||||
}, [defaultValue]);
|
||||
const handleSearchDebounced = useDebouncedCallback((value: string) => {
|
||||
const handleSearchDebounced = useDebouncedCallback((nextValue: string) => {
|
||||
const params = new URLSearchParams(searchParams);
|
||||
const normalizedValue = value.trim();
|
||||
const normalizedValue = nextValue.trim();
|
||||
if (normalizedValue.length === 0) {
|
||||
params.delete("search");
|
||||
} else {
|
||||
@@ -35,7 +34,7 @@ export const SearchInput = ({ placeholder, ariaLabel, defaultValue, flexExpand =
|
||||
}
|
||||
if (params.has("page")) params.set("page", "1"); // Reset page to 1
|
||||
const query = params.toString();
|
||||
replace(query ? `${pathName}?${query}` : pathName);
|
||||
router.replace(query ? `${pathName}?${query}` : pathName);
|
||||
setLoading(false);
|
||||
}, 250);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useSettings } from "@homarr/settings";
|
||||
export interface UserProps {
|
||||
name: string | null;
|
||||
image: string | null;
|
||||
email: string | null;
|
||||
email?: string | null;
|
||||
}
|
||||
|
||||
interface UserAvatarProps {
|
||||
|
||||
@@ -76,7 +76,7 @@ export const IntegrationMultiSelectGrid = ({
|
||||
h={selectGridCardHeight}
|
||||
className={classes.card}
|
||||
style={{
|
||||
borderColor: isSelected ? "var(--mantine-color-blue-6)" : undefined,
|
||||
borderColor: isSelected ? "var(--mantine-primary-color-filled)" : undefined,
|
||||
borderWidth: isSelected ? 2 : undefined,
|
||||
}}
|
||||
withBorder
|
||||
@@ -87,7 +87,7 @@ export const IntegrationMultiSelectGrid = ({
|
||||
<Text fw={500} lh={1.2} size="sm" lineClamp={2} style={{ flex: 1 }}>
|
||||
{integration.name}
|
||||
</Text>
|
||||
{isSelected && <IconCheck size={18} color="var(--mantine-color-blue-6)" />}
|
||||
{isSelected && <IconCheck size={18} color="var(--mantine-primary-color-filled)" />}
|
||||
</Group>
|
||||
<Stack gap={4} mt="auto">
|
||||
{isDetected && (
|
||||
|
||||
@@ -42,6 +42,12 @@ describe("onboarding URL validation", () => {
|
||||
name: "Sonarr",
|
||||
url: "http://sonarr:8989",
|
||||
pingUrl: "file:///etc/passwd",
|
||||
}).success,
|
||||
).toBe(false);
|
||||
expect(
|
||||
onboardingCreateIntegrationSchema.safeParse({
|
||||
name: "Sonarr",
|
||||
url: "http://sonarr:8989",
|
||||
description: "x".repeat(513),
|
||||
}).success,
|
||||
).toBe(false);
|
||||
@@ -78,4 +84,22 @@ describe("onboarding URL validation", () => {
|
||||
}).success,
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("accepts Docker source IDs up to 512 characters", () => {
|
||||
const input = {
|
||||
server: { defaultLocale: "en", defaultColorScheme: "dark" },
|
||||
board: {
|
||||
name: "dashboard",
|
||||
primaryColor: "#228BE6",
|
||||
secondaryColor: "#15AABF",
|
||||
itemRadius: "md",
|
||||
},
|
||||
selectedDockerSourceIds: ["x".repeat(512)],
|
||||
};
|
||||
|
||||
expect(onboardingCompleteSetupSchema.safeParse(input).success).toBe(true);
|
||||
expect(
|
||||
onboardingCompleteSetupSchema.safeParse({ ...input, selectedDockerSourceIds: ["x".repeat(513)] }).success,
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -17,10 +17,11 @@ const httpUrlSchema = z.url().refine((value) => {
|
||||
const protocol = new URL(value).protocol;
|
||||
return protocol === "http:" || protocol === "https:";
|
||||
}, "Only HTTP and HTTPS URLs are permitted");
|
||||
const uniqueIdsSchema = z
|
||||
.array(z.string().trim().min(1).max(255))
|
||||
.max(128)
|
||||
.refine((ids) => new Set(ids).size === ids.length, { message: "IDs must be unique" });
|
||||
const uniqueIdsSchema = (maxLength = 255) =>
|
||||
z
|
||||
.array(z.string().trim().min(1).max(maxLength))
|
||||
.max(128)
|
||||
.refine((ids) => new Set(ids).size === ids.length, { message: "IDs must be unique" });
|
||||
const sourceIdSchema = z.string().trim().min(1).max(512);
|
||||
|
||||
export const onboardingCreateIntegrationSchema = z.object({
|
||||
@@ -87,11 +88,11 @@ export const onboardingCompleteSetupSchema = z
|
||||
leftSidebar: z.boolean().default(false),
|
||||
rightSidebar: z.boolean().default(false),
|
||||
}),
|
||||
selectedIntegrationIds: uniqueIdsSchema.default([]),
|
||||
selectedAppIds: uniqueIdsSchema.default([]),
|
||||
selectedIntegrationIds: uniqueIdsSchema().default([]),
|
||||
selectedAppIds: uniqueIdsSchema().default([]),
|
||||
integrations: integrationDraftsSchema.default([]),
|
||||
apps: appDraftsSchema.default([]),
|
||||
selectedDockerSourceIds: uniqueIdsSchema.default([]),
|
||||
selectedDockerSourceIds: uniqueIdsSchema(512).default([]),
|
||||
selectedWidgetKinds: z
|
||||
.array(z.enum(widgetKinds))
|
||||
.max(widgetKinds.length)
|
||||
|
||||
Reference in new issue
Block a user