Compare commits

..
Author SHA1 Message Date
Manuel 3498fdaebb feat: implement cacheable lookup 2025-02-23 15:48:56 +01:00
Manuel 5dc5d9e04a fix: omv invalid temperature when not available (#2322) 2025-02-23 12:34:04 +01:00
homarr-crowdin[bot] 4f09363823 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-02-23 00:48:50 +00:00
Meier Lukas c132a07213 Merge branch 'main' into dev 2025-02-22 12:08:07 +01:00
homarr-renovate[bot] 86e778db1e fix(deps): update dependency prettier to ^3.5.2 (#2399)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-22 04:39:53 +00:00
homarr-crowdin[bot] ee1ed0d076 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-02-22 00:44:32 +00:00
homarr-renovate[bot] 675ed5bdc1 chore(deps): update dependency eslint to ^9.21.0 (#2395)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-21 22:17:43 +00:00
ManuelandMeier Lukas fb467ac165 feat: add app ping url (#2380)
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-02-21 22:47:30 +01:00
homarr-renovate[bot] 9d54e938c8 chore(deps): update dependency @types/node to ^22.13.5 (#2394)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-21 20:44:17 +00:00
95 changed files with 4282 additions and 365 deletions

No files matched your search

+13
View File
@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="typecheck" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="typecheck" />
</scripts>
<node-interpreter value="project" />
<package-manager value="pnpm" />
<envs />
<method v="2" />
</configuration>
</component>
+3 -3
View File
@@ -92,15 +92,15 @@
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/chroma-js": "3.1.1", "@types/chroma-js": "3.1.1",
"@types/node": "^22.13.4", "@types/node": "^22.13.5",
"@types/prismjs": "^1.26.5", "@types/prismjs": "^1.26.5",
"@types/react": "19.0.10", "@types/react": "19.0.10",
"@types/react-dom": "19.0.4", "@types/react-dom": "19.0.4",
"@types/swagger-ui-react": "^5.18.0", "@types/swagger-ui-react": "^5.18.0",
"concurrently": "^9.1.2", "concurrently": "^9.1.2",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"node-loader": "^2.1.0", "node-loader": "^2.1.0",
"prettier": "^3.5.1", "prettier": "^3.5.2",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+3 -3
View File
@@ -44,10 +44,10 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/node": "^22.13.4", "@types/node": "^22.13.5",
"dotenv-cli": "^8.0.0", "dotenv-cli": "^8.0.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"prettier": "^3.5.1", "prettier": "^3.5.2",
"tsx": "4.19.3", "tsx": "4.19.3",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
+2 -2
View File
@@ -34,8 +34,8 @@
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/ws": "^8.5.14", "@types/ws": "^8.5.14",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"prettier": "^3.5.1", "prettier": "^3.5.2",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -45,7 +45,7 @@
"conventional-changelog-conventionalcommits": "^8.0.0", "conventional-changelog-conventionalcommits": "^8.0.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"jsdom": "^26.0.0", "jsdom": "^26.0.0",
"prettier": "^3.5.1", "prettier": "^3.5.2",
"semantic-release": "^24.2.3", "semantic-release": "^24.2.3",
"testcontainers": "^10.18.0", "testcontainers": "^10.18.0",
"turbo": "^2.4.2", "turbo": "^2.4.2",
+1 -1
View File
@@ -32,7 +32,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+2 -2
View File
@@ -56,8 +56,8 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"prettier": "^3.5.1", "prettier": "^3.5.2",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+8 -1
View File
@@ -56,7 +56,11 @@ export const appRouter = createTRPCRouter({
}), }),
selectable: protectedProcedure selectable: protectedProcedure
.input(z.void()) .input(z.void())
.output(z.array(selectAppSchema.pick({ id: true, name: true, iconUrl: true, href: true, description: true }))) .output(
z.array(
selectAppSchema.pick({ id: true, name: true, iconUrl: true, href: true, pingUrl: true, description: true }),
),
)
.meta({ .meta({
openapi: { openapi: {
method: "GET", method: "GET",
@@ -73,6 +77,7 @@ export const appRouter = createTRPCRouter({
iconUrl: true, iconUrl: true,
description: true, description: true,
href: true, href: true,
pingUrl: true,
}, },
orderBy: asc(apps.name), orderBy: asc(apps.name),
}); });
@@ -121,6 +126,7 @@ export const appRouter = createTRPCRouter({
description: input.description, description: input.description,
iconUrl: input.iconUrl, iconUrl: input.iconUrl,
href: input.href, href: input.href,
pingUrl: input.pingUrl === "" ? null : input.pingUrl,
}); });
return { appId: id }; return { appId: id };
@@ -164,6 +170,7 @@ export const appRouter = createTRPCRouter({
description: input.description, description: input.description,
iconUrl: input.iconUrl, iconUrl: input.iconUrl,
href: input.href, href: input.href,
pingUrl: input.pingUrl === "" ? null : input.pingUrl,
}) })
.where(eq(apps.id, input.id)); .where(eq(apps.id, input.id));
}), }),
+6
View File
@@ -158,6 +158,7 @@ describe("create should create a new app with all arguments", () => {
description: "React components and hooks library", description: "React components and hooks library",
iconUrl: "https://mantine.dev/favicon.svg", iconUrl: "https://mantine.dev/favicon.svg",
href: "https://mantine.dev", href: "https://mantine.dev",
pingUrl: "https://mantine.dev/a",
}; };
// Act // Act
@@ -170,6 +171,7 @@ describe("create should create a new app with all arguments", () => {
expect(dbApp!.description).toBe(input.description); expect(dbApp!.description).toBe(input.description);
expect(dbApp!.iconUrl).toBe(input.iconUrl); expect(dbApp!.iconUrl).toBe(input.iconUrl);
expect(dbApp!.href).toBe(input.href); expect(dbApp!.href).toBe(input.href);
expect(dbApp!.pingUrl).toBe(input.pingUrl);
}); });
test("should create a new app only with required arguments", async () => { test("should create a new app only with required arguments", async () => {
@@ -185,6 +187,7 @@ describe("create should create a new app with all arguments", () => {
description: null, description: null,
iconUrl: "https://mantine.dev/favicon.svg", iconUrl: "https://mantine.dev/favicon.svg",
href: null, href: null,
pingUrl: "",
}; };
// Act // Act
@@ -197,6 +200,7 @@ describe("create should create a new app with all arguments", () => {
expect(dbApp!.description).toBe(input.description); expect(dbApp!.description).toBe(input.description);
expect(dbApp!.iconUrl).toBe(input.iconUrl); expect(dbApp!.iconUrl).toBe(input.iconUrl);
expect(dbApp!.href).toBe(input.href); expect(dbApp!.href).toBe(input.href);
expect(dbApp!.pingUrl).toBe(null);
}); });
}); });
@@ -225,6 +229,7 @@ describe("update should update an app", () => {
description: "React components and hooks library", description: "React components and hooks library",
iconUrl: "https://mantine.dev/favicon.svg2", iconUrl: "https://mantine.dev/favicon.svg2",
href: "https://mantine.dev", href: "https://mantine.dev",
pingUrl: "https://mantine.dev/a",
}; };
// Act // Act
@@ -257,6 +262,7 @@ describe("update should update an app", () => {
iconUrl: "https://mantine.dev/favicon.svg", iconUrl: "https://mantine.dev/favicon.svg",
description: null, description: null,
href: null, href: null,
pingUrl: "",
}); });
// Assert // Assert
+2 -2
View File
@@ -47,8 +47,8 @@
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/bcrypt": "5.0.2", "@types/bcrypt": "5.0.2",
"@types/cookies": "0.9.0", "@types/cookies": "0.9.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"prettier": "^3.5.1", "prettier": "^3.5.2",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -32,7 +32,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+3 -1
View File
@@ -23,13 +23,15 @@
"prettier": "@homarr/prettier-config", "prettier": "@homarr/prettier-config",
"dependencies": { "dependencies": {
"@homarr/common": "workspace:^0.1.0", "@homarr/common": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"cacheable-lookup": "^7.0.0",
"undici": "7.3.0" "undici": "7.3.0"
}, },
"devDependencies": { "devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+44
View File
@@ -8,6 +8,15 @@ import { fetch } from "undici";
import { env } from "@homarr/common/env"; import { env } from "@homarr/common/env";
import { LoggingAgent } from "@homarr/common/server"; import { LoggingAgent } from "@homarr/common/server";
import CacheableLookup from "cacheable-lookup";
import type { LookupOptions } from "node:dns";
import { logger } from "@homarr/log";
const cacheableLookup = new CacheableLookup({
maxTtl: 6_00,
errorTtl: 60,
fallbackDuration: 3600
});
const getCertificateFolder = () => { const getCertificateFolder = () => {
return env.NODE_ENV === "production" return env.NODE_ENV === "production"
@@ -66,15 +75,50 @@ export const createCertificateAgentAsync = async () => {
return new LoggingAgent({ return new LoggingAgent({
connect: { connect: {
ca: rootCertificates.concat(customCertificates.map((cert) => cert.content)), ca: rootCertificates.concat(customCertificates.map((cert) => cert.content)),
// Override the DNS lookup with the https://www.npmjs.com/package/cacheable-lookup library lookup (see https://github.com/nodejs/undici/issues/2440#issuecomment-2181215481)
lookup(hostname, lookupOptions, callback) {
logger.info(`looking up ${hostname} with cacheable lookup`);
cacheableLookup.lookup(hostname, { all: lookupOptions.all, hints: lookupOptions.hints, family: convertToNodeJsIPFamily(lookupOptions.family) }, (err, address, family) => {
if (err) {
logger.error(`DNS Lookup failed for ${hostname}: ${err}`);
} else {
logger.info(`Cacheable Lookup for ${hostname}: ${JSON.stringify(address)}, family: ${family}`);
}
callback(err, address, family);
});
}
}, },
keepAliveTimeout: 10_000, // Keep connection open for 10s
keepAliveMaxTimeout: 30_000,
pipelining: 0
}); });
}; };
/**
* Converts the family
* @see https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback
* @param lookupOptionsFamily the family that should be converted
*/
const convertToNodeJsIPFamily = (lookupOptionsFamily: LookupOptions['family']) => {
switch (lookupOptionsFamily) {
case 'IPv4': {
return 4;
}
case 'IPv6': {
return 6;
}
default: {
return undefined;
}
}
}
export const createAxiosCertificateInstanceAsync = async () => { export const createAxiosCertificateInstanceAsync = async () => {
const customCertificates = await loadCustomRootCertificatesAsync(); const customCertificates = await loadCustomRootCertificatesAsync();
return axios.create({ return axios.create({
httpsAgent: new Agent({ httpsAgent: new Agent({
ca: rootCertificates.concat(customCertificates.map((cert) => cert.content)), ca: rootCertificates.concat(customCertificates.map((cert) => cert.content)),
keepAlive: true
}), }),
}); });
}; };
+1 -1
View File
@@ -33,7 +33,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -40,7 +40,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -30,7 +30,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -29,7 +29,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -32,7 +32,7 @@
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/node-cron": "^3.0.11", "@types/node-cron": "^3.0.11",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -44,7 +44,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
@@ -0,0 +1 @@
ALTER TABLE `app` ADD `ping_url` text;
File diff suppressed because it is too large. Load diff
@@ -197,6 +197,13 @@
"when": 1739915526818, "when": 1739915526818,
"tag": "0027_acoustic_karma", "tag": "0027_acoustic_karma",
"breakpoints": true "breakpoints": true
},
{
"idx": 28,
"version": "5",
"when": 1740086765989,
"tag": "0028_add_app_ping_url",
"breakpoints": true
} }
] ]
} }
@@ -0,0 +1 @@
ALTER TABLE `app` ADD `ping_url` text;
File diff suppressed because it is too large. Load diff
@@ -197,6 +197,13 @@
"when": 1739915486467, "when": 1739915486467,
"tag": "0027_wooden_blizzard", "tag": "0027_wooden_blizzard",
"breakpoints": true "breakpoints": true
},
{
"idx": 28,
"version": "6",
"when": 1740086746417,
"tag": "0028_add_app_ping_url",
"breakpoints": true
} }
] ]
} }
+2 -2
View File
@@ -59,8 +59,8 @@
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/better-sqlite3": "7.6.12", "@types/better-sqlite3": "7.6.12",
"dotenv-cli": "^8.0.0", "dotenv-cli": "^8.0.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"prettier": "^3.5.1", "prettier": "^3.5.2",
"tsx": "4.19.3", "tsx": "4.19.3",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
+1
View File
@@ -376,6 +376,7 @@ export const apps = mysqlTable("app", {
description: text(), description: text(),
iconUrl: text().notNull(), iconUrl: text().notNull(),
href: text(), href: text(),
pingUrl: text(),
}); });
export const integrationItems = mysqlTable( export const integrationItems = mysqlTable(
+1
View File
@@ -361,6 +361,7 @@ export const apps = sqliteTable("app", {
description: text(), description: text(),
iconUrl: text().notNull(), iconUrl: text().notNull(),
href: text(), href: text(),
pingUrl: text(),
}); });
export const integrationItems = sqliteTable( export const integrationItems = sqliteTable(
+1 -1
View File
@@ -29,7 +29,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -32,7 +32,7 @@
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/dockerode": "^3.3.34", "@types/dockerode": "^3.3.34",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -30,7 +30,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -33,7 +33,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -37,7 +37,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
@@ -1,8 +1,10 @@
"use client"; "use client";
import type { ChangeEventHandler } from "react";
import { useRef } from "react"; import { useRef } from "react";
import Link from "next/link"; import Link from "next/link";
import { Button, Group, Stack, Textarea, TextInput } from "@mantine/core"; import { Button, Checkbox, Collapse, Group, Stack, Textarea, TextInput } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import type { z } from "zod"; import type { z } from "zod";
import { useZodForm } from "@homarr/form"; import { useZodForm } from "@homarr/form";
@@ -39,6 +41,7 @@ export const AppForm = ({
description: initialValues?.description ?? "", description: initialValues?.description ?? "",
iconUrl: initialValues?.iconUrl ?? "", iconUrl: initialValues?.iconUrl ?? "",
href: initialValues?.href ?? "", href: initialValues?.href ?? "",
pingUrl: initialValues?.pingUrl ?? "",
}, },
}); });
@@ -54,6 +57,17 @@ export const AppForm = ({
originalHandleSubmit(values, redirect, afterSuccess); originalHandleSubmit(values, redirect, afterSuccess);
}; };
const [opened, { open, close }] = useDisclosure((initialValues?.pingUrl?.length ?? 0) > 0);
const handleClickDifferentUrlPing: ChangeEventHandler<HTMLInputElement> = () => {
if (!opened) {
open();
} else {
close();
form.setFieldValue("pingUrl", "");
}
};
return ( return (
<form onSubmit={form.onSubmit(handleSubmit)}> <form onSubmit={form.onSubmit(handleSubmit)}>
<Stack> <Stack>
@@ -62,6 +76,18 @@ export const AppForm = ({
<Textarea {...form.getInputProps("description")} label={t("app.field.description.label")} /> <Textarea {...form.getInputProps("description")} label={t("app.field.description.label")} />
<TextInput {...form.getInputProps("href")} label={t("app.field.url.label")} /> <TextInput {...form.getInputProps("href")} label={t("app.field.url.label")} />
<Checkbox
checked={opened}
onChange={handleClickDifferentUrlPing}
label={t("app.field.useDifferentUrlForPing.checkbox.label")}
description={t("app.field.useDifferentUrlForPing.checkbox.description")}
mt="md"
/>
<Collapse in={opened}>
<TextInput {...form.getInputProps("pingUrl")} />
</Collapse>
<Group justify="end"> <Group justify="end">
{showBackToOverview && ( {showBackToOverview && (
<Button variant="default" component={Link} href="/manage/apps"> <Button variant="default" component={Link} href="/manage/apps">
+1 -1
View File
@@ -31,7 +31,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -46,7 +46,7 @@
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/xml2js": "^0.4.14", "@types/xml2js": "^0.4.14",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
@@ -21,7 +21,7 @@ export interface HealthMonitoring {
}[]; }[];
smart: { smart: {
deviceName: string; deviceName: string;
temperature: number; temperature: number | null;
overallStatus: string; overallStatus: string;
}[]; }[];
} }
@@ -40,7 +40,7 @@ export const smartSchema = z.object({
// Convert string to number if necessary // Convert string to number if necessary
const temp = typeof val === "string" ? parseFloat(val) : val; const temp = typeof val === "string" ? parseFloat(val) : val;
if (isNaN(temp)) { if (isNaN(temp)) {
throw new Error("Invalid temperature value"); return null;
} }
return temp; return temp;
}), }),
+1 -1
View File
@@ -33,7 +33,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -45,7 +45,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
@@ -52,6 +52,7 @@ export const AddDockerAppToHomarrModal = createModal<AddDockerAppToHomarrProps>(
iconUrl: container.iconUrl, iconUrl: container.iconUrl,
description: null, description: null,
href: form.values.containerUrls[index] ?? null, href: form.values.containerUrls[index] ?? null,
pingUrl: null,
})), })),
); );
}; };
+1 -1
View File
@@ -32,7 +32,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -31,7 +31,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -52,7 +52,7 @@
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/adm-zip": "0.5.7", "@types/adm-zip": "0.5.7",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+3
View File
@@ -120,6 +120,7 @@ const addMappingFor = <TApp extends OldmarrApp | BookmarkApp>(
href: existing.href, href: existing.href,
iconUrl: existing.iconUrl, iconUrl: existing.iconUrl,
description: existing.description, description: existing.description,
pingUrl: existing.pingUrl,
exists: true, exists: true,
}); });
continue; continue;
@@ -144,6 +145,7 @@ const convertApp = (app: OldmarrApp): DbAppWithoutId => ({
href: app.behaviour.externalUrl === "" ? app.url : app.behaviour.externalUrl, href: app.behaviour.externalUrl === "" ? app.url : app.behaviour.externalUrl,
iconUrl: app.appearance.iconUrl, iconUrl: app.appearance.iconUrl,
description: app.behaviour.tooltipDescription ?? null, description: app.behaviour.tooltipDescription ?? null,
pingUrl: app.url.length > 0 ? app.url : null,
}); });
/** /**
@@ -154,4 +156,5 @@ const convertApp = (app: OldmarrApp): DbAppWithoutId => ({
const convertBookmarkApp = (app: BookmarkApp): DbAppWithoutId => ({ const convertBookmarkApp = (app: BookmarkApp): DbAppWithoutId => ({
...app, ...app,
description: null, description: null,
pingUrl: null,
}); });
@@ -11,6 +11,7 @@ export const mapOldmarrApp = (app: OldmarrApp): InferSelectModel<typeof apps> =>
iconUrl: app.appearance.iconUrl, iconUrl: app.appearance.iconUrl,
description: app.behaviour.tooltipDescription ?? null, description: app.behaviour.tooltipDescription ?? null,
href: app.behaviour.externalUrl || app.url, href: app.behaviour.externalUrl || app.url,
pingUrl: app.url.length > 0 ? app.url : null,
}; };
}; };
@@ -23,5 +24,6 @@ export const mapOldmarrBookmarkApp = (
iconUrl: app.iconUrl, iconUrl: app.iconUrl,
description: null, description: null,
href: app.href, href: app.href,
pingUrl: null,
}; };
}; };
+1 -1
View File
@@ -29,7 +29,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -31,7 +31,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -33,7 +33,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -38,7 +38,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -29,7 +29,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -34,7 +34,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -47,7 +47,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -41,7 +41,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "URL" "label": "URL"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "Url" "label": "Url"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "Url" "label": "Url"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "Url" "label": "Url"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "URL" "label": "URL"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "Url" "label": "Url"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "Use different URL for ping",
"description": "Useful if Homarr can directly access using an internal hostname or network to avoid bandwidth usage of ISP"
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "Url" "label": "Url"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "כתובת אתר" "label": "כתובת אתר"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "Url" "label": "Url"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "URL" "label": "URL"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "Url" "label": "Url"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "Adres URL" "label": "Adres URL"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "URL-адрес" "label": "URL-адрес"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "Url" "label": "Url"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "Url" "label": "Url"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "Ping için farklı URL kullan",
"description": "Homarr, İSS'nın bant genişliği kullanımını önlemek için dahili ana bilgisayar adı veya ağ kullanarak doğrudan erişebiliyorsa yararlıdır"
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "URL-адреса" "label": "URL-адреса"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+6
View File
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "" "label": ""
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "",
"description": ""
}
} }
}, },
"action": { "action": {
+34 -28
View File
@@ -307,12 +307,12 @@
"name": "名稱", "name": "名稱",
"members": "成員", "members": "成員",
"homeBoard": { "homeBoard": {
"label": "", "label": "主面板",
"description": "" "description": "僅能選擇該群組可存取的面板"
}, },
"mobileBoard": { "mobileBoard": {
"label": "", "label": "移動裝置面板",
"description": "" "description": "僅能選擇該群組可存取的面板"
} }
}, },
"permission": { "permission": {
@@ -514,12 +514,12 @@
"board": { "board": {
"notification": { "notification": {
"success": { "success": {
"title": "", "title": "設定已儲存",
"message": "" "message": "面板設定已儲存成功"
}, },
"error": { "error": {
"title": "", "title": "設定儲存失敗",
"message": "" "message": "無法儲存設定"
} }
} }
} }
@@ -527,17 +527,17 @@
"changePosition": { "changePosition": {
"notification": { "notification": {
"success": { "success": {
"message": "" "message": "位置變更成功"
}, },
"error": { "error": {
"message": "" "message": "無法變更位置"
} }
} }
} }
}, },
"defaultGroup": { "defaultGroup": {
"name": "", "name": "預設群組",
"description": "" "description": "{name} - 所有已登入的使用者"
} }
}, },
"app": { "app": {
@@ -600,6 +600,12 @@
}, },
"url": { "url": {
"label": "網址" "label": "網址"
},
"useDifferentUrlForPing": {
"checkbox": {
"label": "使用不同的 URL 進行 Ping",
"description": "如果 Homarr 能夠直接透過內部主機名稱或網路存取,則可避免消耗 ISP 的頻寬,這將會很有幫助"
}
} }
}, },
"action": { "action": {
@@ -924,7 +930,7 @@
}, },
"dangerZone": "危險區域", "dangerZone": "危險區域",
"noResults": "未找到結果", "noResults": "未找到結果",
"unsavedChanges": "", "unsavedChanges": "尚未儲存變更",
"preview": { "preview": {
"show": "顯示預覽", "show": "顯示預覽",
"hide": "隱藏預覽" "hide": "隱藏預覽"
@@ -1609,7 +1615,7 @@
"app": { "app": {
"noData": "未找到應用程式", "noData": "未找到應用程式",
"description": "點擊 <here></here> 創建新的應用程式", "description": "點擊 <here></here> 創建新的應用程式",
"quickCreate": "" "quickCreate": "快速建立應用程式"
}, },
"error": { "error": {
"noIntegration": "未選擇集成", "noIntegration": "未選擇集成",
@@ -2011,8 +2017,8 @@
}, },
"quickCreateApp": { "quickCreateApp": {
"modal": { "modal": {
"title": "", "title": "快速建立應用程式",
"createAndUse": "" "createAndUse": "創立和使用"
} }
} }
}, },
@@ -2089,7 +2095,7 @@
"label": "不透明度" "label": "不透明度"
}, },
"iconColor": { "iconColor": {
"label": "" "label": "icon 顏色"
}, },
"customCss": { "customCss": {
"label": "自定義此面板 CSS html", "label": "自定義此面板 CSS html",
@@ -2107,14 +2113,14 @@
"label": "列數" "label": "列數"
}, },
"itemRadius": { "itemRadius": {
"label": "", "label": "項目圓角半徑",
"description": "", "description": "變更面板上磚塊的圓角程度",
"option": { "option": {
"xs": "", "xs": "非常小",
"sm": "", "sm": "小",
"md": "", "md": "中",
"lg": "", "lg": "大",
"xl": "" "xl": "非常大"
} }
}, },
"name": { "name": {
@@ -2142,7 +2148,7 @@
"title": "背景" "title": "背景"
}, },
"appearance": { "appearance": {
"title": "" "title": "外觀"
}, },
"customCss": { "customCss": {
"title": "自定義 CSS html" "title": "自定義 CSS html"
@@ -2473,10 +2479,10 @@
"ownerOfGroupDeleted": "此用戶組的所有者已被移除,目前沒有所有者" "ownerOfGroupDeleted": "此用戶組的所有者已被移除,目前沒有所有者"
}, },
"setting": { "setting": {
"title": "", "title": "設定",
"alert": "", "alert": "群組設定的優先順序由群組在列表中的順序決定,位於上方的設定會覆蓋下方的設定",
"board": { "board": {
"title": "" "title": "面板"
} }
}, },
"members": { "members": {
+1 -1
View File
@@ -43,7 +43,7 @@
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/css-modules": "^1.0.5", "@types/css-modules": "^1.0.5",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -32,7 +32,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+8
View File
@@ -17,6 +17,14 @@ const manageAppSchema = z.object({
.or(z.literal("")) .or(z.literal(""))
.transform((value) => (value.length === 0 ? null : value)) .transform((value) => (value.length === 0 ? null : value))
.nullable(), .nullable(),
pingUrl: z
.string()
.trim()
.url()
.regex(/^https?:\/\//) // Only allow http and https for security reasons (javascript: is not allowed)
.or(z.literal(""))
.transform((value) => (value.length === 0 ? null : value))
.nullable(),
}); });
const editAppSchema = manageAppSchema.and(z.object({ id: z.string() })); const editAppSchema = manageAppSchema.and(z.object({ id: z.string() }));
+1 -1
View File
@@ -76,7 +76,7 @@
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/video.js": "^7.3.58", "@types/video.js": "^7.3.58",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -97,7 +97,7 @@ export default function AppWidget({ options, isEditMode }: WidgetComponentProps<
</Tooltip.Floating> </Tooltip.Floating>
{options.pingEnabled && !settings.forceDisableStatus && !board.disableStatus && app.href ? ( {options.pingEnabled && !settings.forceDisableStatus && !board.disableStatus && app.href ? (
<Suspense fallback={<PingDot icon={IconLoader} color="blue" tooltip={`${t("common.action.loading")}…`} />}> <Suspense fallback={<PingDot icon={IconLoader} color="blue" tooltip={`${t("common.action.loading")}…`} />}>
<PingIndicator href={app.href} /> <PingIndicator href={app.pingUrl ?? app.href} />
</Suspense> </Suspense>
) : null} ) : null}
</AppLink> </AppLink>
@@ -9,7 +9,14 @@ import type { SortableItemListInput } from "../options";
import { AppSelectModal } from "./app-select-modal"; import { AppSelectModal } from "./app-select-modal";
export const BookmarkAddButton: SortableItemListInput< export const BookmarkAddButton: SortableItemListInput<
{ name: string; description: string | null; id: string; iconUrl: string; href: string | null }, {
name: string;
description: string | null;
id: string;
iconUrl: string;
href: string | null;
pingUrl: string | null;
},
string string
>["AddButton"] = ({ addItem, values }) => { >["AddButton"] = ({ addItem, values }) => {
const { openModal } = useModalAction(AppSelectModal); const { openModal } = useModalAction(AppSelectModal);
@@ -64,12 +64,11 @@ export const SystemHealthMonitoring = ({ options, integrationIds }: WidgetCompon
if (!prevData) { if (!prevData) {
return undefined; return undefined;
} }
const newData = prevData.map((item) => return prevData.map((item) =>
item.integrationId === data.integrationId item.integrationId === data.integrationId
? { ...item, healthInfo: data.healthInfo, updatedAt: data.timestamp } ? { ...item, healthInfo: data.healthInfo, updatedAt: data.timestamp }
: item, : item,
); );
return newData;
}); });
}, },
}, },
@@ -294,7 +293,7 @@ interface FileSystem {
interface SmartData { interface SmartData {
deviceName: string; deviceName: string;
temperature: number; temperature: number | null;
overallStatus: string; overallStatus: string;
} }
+283 -279
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -29,7 +29,7 @@
"devDependencies": { "devDependencies": {
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.20.1", "eslint": "^9.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }
+1 -1
View File
@@ -11,7 +11,7 @@
"prettier": "@homarr/prettier-config", "prettier": "@homarr/prettier-config",
"dependencies": { "dependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.4.1", "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
"prettier": "^3.5.1" "prettier": "^3.5.2"
}, },
"devDependencies": { "devDependencies": {
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",