diff --git a/next-i18next.config.js b/next-i18next.config.js index 4c67b5cf3..9aea1577e 100644 --- a/next-i18next.config.js +++ b/next-i18next.config.js @@ -35,6 +35,7 @@ module.exports = { 'vi', 'et', 'lt', + 'ro' ], localeDetection: false, diff --git a/package.json b/package.json index ee7ea990e..255df001d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homarr", - "version": "0.15.2", + "version": "0.15.3", "description": "Homarr - A homepage for your server.", "license": "MIT", "repository": { @@ -106,6 +106,7 @@ "rss-parser": "^3.12.0", "sabnzbd-api": "^1.5.0", "swagger-ui-react": "^5.11.0", + "tldts": "^6.1.18", "trpc-openapi": "^1.2.0", "uuid": "^9.0.0", "xml-js": "^1.6.11", @@ -240,4 +241,4 @@ ] } } -} +} \ No newline at end of file diff --git a/public/locales/cn/modules/health-monitoring.json b/public/locales/cn/modules/health-monitoring.json index 8ef2b45fa..dc3a5d023 100644 --- a/public/locales/cn/modules/health-monitoring.json +++ b/public/locales/cn/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "系统健康监测", - "description": "关于NAS的信息", - "settings": { - "title": "系统健康监测", - "fahrenheit": { - "label": "华氏度" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "系统健康监测", + "description": "显示系统运行状况和状态的信息。", + "settings": { + "title": "系统健康监测设置", + "fahrenheit": { + "label": "CPU 温度(华氏度)" + }, + "cpu": { + "label": "显示CPU信息", "load": "平均负载", - "minute": "{{minute}} 分钟" - }, - "memory": { - "label": "内存", - "totalMem": "内存总量: {{total}}GB", - "available": "可用: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "文件系统", - "available": "可用: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "运行时间", - "updates": "更新", - "reboot": "重启" - }, - "errors": { - "general": { - "title": "找不到您的 NAS", - "text": "连接到您的NAS时出现了问题。请验证您的配置/集成。" + "minute": "{{minute}} 分钟", + "minutes": "{{minutes}} 分钟" + }, + "memory": { + "label": "显示内存信息" + }, + "fileSystem": { + "label": "显示文件系统信息" + }, + "node": { + "label": "按节点名称过滤", + "info": "输入您的 Proxmox 节点名称以仅显示该节点的指标。默认情况下,显示整个集群。" + }, + "defaultViewState": { + "label": "默认打开的部分", + "data": { + "none": "不显示", + "node": "节点", + "vm": "虚拟机", + "lxc": "LXCs", + "storage": "存储" } + }, + "defaultTabState": { + "label": "默认打开选项卡", + "info": "默认打开选项卡。仅当多个集成可用时才使用。", + "data": { + "system": "系统", + "cluster": "集群" + } + }, + "summary": { + "label": "显示摘要部分" + }, + "showNode": { + "label": "显示节点部分" + }, + "showVM": { + "label": "显示虚拟机部分" + }, + "showLXCs": { + "label": "显示 LXC 部分" + }, + "showStorage": { + "label": "显示存储部分" + }, + "sectionIndicatorColor": { + "label": "要求部分状态指示器为“OK”", + "info": "全部 \"要求所有项目都在线,指标才会变为绿色。任意 \"要求至少有一个项目在线。", + "data": { + "any": "任意活动", + "all": "全部活动" + } + }, + "ignoreCert": { + "label": "忽略证书错误", + "info": "如果启用,小工具在访问 Proxmox API 时将忽略证书错误。这在通过 HTTPS 访问 Proxmox 时很有帮助。" + } } + }, + "cpu": { + "label": "CPU", + "load": "平均负载", + "minute": "{{minute}} 分钟" + }, + "memory": { + "label": "内存", + "totalMem": "内存总量: {{total}}GB", + "available": "可用: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "文件系统", + "available": "可用: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "运行时间", + "uptimeFormat": "{{days}} 天, {{hours}} 小时", + "updates": "可用更新", + "reboot": "重启" + }, + "errors": { + "general": { + "title": "无法找到您的系统。", + "text": "连接到您的系统时出现问题。请验证您的配置/集成。" + } + }, + "headings": { + "system": "系统", + "cluster": "集群" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "内存" + }, + "accordion": { + "title": { + "nodes": "节点", + "vms": "虚拟机", + "lxcs": "LXCs", + "storage": "存储" + } + }, + "table": { + "header": { + "name": "名称", + "cpu": "CPU", + "ram": "内存", + "node": "节点" + } + }, + "popover": { + "node": "节点", + "vmid": "VMID", + "details": "详情", + "cores": "核心 - {{maxCpu}}", + "memSize": "内存 - {{maxMem}}", + "memRatio": "内存 - {{usedMem}} / {{maxMem}}", + "diskSize": "磁盘 - {{maxDisk}}", + "diskRatio": "磁盘 - {{usedDisk}} / {{maxDisk}}", + "uptime": "运行时间 - {{uptime}}", + "plugin": "插件", + "ha": "状态 - {{haState}}", + "sharedStorage": "共享存储", + "localStorage": "本地存储", + "na": "不可用" + } + } } \ No newline at end of file diff --git a/public/locales/cn/modules/indexer-manager.json b/public/locales/cn/modules/indexer-manager.json index 542bd772a..eb9d92813 100644 --- a/public/locales/cn/modules/indexer-manager.json +++ b/public/locales/cn/modules/indexer-manager.json @@ -1,13 +1,13 @@ { "descriptor": { - "name": "索引管理器状态", + "name": "索引器管理状态", "description": "有关索引器的状态", "settings": { - "title": "索引管理器状态" + "title": "索引器管理状态" } }, "indexersStatus": { - "title": "索引管理器", + "title": "索引器管理", "testAllButton": "测试全部" }, "errors": { diff --git a/public/locales/cn/modules/media-transcoding.json b/public/locales/cn/modules/media-transcoding.json new file mode 100644 index 000000000..b9c4a9d2b --- /dev/null +++ b/public/locales/cn/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "媒体转码", + "description": "显示有关媒体转码的信息", + "settings": { + "title": "媒体转码设置", + "appId": { + "label": "选择一个应用" + }, + "defaultView": { + "label": "默认视图", + "data": { + "workers": "工作种", + "queue": "队列", + "statistics": "统计" + } + }, + "showHealthCheck": { + "label": "显示健康检查指示器" + }, + "showHealthChecksInQueue": { + "label": "在队列中显示健康检查" + }, + "queuePageSize": { + "label": "队列:每页项目数" + }, + "showAppIcon": { + "label": "在右下角显示应用程序图标" + } + } + }, + "noAppSelected": "请在小组件设置中选择一个应用程序", + "views": { + "workers": { + "table": { + "header": { + "name": "文件", + "eta": "剩余时间", + "progress": "进度" + }, + "empty": "空", + "tooltip": { + "transcode": "转码", + "healthCheck": "健康检查" + } + } + }, + "queue": { + "table": { + "header": { + "name": "文件", + "size": "大小" + }, + "footer": { + "currentIndex": "{{start}}-{{end}} 共 {{total}}" + }, + "empty": "空", + "tooltip": { + "transcode": "转码", + "healthCheck": "健康检查" + } + } + }, + "statistics": { + "empty": "空", + "box": { + "transcodes": "转码: {{value}}", + "healthChecks": "健康检查: {{value}}", + "files": "文件: {{value}}", + "spaceSaved": "已保存: {{value}}" + }, + "pies": { + "transcodes": "转码", + "healthChecks": "健康检查", + "videoCodecs": "编码", + "videoContainers": "容器", + "videoResolutions": "分辨率" + } + } + }, + "error": { + "title": "错误", + "message": "从 Tdarr 获取数据时发生错误。" + }, + "tabs": { + "workers": "工作种", + "queue": "队列", + "statistics": "统计" + }, + "healthCheckStatus": { + "title": "健康检查", + "queued": "排队中", + "healthy": "健康", + "unhealthy": "不良" + } +} diff --git a/public/locales/cn/modules/smart-home/entity-state.json b/public/locales/cn/modules/smart-home/entity-state.json index 10a84e2be..fac39e4f3 100644 --- a/public/locales/cn/modules/smart-home/entity-state.json +++ b/public/locales/cn/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "显示友好名称", - "info": "显示来自家庭助理的友好名称,而不是显示名称" + "info": "显示来自家庭助理的友好名称,而不是显示名称." + }, + "genericToggle": { + "label": "实体切换", + "info": "单击时对实体执行通用的家庭助理切换操作。" } } } -} \ No newline at end of file +} + diff --git a/public/locales/cn/modules/torrents-status.json b/public/locales/cn/modules/torrents-status.json index 9570a8696..7ead835c0 100644 --- a/public/locales/cn/modules/torrents-status.json +++ b/public/locales/cn/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "显示过滤后的 torrents 列表比例", "info": "如果禁用,则只显示全局比率。如果设置为 \"禁用\",全局比率仍将使用标签。" + }, + "columnOrdering": { + "label": "启用重新排序列" + }, + "rowSorting": { + "label": "启用行排序" + }, + "columns": { + "label": "选择要显示的列", + "data": { + "date": "日期已添加", + "down": "下载", + "up": "上传", + "eta": "剩余时间", + "progress": "进度" + } + }, + "nameColumnSize": { + "label": "更改名称列大小" } } }, @@ -84,10 +103,6 @@ "text": "无法与您的 Torrent 客户端通信。请检查您的配置" } }, - "loading": { - "title": "加载中", - "description": "建立连接中" - }, "popover": { "introductionPrefix": "管理方:", "metrics": { diff --git a/public/locales/cr/modules/health-monitoring.json b/public/locales/cr/modules/health-monitoring.json index cb978df5b..1a1eb2719 100644 --- a/public/locales/cr/modules/health-monitoring.json +++ b/public/locales/cr/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "crwdns4202:0crwdne4202:0", - "description": "crwdns4204:0crwdne4204:0", - "settings": { - "title": "crwdns4206:0crwdne4206:0", - "fahrenheit": { - "label": "crwdns4208:0crwdne4208:0" - } + "descriptor": { + "name": "crwdns4202:0crwdne4202:0", + "description": "crwdns4246:0crwdne4246:0", + "settings": { + "title": "crwdns4248:0crwdne4248:0", + "fahrenheit": { + "label": "crwdns4250:0crwdne4250:0" + }, + "cpu": { + "label": "crwdns4252:0crwdne4252:0", + "load": "crwdns4254:0crwdne4254:0", + "minute": "crwdns4256:0{{minute}}crwdne4256:0", + "minutes": "crwdns4258:0{{minutes}}crwdne4258:0" + }, + "memory": { + "label": "crwdns4260:0crwdne4260:0" + }, + "fileSystem": { + "label": "crwdns4262:0crwdne4262:0" + }, + "node": { + "label": "crwdns4264:0crwdne4264:0", + "info": "crwdns4266:0crwdne4266:0" + }, + "defaultViewState": { + "label": "crwdns4268:0crwdne4268:0", + "data": { + "none": "crwdns4270:0crwdne4270:0", + "node": "crwdns4272:0crwdne4272:0", + "vm": "crwdns4274:0crwdne4274:0", + "lxc": "crwdns4276:0crwdne4276:0", + "storage": "crwdns4278:0crwdne4278:0" } - }, - "cpu": { - "label": "crwdns4210:0crwdne4210:0", - "load": "crwdns4212:0crwdne4212:0", - "minute": "crwdns4214:0{{minute}}crwdne4214:0" - }, - "memory": { - "label": "crwdns4216:0crwdne4216:0", - "totalMem": "crwdns4218:0{{total}}crwdne4218:0", - "available": "crwdns4220:0{{available}}crwdnd4220:0{{percentage}}crwdne4220:0" - }, - "fileSystem": { - "label": "crwdns4222:0crwdne4222:0", - "available": "crwdns4224:0{{available}}crwdnd4224:0{{percentage}}crwdne4224:0" - }, - "info": { - "uptime": "crwdns4226:0crwdne4226:0", - "updates": "crwdns4228:0crwdne4228:0", - "reboot": "crwdns4230:0crwdne4230:0" - }, - "errors": { - "general": { - "title": "crwdns4232:0crwdne4232:0", - "text": "crwdns4234:0crwdne4234:0" + }, + "defaultTabState": { + "label": "crwdns4280:0crwdne4280:0", + "info": "crwdns4282:0crwdne4282:0", + "data": { + "system": "crwdns4284:0crwdne4284:0", + "cluster": "crwdns4286:0crwdne4286:0" } + }, + "summary": { + "label": "crwdns4288:0crwdne4288:0" + }, + "showNode": { + "label": "crwdns4290:0crwdne4290:0" + }, + "showVM": { + "label": "crwdns4292:0crwdne4292:0" + }, + "showLXCs": { + "label": "crwdns4294:0crwdne4294:0" + }, + "showStorage": { + "label": "crwdns4296:0crwdne4296:0" + }, + "sectionIndicatorColor": { + "label": "crwdns4298:0crwdne4298:0", + "info": "crwdns4300:0crwdne4300:0", + "data": { + "any": "crwdns4302:0crwdne4302:0", + "all": "crwdns4304:0crwdne4304:0" + } + }, + "ignoreCert": { + "label": "crwdns4306:0crwdne4306:0", + "info": "crwdns4308:0crwdne4308:0" + } } + }, + "cpu": { + "label": "crwdns4210:0crwdne4210:0", + "load": "crwdns4212:0crwdne4212:0", + "minute": "crwdns4214:0{{minute}}crwdne4214:0" + }, + "memory": { + "label": "crwdns4216:0crwdne4216:0", + "totalMem": "crwdns4218:0{{total}}crwdne4218:0", + "available": "crwdns4220:0{{available}}crwdnd4220:0{{percentage}}crwdne4220:0" + }, + "fileSystem": { + "label": "crwdns4222:0crwdne4222:0", + "available": "crwdns4224:0{{available}}crwdnd4224:0{{percentage}}crwdne4224:0" + }, + "info": { + "uptime": "crwdns4226:0crwdne4226:0", + "uptimeFormat": "crwdns4310:0{{days}}crwdnd4310:0{{hours}}crwdne4310:0", + "updates": "crwdns4312:0crwdne4312:0", + "reboot": "crwdns4230:0crwdne4230:0" + }, + "errors": { + "general": { + "title": "crwdns4314:0crwdne4314:0", + "text": "crwdns4316:0crwdne4316:0" + } + }, + "headings": { + "system": "crwdns4318:0crwdne4318:0", + "cluster": "crwdns4320:0crwdne4320:0" + }, + "cluster": { + "summary": { + "cpu": "crwdns4322:0crwdne4322:0", + "ram": "crwdns4324:0crwdne4324:0" + }, + "accordion": { + "title": { + "nodes": "crwdns4326:0crwdne4326:0", + "vms": "crwdns4328:0crwdne4328:0", + "lxcs": "crwdns4330:0crwdne4330:0", + "storage": "crwdns4332:0crwdne4332:0" + } + }, + "table": { + "header": { + "name": "crwdns4334:0crwdne4334:0", + "cpu": "crwdns4336:0crwdne4336:0", + "ram": "crwdns4338:0crwdne4338:0", + "node": "crwdns4340:0crwdne4340:0" + } + }, + "popover": { + "node": "crwdns4342:0crwdne4342:0", + "vmid": "crwdns4344:0crwdne4344:0", + "details": "crwdns4346:0crwdne4346:0", + "cores": "crwdns4348:0{{maxCpu}}crwdne4348:0", + "memSize": "crwdns4350:0{{maxMem}}crwdne4350:0", + "memRatio": "crwdns4352:0{{usedMem}}crwdnd4352:0{{maxMem}}crwdne4352:0", + "diskSize": "crwdns4354:0{{maxDisk}}crwdne4354:0", + "diskRatio": "crwdns4356:0{{usedDisk}}crwdnd4356:0{{maxDisk}}crwdne4356:0", + "uptime": "crwdns4358:0{{uptime}}crwdne4358:0", + "plugin": "crwdns4360:0crwdne4360:0", + "ha": "crwdns4362:0{{haState}}crwdne4362:0", + "sharedStorage": "crwdns4364:0crwdne4364:0", + "localStorage": "crwdns4366:0crwdne4366:0", + "na": "crwdns4368:0crwdne4368:0" + } + } } \ No newline at end of file diff --git a/public/locales/cr/modules/media-transcoding.json b/public/locales/cr/modules/media-transcoding.json new file mode 100644 index 000000000..767f633ae --- /dev/null +++ b/public/locales/cr/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "crwdns4382:0crwdne4382:0", + "description": "crwdns4384:0crwdne4384:0", + "settings": { + "title": "crwdns4386:0crwdne4386:0", + "appId": { + "label": "crwdns4388:0crwdne4388:0" + }, + "defaultView": { + "label": "crwdns4390:0crwdne4390:0", + "data": { + "workers": "crwdns4392:0crwdne4392:0", + "queue": "crwdns4394:0crwdne4394:0", + "statistics": "crwdns4396:0crwdne4396:0" + } + }, + "showHealthCheck": { + "label": "crwdns4398:0crwdne4398:0" + }, + "showHealthChecksInQueue": { + "label": "crwdns4400:0crwdne4400:0" + }, + "queuePageSize": { + "label": "crwdns4402:0crwdne4402:0" + }, + "showAppIcon": { + "label": "crwdns4404:0crwdne4404:0" + } + } + }, + "noAppSelected": "crwdns4406:0crwdne4406:0", + "views": { + "workers": { + "table": { + "header": { + "name": "crwdns4408:0crwdne4408:0", + "eta": "crwdns4410:0crwdne4410:0", + "progress": "crwdns4412:0crwdne4412:0" + }, + "empty": "crwdns4414:0crwdne4414:0", + "tooltip": { + "transcode": "crwdns4416:0crwdne4416:0", + "healthCheck": "crwdns4418:0crwdne4418:0" + } + } + }, + "queue": { + "table": { + "header": { + "name": "crwdns4420:0crwdne4420:0", + "size": "crwdns4422:0crwdne4422:0" + }, + "footer": { + "currentIndex": "crwdns4424:0{{start}}crwdnd4424:0{{end}}crwdnd4424:0{{total}}crwdne4424:0" + }, + "empty": "crwdns4426:0crwdne4426:0", + "tooltip": { + "transcode": "crwdns4428:0crwdne4428:0", + "healthCheck": "crwdns4430:0crwdne4430:0" + } + } + }, + "statistics": { + "empty": "crwdns4432:0crwdne4432:0", + "box": { + "transcodes": "crwdns4434:0{{value}}crwdne4434:0", + "healthChecks": "crwdns4436:0{{value}}crwdne4436:0", + "files": "crwdns4438:0{{value}}crwdne4438:0", + "spaceSaved": "crwdns4440:0{{value}}crwdne4440:0" + }, + "pies": { + "transcodes": "crwdns4442:0crwdne4442:0", + "healthChecks": "crwdns4444:0crwdne4444:0", + "videoCodecs": "crwdns4446:0crwdne4446:0", + "videoContainers": "crwdns4448:0crwdne4448:0", + "videoResolutions": "crwdns4450:0crwdne4450:0" + } + } + }, + "error": { + "title": "crwdns4452:0crwdne4452:0", + "message": "crwdns4454:0crwdne4454:0" + }, + "tabs": { + "workers": "crwdns4456:0crwdne4456:0", + "queue": "crwdns4458:0crwdne4458:0", + "statistics": "crwdns4460:0crwdne4460:0" + }, + "healthCheckStatus": { + "title": "crwdns4462:0crwdne4462:0", + "queued": "crwdns4464:0crwdne4464:0", + "healthy": "crwdns4466:0crwdne4466:0", + "unhealthy": "crwdns4468:0crwdne4468:0" + } +} diff --git a/public/locales/cr/modules/smart-home/entity-state.json b/public/locales/cr/modules/smart-home/entity-state.json index 4de87682e..11b4bea86 100644 --- a/public/locales/cr/modules/smart-home/entity-state.json +++ b/public/locales/cr/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "crwdns4184:0crwdne4184:0", - "info": "crwdns4186:0crwdne4186:0" + "info": "crwdns4476:0crwdne4476:0" + }, + "genericToggle": { + "label": "crwdns4478:0crwdne4478:0", + "info": "crwdns4480:0crwdne4480:0" } } } -} \ No newline at end of file +} + diff --git a/public/locales/cr/modules/torrents-status.json b/public/locales/cr/modules/torrents-status.json index 226de309c..affe9434d 100644 --- a/public/locales/cr/modules/torrents-status.json +++ b/public/locales/cr/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "crwdns4000:0crwdne4000:0", "info": "crwdns4002:0crwdne4002:0" + }, + "columnOrdering": { + "label": "crwdns4470:0crwdne4470:0" + }, + "rowSorting": { + "label": "crwdns4472:0crwdne4472:0" + }, + "columns": { + "label": "crwdns4370:0crwdne4370:0", + "data": { + "date": "crwdns4474:0crwdne4474:0", + "down": "crwdns4372:0crwdne4372:0", + "up": "crwdns4374:0crwdne4374:0", + "eta": "crwdns4376:0crwdne4376:0", + "progress": "crwdns4378:0crwdne4378:0" + } + }, + "nameColumnSize": { + "label": "crwdns4380:0crwdne4380:0" } } }, @@ -84,10 +103,6 @@ "text": "crwdns3193:0crwdne3193:0" } }, - "loading": { - "title": "crwdns3195:0crwdne3195:0", - "description": "crwdns3197:0crwdne3197:0" - }, "popover": { "introductionPrefix": "crwdns2463:0crwdne2463:0", "metrics": { diff --git a/public/locales/cs/modules/dns-hole-controls.json b/public/locales/cs/modules/dns-hole-controls.json index 0be5fff39..4bd1c271e 100644 --- a/public/locales/cs/modules/dns-hole-controls.json +++ b/public/locales/cs/modules/dns-hole-controls.json @@ -11,7 +11,7 @@ "errors": { "general": { "title": "Nepodařilo se najít DNS hole", - "text": "Došlo k problému s připojením k Vaší DNS Hole. Ověřte prosím svou konfiguraci/integraci." + "text": "Došlo k problému s připojením k Vaší DNS Hole. Ověřte prosím svou konfiguraci." } } } diff --git a/public/locales/cs/modules/health-monitoring.json b/public/locales/cs/modules/health-monitoring.json index 8c12b2567..0db0b942f 100644 --- a/public/locales/cs/modules/health-monitoring.json +++ b/public/locales/cs/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Monitorování stavu systému", - "description": "Informace o Vaší NAS", - "settings": { - "title": "Monitorování stavu systému", - "fahrenheit": { - "label": "Stupně Fahrenheit" - } - } - }, - "cpu": { - "label": "Procesor", + "descriptor": { + "name": "Monitorování stavu systému", + "description": "Zobrazuje informace o stavu a kondici Vašeho systému (systémů).", + "settings": { + "title": "Nastavení pro sledování stavu systému", + "fahrenheit": { + "label": "Teplota CPU ve stupních Fahrenheit" + }, + "cpu": { + "label": "Zobrazit info o CPU", "load": "Průměrné zatížení", - "minute": "{{minute}} minut" - }, - "memory": { - "label": "Pamět", - "totalMem": "Celková paměť: {{total}}GB", - "available": "K dispozici: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "Souborový systém", - "available": "K dispozici: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "Doba provozu", - "updates": "Aktualizace", - "reboot": "Restartovat" - }, - "errors": { - "general": { - "title": "Nepodařilo se najít Vaší NAS", - "text": "Došlo k problému s připojením k Vaší NAS. Ověřte prosím svou konfiguraci/integraci." + "minute": "{{minute}} minut", + "minutes": "{{minutes}} minut/y" + }, + "memory": { + "label": "Zobrazit informace o paměti" + }, + "fileSystem": { + "label": "Zobrazit informace o souborovém systému" + }, + "node": { + "label": "Filtrovat podle názvu uzlu", + "info": "Zadejte název uzlu Proxmox, aby se zobrazovaly metriky pouze pro tento uzel. Ve výchozím nastavení se zobrazí celý cluster." + }, + "defaultViewState": { + "label": "Sekce bude otevřená ve výchozím nastavení", + "data": { + "none": "Žádný", + "node": "Uzly", + "vm": "Virtuální Stroje", + "lxc": "LXC", + "storage": "Úložiště" } + }, + "defaultTabState": { + "label": "Karta je ve výchozím nastavení otevřena", + "info": "Karta je ve výchozím nastavení otevřená. Používá se pouze v případě, že je k dispozici více integrací.", + "data": { + "system": "Systém", + "cluster": "Cluster" + } + }, + "summary": { + "label": "Zobrazit sekci shrnutí" + }, + "showNode": { + "label": "Zobrazit sekci uzlů" + }, + "showVM": { + "label": "Zobrazit sekci virutálních strojů" + }, + "showLXCs": { + "label": "Zobrazit sekci s LXC" + }, + "showStorage": { + "label": "Zobrazit sekci úložiště" + }, + "sectionIndicatorColor": { + "label": "Požadavky, aby indikátor stavu sekce byl \"OK“", + "info": "'Vše' vyžaduje, aby všechny položky byly online, aby byl indikátor zelený. 'Cokoliv' vyžaduje, aby alespoň jedna položka byla online.", + "data": { + "any": "Jakýkoli aktivní", + "all": "Všechny aktivní" + } + }, + "ignoreCert": { + "label": "Ignorovat chyby certifikátu", + "info": "Pokud je tato možnost povolena, bude widget při přístupu k rozhraní API Proxmox ignorovat chyby certifikátu. To může být užitečné při přístupu k Proxmoxu přes HTTPS." + } } + }, + "cpu": { + "label": "Procesor", + "load": "Průměrné zatížení", + "minute": "{{minute}} minut" + }, + "memory": { + "label": "Pamět", + "totalMem": "Celková paměť: {{total}}GB", + "available": "K dispozici: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Souborový systém", + "available": "K dispozici: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Doba provozu", + "uptimeFormat": "{{days}} dny/ů, {{hours}} hodin/a/y", + "updates": "Dostupné aktualizace", + "reboot": "Restartovat" + }, + "errors": { + "general": { + "title": "Nepodařilo se najít Váš systém/Vaše systémy.", + "text": "Došlo k problému s připojením k Vašemu systému. Ověřte prosím svou konfiguraci." + } + }, + "headings": { + "system": "Systém", + "cluster": "Cluster" + }, + "cluster": { + "summary": { + "cpu": "Procesor", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Uzly", + "vms": "Virtuální Stroje", + "lxcs": "LXC", + "storage": "Úložiště" + } + }, + "table": { + "header": { + "name": "Název", + "cpu": "Procesor", + "ram": "RAM", + "node": "Uzel" + } + }, + "popover": { + "node": "Uzel", + "vmid": "ID virtuálního stroje", + "details": "Podrobnosti", + "cores": "Jádra - {{maxCpu}}", + "memSize": "Paměť - {{maxMem}}", + "memRatio": "Paměť - {{usedMem}} / {{maxMem}}", + "diskSize": "Disk - {{maxDisk}}", + "diskRatio": "Disk - {{usedDisk}} / {{maxDisk}}", + "uptime": "Doba provozu - {{uptime}}", + "plugin": "Plugin", + "ha": "Stav HA - {{haState}}", + "sharedStorage": "Sdílené úložiště", + "localStorage": "Místní úložiště", + "na": "N/A" + } + } } \ No newline at end of file diff --git a/public/locales/cs/modules/indexer-manager.json b/public/locales/cs/modules/indexer-manager.json index d31ea6a9f..dd2e9a365 100644 --- a/public/locales/cs/modules/indexer-manager.json +++ b/public/locales/cs/modules/indexer-manager.json @@ -13,7 +13,7 @@ "errors": { "general": { "title": "Nepodařilo se najít správce indexeru", - "text": "Došlo k problému s připojením k Vašemu správci indexeru. Ověřte prosím svou konfiguraci/integraci." + "text": "Došlo k problému s připojením k Vašemu správci indexeru. Ověřte prosím svou konfiguraci." } } } \ No newline at end of file diff --git a/public/locales/cs/modules/media-transcoding.json b/public/locales/cs/modules/media-transcoding.json new file mode 100644 index 000000000..3bbebf7d6 --- /dev/null +++ b/public/locales/cs/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Překódování médií", + "description": "Zobrazuje informace o překódování médií", + "settings": { + "title": "Nastavení překódování médií", + "appId": { + "label": "Vyberte aplikaci" + }, + "defaultView": { + "label": "Výchozí zobrazení", + "data": { + "workers": "Stroje", + "queue": "Fronta", + "statistics": "Statistiky" + } + }, + "showHealthCheck": { + "label": "Zobrazit indikátor kontroly stavu" + }, + "showHealthChecksInQueue": { + "label": "Zobrazit kontroly stavu ve frontě" + }, + "queuePageSize": { + "label": "Fronta: Počet položek na stránku" + }, + "showAppIcon": { + "label": "Zobrazovat ikonu aplikace v pravém dolním rohu" + } + } + }, + "noAppSelected": "Prosím vyberte aplikaci v nastavení widgetu", + "views": { + "workers": { + "table": { + "header": { + "name": "Soubor", + "eta": "Odhadovaný čas", + "progress": "Postup" + }, + "empty": "Prázdné", + "tooltip": { + "transcode": "Překódovat", + "healthCheck": "Kontrola stavu" + } + } + }, + "queue": { + "table": { + "header": { + "name": "Soubor", + "size": "Velikost" + }, + "footer": { + "currentIndex": "{{start}}-{{end}} z {{total}}" + }, + "empty": "Prázdné", + "tooltip": { + "transcode": "Překódovat", + "healthCheck": "Kontrola stavu" + } + } + }, + "statistics": { + "empty": "Prázdné", + "box": { + "transcodes": "Překódování: {{value}}", + "healthChecks": "Kontroly stavu: {{value}}", + "files": "Soubory: {{value}}", + "spaceSaved": "Uloženo: {{value}}" + }, + "pies": { + "transcodes": "Překódování", + "healthChecks": "Kontroly stavu", + "videoCodecs": "Kodeky", + "videoContainers": "Kontejnery", + "videoResolutions": "Rozlišení" + } + } + }, + "error": { + "title": "Chyba", + "message": "Při načítání dat z Tdarru došlo k chybě." + }, + "tabs": { + "workers": "Stroje", + "queue": "Fronta", + "statistics": "Statistiky" + }, + "healthCheckStatus": { + "title": "Kontrola stavu", + "queued": "Ve frontě", + "healthy": "V pořádku", + "unhealthy": "Nastal problém" + } +} diff --git a/public/locales/cs/modules/smart-home/entity-state.json b/public/locales/cs/modules/smart-home/entity-state.json index 72746d738..764edd299 100644 --- a/public/locales/cs/modules/smart-home/entity-state.json +++ b/public/locales/cs/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Zobrazovat čitelné jméno", - "info": "Zobrazovat přátelské jméno z Home Assistantu místo zobrazovaného jména" + "info": "Zobrazovat friendly jméno z Home Assistantu místo display jména." + }, + "genericToggle": { + "label": "Přepínač entity", + "info": "Provést obecnou Home Assistant akci přepnutí na entitě po kliknutí." } } } -} \ No newline at end of file +} + diff --git a/public/locales/cs/modules/torrents-status.json b/public/locales/cs/modules/torrents-status.json index 36dc4d95f..bdd8320a5 100644 --- a/public/locales/cs/modules/torrents-status.json +++ b/public/locales/cs/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Zobrazení filtrovaného poměru seznamu torrentů", "info": "Pokud je vypnuto, zobrazí se pouze obecný poměr. Obecný poměr bude stále používat štítky, pokud jsou nastaveny" + }, + "columnOrdering": { + "label": "Povolit změnu pořadí sloupců" + }, + "rowSorting": { + "label": "Povolit řazení řádků" + }, + "columns": { + "label": "Vyberte sloupce k zobrazení", + "data": { + "date": "Datum přidání", + "down": "Stahování", + "up": "Nahrávání", + "eta": "Odhadovaný čas", + "progress": "Postup" + } + }, + "nameColumnSize": { + "label": "Změna velikosti sloupce s názvem" } } }, @@ -84,10 +103,6 @@ "text": "Nelze komunikovat s Vašimi klienty Torrentu. Zkontrolujte prosím Vaši konfiguraci" } }, - "loading": { - "title": "Načítání", - "description": "Navazování spojení" - }, "popover": { "introductionPrefix": "Spravuje", "metrics": { diff --git a/public/locales/da/modules/health-monitoring.json b/public/locales/da/modules/health-monitoring.json index d4c524ffa..9e35bf02f 100644 --- a/public/locales/da/modules/health-monitoring.json +++ b/public/locales/da/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Systemsundhedsovervågning", - "description": "Oplysninger om din NAS", - "settings": { - "title": "Systemsundhedsovervågning", - "fahrenheit": { - "label": "Fahrenheit" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Systemsundhedsovervågning", + "description": "Viser oplysninger om dit/dine systems tilstand og status.", + "settings": { + "title": "Indstillinger for systemsundhedsovervågning", + "fahrenheit": { + "label": "CPU-temperatur i Fahrenheit" + }, + "cpu": { + "label": "Vis CPU-info", "load": "Load Gennemsnit", - "minute": "{{minute}} minutter" - }, - "memory": { - "label": "Hukommelse", - "totalMem": "Samlet hukommelse: {{total}}GB", - "available": "Tilgængelig: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "Filsystem", - "available": "Tilgængelig: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "Oppetid", - "updates": "Opdateringer", - "reboot": "Genstart" - }, - "errors": { - "general": { - "title": "Kan ikke finde din NAS", - "text": "Der opstod et problem med at oprette forbindelse til din NAS. Bekræft venligst din konfiguration/integration(er)." + "minute": "{{minute}} minutter", + "minutes": "{{minutes}} minutter" + }, + "memory": { + "label": "Vis hukommelsesoplysninger" + }, + "fileSystem": { + "label": "Vis information om filsystemet" + }, + "node": { + "label": "Filtrer efter nodenavn", + "info": "Indtast navnet på din Proxmox-node for kun at vise metrikker for den node. Som standard vises hele klyngen." + }, + "defaultViewState": { + "label": "Sektion åben som standard", + "data": { + "none": "Intet", + "node": "Noder", + "vm": "VM'er", + "lxc": "LXC'er", + "storage": "Lager" } + }, + "defaultTabState": { + "label": "Fanen åben som standard", + "info": "Fanen åben som standard. Bruges kun, når flere integrationer er tilgængelige.", + "data": { + "system": "System", + "cluster": "Klynge" + } + }, + "summary": { + "label": "Vis oversigtssektion" + }, + "showNode": { + "label": "Vis nodesektion" + }, + "showVM": { + "label": "Vis VM-sektion" + }, + "showLXCs": { + "label": "Vis LXC sektion" + }, + "showStorage": { + "label": "Vis lagerplads sektion" + }, + "sectionIndicatorColor": { + "label": "Krav om, at sektionsstatusindikator skal være 'OK'", + "info": "\"Alle\" kræver, at alle elementer er online, for at indikatoren er grøn. 'Any' kræver, at mindst ét element er online.", + "data": { + "any": "Enhver aktiv", + "all": "Alle aktive" + } + }, + "ignoreCert": { + "label": "Ignorer certifikatfejl", + "info": "Hvis den er aktiveret, vil widgetten ignorere certifikatfejl, når den tilgår Proxmox API. Dette kan være nyttigt, når du får adgang til Proxmox via HTTPS." + } } + }, + "cpu": { + "label": "CPU", + "load": "Load Gennemsnit", + "minute": "{{minute}} minutter" + }, + "memory": { + "label": "Hukommelse", + "totalMem": "Samlet hukommelse: {{total}}GB", + "available": "Tilgængelig: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Filsystem", + "available": "Tilgængelig: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Oppetid", + "uptimeFormat": "{{days}} dage, {{hours}} timer", + "updates": "Opdateringer tilgængelige", + "reboot": "Genstart" + }, + "errors": { + "general": { + "title": "Kan ikke finde dit/dine system(er).", + "text": "Der opstod et problem med at oprette forbindelse til dit system. Bekræft venligst din konfiguration/integration(er)." + } + }, + "headings": { + "system": "System", + "cluster": "Klynge" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Noder", + "vms": "VM'er", + "lxcs": "LXC'er", + "storage": "Lager" + } + }, + "table": { + "header": { + "name": "Navn", + "cpu": "CPU", + "ram": "RAM", + "node": "Node" + } + }, + "popover": { + "node": "Node", + "vmid": "VMID", + "details": "Detaljer", + "cores": "Kerner - {{maxCpu}}", + "memSize": "Hukommelse - {{maxMem}}", + "memRatio": "Hukommelse - {{usedMem}} / {{maxMem}}", + "diskSize": "Disk - {{maxDisk}}", + "diskRatio": "Disk - {{usedDisk}} / {{maxDisk}}", + "uptime": "Oppetid - {{uptime}}", + "plugin": "Plugin", + "ha": "HA Tilstand - {{haState}}", + "sharedStorage": "Delt Lager", + "localStorage": "Lokalt lager", + "na": "Ikke tilgængelig" + } + } } \ No newline at end of file diff --git a/public/locales/da/modules/media-transcoding.json b/public/locales/da/modules/media-transcoding.json new file mode 100644 index 000000000..be37ab7d6 --- /dev/null +++ b/public/locales/da/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Medietranskodning", + "description": "Viser information om medietranskoding", + "settings": { + "title": "Indstillinger for medietranskodning", + "appId": { + "label": "Vælg en app" + }, + "defaultView": { + "label": "Standardvisning", + "data": { + "workers": "Arbejdere", + "queue": "Kø", + "statistics": "Statistikker" + } + }, + "showHealthCheck": { + "label": "Vis indikator for sundhedstjek" + }, + "showHealthChecksInQueue": { + "label": "Vis sundhedstjek i kø" + }, + "queuePageSize": { + "label": "Kø: Elementer pr. side" + }, + "showAppIcon": { + "label": "Vis app-ikonet i nederste højre hjørne" + } + } + }, + "noAppSelected": "Vælg venligst en app i widgetindstillingerne", + "views": { + "workers": { + "table": { + "header": { + "name": "Fil", + "eta": "ETA", + "progress": "Fremskridt" + }, + "empty": "Tom", + "tooltip": { + "transcode": "Transkod", + "healthCheck": "Sundhedstjek" + } + } + }, + "queue": { + "table": { + "header": { + "name": "Fil", + "size": "Størrelse" + }, + "footer": { + "currentIndex": "{{start}}-{{end}} af {{total}}" + }, + "empty": "Tom", + "tooltip": { + "transcode": "Transkod", + "healthCheck": "Sundhedstjek" + } + } + }, + "statistics": { + "empty": "Tom", + "box": { + "transcodes": "Transkodninger: {{value}}", + "healthChecks": "Sundhedstjek: {{value}}", + "files": "Filer: {{value}}", + "spaceSaved": "Gemt: {{value}}" + }, + "pies": { + "transcodes": "Transkoder", + "healthChecks": "Sundhedstjek", + "videoCodecs": "Kodeks", + "videoContainers": "Containere", + "videoResolutions": "Opløsninger" + } + } + }, + "error": { + "title": "Fejl", + "message": "Der opstod en fejl under hentning af data fra Tdarr." + }, + "tabs": { + "workers": "Arbejdere", + "queue": "Kø", + "statistics": "Statistikker" + }, + "healthCheckStatus": { + "title": "Sundhedstjek", + "queued": "I kø", + "healthy": "Sund", + "unhealthy": "Usund" + } +} diff --git a/public/locales/da/modules/smart-home/entity-state.json b/public/locales/da/modules/smart-home/entity-state.json index 70a3e8531..f4eca13ef 100644 --- a/public/locales/da/modules/smart-home/entity-state.json +++ b/public/locales/da/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Vis brugervenligt navn", - "info": "Vis brugervenligt navn fra Home Assistant i stedet for visningsnavn" + "info": "Vis brugervenligt navn fra Home Assistant i stedet for visningsnavn." + }, + "genericToggle": { + "label": "Entitetsskift", + "info": "Udfør en generisk Home Assistant-skiftehandling på entitet, når der klikkes på den." } } } -} \ No newline at end of file +} + diff --git a/public/locales/da/modules/torrents-status.json b/public/locales/da/modules/torrents-status.json index 0e00e3bbd..ef49ae795 100644 --- a/public/locales/da/modules/torrents-status.json +++ b/public/locales/da/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Vis filtrerede torrents liste ratio", "info": "Hvis deaktiveret, vil kun den globale ratio blive vist. Den globale ratio vil stadig bruge etiketter hvis sat" + }, + "columnOrdering": { + "label": "Aktiver reorganisering af kolonnerne" + }, + "rowSorting": { + "label": "Aktiver sortering af rækker" + }, + "columns": { + "label": "Vælg kolonner, der skal vises", + "data": { + "date": "Dato tilføjet", + "down": "Down", + "up": "Up", + "eta": "ETA", + "progress": "Fremskridt" + } + }, + "nameColumnSize": { + "label": "Skift størrelsen på navnekolonnen" } } }, @@ -84,10 +103,6 @@ "text": "Kan ikke kommunikere med dine Torrent-klienter. Tjek venligst din konfiguration" } }, - "loading": { - "title": "Indlæser", - "description": "Etablerer en forbindelse" - }, "popover": { "introductionPrefix": "Administreret af", "metrics": { diff --git a/public/locales/de/modules/health-monitoring.json b/public/locales/de/modules/health-monitoring.json index 3b105dde3..22246ac92 100644 --- a/public/locales/de/modules/health-monitoring.json +++ b/public/locales/de/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Überwachung des Systemzustands", - "description": "Informationen zu Ihrem NAS", - "settings": { - "title": "Überwachung des Systemzustands", - "fahrenheit": { - "label": "Fahrenheit" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Überwachung des Systemzustands", + "description": "Zeigt Informationen zum Zustand und Status Ihres/Ihrer Systeme(s) an.", + "settings": { + "title": "Einstellungen für die Überwachung des Systemzustands", + "fahrenheit": { + "label": "CPU-Temperatur in Fahrenheit" + }, + "cpu": { + "label": "CPU-Info anzeigen", "load": "Durchschnittliche Last", - "minute": "{{minute}} Minuten" - }, - "memory": { - "label": "Arbeitsspeicher", - "totalMem": "Gesamtspeicher: {{total}} GB", - "available": "Verfügbar: {{available}} GB - {{percentage}}%" - }, - "fileSystem": { - "label": "Dateisystem", - "available": "Verfügbar: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "Betriebszeit", - "updates": "Aktualisierungen", - "reboot": "Neustart" - }, - "errors": { - "general": { - "title": "Ihr NAS konnte nicht gefunden werden", - "text": "Es gab ein Problem bei der Verbindung zu Ihrem NAS. Bitte überprüfen Sie Ihre Konfiguration/Integration(en)." + "minute": "{{minute}} Minuten", + "minutes": "{{minutes}} Minuten" + }, + "memory": { + "label": "Speicher-Info anzeigen" + }, + "fileSystem": { + "label": "Dateisystem Info anzeigen" + }, + "node": { + "label": "Nach Knotennamen filtern", + "info": "Geben Sie den Namen Ihres Proxmox-Knotens ein, um nur Metriken für diesen Knoten anzuzeigen. Standardmäßig wird der gesamte Cluster angezeigt." + }, + "defaultViewState": { + "label": "Abschnitt standardmäßig geöffnet", + "data": { + "none": "Keine", + "node": "Knoten", + "vm": "VMs", + "lxc": "LXCs", + "storage": "Speicher" } + }, + "defaultTabState": { + "label": "Tab standardmäßig geöffnet", + "info": "Tab standardmäßig geöffnet. Wird nur verwendet, wenn mehrere Integrationen verfügbar sind.", + "data": { + "system": "System", + "cluster": "Cluster" + } + }, + "summary": { + "label": "Abschnitt Zusammenfassung anzeigen" + }, + "showNode": { + "label": "Abschnitt Knoten anzeigen" + }, + "showVM": { + "label": "Abschnitt VMs anzeigen" + }, + "showLXCs": { + "label": "Abschnitt LXCs anzeigen" + }, + "showStorage": { + "label": "Abschnitt Speicherbereich anzeigen" + }, + "sectionIndicatorColor": { + "label": "Voraussetzung dafür, dass die Abschnittsstatusanzeige „OK“ ist", + "info": "Bei „Alle“ müssen alle Elemente online sein, damit die Anzeige grün ist. Für „Mindestens“ muss mindestens ein Artikel online sein.", + "data": { + "any": "Mindestens aktiv", + "all": "Alle aktiv" + } + }, + "ignoreCert": { + "label": "Zertifikatfehler ignorieren", + "info": "Wenn aktiviert, ignoriert das Widget Zertifikatsfehler beim Zugriff auf die Proxmox-API. Dies kann hilfreich sein, wenn Sie über HTTPS auf Proxmox zugreifen." + } } + }, + "cpu": { + "label": "CPU", + "load": "Durchschnittliche Last", + "minute": "{{minute}} Minuten" + }, + "memory": { + "label": "Arbeitsspeicher", + "totalMem": "Gesamtspeicher: {{total}} GB", + "available": "Verfügbar: {{available}} GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Dateisystem", + "available": "Verfügbar: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Betriebszeit", + "uptimeFormat": "{{days}} Tage, {{hours}} Stunden", + "updates": "Updates verfügbar", + "reboot": "Neustart" + }, + "errors": { + "general": { + "title": "Ihr(e) System(e) konnte nicht gefunden werden.", + "text": "Beim Herstellen der Verbindung zu Ihrem System ist ein Problem aufgetreten. Bitte überprüfen Sie Ihre Konfiguration/Integration(en)." + } + }, + "headings": { + "system": "System", + "cluster": "Cluster" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Knoten", + "vms": "VMs", + "lxcs": "LXCs", + "storage": "Speicher" + } + }, + "table": { + "header": { + "name": "Name", + "cpu": "CPU", + "ram": "RAM", + "node": "Knoten" + } + }, + "popover": { + "node": "Knoten", + "vmid": "VMID", + "details": "Details", + "cores": "Kerne – {{maxCpu}}", + "memSize": "Speicher – {{maxMem}}", + "memRatio": "Speicher - {{usedMem}} / {{maxMem}}", + "diskSize": "Festplatte – {{maxDisk}}", + "diskRatio": "Festplatte - {{usedDisk}} / {{maxDisk}}", + "uptime": "Betriebszeit – {{uptime}}", + "plugin": "Erweiterung", + "ha": "HA Status - {{haState}}", + "sharedStorage": "Geteilter Speicher", + "localStorage": "Lokaler Speicher", + "na": "nicht verfügbar" + } + } } \ No newline at end of file diff --git a/public/locales/de/modules/media-transcoding.json b/public/locales/de/modules/media-transcoding.json new file mode 100644 index 000000000..74dab712f --- /dev/null +++ b/public/locales/de/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Medientranskodierung", + "description": "Zeigt Informationen zur Medientranskodierung an", + "settings": { + "title": "Einstellungen für Medientranskodierung", + "appId": { + "label": "Wähle eine App" + }, + "defaultView": { + "label": "Standardansicht", + "data": { + "workers": "Workers", + "queue": "Warteschlange", + "statistics": "Statistiken" + } + }, + "showHealthCheck": { + "label": "Indikator für Gesundheitscheck anzeigen" + }, + "showHealthChecksInQueue": { + "label": "Gesundheitschecks in Warteschlange anzeigen" + }, + "queuePageSize": { + "label": "Warteschlange: Elemente pro Seite" + }, + "showAppIcon": { + "label": "App-Symbol in der unteren rechten Ecke anzeigen" + } + } + }, + "noAppSelected": "Bitte wählen Sie eine App in den Widget Einstellungen", + "views": { + "workers": { + "table": { + "header": { + "name": "Datei", + "eta": "Voraussichtlicher Abschluss", + "progress": "Fortschritt" + }, + "empty": "Leer", + "tooltip": { + "transcode": "Transkodieren", + "healthCheck": "Gesundheitscheck" + } + } + }, + "queue": { + "table": { + "header": { + "name": "Datei", + "size": "Größe" + }, + "footer": { + "currentIndex": "{{start}} - {{end}} von {{total}}" + }, + "empty": "Leer", + "tooltip": { + "transcode": "Transkodieren", + "healthCheck": "Gesundheitscheck" + } + } + }, + "statistics": { + "empty": "Leer", + "box": { + "transcodes": "Transkodierung: {{value}}", + "healthChecks": "Gesundheitscheck: {{value}}", + "files": "Dateien: {{value}}", + "spaceSaved": "Gespeichert: {{value}}" + }, + "pies": { + "transcodes": "Transkodieren", + "healthChecks": "Gesundheitscheck", + "videoCodecs": "Codecs", + "videoContainers": "Container", + "videoResolutions": "Auflösungen" + } + } + }, + "error": { + "title": "Fehler", + "message": "Beim Laden der Daten von Tdarr ist ein Fehler aufgetreten." + }, + "tabs": { + "workers": "Workers", + "queue": "Warteschlange", + "statistics": "Statistiken" + }, + "healthCheckStatus": { + "title": "Gesundheitscheck", + "queued": "In der Warteschlange", + "healthy": "Gesund", + "unhealthy": "Fehlerhaft" + } +} diff --git a/public/locales/de/modules/smart-home/entity-state.json b/public/locales/de/modules/smart-home/entity-state.json index f6aec7202..501cedf5d 100644 --- a/public/locales/de/modules/smart-home/entity-state.json +++ b/public/locales/de/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Benutzerdefinierten Namen anzeigen", - "info": "Zeige Zeige Benutzerdefinierten Namen statt Anzeigename vom Home-Assistenten an" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/de/modules/torrents-status.json b/public/locales/de/modules/torrents-status.json index 9effe7066..9fc513a5a 100644 --- a/public/locales/de/modules/torrents-status.json +++ b/public/locales/de/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Verhältnis der gefilterten Torrents-Liste anzeigen", "info": "Ist diese Option deaktiviert, wird nur das globale Verhältnis angezeigt. Für das globale Verhältnis werden weiterhin die Beschriftungen verwendet, wenn diese eingestellt sind" + }, + "columnOrdering": { + "label": "Sortierung der Zeilen einschalten" + }, + "rowSorting": { + "label": "Sortierung der Reihen einschalten" + }, + "columns": { + "label": "Spalten zur Anzeige auswählen", + "data": { + "date": "Hinzugefügt am", + "down": "Down", + "up": "Up", + "eta": "Voraussichtlicher Abschluss", + "progress": "Fortschritt" + } + }, + "nameColumnSize": { + "label": "Ändern Sie die Größe der Namensspalte" } } }, @@ -84,10 +103,6 @@ "text": "Homarr konnte nicht mit Ihren Torrent Clients kommunizieren. Bitte überprüfen Sie Ihre Konfiguration" } }, - "loading": { - "title": "Wird geladen...", - "description": "Herstellen der Verbindung" - }, "popover": { "introductionPrefix": "Verwaltet von", "metrics": { diff --git a/public/locales/el/modules/health-monitoring.json b/public/locales/el/modules/health-monitoring.json index 686a5cf08..5f256c95e 100644 --- a/public/locales/el/modules/health-monitoring.json +++ b/public/locales/el/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Παρακολούθηση της υγείας του συστήματος", - "description": "Πληροφορίες για το NAS σας", - "settings": { - "title": "Παρακολούθηση της υγείας του συστήματος", - "fahrenheit": { - "label": "Φαρενάιτ (°F)" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Παρακολούθηση της υγείας του συστήματος", + "description": "Εμφανίζει πληροφορίες που δείχνουν την κατάσταση και την υγεία του/ων συστήματος/ων σας.", + "settings": { + "title": "Ρυθμίσεις για την παρακολούθηση της υγείας του συστήματος", + "fahrenheit": { + "label": "Θερμοκρασία CPU σε Φαρενάιτ" + }, + "cpu": { + "label": "Εμφάνιση πληροφοριών επεξεργαστή", "load": "Μέσος Όρος Φόρτου", - "minute": "{{minute}} λεπτό" - }, - "memory": { - "label": "Μνήμη", - "totalMem": "Συνολική μνήμη: {{total}}GB", - "available": "Διαθέσιμα: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "Σύστημα Αρχείων", - "available": "Διαθέσιμα: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "Χρόνος Λειτουργίας", - "updates": "Ενημερώσεις", - "reboot": "Επανεκκίνηση" - }, - "errors": { - "general": { - "title": "Δεν είναι δυνατή η εύρεση του NAS σας", - "text": "Υπήρξε πρόβλημα σύνδεσης με το NAS σας. Παρακαλούμε επαληθεύστε τις ρυθμίσεις/ενσωμάτωση(ες) σας." + "minute": "{{minute}} λεπτό", + "minutes": "{{minutes}} λεπτά" + }, + "memory": { + "label": "Εμφάνιση Πληροφοριών Μνήμης" + }, + "fileSystem": { + "label": "Εμφάνιση Πληροφοριών Συστήματος Αρχείων" + }, + "node": { + "label": "Φίλτρο με βάση το όνομα του κόμβου", + "info": "Πληκτρολογήστε το όνομα του κόμβου Proxmox για να εμφανίζονται μόνο οι μετρήσεις για αυτόν τον κόμβο. Από προεπιλογή, εμφανίζεται ολόκληρη η συστάδα." + }, + "defaultViewState": { + "label": "Τμήμα ανοιχτό από προεπιλογή", + "data": { + "none": "Κανένα", + "node": "Κόμβοι", + "vm": "VMs", + "lxc": "LXCs", + "storage": "Αποθηκευτικός χώρος" } + }, + "defaultTabState": { + "label": "Ανοιχτή καρτέλα από προεπιλογή", + "info": "Ανοιχτή καρτέλα από προεπιλογή. Χρησιμοποιείται μόνο όταν είναι διαθέσιμες πολλαπλές ενσωματώσεις.", + "data": { + "system": "Σύστημα", + "cluster": "Συστάδα" + } + }, + "summary": { + "label": "Εμφάνιση ενότητας σύνοψης" + }, + "showNode": { + "label": "Εμφάνιση τμήματος κόμβων" + }, + "showVM": { + "label": "Εμφάνιση ενότητας VMs" + }, + "showLXCs": { + "label": "Εμφάνιση ενότητας LXC" + }, + "showStorage": { + "label": "Εμφάνιση ενότητας αποθήκευσης" + }, + "sectionIndicatorColor": { + "label": "Απαίτηση για την ένδειξη κατάστασης του τμήματος να είναι 'OK'", + "info": "Η επιλογή \"Όλα\" απαιτεί να είναι όλα τα στοιχεία σε λειτουργία για να είναι ο δείκτης πράσινος. Το \"Οποιοδήποτε\" απαιτεί τουλάχιστον ένα στοιχείο να είναι σε λειτουργία.", + "data": { + "any": "Οποιοδήποτε ενεργό", + "all": "Όλα Ενεργά" + } + }, + "ignoreCert": { + "label": "Παράβλεψη Σφαλμάτων Πιστοποιητικού", + "info": "Εάν είναι ενεργοποιημένο, το widget θα αγνοεί τα σφάλματα πιστοποιητικών κατά την πρόσβαση στο API του Proxmox. Αυτό μπορεί να είναι χρήσιμο κατά την πρόσβαση στο Proxmox μέσω HTTPS." + } } + }, + "cpu": { + "label": "CPU", + "load": "Μέσος Όρος Φόρτου", + "minute": "{{minute}} λεπτό" + }, + "memory": { + "label": "Μνήμη", + "totalMem": "Συνολική μνήμη: {{total}}GB", + "available": "Διαθέσιμα: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Σύστημα Αρχείων", + "available": "Διαθέσιμα: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Χρόνος Λειτουργίας", + "uptimeFormat": "{{days}} ημέρες, {{hours}} ώρες", + "updates": "Διαθέσιμες ενημερώσεις", + "reboot": "Επανεκκίνηση" + }, + "errors": { + "general": { + "title": "Δεν είναι δυνατή η εύρεση του συστήματός σας.", + "text": "Υπήρξε πρόβλημα σύνδεσης με το σύστημά σας. Παρακαλούμε επαληθεύστε τις ρυθμίσεις/ενσωμάτωση(ες) σας." + } + }, + "headings": { + "system": "Σύστημα", + "cluster": "Συστάδα" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Κόμβοι", + "vms": "VMs", + "lxcs": "LXCs", + "storage": "Αποθηκευτικός χώρος" + } + }, + "table": { + "header": { + "name": "Όνομα", + "cpu": "CPU", + "ram": "RAM", + "node": "Κόμβος" + } + }, + "popover": { + "node": "Κόμβος", + "vmid": "VMID", + "details": "Λεπτομέρειες", + "cores": "Πυρήνες - {{maxCpu}}", + "memSize": "Μνήμη - {{maxMem}}", + "memRatio": "Μνήμη - {{usedMem}} / {{maxMem}}", + "diskSize": "Δίσκος - {{maxDisk}}", + "diskRatio": "Δίσκος - {{usedDisk}} / {{maxDisk}}", + "uptime": "Χρόνος λειτουργίας - {{uptime}}", + "plugin": "Πρόσθετα", + "ha": "Κατάσταση HA - {{haState}}", + "sharedStorage": "Κοινόχρηστος αποθηκευτικός χώρος", + "localStorage": "Τοπικός Αποθηκευτικός Χώρος", + "na": "Μη διαθέσιμο" + } + } } \ No newline at end of file diff --git a/public/locales/el/modules/media-transcoding.json b/public/locales/el/modules/media-transcoding.json new file mode 100644 index 000000000..05f920472 --- /dev/null +++ b/public/locales/el/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Μετακωδικοποίηση πολυμέσων", + "description": "Εμφανίζει πληροφορίες σχετικά με τη μετακωδικοποίηση πολυμέσων", + "settings": { + "title": "Ρυθμίσεις μετακωδικοποίησης πολυμέσων", + "appId": { + "label": "Επιλέξτε μια εφαρμογή" + }, + "defaultView": { + "label": "Προεπιλεγμένη προβολή", + "data": { + "workers": "Εργάτες", + "queue": "Ουρά", + "statistics": "Στατιστικά" + } + }, + "showHealthCheck": { + "label": "Εμφάνιση δείκτη ελέγχου υγείας" + }, + "showHealthChecksInQueue": { + "label": "Εμφάνιση ελέγχων υγείας στην ουρά" + }, + "queuePageSize": { + "label": "Ουρά: Στοιχεία ανά σελίδα" + }, + "showAppIcon": { + "label": "Εμφάνιση εικονιδίου εφαρμογής στην κάτω δεξιά γωνία" + } + } + }, + "noAppSelected": "Παρακαλούμε επιλέξτε μια εφαρμογή στις ρυθμίσεις του widget", + "views": { + "workers": { + "table": { + "header": { + "name": "Αρχείο", + "eta": "Εκτιμώμενος χρόνος αναμονής", + "progress": "Πρόοδος" + }, + "empty": "Άδειο", + "tooltip": { + "transcode": "Μετακωδικοποίηση", + "healthCheck": "Έλεγχος υγείας" + } + } + }, + "queue": { + "table": { + "header": { + "name": "Αρχείο", + "size": "Μέγεθος" + }, + "footer": { + "currentIndex": "{{start}}-{{end}} από {{total}}" + }, + "empty": "Άδειο", + "tooltip": { + "transcode": "Μετακωδικοποίηση", + "healthCheck": "Έλεγχος υγείας" + } + } + }, + "statistics": { + "empty": "Άδειο", + "box": { + "transcodes": "Κωδικοποιήσεις: {{value}}", + "healthChecks": "Έλεγχοι υγείας: {{value}}", + "files": "Αρχεία: {{value}}", + "spaceSaved": "Αποθηκεύτηκαν: {{value}}" + }, + "pies": { + "transcodes": "Μετακωδικοποιήσεις", + "healthChecks": "Έλεγχοι υγείας", + "videoCodecs": "Κωδικοποιητές", + "videoContainers": "Containers", + "videoResolutions": "Αναλύσεις" + } + } + }, + "error": { + "title": "Σφάλμα", + "message": "Παρουσιάστηκε σφάλμα κατά την ανάκτηση δεδομένων από το Tdarr." + }, + "tabs": { + "workers": "Εργάτες", + "queue": "Ουρά", + "statistics": "Στατιστικά" + }, + "healthCheckStatus": { + "title": "Έλεγχος υγείας", + "queued": "Στην ουρά", + "healthy": "Υγιές", + "unhealthy": "Μη υγιές" + } +} diff --git a/public/locales/el/modules/smart-home/entity-state.json b/public/locales/el/modules/smart-home/entity-state.json index cf850c734..6b33912c0 100644 --- a/public/locales/el/modules/smart-home/entity-state.json +++ b/public/locales/el/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Εμφάνιση φιλικού ονόματος", - "info": "Εμφάνιση φιλικού ονόματος από το Home Assistant αντί για το εμφανιζόμενο όνομα" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/el/modules/torrents-status.json b/public/locales/el/modules/torrents-status.json index 2436f3a9a..86903964c 100644 --- a/public/locales/el/modules/torrents-status.json +++ b/public/locales/el/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Εμφάνιση φιλτραρισμένης αναλογίας λίστας torrents", "info": "Εάν απενεργοποιηθεί, θα εμφανιστεί μόνο η συνολική αναλογία. Η συνολική αναλογία θα εξακολουθεί να χρησιμοποιεί τις ετικέτες αν έχει οριστεί" + }, + "columnOrdering": { + "label": "Ενεργοποίηση της αναδιάταξης των στηλών" + }, + "rowSorting": { + "label": "Ενεργοποίηση της ταξινόμησης των γραμμών" + }, + "columns": { + "label": "Επιλογή στηλών για εμφάνιση", + "data": { + "date": "Ημερομηνία Προσθήκης", + "down": "Κάτω", + "up": "Πάνω", + "eta": "Εκτιμώμενος χρόνος αναμονής", + "progress": "Πρόοδος" + } + }, + "nameColumnSize": { + "label": "Αλλαγή του μεγέθους της στήλης ονόματος" } } }, @@ -84,10 +103,6 @@ "text": "Αδυναμία επικοινωνίας με το πρόγραμμα Torrent σας. Ελέγξτε τη διαμόρφωσή σας" } }, - "loading": { - "title": "Φόρτωση", - "description": "Δημιουργία σύνδεσης" - }, "popover": { "introductionPrefix": "Διαχειριζόμενα από", "metrics": { diff --git a/public/locales/en/layout/modals/add-app.json b/public/locales/en/layout/modals/add-app.json index ce8d7f37c..149519b93 100644 --- a/public/locales/en/layout/modals/add-app.json +++ b/public/locales/en/layout/modals/add-app.json @@ -31,7 +31,8 @@ }, "externalAddress": { "label": "External address", - "description": "URL that will be opened when clicking on the app." + "description": "URL that will be opened when clicking on the app.", + "tooltip": "You can use a few variables to create dynamic addresses:

[homarr_base] : full address excluding port and path. (Example: 'https://subdomain.homarr.dev')
[homarr_hostname] : full base url including it's current subdomain. (Example: 'subdomain.homarr.dev')
[homarr_domain] : domain with subdomain filtered out. (Example: `homarr.dev')
[homarr_protocol] : http/https

These variables all depend on the current url." } }, "behaviour": { @@ -39,7 +40,7 @@ "label": "Open in new tab", "description": "Open the app in a new tab instead of the current one." }, - "tooltipDescription":{ + "tooltipDescription": { "label": "Application Description", "description": "The text you enter will appear when hovering over your app.\r\nUse this to give users more details about your app or leave empty to have nothing." }, @@ -68,32 +69,32 @@ "text": "This may take a few seconds" } }, - "appNameFontSize":{ - "label":"App Name Font Size", - "description":"Set the font size for when the app name is shown on the tile." + "appNameFontSize": { + "label": "App Name Font Size", + "description": "Set the font size for when the app name is shown on the tile." }, - "appNameStatus":{ - "label":"App Name Status", - "description":"Choose where you want the title to show up, if at all.", + "appNameStatus": { + "label": "App Name Status", + "description": "Choose where you want the title to show up, if at all.", "dropdown": { - "normal":"Show title on tile only", - "hover":"Show title on tooltip hover only", - "hidden":"Don't show at all" + "normal": "Show title on tile only", + "hover": "Show title on tooltip hover only", + "hidden": "Don't show at all" } }, - "positionAppName":{ - "label":"App Name Position", - "description":"Position of the app's name relative to the icon.", + "positionAppName": { + "label": "App Name Position", + "description": "Position of the app's name relative to the icon.", "dropdown": { - "top":"Top", - "right":"Right", - "bottom":"Bottom", - "left":"Left" + "top": "Top", + "right": "Right", + "bottom": "Bottom", + "left": "Left" } }, - "lineClampAppName":{ - "label":"App Name Line Clamp", - "description":"Defines on how many lines your title should fit at it's maximum. Set 0 for unlimited." + "lineClampAppName": { + "label": "App Name Line Clamp", + "description": "Defines on how many lines your title should fit at it's maximum. Set 0 for unlimited." } }, "integration": { diff --git a/public/locales/en/modules/health-monitoring.json b/public/locales/en/modules/health-monitoring.json index 8642591e6..be6e085e4 100644 --- a/public/locales/en/modules/health-monitoring.json +++ b/public/locales/en/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "System Health Monitoring", - "description": "Information about your NAS", - "settings": { - "title": "System Health Monitoring", - "fahrenheit": { - "label": "Fahrenheit" - } - } - }, + "descriptor": { + "name": "System Health Monitoring", + "description": "Displays information showing the health and status of your system(s).", + "settings": { + "title": "Settings for system health monitoring", + "fahrenheit": { + "label": "CPU Temp in Fahrenheit" + }, "cpu": { - "label": "CPU", + "label": "Show CPU Info", "load": "Load Average", - "minute": "{{minute}} minute" + "minute": "{{minute}} minute", + "minutes": "{{minutes}} minutes" }, "memory": { - "label": "Memory", - "totalMem": "Total memory: {{total}}GB", - "available": "Available: {{available}}GB - {{percentage}}%" + "label": "Show Memory Info" }, "fileSystem": { - "label": "File System", - "available": "Available: {{available}} - {{percentage}}%" + "label": "Show Filesystem Info" }, - "info": { - "uptime": "Uptime", - "updates": "Updates", - "reboot": "Reboot" + "node": { + "label": "Filter by node name", + "info": "Enter your Proxmox node name to only show metrics for that node. By default, the entire cluster is shown." }, - "errors": { - "general": { - "title": "Unable to find your NAS", - "text": "There was a problem connecting to your NAS. Please verify your configuration/integration(s)." + "defaultViewState": { + "label": "Section open by default", + "data": { + "none": "None", + "node": "Nodes", + "vm": "VMs", + "lxc": "LXCs", + "storage": "Storage" } + }, + "defaultTabState": { + "label": "Tab open by default", + "info": "Tab open by default. Only used when multiple integrations are available.", + "data": { + "system": "System", + "cluster": "Cluster" + } + }, + "summary": { + "label": "Show summary section" + }, + "showNode": { + "label": "Show nodes section" + }, + "showVM": { + "label": "Show VMs section" + }, + "showLXCs": { + "label": "Show LXCs section" + }, + "showStorage": { + "label": "Show storage section" + }, + "sectionIndicatorColor": { + "label": "Requirement for section status indicator to be 'OK'", + "info": "'All' requires that all items be online for the indicator to be green. 'Any' requires at least one item to be online.", + "data": { + "any": "Any Active", + "all": "All Active" + } + }, + "ignoreCert": { + "label": "Ignore Certificate Errors", + "info": "If enabled, the widget will ignore certificate errors when accessing the Proxmox API. This can be helpful when accessing Proxmox through HTTPS." } - } \ No newline at end of file + } + }, + "cpu": { + "label": "CPU", + "load": "Load Average", + "minute": "{{minute}} minute" + }, + "memory": { + "label": "Memory", + "totalMem": "Total memory: {{total}}GB", + "available": "Available: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "File System", + "available": "Available: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Uptime", + "uptimeFormat": "{{days}} days, {{hours}} hours", + "updates": "Updates Available", + "reboot": "Reboot" + }, + "errors": { + "general": { + "title": "Unable to find your system(s).", + "text": "There was a problem connecting to your system. Please verify your configuration/integration(s)." + } + }, + "headings": { + "system": "System", + "cluster": "Cluster" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Nodes", + "vms": "VMs", + "lxcs": "LXCs", + "storage": "Storage" + } + }, + "table": { + "header": { + "name": "Name", + "cpu": "CPU", + "ram": "RAM", + "node": "Node" + } + }, + "popover": { + "node": "Node", + "vmid": "VMID", + "details": "Details", + "cores": "Cores - {{maxCpu}}", + "memSize": "Memory - {{maxMem}}", + "memRatio": "Memory - {{usedMem}} / {{maxMem}}", + "diskSize": "Disk - {{maxDisk}}", + "diskRatio": "Disk - {{usedDisk}} / {{maxDisk}}", + "uptime": "Uptime - {{uptime}}", + "plugin": "Plugin", + "ha": "HA State - {{haState}}", + "sharedStorage": "Shared Storage", + "localStorage": "Local Storage", + "na": "N/A" + } + } +} \ No newline at end of file diff --git a/public/locales/en/modules/media-transcoding.json b/public/locales/en/modules/media-transcoding.json new file mode 100644 index 000000000..d391c54bf --- /dev/null +++ b/public/locales/en/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Media Transcoding", + "description": "Displays information about media transcoding", + "settings": { + "title": "Media Transcoding Settings", + "appId": { + "label": "Select an app" + }, + "defaultView": { + "label": "Default view", + "data": { + "workers": "Workers", + "queue": "Queue", + "statistics": "Statistics" + } + }, + "showHealthCheck": { + "label": "Show Health Check indicator" + }, + "showHealthChecksInQueue": { + "label": "Show Health Checks in queue" + }, + "queuePageSize": { + "label": "Queue: Items per page" + }, + "showAppIcon": { + "label": "Show app icon in the bottom right corner" + } + } + }, + "noAppSelected": "Please select an app in the widget settings", + "views": { + "workers": { + "table": { + "header": { + "name": "File", + "eta": "ETA", + "progress": "Progress" + }, + "empty": "Empty", + "tooltip": { + "transcode": "Transcode", + "healthCheck": "Health Check" + } + } + }, + "queue": { + "table": { + "header": { + "name": "File", + "size": "Size" + }, + "footer": { + "currentIndex": "{{start}}-{{end}} of {{total}}" + }, + "empty": "Empty", + "tooltip": { + "transcode": "Transcode", + "healthCheck": "Health Check" + } + } + }, + "statistics": { + "empty": "Empty", + "box": { + "transcodes": "Transcodes: {{value}}", + "healthChecks": "Health Checks: {{value}}", + "files": "Files: {{value}}", + "spaceSaved": "Saved: {{value}}" + }, + "pies": { + "transcodes": "Transcodes", + "healthChecks": "Health Checks", + "videoCodecs": "Codecs", + "videoContainers": "Containers", + "videoResolutions": "Resolutions" + } + } + }, + "error": { + "title": "Error", + "message": "An error occurred while fetching data from Tdarr." + }, + "tabs": { + "workers": "Workers", + "queue": "Queue", + "statistics": "Statistics" + }, + "healthCheckStatus": { + "title": "Health Check", + "queued": "Queued", + "healthy": "Healthy", + "unhealthy": "Unhealthy" + } +} diff --git a/public/locales/en/modules/smart-home/entity-state.json b/public/locales/en/modules/smart-home/entity-state.json index f7eacbbb2..99048e629 100644 --- a/public/locales/en/modules/smart-home/entity-state.json +++ b/public/locales/en/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Display friendly name", - "info": "Display friendly name from Home Assistant instead instead of display name" + "info": "Display friendly name from Home Assistant instead instead of display name." + }, + "genericToggle": { + "label": "Entity toggle", + "info": "Perform a generic Home Assistant toggle action on entity when clicked." } } } -} \ No newline at end of file +} + diff --git a/public/locales/en/modules/torrents-status.json b/public/locales/en/modules/torrents-status.json index 594b34e00..cb9ce1876 100644 --- a/public/locales/en/modules/torrents-status.json +++ b/public/locales/en/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Display filtered torrents list ratio", "info": "If disabled, only the global ratio will be display. The global ratio will still use the labels if set" + }, + "columnOrdering":{ + "label": "Enable reordering the columns" + }, + "rowSorting":{ + "label": "Enable sorting the rows" + }, + "columns": { + "label": "Select columns to display", + "data": { + "date": "Date Added", + "down": "Down", + "up": "Up", + "eta": "ETA", + "progress": "Progress" + } + }, + "nameColumnSize": { + "label": "Change the name column size" } } }, @@ -84,10 +103,6 @@ "text": "Unable to communicate with your Torrent clients. Please check your configuration" } }, - "loading": { - "title": "Loading", - "description": "Establishing a connection" - }, "popover": { "introductionPrefix": "Managed by", "metrics": { diff --git a/public/locales/es/authentication/login.json b/public/locales/es/authentication/login.json index 4991a1a9f..a5be45714 100644 --- a/public/locales/es/authentication/login.json +++ b/public/locales/es/authentication/login.json @@ -16,8 +16,8 @@ }, "afterLoginRedirection": "Después de iniciar sesión, serás redirigido a {{url}}", "providersEmpty": { - "title": "", - "message": "" + "title": "Error del proveedor de autenticación", + "message": "Los proveedor(es) no están configurados; consulte sus registros para obtener más información." } }, "alert": "Tus credenciales son incorrectas o esta cuenta no existe. Por favor, inténtalo de nuevo." diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 251b317c7..7f9cf06a6 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -13,7 +13,7 @@ "previous": "Anterior", "confirm": "Confirmar", "enabled": "Activado", - "duplicate": "", + "duplicate": "Duplicar", "disabled": "Desactivado", "enableAll": "Activar todo", "disableAll": "Desactivar todo", diff --git a/public/locales/es/layout/manage.json b/public/locales/es/layout/manage.json index e1f7b635b..cd556ada2 100644 --- a/public/locales/es/layout/manage.json +++ b/public/locales/es/layout/manage.json @@ -26,7 +26,7 @@ "title": "Herramientas", "items": { "docker": "Docker", - "api": "" + "api": "API" } }, "about": { diff --git a/public/locales/es/manage/boards.json b/public/locales/es/manage/boards.json index 96bf5ea70..91fa9b956 100644 --- a/public/locales/es/manage/boards.json +++ b/public/locales/es/manage/boards.json @@ -16,15 +16,15 @@ "label": "Eliminar permanentemente", "disabled": "Eliminación deshabilitada, porque los componentes más antiguos de Homarr no permiten la eliminación de la configuración predeterminada. La eliminación será posible en el futuro." }, - "duplicate": "", + "duplicate": "Duplicar", "rename": { - "label": "", + "label": "Renombrar", "modal": { - "title": "", + "title": "Renombrar tablero {{name}}", "fields": { "name": { - "label": "", - "placeholder": "" + "label": "Nuevo nombre", + "placeholder": "Nuevo nombre del tablero" } } } diff --git a/public/locales/es/modules/health-monitoring.json b/public/locales/es/modules/health-monitoring.json index dd45386b4..0800c43a7 100644 --- a/public/locales/es/modules/health-monitoring.json +++ b/public/locales/es/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Monitorización de Salud del Sistema", + "description": "Muestra información sobre la salud y el estado de tu(s) sistema(s).", + "settings": { + "title": "Configuración del sistema de control de salud", + "fahrenheit": { + "label": "Temperatura de la CPU en grados Fahrenheit" + }, + "cpu": { + "label": "Mostrar información de la CPU", "load": "", - "minute": "" - }, - "memory": { - "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { - "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "minute": "", + "minutes": "{{minutes}} Minutos" + }, + "memory": { + "label": "Mostrar información de la memoria" + }, + "fileSystem": { + "label": "Mostrar información del sistema de archivos" + }, + "node": { + "label": "Filtrar por nombre de nodo", + "info": "Ingrese el nombre de su nodo Proxmox para mostrar solo las métricas de ese nodo. De forma predeterminada, se muestra todo el clúster." + }, + "defaultViewState": { + "label": "Sección abierta por defecto", + "data": { + "none": "Nada", + "node": "Nodos", + "vm": "VMs", + "lxc": "LXCs", + "storage": "Almacenamiento" } + }, + "defaultTabState": { + "label": "Pestaña abierta por defecto", + "info": "Pestaña abierta por defecto. Solo se usa cuando hay múltiples integraciones disponibles.", + "data": { + "system": "Sistema", + "cluster": "Cluster" + } + }, + "summary": { + "label": "Mostrar sección de resumen" + }, + "showNode": { + "label": "Mostrar sección de nodos" + }, + "showVM": { + "label": "Mostrar sección de VMs" + }, + "showLXCs": { + "label": "Mostrar sección LXCs" + }, + "showStorage": { + "label": "Mostrar sección de almacenamiento" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "", + "minute": "" + }, + "memory": { + "label": "", + "totalMem": "", + "available": "" + }, + "fileSystem": { + "label": "", + "available": "" + }, + "info": { + "uptime": "", + "uptimeFormat": "", + "updates": "", + "reboot": "" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "Sistema", + "cluster": "Cluster" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Nodos", + "vms": "VMs", + "lxcs": "LXCs", + "storage": "Almacenamiento" + } + }, + "table": { + "header": { + "name": "Nombre", + "cpu": "CPU", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Detalles", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/es/modules/media-transcoding.json b/public/locales/es/modules/media-transcoding.json new file mode 100644 index 000000000..f6086ab5e --- /dev/null +++ b/public/locales/es/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Cola", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "Tiempo restante", + "progress": "Completado %" + }, + "empty": "Vacío", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Tamaño" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Vacío", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Vacío", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Error", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Cola", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/es/modules/smart-home/entity-state.json b/public/locales/es/modules/smart-home/entity-state.json index ea26580f2..084a64a20 100644 --- a/public/locales/es/modules/smart-home/entity-state.json +++ b/public/locales/es/modules/smart-home/entity-state.json @@ -10,8 +10,8 @@ "info": "ID de entidad única de Home Assistant. Copia haciendo clic en la entidad > Clic en el icono de engranaje > Clic en el botón copiar en 'ID de la entidad'. Algunas entidades personalizadas pueden no ser compatibles." }, "appendUnit": { - "label": "", - "info": "" + "label": "Añadir unidad de medida", + "info": "Añadir el atributo unidad de medida al estado de la entidad." }, "automationId": { "label": "ID de automatización opcional", @@ -21,9 +21,14 @@ "label": "Nombre a mostrar" }, "displayFriendlyName": { - "label": "", - "info": "" + "label": "Mostrar nombre descriptivo", + "info": "Mostrar el nombre descriptivo de Home Assistant en lugar del nombre para mostrar." + }, + "genericToggle": { + "label": "Cambio de entidad", + "info": "Realizar una acción genérica de Home Assistant en la entidad cuando se hace clic." } } } -} \ No newline at end of file +} + diff --git a/public/locales/es/modules/torrents-status.json b/public/locales/es/modules/torrents-status.json index 7032f9178..9bfd10a9f 100644 --- a/public/locales/es/modules/torrents-status.json +++ b/public/locales/es/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Mostrar la relación de la lista de torrents filtrados", "info": "Si está deshabilitado, solo se mostrará la relación global. La relación global seguirá usando las etiquetas si están configuradas" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "Descarga", + "up": "Subida", + "eta": "Tiempo restante", + "progress": "Completado %" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "No se puede comunicar con tus clientes de Torrent. Por favor, verifica tu configuración" } }, - "loading": { - "title": "Cargando", - "description": "Estableciendo una conexión" - }, "popover": { "introductionPrefix": "Gestionado por", "metrics": { diff --git a/public/locales/et/modules/health-monitoring.json b/public/locales/et/modules/health-monitoring.json index a00b40dd5..983ad93fe 100644 --- a/public/locales/et/modules/health-monitoring.json +++ b/public/locales/et/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } - } - }, - "cpu": { + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { "label": "", "load": "", - "minute": "" - }, - "memory": { + "minute": "", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { + "info": "" + }, + "defaultViewState": { "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "data": { + "none": "", + "node": "", + "vm": "", + "lxc": "", + "storage": "" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "", + "load": "", + "minute": "" + }, + "memory": { + "label": "", + "totalMem": "", + "available": "" + }, + "fileSystem": { + "label": "", + "available": "" + }, + "info": { + "uptime": "", + "uptimeFormat": "", + "updates": "", + "reboot": "" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "", + "ram": "" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "" + } + }, + "table": { + "header": { + "name": "", + "cpu": "", + "ram": "", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/et/modules/media-transcoding.json b/public/locales/et/modules/media-transcoding.json new file mode 100644 index 000000000..66a136cfd --- /dev/null +++ b/public/locales/et/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "", + "progress": "" + }, + "empty": "", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "" + }, + "footer": { + "currentIndex": "" + }, + "empty": "", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/et/modules/smart-home/entity-state.json b/public/locales/et/modules/smart-home/entity-state.json index 75dd923c8..45587f0a5 100644 --- a/public/locales/et/modules/smart-home/entity-state.json +++ b/public/locales/et/modules/smart-home/entity-state.json @@ -23,7 +23,12 @@ "displayFriendlyName": { "label": "", "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/et/modules/torrents-status.json b/public/locales/et/modules/torrents-status.json index 2475ec833..b8cfac5a5 100644 --- a/public/locales/et/modules/torrents-status.json +++ b/public/locales/et/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "", "info": "" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "", + "up": "", + "eta": "", + "progress": "" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "" } }, - "loading": { - "title": "", - "description": "" - }, "popover": { "introductionPrefix": "", "metrics": { diff --git a/public/locales/fr/authentication/login.json b/public/locales/fr/authentication/login.json index 02fde6d7b..33a136eaa 100644 --- a/public/locales/fr/authentication/login.json +++ b/public/locales/fr/authentication/login.json @@ -16,8 +16,8 @@ }, "afterLoginRedirection": "Après la connexion, vous serez redirigé vers {{url}}", "providersEmpty": { - "title": "", - "message": "" + "title": "Erreur de fournisseur d'authentification", + "message": "Le(s) fournisseur(s) n'est (ne sont) pas défini(s), veuillez vérifier les journaux pour plus d'informations." } }, "alert": "Vos identifiants sont incorrects ou ce compte n'existe pas. Veuillez réessayer." diff --git a/public/locales/fr/modules/health-monitoring.json b/public/locales/fr/modules/health-monitoring.json index dd45386b4..e50b9c629 100644 --- a/public/locales/fr/modules/health-monitoring.json +++ b/public/locales/fr/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } + "descriptor": { + "name": "Surveillance de l'état du système", + "description": "Affiche des informations sur l'état et la santé de votre (vos) système(s).", + "settings": { + "title": "Paramètres de la surveillance d'état du système", + "fahrenheit": { + "label": "Température du processeur en Fahrenheit" + }, + "cpu": { + "label": "Afficher les infos du processeur", + "load": "Charge moyenne", + "minute": "{{minute}} minute", + "minutes": "{{minutes}} minutes" + }, + "memory": { + "label": "Afficher les infos de la mémoire" + }, + "fileSystem": { + "label": "Afficher les infos sur le système de fichiers" + }, + "node": { + "label": "Filtrer par nom de nœud", + "info": "Entrez le nom de votre nœud Proxmox pour n'afficher que les métriques de ce nœud. Par défaut, l'ensemble du cluster est affiché." + }, + "defaultViewState": { + "label": "Section ouverte par défaut", + "data": { + "none": "Aucun", + "node": "Nœuds", + "vm": "Machines virtuelles", + "lxc": "LXCs", + "storage": "Stockage" } - }, - "cpu": { - "label": "CPU", - "load": "", - "minute": "" - }, - "memory": { - "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { - "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + }, + "defaultTabState": { + "label": "Onglet ouvert par défaut", + "info": "Onglet ouvert par défaut. Utilisé uniquement lorsque plusieurs intégrations sont disponibles.", + "data": { + "system": "Système", + "cluster": "Cluster" } + }, + "summary": { + "label": "Afficher la section de synthèse" + }, + "showNode": { + "label": "Afficher la section des nœuds" + }, + "showVM": { + "label": "Afficher la section des machines virtuelles" + }, + "showLXCs": { + "label": "Afficher la section des LXCs" + }, + "showStorage": { + "label": "Afficher la section de stockage" + }, + "sectionIndicatorColor": { + "label": "Nécessité que l'indicateur d'état de la section soit \"OK\"", + "info": "\"Tous\" exige que tous les éléments soient en ligne pour que l'indicateur soit vert. L'option \"Tous\" exige qu'au moins un élément soit en ligne.", + "data": { + "any": "Tout actifs", + "all": "Tous actifs" + } + }, + "ignoreCert": { + "label": "Ignorer les erreurs de certificat", + "info": "Si cette option est activée, le widget ignorera les erreurs de certificat lors de l'accès à l'API Proxmox. Cela peut être utile pour accéder à Proxmox via HTTPS." + } } + }, + "cpu": { + "label": "CPU", + "load": "Charge moyenne", + "minute": "{{minute}} minute" + }, + "memory": { + "label": "Mémoire", + "totalMem": "Mémoire totale : {{total}}GB", + "available": "Disponible : {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Système de fichiers", + "available": "Disponible : {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Temps de disponibilité", + "uptimeFormat": "{{days}} jours, {{hours}} heures", + "updates": "Mises à jour disponibles", + "reboot": "Redémarrage" + }, + "errors": { + "general": { + "title": "Impossible de trouver votre (vos) système(s).", + "text": "Il y a eu un problème de connexion à votre système. Veuillez vérifier votre configuration/intégration(s)." + } + }, + "headings": { + "system": "Système", + "cluster": "Cluster" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Nœuds", + "vms": "Machines virtuelles", + "lxcs": "LXCs", + "storage": "Stockage" + } + }, + "table": { + "header": { + "name": "Nom", + "cpu": "CPU", + "ram": "RAM", + "node": "Nœuds" + } + }, + "popover": { + "node": "Nœuds", + "vmid": "VMID", + "details": "Détails", + "cores": "Cœurs - {{maxCpu}}", + "memSize": "Mémoire - {{maxMem}}", + "memRatio": "Mémoire - {{usedMem}} / {{maxMem}}", + "diskSize": "Disque - {{maxDisk}}", + "diskRatio": "Disque - {{usedDisk}} / {{maxDisk}}", + "uptime": "Disponibilité - {{uptime}}", + "plugin": "Plugin", + "ha": "État HA - {{haState}}", + "sharedStorage": "Stockage partagé", + "localStorage": "Stockage local", + "na": "N/A" + } + } } \ No newline at end of file diff --git a/public/locales/fr/modules/media-transcoding.json b/public/locales/fr/modules/media-transcoding.json new file mode 100644 index 000000000..eb5c63a64 --- /dev/null +++ b/public/locales/fr/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Transcodage multimédia", + "description": "Affiche des informations à propos du transcodage des médias", + "settings": { + "title": "Paramètres de transcodage des médias", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "File d'attente", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "ETA", + "progress": "Progrès" + }, + "empty": "Vide", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Taille" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Vide", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Vide", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Erreur", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "File d'attente", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/fr/modules/smart-home/entity-state.json b/public/locales/fr/modules/smart-home/entity-state.json index 975fd3003..742db046b 100644 --- a/public/locales/fr/modules/smart-home/entity-state.json +++ b/public/locales/fr/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Afficher le nom personnalisé", - "info": "Afficher le nom personnalisé de Home Assistant au lieu du nom d'affichage" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/fr/modules/torrents-status.json b/public/locales/fr/modules/torrents-status.json index dd82ce7e5..50313ab90 100644 --- a/public/locales/fr/modules/torrents-status.json +++ b/public/locales/fr/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Afficher le ratio de la liste des torrents filtrés", "info": "Si désactivé, seul le ratio global sera affiché. Le ratio global utilisera toujours les labels si définis" + }, + "columnOrdering": { + "label": "Permettre la réorganisation des colonnes" + }, + "rowSorting": { + "label": "Permettre l'organisation des lignes" + }, + "columns": { + "label": "Sélectionner les colonnes à afficher", + "data": { + "date": "Date d’ajout", + "down": "Descendant", + "up": "Montant", + "eta": "ETA", + "progress": "Progrès" + } + }, + "nameColumnSize": { + "label": "Modifier la taille de la colonne des noms" } } }, @@ -84,10 +103,6 @@ "text": "Impossible de communiquer avec vos clients Torrent. Veuillez vérifier votre configuration" } }, - "loading": { - "title": "Chargement", - "description": "Connexion en cours" - }, "popover": { "introductionPrefix": "Géré par", "metrics": { diff --git a/public/locales/fr/modules/weather.json b/public/locales/fr/modules/weather.json index 8ba6181f0..4a6ab639a 100644 --- a/public/locales/fr/modules/weather.json +++ b/public/locales/fr/modules/weather.json @@ -11,10 +11,10 @@ "label": "Afficher le nom de la ville" }, "displayWeekly": { - "label": "" + "label": "Afficher les prévisions hebdomadaires" }, "forecastDays": { - "label": "" + "label": "Nombre de jours à afficher" }, "location": { "label": "Lieu de la météo" @@ -40,4 +40,4 @@ } }, "error": "Une erreur s'est produite" -} +} \ No newline at end of file diff --git a/public/locales/he/modules/health-monitoring.json b/public/locales/he/modules/health-monitoring.json index 20c70f59a..66d407c0b 100644 --- a/public/locales/he/modules/health-monitoring.json +++ b/public/locales/he/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "ניטור בריאות המערכת", - "description": "מידע על ה-NAS שלך", - "settings": { - "title": "ניטור בריאות המערכת", - "fahrenheit": { - "label": "פרנהייט" - } - } - }, - "cpu": { - "label": "מעבד", + "descriptor": { + "name": "ניטור בריאות המערכת", + "description": "מציג מידע המציג את התקינות והסטטוס של המערכות שלך.", + "settings": { + "title": "הגדרות עבור מערכת ניטור תקינות", + "fahrenheit": { + "label": "טמפרטורת המעבד בפרנהייט" + }, + "cpu": { + "label": "הצג מידע על המעבד", "load": "טעינה ממוצעת", - "minute": "{{minute}} דקה" - }, - "memory": { - "label": "זיכרון", - "totalMem": "סך הזיכרון: {{total}}GB", - "available": "זמין: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "מערכת קבצים", - "available": "זמין: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "זמן פעילות", - "updates": "עדכונים", - "reboot": "אתחול מחדש" - }, - "errors": { - "general": { - "title": "לא מצליח למצוא את ה-NAS שלך", - "text": "הייתה בעיה בחיבור ל-NAS שלך. נא ודא את התצורה/השילובים שלך." + "minute": "{{minute}} דקה", + "minutes": "{{minutes}} דקות" + }, + "memory": { + "label": "הצג מידע זיכרון" + }, + "fileSystem": { + "label": "הצג מידע על מערכת הקבצים" + }, + "node": { + "label": "סנן לפי שם צומת", + "info": "" + }, + "defaultViewState": { + "label": "", + "data": { + "none": "ללא", + "node": "צמתים", + "vm": "VMs", + "lxc": "LXCs", + "storage": "אחסון" } + }, + "defaultTabState": { + "label": "כרטיסייה פתוחה כברירת מחדל", + "info": "כרטיסייה פתוחה כברירת מחדל. משמש רק כאשר זמינות אינטגרציות מרובות.", + "data": { + "system": "מערכת", + "cluster": "אֶשׁכּוֹל" + } + }, + "summary": { + "label": "הצג קטע סיכום" + }, + "showNode": { + "label": "הצג קטע צמתים" + }, + "showVM": { + "label": "הצג את הקטע VMs" + }, + "showLXCs": { + "label": "הצג את קטע LXCs" + }, + "showStorage": { + "label": "הצג קטע אחסון" + }, + "sectionIndicatorColor": { + "label": "דרישה שמחוון מצב הסעיף יהיה 'בסדר'", + "info": "'הכל' דורש שכל הפריטים יהיו מקוונים כדי שהמחוון יהיה ירוק. 'כל' דורש לפחות פריט אחד להיות מקוון.", + "data": { + "any": "אקטיבי", + "all": "הכל פעיל" + } + }, + "ignoreCert": { + "label": "התעלם משגיאות אישור", + "info": "אם מופעל, הווידג'ט יתעלם משגיאות אישור בעת גישה ל-Proxmox API. זה יכול להיות מועיל בעת גישה ל-Proxmox דרך HTTPS." + } } + }, + "cpu": { + "label": "מעבד", + "load": "טעינה ממוצעת", + "minute": "{{minute}} דקה" + }, + "memory": { + "label": "זיכרון", + "totalMem": "סך הזיכרון: {{total}}GB", + "available": "זמין: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "מערכת קבצים", + "available": "זמין: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "זמן פעילות", + "uptimeFormat": "{{days}} ימים, {{hours}} שעות", + "updates": "עדכונים זמינים", + "reboot": "אתחול מחדש" + }, + "errors": { + "general": { + "title": "לא ניתן למצוא את המערכת שלך.", + "text": "הייתה בעיה בחיבור למערכת שלך. נא ודא את התצורה/השילובים שלך." + } + }, + "headings": { + "system": "מערכת", + "cluster": "אֶשׁכּוֹל" + }, + "cluster": { + "summary": { + "cpu": "מעבד", + "ram": "זיכרון פנימי" + }, + "accordion": { + "title": { + "nodes": "צמתים", + "vms": "VMs", + "lxcs": "LXCs", + "storage": "אחסון" + } + }, + "table": { + "header": { + "name": "שם", + "cpu": "מעבד", + "ram": "זיכרון פנימי", + "node": "צוֹמֶת" + } + }, + "popover": { + "node": "צוֹמֶת", + "vmid": "VMID", + "details": "פרטים", + "cores": "ליבות - {{maxCpu}}", + "memSize": "זיכרון - {{maxMem}}", + "memRatio": "זיכרון - {{usedMem}} / {{maxMem}}", + "diskSize": "דיסק - {{maxDisk}}", + "diskRatio": "דיסק - {{usedDisk}} / {{maxDisk}}", + "uptime": "זמן פעילות - {{uptime}}", + "plugin": "תוסף", + "ha": "מצב - {{haState}}", + "sharedStorage": "אחסון משותף", + "localStorage": "אחסון מקומי", + "na": "לא זמין" + } + } } \ No newline at end of file diff --git a/public/locales/he/modules/media-transcoding.json b/public/locales/he/modules/media-transcoding.json new file mode 100644 index 000000000..6d9d3c5b9 --- /dev/null +++ b/public/locales/he/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "קידוד מדיה", + "description": "מציג מידע על המרת מדיה", + "settings": { + "title": "הגדרות קידוד מדיה", + "appId": { + "label": "בחר אפליקציה" + }, + "defaultView": { + "label": "תצוגת ברירת מחדל", + "data": { + "workers": "עובדים", + "queue": "תור", + "statistics": "סטָטִיסטִיקָה" + } + }, + "showHealthCheck": { + "label": "הצג מחוון בדיקת בריאות" + }, + "showHealthChecksInQueue": { + "label": "הצג בדיקות בריאות בתור" + }, + "queuePageSize": { + "label": "תור: פריטים בעמוד" + }, + "showAppIcon": { + "label": "הצג את סמל האפליקציה בפינה השמאלית התחתונה" + } + } + }, + "noAppSelected": "אנא בחר אפליקציה בהגדרות הווידג'ט", + "views": { + "workers": { + "table": { + "header": { + "name": "קוֹבֶץ", + "eta": "זמן סיום משוער", + "progress": "התקדמות" + }, + "empty": "ריק", + "tooltip": { + "transcode": "קידוד", + "healthCheck": "בדיקת בריאות" + } + } + }, + "queue": { + "table": { + "header": { + "name": "קוֹבֶץ", + "size": "גודל" + }, + "footer": { + "currentIndex": "{{start}}-{{end}} מתוך {{total}}" + }, + "empty": "ריק", + "tooltip": { + "transcode": "קידוד", + "healthCheck": "בדיקת בריאות" + } + } + }, + "statistics": { + "empty": "ריק", + "box": { + "transcodes": "קידודים: {{value}}", + "healthChecks": "בדיקות בריאות: {{value}}", + "files": "קבצים: {{value}}", + "spaceSaved": "נשמר: {{value}}" + }, + "pies": { + "transcodes": "קידודים", + "healthChecks": "בדיקות בריאות", + "videoCodecs": "קודקים", + "videoContainers": "מיכלים", + "videoResolutions": "רזולוציות" + } + } + }, + "error": { + "title": "שגיאה", + "message": "אירעה שגיאה בעת שליפת נתונים מ-Tdarr." + }, + "tabs": { + "workers": "עובדים", + "queue": "תור", + "statistics": "סטָטִיסטִיקָה" + }, + "healthCheckStatus": { + "title": "בדיקת בריאות", + "queued": "בתור", + "healthy": "בָּרִיא", + "unhealthy": "לא בריא" + } +} diff --git a/public/locales/he/modules/smart-home/entity-state.json b/public/locales/he/modules/smart-home/entity-state.json index fa9e016b6..da0831eb2 100644 --- a/public/locales/he/modules/smart-home/entity-state.json +++ b/public/locales/he/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "הצג שם ידידותי", - "info": "הצג שם ידידותי מ-Home Assistant במקום שם תצוגה" + "info": "הצג שם ידידותי מ-Home Assistant במקום שם תצוגה." + }, + "genericToggle": { + "label": "החלפת ישות", + "info": "בצע פעולת החלפה כללית של Home Assistant על ישות בעת לחיצה." } } } -} \ No newline at end of file +} + diff --git a/public/locales/he/modules/torrents-status.json b/public/locales/he/modules/torrents-status.json index 90285ffc1..c4054a6c8 100644 --- a/public/locales/he/modules/torrents-status.json +++ b/public/locales/he/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "הצגת יחס רשימת טורנטים מסוננים", "info": "אם מושבת, רק היחס הגלובלי יוצג. היחס הגלובלי עדיין ישתמש בתוויות אם מוגדר" + }, + "columnOrdering": { + "label": "אפשר סידור מחדש של העמודות" + }, + "rowSorting": { + "label": "אפשר מיון השורות" + }, + "columns": { + "label": "בחר עמודות להצגה", + "data": { + "date": "נוסף בתאריך", + "down": "הורדה", + "up": "העלאה", + "eta": "זמן סיום משוער", + "progress": "התקדמות" + } + }, + "nameColumnSize": { + "label": "שנה את גודל עמודת השם" } } }, @@ -84,10 +103,6 @@ "text": "לא ניתן לתקשר עם לקוחות הטורנט שלך. אנא בדוק את התצורה שלך" } }, - "loading": { - "title": "טוען", - "description": "יוצר קשר" - }, "popover": { "introductionPrefix": "מנוהל על ידי", "metrics": { diff --git a/public/locales/hr/modules/health-monitoring.json b/public/locales/hr/modules/health-monitoring.json index dd45386b4..3b06a6577 100644 --- a/public/locales/hr/modules/health-monitoring.json +++ b/public/locales/hr/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { + "label": "", "load": "", - "minute": "" - }, - "memory": { + "minute": "", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { + "info": "" + }, + "defaultViewState": { "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "data": { + "none": "Nijedan", + "node": "", + "vm": "", + "lxc": "", + "storage": "Pohrana" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "", + "minute": "" + }, + "memory": { + "label": "", + "totalMem": "", + "available": "" + }, + "fileSystem": { + "label": "", + "available": "" + }, + "info": { + "uptime": "", + "uptimeFormat": "", + "updates": "", + "reboot": "" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "Pohrana" + } + }, + "table": { + "header": { + "name": "Naziv", + "cpu": "CPU", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Pojedinosti", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/hr/modules/media-transcoding.json b/public/locales/hr/modules/media-transcoding.json new file mode 100644 index 000000000..726d28d55 --- /dev/null +++ b/public/locales/hr/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Red čekanja", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "ETA", + "progress": "Napredak" + }, + "empty": "Isprazni", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Veličina" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Isprazni", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Isprazni", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Pogreška", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Red čekanja", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/hr/modules/smart-home/entity-state.json b/public/locales/hr/modules/smart-home/entity-state.json index 75dd923c8..45587f0a5 100644 --- a/public/locales/hr/modules/smart-home/entity-state.json +++ b/public/locales/hr/modules/smart-home/entity-state.json @@ -23,7 +23,12 @@ "displayFriendlyName": { "label": "", "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/hr/modules/torrents-status.json b/public/locales/hr/modules/torrents-status.json index 1d9bdf2bb..4517e96ca 100644 --- a/public/locales/hr/modules/torrents-status.json +++ b/public/locales/hr/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "", "info": "" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "Isključeno", + "up": "Uključeno", + "eta": "ETA", + "progress": "Napredak" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "Nije moguće komunicirati s vašim Torrent klijentima. Provjerite svoju konfiguraciju" } }, - "loading": { - "title": "Učitavam", - "description": "Uspostavljanje veze" - }, "popover": { "introductionPrefix": "Upravlja s", "metrics": { diff --git a/public/locales/hu/authentication/login.json b/public/locales/hu/authentication/login.json index 1b601ee99..f11bc6e13 100644 --- a/public/locales/hu/authentication/login.json +++ b/public/locales/hu/authentication/login.json @@ -16,8 +16,8 @@ }, "afterLoginRedirection": "A bejelentkezés után a {{url}} oldalra kerül átirányításra", "providersEmpty": { - "title": "", - "message": "" + "title": "Hitelesítés-szolgáltató hiba", + "message": "A szolgáltató(k) nincs(ek) beállítva, kérjük, ellenőrizze a naplófájlokat további információkért." } }, "alert": "A hitelesítő adatok helytelenek, vagy ez a fiók nem létezik. Kérjük, próbálja meg újra." diff --git a/public/locales/hu/modules/health-monitoring.json b/public/locales/hu/modules/health-monitoring.json index 8efa9674f..ffba03b8f 100644 --- a/public/locales/hu/modules/health-monitoring.json +++ b/public/locales/hu/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } + "descriptor": { + "name": "Rendszerállapot-felügyelet", + "description": "Megjeleníti a rendszer(ek) állapotát és állapotát mutató információkat.", + "settings": { + "title": "A rendszer állapotfigyelésének beállításai", + "fahrenheit": { + "label": "CPU hőmérséklet Fahrenheitben" + }, + "cpu": { + "label": "CPU-információk megjelenítése", + "load": "Átlagos terhelés", + "minute": "{{minute}} perc", + "minutes": "{{minutes}} percek" + }, + "memory": { + "label": "Memóriainformációk megjelenítése" + }, + "fileSystem": { + "label": "Fájlrendszer-információk megjelenítése" + }, + "node": { + "label": "Szűrés a csomópont neve alapján", + "info": "Adja meg a Proxmox-csomópont nevét, hogy csak az adott csomópont metrikái jelenjenek meg. Alapértelmezés szerint a teljes fürt jelenik meg." + }, + "defaultViewState": { + "label": "Alapértelmezés szerint nyitott szekció", + "data": { + "none": "Semmi", + "node": "Csomópont", + "vm": "Virtuális gépek", + "lxc": "Linux konténerek", + "storage": "Tárhely" } - }, - "cpu": { - "label": "Processzor", - "load": "", - "minute": "" - }, - "memory": { - "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { - "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + }, + "defaultTabState": { + "label": "Alapértelmezés szerint nyitott lap", + "info": "Alapértelmezés szerint nyitott lap. Csak akkor használatos, ha több integráció is elérhető.", + "data": { + "system": "Rendszer", + "cluster": "Klaszter" } + }, + "summary": { + "label": "Könyvtárak megjelenítése" + }, + "showNode": { + "label": "Csomópontok szakasz megjelenítése" + }, + "showVM": { + "label": "Virtuális gépek szakasz megjelenítése" + }, + "showLXCs": { + "label": "Linux konténer szakasz megjelenítése" + }, + "showStorage": { + "label": "Könyvtárak megjelenítése" + }, + "sectionIndicatorColor": { + "label": "A szakasz állapotjelzőjének „OK” állapotának kell lennie", + "info": "Az \"Összes\" jelzőhöz az összes elemnek online kell lennie ahhoz, hogy a mutató zöld legyen. A \"Bármely\" jelzőhöz legalább egy elemnek online kell lennie.", + "data": { + "any": "Bármilyen aktív", + "all": "Minden aktív" + } + }, + "ignoreCert": { + "label": "Tanúsítvány hibák figyelmen kívül hagyása", + "info": "Ha engedélyezve van, a widget figyelmen kívül hagyja a tanúsítvány hibáit a Proxmox API elérésekor. Ez hasznos lehet a Proxmox HTTPS-en keresztüli elérésekor." + } } + }, + "cpu": { + "label": "Processzor", + "load": "Átlagos terhelés", + "minute": "{{minute}} perc" + }, + "memory": { + "label": "Memória", + "totalMem": "Teljes memória: {{total}}GB", + "available": "Elérhető: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Fájlrendszer", + "available": "Elérhető: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Üzemidő", + "uptimeFormat": "{{days}} nap, {{hours}} óra", + "updates": "Frissítés elérhető", + "reboot": "Újraindítás" + }, + "errors": { + "general": { + "title": "Nem találhatók a rendszer(ek).", + "text": "Probléma adódott a Dns-blokkoló(k) hoz való csatlakozással. Kérjük, ellenőrizze a konfigurációt/integráció(ka) t." + } + }, + "headings": { + "system": "Rendszer", + "cluster": "Klaszter" + }, + "cluster": { + "summary": { + "cpu": "Processzor", + "ram": "Memória" + }, + "accordion": { + "title": { + "nodes": "Csomópont", + "vms": "Virtuális gépek", + "lxcs": "Linux konténerek", + "storage": "Tárhely" + } + }, + "table": { + "header": { + "name": "Név", + "cpu": "Processzor", + "ram": "Memória", + "node": "Csomópont" + } + }, + "popover": { + "node": "Csomópont", + "vmid": "VMID", + "details": "Részletek", + "cores": "Magok - {{maxCpu}}", + "memSize": "Memória - {{maxMem}}", + "memRatio": "Memória - {{usedMem}} / {{maxMem}}", + "diskSize": "Lemez - {{maxDisk}}", + "diskRatio": "Lemez - {{usedDisk}} / {{maxDisk}}", + "uptime": "Üzemidő - {{uptime}}", + "plugin": "Bővítmény", + "ha": "Home Assistant állapot - {{haState}}", + "sharedStorage": "Megosztott tárhely", + "localStorage": "Helyi tárhely", + "na": "Nincs adat" + } + } } \ No newline at end of file diff --git a/public/locales/hu/modules/indexer-manager.json b/public/locales/hu/modules/indexer-manager.json index 9b01e3093..1d37a8824 100644 --- a/public/locales/hu/modules/indexer-manager.json +++ b/public/locales/hu/modules/indexer-manager.json @@ -1,19 +1,19 @@ { "descriptor": { - "name": "", - "description": "", + "name": "Indexelő menedzser állapota", + "description": "Az indexelők állapota", "settings": { - "title": "" + "title": "Indexelő menedzser állapota" } }, "indexersStatus": { - "title": "", - "testAllButton": "" + "title": "Indexelő menedzser", + "testAllButton": "Teszteld az összeset" }, "errors": { "general": { - "title": "", - "text": "" + "title": "Nem található indexelő menedzser", + "text": "Probléma adódott a Dns-blokkoló(k) hoz való csatlakozással. Kérjük, ellenőrizze a konfigurációt/integráció(ka) t." } } } \ No newline at end of file diff --git a/public/locales/hu/modules/media-transcoding.json b/public/locales/hu/modules/media-transcoding.json new file mode 100644 index 000000000..d3dee7442 --- /dev/null +++ b/public/locales/hu/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Média átkódolás", + "description": "Megjeleníti a média átkódolásával kapcsolatos információkat", + "settings": { + "title": "Média átkódolási beállítások", + "appId": { + "label": "Válasszon egy alkalmazást" + }, + "defaultView": { + "label": "Alapértelmezett nézet", + "data": { + "workers": "Munkások", + "queue": "Várólista", + "statistics": "Statisztikák" + } + }, + "showHealthCheck": { + "label": "Az állapotfelmérés jelzője megjelenítése" + }, + "showHealthChecksInQueue": { + "label": "Az állapotfelmérés jelzője megjelenítése" + }, + "queuePageSize": { + "label": "Sor: Elemek oldalanként" + }, + "showAppIcon": { + "label": "Alkalmazásikon megjelenítése a jobb alsó sarokban" + } + } + }, + "noAppSelected": "Kérjük, válasszon egy alkalmazást a widget beállításainál", + "views": { + "workers": { + "table": { + "header": { + "name": "Fájl", + "eta": "Hátralévő idő", + "progress": "Folyamat" + }, + "empty": "Üres", + "tooltip": { + "transcode": "Átkódolás", + "healthCheck": "Állapotfelmérés" + } + } + }, + "queue": { + "table": { + "header": { + "name": "Fájl", + "size": "Méret" + }, + "footer": { + "currentIndex": "{{start}}-{{end}} / {{total}}" + }, + "empty": "Üres", + "tooltip": { + "transcode": "Átkódolás", + "healthCheck": "Állapotfelmérés" + } + } + }, + "statistics": { + "empty": "Üres", + "box": { + "transcodes": "Átkódol: {{value}}", + "healthChecks": "Egészségügyi ellenőrzések: {{value}}", + "files": "Fájlok: {{value}}", + "spaceSaved": "Mentve: {{value}}" + }, + "pies": { + "transcodes": "Átkódolás", + "healthChecks": "Egészségügyi ellenőrzések", + "videoCodecs": "Kodekek", + "videoContainers": "Tartály", + "videoResolutions": "Felbontás" + } + } + }, + "error": { + "title": "Hiba", + "message": "Hiba történt az adatok Tdarrból való lekérése közben." + }, + "tabs": { + "workers": "Munkások", + "queue": "Várólista", + "statistics": "Statisztikák" + }, + "healthCheckStatus": { + "title": "Állapotfelmérés", + "queued": "Sorban áll", + "healthy": "Egészséges", + "unhealthy": "Egészségtelen" + } +} diff --git a/public/locales/hu/modules/rss.json b/public/locales/hu/modules/rss.json index 7e1fb16a6..8357b15d2 100644 --- a/public/locales/hu/modules/rss.json +++ b/public/locales/hu/modules/rss.json @@ -22,10 +22,10 @@ "label": "Rendezés a közzététel dátuma szerint (növekvő)" }, "sortPostsWithoutPublishDateToTheTop": { - "label": "" + "label": "Tegye a tetejére a közzétételi dátum nélküli bejegyzéseket" }, "maximumAmountOfPosts": { - "label": "" + "label": "A hozzászólások maximális száma" } }, "card": { diff --git a/public/locales/hu/modules/smart-home/entity-state.json b/public/locales/hu/modules/smart-home/entity-state.json index 17e2f8abd..40a236c45 100644 --- a/public/locales/hu/modules/smart-home/entity-state.json +++ b/public/locales/hu/modules/smart-home/entity-state.json @@ -10,8 +10,8 @@ "info": "Egyedi egység ID a Home Assistantben. Másolás az egységre kattintva > Kattintson a fogaskerék ikonra > Kattintson a másolás gombra az „Egység ID”-nél. Előfordulhat, hogy egyes egyéni egységek nem támogatottak." }, "appendUnit": { - "label": "", - "info": "" + "label": "Mértékegység hozzáfűzése", + "info": "Adja hozzá a mértékegység attribútumot az entitás állapotához." }, "automationId": { "label": "Választható automatizálási azonosító", @@ -21,9 +21,14 @@ "label": "Megjelenített név" }, "displayFriendlyName": { - "label": "", - "info": "" + "label": "Barátságos név megjelenítése", + "info": "A Home Assistant barátságos nevet jelenítse meg a megjelenített név helyett." + }, + "genericToggle": { + "label": "Entitás kapcsoló", + "info": "Ha rákattint, hajtson végre egy általános Home Assistant váltási műveletet az entitáson." } } } -} \ No newline at end of file +} + diff --git a/public/locales/hu/modules/torrents-status.json b/public/locales/hu/modules/torrents-status.json index d4e0a877a..d607b6ea4 100644 --- a/public/locales/hu/modules/torrents-status.json +++ b/public/locales/hu/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Szűrt torrentek listájának aránya", "info": "Ha letiltja, csak a globális arány jelenik meg. A globális arány továbbra is a címkéket használja, ha be van állítva" + }, + "columnOrdering": { + "label": "Az oszlopok átrendezésének engedélyezése" + }, + "rowSorting": { + "label": "A sorok rendezésének engedélyezése" + }, + "columns": { + "label": "Megjelenítendő oszlopok kiválasztása", + "data": { + "date": "Hozzáadás dátuma", + "down": "Le", + "up": "Fel", + "eta": "Hátralévő idő", + "progress": "Folyamat" + } + }, + "nameColumnSize": { + "label": "A névoszlop méretének módosítása" } } }, @@ -84,10 +103,6 @@ "text": "Nem tud kommunikálni a Torrent kliensekkel. Kérjük, ellenőrizze a konfigurációt" } }, - "loading": { - "title": "Betöltés", - "description": "Kapcsolat létrehozása" - }, "popover": { "introductionPrefix": "Irányítja", "metrics": { diff --git a/public/locales/hu/modules/weather.json b/public/locales/hu/modules/weather.json index 4a2f6c45c..21f4781b3 100644 --- a/public/locales/hu/modules/weather.json +++ b/public/locales/hu/modules/weather.json @@ -11,10 +11,10 @@ "label": "Városnév megjelenítése" }, "displayWeekly": { - "label": "" + "label": "Heti előrejelzés megjelenítése" }, "forecastDays": { - "label": "" + "label": "Megjelenítendő napok" }, "location": { "label": "Időjárás helye" @@ -40,4 +40,4 @@ } }, "error": "Hiba történt" -} +} \ No newline at end of file diff --git a/public/locales/it/modules/health-monitoring.json b/public/locales/it/modules/health-monitoring.json index 5dc0e2d4f..2d9f21ad6 100644 --- a/public/locales/it/modules/health-monitoring.json +++ b/public/locales/it/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Monitoraggio dello stato del sistema", - "description": "Informazioni sul tuo NAS", - "settings": { - "title": "Monitoraggio dello stato del sistema", - "fahrenheit": { - "label": "Fahrenheit" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Monitoraggio dello stato del sistema", + "description": "Visualizza informazioni sulla salute e stato dei tuoi sistemi.", + "settings": { + "title": "Impostazioni per il monitoring della salute di sistema", + "fahrenheit": { + "label": "Temperatura CPU in Fahrenheit" + }, + "cpu": { + "label": "Mostra info CPU", "load": "Utilizzo medio", - "minute": "{{minute}} minuto" - }, - "memory": { - "label": "Memoria", - "totalMem": "Memoria totale: {{total}}GB", - "available": "Disponibile: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "File System", - "available": "Disponibile: {{available}}- {{percentage}}%" - }, - "info": { - "uptime": "Uptime", - "updates": "Aggiornamenti", - "reboot": "Riavvio" - }, - "errors": { - "general": { - "title": "Impossibile trovare il tuo NAS", - "text": "Si è verificato un problema di connessione al tuo NAS. Verifica la configurazione/integrazione." + "minute": "{{minute}} minuto", + "minutes": "{{minutes}} minuti" + }, + "memory": { + "label": "Mostra Informazioni Memoria" + }, + "fileSystem": { + "label": "Mostra Informazioni Filesystem" + }, + "node": { + "label": "Filtra per nome nodo", + "info": "Inserisci il nome del tuo nodo Proxmox per mostrare solo le metriche per quel nodo/ Di default, viene mostrato l'intero cluster." + }, + "defaultViewState": { + "label": "Sezione aperta di default", + "data": { + "none": "Niente", + "node": "Nodi", + "vm": "Macchine Virtuali", + "lxc": "LXC", + "storage": "Spazio di archiviazione" } + }, + "defaultTabState": { + "label": "Scheda aperta di default", + "info": "Tab aperta di default. Usato solo quando più integrazioni sono disponibili.", + "data": { + "system": "Sistema", + "cluster": "Cluster" + } + }, + "summary": { + "label": "Mostra sezione riepilogo" + }, + "showNode": { + "label": "Mostra sezione nodi" + }, + "showVM": { + "label": "Mostra sezione macchine virtuali" + }, + "showLXCs": { + "label": "Mostra sezione LXC" + }, + "showStorage": { + "label": "Mostra sezione archiviazione" + }, + "sectionIndicatorColor": { + "label": "Requisito per la sezione indicatore stato per essere 'OK'", + "info": "'Tutto' richiede che tutti gli elementi siano online per far si' che l'indicatore sia verde. 'Qualunque' richiede almeno un elemento per essere online.", + "data": { + "any": "Qualsiasi Attivo", + "all": "Tutti attivi" + } + }, + "ignoreCert": { + "label": "Ignora Errori Certificato", + "info": "Se abilitato, il widget ignorerà gli errori di certificato durante l'accesso all'API Proxmox. Questo può essere utile quando si accede a Proxmox tramite HTTPS." + } } + }, + "cpu": { + "label": "CPU", + "load": "Utilizzo medio", + "minute": "{{minute}} minuto" + }, + "memory": { + "label": "Memoria", + "totalMem": "Memoria totale: {{total}}GB", + "available": "Disponibile: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "File System", + "available": "Disponibile: {{available}}- {{percentage}}%" + }, + "info": { + "uptime": "Uptime", + "uptimeFormat": "{{days}} giorni, {{hours}} ore", + "updates": "Aggiornamenti disponibili", + "reboot": "Riavvio" + }, + "errors": { + "general": { + "title": "Impossibile trovare il tuo sistema", + "text": "Si è verificato un problema durante la connessione al tuo sistema. Verifica la tua configurazione/integrazione." + } + }, + "headings": { + "system": "Sistema", + "cluster": "Cluster" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Nodi", + "vms": "Macchine Virtuali", + "lxcs": "LXC", + "storage": "Spazio di archiviazione" + } + }, + "table": { + "header": { + "name": "Nome", + "cpu": "CPU", + "ram": "RAM", + "node": "Nodo" + } + }, + "popover": { + "node": "Nodo", + "vmid": "VMID", + "details": "Dettagli", + "cores": "Cores - {{maxCpu}}", + "memSize": "Memoria - {{maxMem}}", + "memRatio": "Memoria: {{usedMem}} / {{maxMem}}", + "diskSize": "Disco - {{maxDisk}}", + "diskRatio": "Disco - {{usedDisk}} / {{maxDisk}}", + "uptime": "Tempo di attività - {{uptime}}", + "plugin": "Plugin", + "ha": "Stato HA - {{haState}}", + "sharedStorage": "Archiviazione condivisa", + "localStorage": "Archiviazione locale", + "na": "N/A" + } + } } \ No newline at end of file diff --git a/public/locales/it/modules/media-transcoding.json b/public/locales/it/modules/media-transcoding.json new file mode 100644 index 000000000..1715ecdaf --- /dev/null +++ b/public/locales/it/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Transcodifica Multimediale", + "description": "Mostra informazioni sulla transcodifica multimediale", + "settings": { + "title": "Impostazioni Transcodifica Multimediale", + "appId": { + "label": "Seleziona un'app" + }, + "defaultView": { + "label": "Vista predefinita", + "data": { + "workers": "Worker", + "queue": "Coda", + "statistics": "Statistiche" + } + }, + "showHealthCheck": { + "label": "Mostra l'indicatore del Controllo Integrità" + }, + "showHealthChecksInQueue": { + "label": "Mostra i Controlli Integrità in coda" + }, + "queuePageSize": { + "label": "Coda: Elementi per pagina" + }, + "showAppIcon": { + "label": "Mostra l'icona dell'app nell'angolo in basso a destra" + } + } + }, + "noAppSelected": "Seleziona un'app nelle impostazioni del widget", + "views": { + "workers": { + "table": { + "header": { + "name": "File", + "eta": "ETA", + "progress": "Avanzamento" + }, + "empty": "Vuoto", + "tooltip": { + "transcode": "Transcodifica", + "healthCheck": "Controllo Integrità" + } + } + }, + "queue": { + "table": { + "header": { + "name": "File", + "size": "Dimensione" + }, + "footer": { + "currentIndex": "{{start}}-{{end}} di {{total}}" + }, + "empty": "Vuoto", + "tooltip": { + "transcode": "Transcodifica", + "healthCheck": "Controllo Integrità" + } + } + }, + "statistics": { + "empty": "Vuoto", + "box": { + "transcodes": "Transcodifiche: {{value}}", + "healthChecks": "Controlli Integrità: {{value}}", + "files": "File: {{value}}", + "spaceSaved": "Salvati: {{value}}" + }, + "pies": { + "transcodes": "Transcodifiche", + "healthChecks": "Controlli Integrità", + "videoCodecs": "Codec", + "videoContainers": "Container", + "videoResolutions": "Risoluzioni" + } + } + }, + "error": { + "title": "Errore", + "message": "Si è verificato un errore durante il recupero dei dati da Tdarr." + }, + "tabs": { + "workers": "Worker", + "queue": "Coda", + "statistics": "Statistiche" + }, + "healthCheckStatus": { + "title": "Controllo Integrità", + "queued": "In coda", + "healthy": "Sano", + "unhealthy": "Non integro" + } +} diff --git a/public/locales/it/modules/smart-home/entity-state.json b/public/locales/it/modules/smart-home/entity-state.json index 5c86b3fa1..31a76f279 100644 --- a/public/locales/it/modules/smart-home/entity-state.json +++ b/public/locales/it/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Visualizza il nome descrittivo", - "info": "Visualizza il nome descrittivo di Home Assistant invece del nome visualizzato" + "info": "Visualizza il nome descrittivo da Home Assistant invece del nome visualizzato." + }, + "genericToggle": { + "label": "Attiva/disattiva entità", + "info": "Esegue un'azione generica di attivazione/disattivazione di Home Assistant sull'entità quando clicchi." } } } -} \ No newline at end of file +} + diff --git a/public/locales/it/modules/torrents-status.json b/public/locales/it/modules/torrents-status.json index 2160905c6..97c099d9f 100644 --- a/public/locales/it/modules/torrents-status.json +++ b/public/locales/it/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Visualizza il ratio dell'elenco dei torrent filtrati", "info": "Se disabilitato, verrà visualizzato solo il ratio globale. Il ratio globale utilizzerà comunque i label, se impostati" + }, + "columnOrdering": { + "label": "Abilita il riordinamento delle colonne" + }, + "rowSorting": { + "label": "Abilita l'ordinamento delle righe" + }, + "columns": { + "label": "Seleziona colonne da visualizzare", + "data": { + "date": "Aggiunto in data", + "down": "Down", + "up": "Up", + "eta": "ETA", + "progress": "Avanzamento" + } + }, + "nameColumnSize": { + "label": "Cambia nome dimensione colonna" } } }, @@ -84,10 +103,6 @@ "text": "Impossibile comunicare con i client Torrent. Controllare la configurazione" } }, - "loading": { - "title": "Caricamento in corso", - "description": "Connessione in corso" - }, "popover": { "introductionPrefix": "Gestito da", "metrics": { diff --git a/public/locales/it/modules/weather.json b/public/locales/it/modules/weather.json index 24495d3cd..a677bb782 100644 --- a/public/locales/it/modules/weather.json +++ b/public/locales/it/modules/weather.json @@ -11,10 +11,10 @@ "label": "Visualizza nome città" }, "displayWeekly": { - "label": "" + "label": "Visualizza Previsioni Settimanali" }, "forecastDays": { - "label": "" + "label": "Giorni Da Mostrare" }, "location": { "label": "Località meteo" @@ -40,4 +40,4 @@ } }, "error": "Si è verificato un errore" -} +} \ No newline at end of file diff --git a/public/locales/ja/modules/health-monitoring.json b/public/locales/ja/modules/health-monitoring.json index dd45386b4..215e5631e 100644 --- a/public/locales/ja/modules/health-monitoring.json +++ b/public/locales/ja/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { + "label": "", "load": "", - "minute": "" - }, - "memory": { + "minute": "", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { + "info": "" + }, + "defaultViewState": { "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "data": { + "none": "なし", + "node": "", + "vm": "", + "lxc": "", + "storage": "ストレージ" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "", + "minute": "" + }, + "memory": { + "label": "", + "totalMem": "", + "available": "" + }, + "fileSystem": { + "label": "", + "available": "" + }, + "info": { + "uptime": "", + "uptimeFormat": "", + "updates": "", + "reboot": "" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "メモリ" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "ストレージ" + } + }, + "table": { + "header": { + "name": "名称", + "cpu": "CPU", + "ram": "メモリ", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "詳細", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/ja/modules/media-transcoding.json b/public/locales/ja/modules/media-transcoding.json new file mode 100644 index 000000000..c23b80329 --- /dev/null +++ b/public/locales/ja/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "キュー", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "ETA", + "progress": "進捗状況" + }, + "empty": "空", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "サイズ" + }, + "footer": { + "currentIndex": "" + }, + "empty": "空", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "空", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "エラー", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "キュー", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/ja/modules/smart-home/entity-state.json b/public/locales/ja/modules/smart-home/entity-state.json index 75dd923c8..45587f0a5 100644 --- a/public/locales/ja/modules/smart-home/entity-state.json +++ b/public/locales/ja/modules/smart-home/entity-state.json @@ -23,7 +23,12 @@ "displayFriendlyName": { "label": "", "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/ja/modules/torrents-status.json b/public/locales/ja/modules/torrents-status.json index 46032f5bf..a6fb63a44 100644 --- a/public/locales/ja/modules/torrents-status.json +++ b/public/locales/ja/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "", "info": "" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "ダウンロード", + "up": "アップロード", + "eta": "ETA", + "progress": "進捗状況" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "Torrentクライアントと通信できません。設定を確認してください。" } }, - "loading": { - "title": "読み込み中", - "description": "接続中..." - }, "popover": { "introductionPrefix": "管理者:", "metrics": { diff --git a/public/locales/ko/modules/health-monitoring.json b/public/locales/ko/modules/health-monitoring.json index dd45386b4..7ebe6cf9d 100644 --- a/public/locales/ko/modules/health-monitoring.json +++ b/public/locales/ko/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { + "label": "", "load": "", - "minute": "" - }, - "memory": { + "minute": "", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { + "info": "" + }, + "defaultViewState": { "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "data": { + "none": "없음", + "node": "", + "vm": "", + "lxc": "", + "storage": "저장소" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "", + "minute": "" + }, + "memory": { + "label": "", + "totalMem": "", + "available": "" + }, + "fileSystem": { + "label": "", + "available": "" + }, + "info": { + "uptime": "", + "uptimeFormat": "", + "updates": "", + "reboot": "" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "저장소" + } + }, + "table": { + "header": { + "name": "이름", + "cpu": "CPU", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "세부 정보", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/ko/modules/media-transcoding.json b/public/locales/ko/modules/media-transcoding.json new file mode 100644 index 000000000..c5c6b97e1 --- /dev/null +++ b/public/locales/ko/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "대기열", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "남은 시간", + "progress": "진행률" + }, + "empty": "비어 있음", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "크기" + }, + "footer": { + "currentIndex": "" + }, + "empty": "비어 있음", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "비어 있음", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "오류", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "대기열", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/ko/modules/smart-home/entity-state.json b/public/locales/ko/modules/smart-home/entity-state.json index 75dd923c8..45587f0a5 100644 --- a/public/locales/ko/modules/smart-home/entity-state.json +++ b/public/locales/ko/modules/smart-home/entity-state.json @@ -23,7 +23,12 @@ "displayFriendlyName": { "label": "", "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/ko/modules/torrents-status.json b/public/locales/ko/modules/torrents-status.json index 80b2d165b..06ae4848f 100644 --- a/public/locales/ko/modules/torrents-status.json +++ b/public/locales/ko/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "", "info": "" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "다운로드", + "up": "업로드", + "eta": "남은 시간", + "progress": "진행률" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "토렌트 클라이언트와 통신할 수 없습니다. 구성을 확인하세요." } }, - "loading": { - "title": "로드 중", - "description": "연결 설정하기" - }, "popover": { "introductionPrefix": "관리 주체", "metrics": { diff --git a/public/locales/lt/modules/health-monitoring.json b/public/locales/lt/modules/health-monitoring.json index 083c6f96b..97058ccb9 100644 --- a/public/locales/lt/modules/health-monitoring.json +++ b/public/locales/lt/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Sistemos būklės stebėjimas", - "description": "Informacija apie jūsų NAS", - "settings": { - "title": "Sistemos būklės stebėjimas", - "fahrenheit": { - "label": "Farenheitas" - } - } - }, - "cpu": { - "label": "Procesorius", + "descriptor": { + "name": "Sistemos būklės stebėjimas", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { + "label": "", "load": "Apkrovos vidurkis", - "minute": "{{minute}} minutė" - }, - "memory": { - "label": "Atmintis", - "totalMem": "Bendra atmintis: {{total}}GB", - "available": "Galimi: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "Failų sistema", - "available": "Galimi: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "Veikimo laikas", - "updates": "Atnaujinimai", - "reboot": "Paleisti iš naujo" - }, - "errors": { - "general": { - "title": "Nepavyko rasti jūsų NAS", - "text": "Prisijungiant prie NAS kilo problema. Patikrinkite savo konfigūraciją / integraciją (-as)." + "minute": "{{minute}} minutė", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { + "label": "", + "info": "" + }, + "defaultViewState": { + "label": "", + "data": { + "none": "Nėra", + "node": "", + "vm": "", + "lxc": "", + "storage": "Saugykla" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "Procesorius", + "load": "Apkrovos vidurkis", + "minute": "{{minute}} minutė" + }, + "memory": { + "label": "Atmintis", + "totalMem": "Bendra atmintis: {{total}}GB", + "available": "Galimi: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Failų sistema", + "available": "Galimi: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Veikimo laikas", + "uptimeFormat": "", + "updates": "", + "reboot": "Paleisti iš naujo" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "Procesorius", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "Saugykla" + } + }, + "table": { + "header": { + "name": "Pavadinimas", + "cpu": "Procesorius", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/lt/modules/media-transcoding.json b/public/locales/lt/modules/media-transcoding.json new file mode 100644 index 000000000..66a136cfd --- /dev/null +++ b/public/locales/lt/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "", + "progress": "" + }, + "empty": "", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "" + }, + "footer": { + "currentIndex": "" + }, + "empty": "", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/lt/modules/smart-home/entity-state.json b/public/locales/lt/modules/smart-home/entity-state.json index 9222d7443..7c038e711 100644 --- a/public/locales/lt/modules/smart-home/entity-state.json +++ b/public/locales/lt/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Rodyti draugišką pavadinimą", - "info": "Rodyti draugišką vardą iš \"Home Assistant\", o ne rodomą vardą" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/lt/modules/torrents-status.json b/public/locales/lt/modules/torrents-status.json index 2e259d5fd..4c79d0bdc 100644 --- a/public/locales/lt/modules/torrents-status.json +++ b/public/locales/lt/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "", "info": "" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "Žemyn", + "up": "Aukštyn", + "eta": "", + "progress": "" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "" } }, - "loading": { - "title": "", - "description": "" - }, "popover": { "introductionPrefix": "", "metrics": { diff --git a/public/locales/lv/authentication/login.json b/public/locales/lv/authentication/login.json index 420928116..0d4b49894 100644 --- a/public/locales/lv/authentication/login.json +++ b/public/locales/lv/authentication/login.json @@ -16,8 +16,8 @@ }, "afterLoginRedirection": "Pēc pieslēgšanās tiksiet novirzīts uz {{url}}", "providersEmpty": { - "title": "", - "message": "" + "title": "Autentifikācijas pakalpojuma kļūda", + "message": "Pakalpojuma sniedzējs(-i) nav iestatīts(-i), lūdzu, pārbaudiet žurnālus, lai iegūtu vairāk informācijas." } }, "alert": "Jūsu pieslēgšanās dati ir nepareizi vai šis konts nepastāv. Lūdzu, mēģiniet vēlreiz." diff --git a/public/locales/lv/modules/health-monitoring.json b/public/locales/lv/modules/health-monitoring.json index dd45386b4..c5b198995 100644 --- a/public/locales/lv/modules/health-monitoring.json +++ b/public/locales/lv/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } + "descriptor": { + "name": "Sistēmas Stāvokļa Uzraudzība", + "description": "Tiek parādīta informācija par sistēmas(-u) stāvokli un stāvokli.", + "settings": { + "title": "Sistēmas veselības stāvokļa uzraudzības iestatījumi", + "fahrenheit": { + "label": "CPU temperatūra pēc Fārenheita" + }, + "cpu": { + "label": "Rādīt CPU informāciju", + "load": "Vidējā slodze", + "minute": "{{minute}} minūte", + "minutes": "{{minutes}} minūtes" + }, + "memory": { + "label": "Rādīt atmiņas informāciju" + }, + "fileSystem": { + "label": "Rādīt failu sistēmas informāciju" + }, + "node": { + "label": "Filtrēšana pēc mezgla nosaukuma", + "info": "Ievadiet savu Proxmox mezgla nosaukumu, lai rādītu tikai šā mezgla metriku. Pēc noklusējuma tiek rādīts viss klasteris." + }, + "defaultViewState": { + "label": "Sadaļa atvērta pēc noklusējuma", + "data": { + "none": "Nekas", + "node": "Mezgli", + "vm": "VM", + "lxc": "LXC", + "storage": "Krātuve" } - }, - "cpu": { - "label": "CPU", - "load": "", - "minute": "" - }, - "memory": { + }, + "defaultTabState": { "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { - "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "info": "", + "data": { + "system": "", + "cluster": "" } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "Vidējā slodze", + "minute": "{{minute}} minūte" + }, + "memory": { + "label": "Atmiņa", + "totalMem": "Kopējā atmiņa: {{total}}GB", + "available": "Pieejams: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Failu Sistēma", + "available": "Pieejams: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Darbības laiks", + "uptimeFormat": "", + "updates": "", + "reboot": "Pārstartēt" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Mezgli", + "vms": "VM", + "lxcs": "LXC", + "storage": "Krātuve" + } + }, + "table": { + "header": { + "name": "Nosaukums", + "cpu": "CPU", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Detaļas", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/lv/modules/media-transcoding.json b/public/locales/lv/modules/media-transcoding.json new file mode 100644 index 000000000..929d6a70f --- /dev/null +++ b/public/locales/lv/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Rinda", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "ETA", + "progress": "Progress" + }, + "empty": "Tukšs", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Lielums" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Tukšs", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Tukšs", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Kļūda", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Rinda", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/lv/modules/smart-home/entity-state.json b/public/locales/lv/modules/smart-home/entity-state.json index e2da207b3..6c872baf5 100644 --- a/public/locales/lv/modules/smart-home/entity-state.json +++ b/public/locales/lv/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Draudzīgais nosaukums", - "info": "Draudzīgā nosaukuma vietā parādiet no Home Assistant izgulto draudzīgo nosaukumu" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/lv/modules/torrents-status.json b/public/locales/lv/modules/torrents-status.json index 5f8e671d5..165080a2c 100644 --- a/public/locales/lv/modules/torrents-status.json +++ b/public/locales/lv/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Rādīt filtrēto torentu saraksta attiecību", "info": "Ja ir atspējots, tiks parādīta tikai globālā attiecība. Globālā attiecība joprojām izmantos etiķetes, ja tā būs iestatītas" + }, + "columnOrdering": { + "label": "Iespējot kolonnu pārkārtošanu" + }, + "rowSorting": { + "label": "Iespējot rindu kārtošanu" + }, + "columns": { + "label": "Atlasiet kolonnas, kuras vēlaties parādīt", + "data": { + "date": "Pievienošanas datums", + "down": "Lejupielāde", + "up": "Augšupielāde", + "eta": "ETA", + "progress": "Progress" + } + }, + "nameColumnSize": { + "label": "Mainiet nosaukuma kolonnas lielumu" } } }, @@ -84,10 +103,6 @@ "text": "Neizdevās sazināties ar jūsu Torrent klientiem. Lūdzu, pārbaudiet savu konfigurāciju" } }, - "loading": { - "title": "Notiek ielāde", - "description": "Savienojuma izveide" - }, "popover": { "introductionPrefix": "Pārvalda", "metrics": { diff --git a/public/locales/lv/modules/weather.json b/public/locales/lv/modules/weather.json index f860f1b09..96690ae63 100644 --- a/public/locales/lv/modules/weather.json +++ b/public/locales/lv/modules/weather.json @@ -11,10 +11,10 @@ "label": "Parādāmais Pilsētas Nosaukums" }, "displayWeekly": { - "label": "" + "label": "Rādīt nedēļas laika prognozi" }, "forecastDays": { - "label": "" + "label": "Rādāmās dienas" }, "location": { "label": "Laikapstākļu atrašānās vieta" @@ -40,4 +40,4 @@ } }, "error": "Radās kļūda" -} +} \ No newline at end of file diff --git a/public/locales/nl/authentication/invite.json b/public/locales/nl/authentication/invite.json index bba28aae5..5b5b7dfe4 100644 --- a/public/locales/nl/authentication/invite.json +++ b/public/locales/nl/authentication/invite.json @@ -1,7 +1,7 @@ { "metaTitle": "Account aanmaken", "title": "Account aanmaken", - "text": "Geef hieronder uw referenties aan", + "text": "Geef hieronder je inloggegevens op", "form": { "fields": { "username": { diff --git a/public/locales/nl/authentication/login.json b/public/locales/nl/authentication/login.json index 899a9a08d..13385aca3 100644 --- a/public/locales/nl/authentication/login.json +++ b/public/locales/nl/authentication/login.json @@ -1,7 +1,7 @@ { "metaTitle": "Inloggen", "title": "Welkom terug!", - "text": "Voer uw referenties in", + "text": "Voer je inloggegevens in", "form": { "fields": { "username": { diff --git a/public/locales/nl/boards/customize.json b/public/locales/nl/boards/customize.json index 1e5392c12..89f37860b 100644 --- a/public/locales/nl/boards/customize.json +++ b/public/locales/nl/boards/customize.json @@ -19,7 +19,7 @@ }, "success": { "title": "Opgeslagen aanpassingen", - "message": "Uw aanpassing is succesvol opgeslagen" + "message": "Je aanpassing is succesvol opgeslagen" }, "error": { "title": "Fout", diff --git a/public/locales/nl/common.json b/public/locales/nl/common.json index f6a9faf67..ac142d66c 100644 --- a/public/locales/nl/common.json +++ b/public/locales/nl/common.json @@ -1,17 +1,17 @@ { "save": "Opslaan", - "apply": "", - "insert": "", + "apply": "Toepassen", + "insert": "Invoegen", "about": "Over", - "cancel": "Annuleer", + "cancel": "Annuleren", "close": "Sluiten", "back": "Terug", - "delete": "Verwijder", - "ok": "OK", - "edit": "Wijzig", + "delete": "Verwijderen", + "ok": "OKÉ", + "edit": "Wijzigen", "next": "Volgende", "previous": "Vorige", - "confirm": "Bevestig", + "confirm": "Bevestigen", "enabled": "Ingeschakeld", "duplicate": "", "disabled": "Uitgeschakeld", @@ -19,15 +19,15 @@ "disableAll": "Alles uitschakelen", "version": "Versie", "changePosition": "Positie wijzigen", - "remove": "Verwijder", + "remove": "Verwijderen", "removeConfirm": "Weet u zeker dat u {{item}} wilt verwijderen?", - "createItem": "+ creëer {{item}}", + "createItem": "+ {{item}} aanmaken", "sections": { "settings": "Instellingen", "dangerZone": "Gevarenzone" }, "secrets": { - "apiKey": "API sleutel", + "apiKey": "API-sleutel", "username": "Gebruikersnaam", "password": "Wachtwoord" }, @@ -40,13 +40,13 @@ "loading": "Bezig met laden...", "breakPoints": { "small": "klein", - "medium": "gemiddeld", + "medium": "middel", "large": "groot" }, "seeMore": "Zie meer...", "position": { "left": "Links", - "center": "", + "center": "Centreren", "right": "Rechts" }, "attributes": { @@ -54,5 +54,5 @@ "height": "Hoogte" }, "public": "Openbaar", - "restricted": "" + "restricted": "Beperkt" } \ No newline at end of file diff --git a/public/locales/nl/layout/common.json b/public/locales/nl/layout/common.json index 0c064b81d..0e5a127e5 100644 --- a/public/locales/nl/layout/common.json +++ b/public/locales/nl/layout/common.json @@ -5,7 +5,7 @@ "text": "Je browser heeft de toegang tot Homarr's API geblokkeerd. Dit wordt meestal veroorzaakt door AdBlockers of geweigerde toestemmingen. Homarr is niet in staat om automatisch rechten aan te vragen.", "list": { "browserPermission": "Klik op het pictogram naast de URL en controleer de toestemmingen. Pop-ups en vensters toestaan", - "adBlockers": "Schakel advertentieblokkers en beveiligingsprogramma's van uw browser uit", + "adBlockers": "Schakel advertentieblokkers en beveiligingsprogramma's van je browser uit", "otherBrowser": "Probeer een andere browser" } } diff --git a/public/locales/nl/layout/element-selector/selector.json b/public/locales/nl/layout/element-selector/selector.json index 4a0332d57..9cdac4576 100644 --- a/public/locales/nl/layout/element-selector/selector.json +++ b/public/locales/nl/layout/element-selector/selector.json @@ -3,14 +3,14 @@ "title": "Nieuwe tegel toevoegen", "text": "Tegels zijn het belangrijkste element van Homarr. Ze worden gebruikt om je apps en andere informatie weer te geven. Je kunt zoveel tegels toevoegen als je wilt." }, - "widgetDescription": "Widgets werken samen met uw apps, om u meer controle over uw toepassingen te geven. Ze vereisen meestal extra configuratie voor gebruik.", + "widgetDescription": "Widgets werken samen met je apps, om je meer controle over je applicaties te geven. Ze vereisen meestal extra configuratie voor gebruik.", "goBack": "Ga terug naar de vorige stap", "actionIcon": { "tooltip": "Tegel toevoegen" }, "apps": "Apps", "app": { - "defaultName": "Uw app" + "defaultName": "Jouw app" }, "widgets": "Widgets", "categories": "Categorieën", diff --git a/public/locales/nl/layout/header/actions/toggle-edit-mode.json b/public/locales/nl/layout/header/actions/toggle-edit-mode.json index 8c23f1dc2..c0ad9da21 100644 --- a/public/locales/nl/layout/header/actions/toggle-edit-mode.json +++ b/public/locales/nl/layout/header/actions/toggle-edit-mode.json @@ -1,12 +1,12 @@ { - "description": "In de bewerkingsmodus kunt u tegels aanpassen en apps configureren. Wijzigingen worden niet opgeslagen totdat u de bewerkingsmodus afsluit.", + "description": "In de bewerkmodus kan je tegels aanpassen en apps configureren. Wijzigingen worden niet opgeslagen totdat je de bewerkingsmodus afsluit.", "button": { - "disabled": "Ga naar de bewerkingsmodus", + "disabled": "Ga naar bewerkmodus", "enabled": "Afsluiten en opslaan" }, "popover": { - "title": "Bewerkingsmodus is ingeschakeld voor de <1>{{size}} grootte", - "text": "U kunt uw apps nu aanpassen en configureren. Wijzigingen zijn niet opgeslagen totdat u de bewerkingsmodus verlaat" + "title": "Bewerkmodus is ingeschakeld voor de <1>{{size}} grootte", + "text": "Je kan je apps nu aanpassen en configureren. Wijzigingen zijn niet opgeslagen totdat je de bewerkmodus verlaat" }, - "unloadEvent": "Sluit de bewerkingsmodus af om uw wijzigingen op te slaan" + "unloadEvent": "Sluit de bewerkmodus af om je wijzigingen op te slaan" } diff --git a/public/locales/nl/layout/modals/about.json b/public/locales/nl/layout/modals/about.json index 97e469a2d..c0ae18d74 100644 --- a/public/locales/nl/layout/modals/about.json +++ b/public/locales/nl/layout/modals/about.json @@ -1,7 +1,7 @@ { "description": "Homarr is een sterk, modern dashboard dat al je apps en diensten binnen handbereik brengt. Met Homarr heb je toegang tot en controle over alles op één handige locatie. Homarr integreert naadloos met de apps die je hebt toegevoegd en geeft je waardevolle informatie en volledige controle. Installatie is een fluitje van een cent en Homarr ondersteunt een breed scala aan implementatiemethoden.", "addToDashboard": "Aan dashboard toevoegen", - "tip": "Mod verwijst naar uw modifier toets, dat zijn de Ctrl en Commando/Super/Windows toets", + "tip": "Mod verwijst naar je modifier toets, dat zijn de Ctrl en Commando/Super/Windows toets", "key": "Sneltoets", "action": "Actie", "keybinds": "Sneltoetsen", @@ -21,7 +21,7 @@ "nodeEnvironment": "Node environment", "i18n": "I18n vertaling namespaces geladen", "locales": "I18n talen geconfigureerd", - "experimental_disableEditMode": "EXPERIMENTEEL: Bewerkingsmodus uitschakelen" + "experimental_disableEditMode": "EXPERIMENTEEL: Bewerkmodus uitschakelen" }, "version": { "new": "Nieuw: {{newVersion}}", diff --git a/public/locales/nl/layout/modals/add-app.json b/public/locales/nl/layout/modals/add-app.json index 751a1478c..d29b94b15 100644 --- a/public/locales/nl/layout/modals/add-app.json +++ b/public/locales/nl/layout/modals/add-app.json @@ -61,7 +61,7 @@ "description": "Begin te typen om een pictogram te vinden. Je kunt ook een URL van een afbeelding plakken om een aangepast pictogram te gebruiken.", "autocomplete": { "title": "Geen resultaten gevonden", - "text": "Probeer een specifiekere zoekterm te gebruiken. Als u het gewenste pictogram niet kunt vinden, plak dan de bovenstaande URL van de afbeelding voor een aangepast pictogram" + "text": "Probeer een specifiekere zoekterm te gebruiken. Als je het gewenste pictogram niet kan vinden, plak dan de bovenstaande URL van de afbeelding voor een aangepast pictogram" }, "noItems": { "title": "Externe pictogrammen laden", @@ -99,30 +99,30 @@ "integration": { "type": { "label": "Integratie configuratie", - "description": "De integratieconfiguratie die zal worden gebruikt om verbinding te maken met uw app.", + "description": "De integratie configuratie die zal worden gebruikt om verbinding te maken met je app.", "placeholder": "Selecteer een integratie", "defined": "Gedefinieerd", "undefined": "Ongedefinieerd", "public": "Openbaar", "private": "Privé", - "explanationPrivate": "Een geheim wordt slechts eenmaal naar de server gestuurd. Zodra uw browser de pagina heeft ververst, wordt het nooit meer verzonden.", + "explanationPrivate": "Een geheim wordt slechts eenmaal naar de server gestuurd. Zodra je browser de pagina heeft ververst, wordt het nooit meer verzonden.", "explanationPublic": "Een publiek geheim wordt altijd naar de client gestuurd en is toegankelijk via de API. Het mag geen vertrouwelijke waarden bevatten zoals gebruikersnamen, wachtwoorden, tokens, certificaten en dergelijke!" }, "secrets": { "description": "Om een geheim bij te werken, voert u een waarde in en klikt u op de knop Opslaan. Om een geheim te verwijderen, gebruikt u de knop wissen.", - "warning": "Uw referenties fungeren als de toegang tot uw integraties en u zou deze nooit hoeven delen met iemand anders. Het Homarr team zal nooit om inloggegevens vragen. Zorg ervoor dat uw geheimen veilig opslaat en beheert.", + "warning": "Je referenties fungeren als de toegang tot uw integraties en je zou deze nooit moeten delen met iemand anders. Het Homarr team zal nooit om inloggegevens vragen. Zorg ervoor dat je geheimen veilig opslaat en beheert.", "clear": "Wis geheim", "save": "Geheim opslaan", - "update": "Update geheim" + "update": "Geheim updaten" } }, "validation": { - "popover": "Uw formulier bevat ongeldige gegevens. Daarom kan het niet worden opgeslagen. Los alle problemen op en klik opnieuw op deze knop om uw wijzigingen op te slaan", + "popover": "Je formulier bevat ongeldige gegevens. Daarom kan het niet worden opgeslagen. Los alle problemen op en klik opnieuw op deze knop om je wijzigingen op te slaan", "name": "Naam is vereist", - "noUrl": "Url is vereist", + "noUrl": "URL is vereist", "invalidUrl": "Waarde is geen geldige url", "noIconUrl": "Dit veld is verplicht", - "noExternalUri": "Externe URI is vereist", - "invalidExternalUri": "Externe URI is geen geldige uri" + "noExternalUri": "Externe URL is vereist", + "invalidExternalUri": "Externe URL is geen geldige uri" } } diff --git a/public/locales/nl/manage/boards.json b/public/locales/nl/manage/boards.json index 10a2f2dd3..8b8d7d94a 100644 --- a/public/locales/nl/manage/boards.json +++ b/public/locales/nl/manage/boards.json @@ -8,7 +8,7 @@ "categories": "Categorieën" }, "buttons": { - "view": "Bekijk bord" + "view": "Bord bekijken" }, "menu": { "setAsDefault": "Instellen als standaardkaart", @@ -40,7 +40,7 @@ }, "modals": { "delete": { - "title": "Verwijder bord", + "title": "Bord verwijderen", "text": "Weet je zeker dat je dit bord wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt en je gegevens zullen permanent verloren gaan." }, "create": { diff --git a/public/locales/nl/manage/index.json b/public/locales/nl/manage/index.json index 4751160c2..402609c82 100644 --- a/public/locales/nl/manage/index.json +++ b/public/locales/nl/manage/index.json @@ -8,7 +8,7 @@ "quickActions": { "title": "Snelle acties", "boards": { - "title": "Uw borden", + "title": "Jouw borden", "subtitle": "Uw borden maken en beheren" }, "inviteUsers": { diff --git a/public/locales/nl/manage/users.json b/public/locales/nl/manage/users.json index 176acda75..54780524d 100644 --- a/public/locales/nl/manage/users.json +++ b/public/locales/nl/manage/users.json @@ -37,8 +37,8 @@ "title": "Degradeer gebruiker {{name}} naar gebruiker", "text": "Weet je zeker dat je de gebruiker {{name}} wilt degraderen naar gebruiker? Dit zal de toegang van de gebruiker tot alle bronnen op je Homarr-instantie verwijderen." }, - "confirm": "Bevestig" + "confirm": "Bevestigen" } }, - "searchDoesntMatch": "Je zoekopdracht komt niet overeen met items. Pas uw filter aan." + "searchDoesntMatch": "Je zoekopdracht komt niet overeen met items. Pas je filter aan." } \ No newline at end of file diff --git a/public/locales/nl/modules/bookmark.json b/public/locales/nl/modules/bookmark.json index 29d92d78e..0570423c4 100644 --- a/public/locales/nl/modules/bookmark.json +++ b/public/locales/nl/modules/bookmark.json @@ -31,13 +31,13 @@ "validation": { "length": "De lengte moet tussen {{shortest}} en {{longest}}liggen.", "invalidLink": "Geen geldige link", - "errorMsg": "Niet opgeslagen omdat er validatiefouten waren. Herhaal uw invoer a.u.b." + "errorMsg": "Niet opgeslagen, omdat er validatiefouten waren. Pas je invoer aan" }, "name": "Naam", "url": "URL", "newTab": "Open in nieuw tabblad", "hideHostname": "Hostnaam verbergen", "hideIcon": "Pictogram verbergen", - "delete": "Verwijder" + "delete": "Verwijderen" } } diff --git a/public/locales/nl/modules/dashdot.json b/public/locales/nl/modules/dashdot.json index 3077e9a91..fa7e98574 100644 --- a/public/locales/nl/modules/dashdot.json +++ b/public/locales/nl/modules/dashdot.json @@ -5,7 +5,7 @@ "settings": { "title": "Instellingen voor Dash. widget", "dashName": { - "label": "Dash. Naam" + "label": "Dash. naam" }, "url": { "label": "Dash. URL" @@ -17,53 +17,53 @@ "label": "Kolommen weergeven" }, "graphHeight": { - "label": "Hoogte van de grafieken" + "label": "Hoogte van grafieken" }, "graphsOrder": { "label": "Grafieken (volgorde)", "storage": { "label": "Opslagruimte", "enabled": { - "label": "Toon in widget" + "label": "Weergeven in widget" }, "span": { "label": "Kolombreedte" }, "compactView": { - "label": "Toon als tekst (compact)" + "label": "Weergeven als tekst (compact)" }, "multiView": { - "label": "Toon als multi-drive-weergave" + "label": "Weergeven als multi-drive weergave" } }, "network": { "label": "Netwerk", "enabled": { - "label": "Toon in widget" + "label": "Weergeven in widget" }, "span": { "label": "Kolombreedte" }, "compactView": { - "label": "Toon als tekst (compact)" + "label": "Weergeven als tekst (compact)" } }, "cpu": { "label": "CPU", "enabled": { - "label": "Toon in widget" + "label": "Weergeven in widget" }, "span": { "label": "Kolombreedte" }, "multiView": { - "label": "Toon als multi-core-weergave" + "label": "Weergeven als multi-core weergave" } }, "ram": { "label": "RAM", "enabled": { - "label": "Toon in widget" + "label": "Weergeven in widget" }, "span": { "label": "Kolombreedte" @@ -72,7 +72,7 @@ "gpu": { "label": "GPU", "enabled": { - "label": "Toon in widget" + "label": "Weergeven in widget" }, "span": { "label": "Kolombreedte" @@ -84,8 +84,8 @@ "card": { "title": "Dash.", "errors": { - "noService": "Geen Dash. service gevonden. Voeg er een toe aan uw Homarr dashboard of stel een Dashdot URL in in de opties van de module", - "noInformation": "Kan geen informatie verkrijgen van dash. - gebruikt u de laatste versie?", + "noService": "Geen Dash. service gevonden. Voeg er een toe aan je Homarr dashboard of stel een Dash. URL in in de module opties", + "noInformation": "Kan geen informatie verkrijgen van dash. - gebruik je de laatste versie?", "protocolDowngrade": { "title": "Protocol downgrade gedetecteerd", "text": "De verbinding met uw Dash. instantie gebruikt HTTP. Dit is een veiligheidsrisico, want HTTP is niet gecodeerd en aanvallers zouden deze verbinding kunnen misbruiken. Zorg ervoor dat Dash. HTTPS gebruikt, of downgrade Homarr naar HTTP (niet aanbevolen)." diff --git a/public/locales/nl/modules/date.json b/public/locales/nl/modules/date.json index 5d4269b53..d79cd7714 100644 --- a/public/locales/nl/modules/date.json +++ b/public/locales/nl/modules/date.json @@ -5,11 +5,11 @@ "settings": { "title": "Instellingen voor datum en tijd widget", "timezone": { - "label": "", - "info": "" + "label": "Tijdzone", + "info": "Selecteer de naam van je tijdzone, vind de jouwe hier: " }, "customTitle": { - "label": "" + "label": "Plaatsnaam of aangepaste titel" }, "display24HourFormat": { "label": "Volledige tijd weergeven (24-uur)" @@ -21,11 +21,11 @@ } }, "titleState": { - "label": "", + "label": "Klok titel", "info": "", "data": { "both": "", - "city": "", + "city": "Alleen titel", "none": "Geen" } } diff --git a/public/locales/nl/modules/dns-hole-summary.json b/public/locales/nl/modules/dns-hole-summary.json index a4b8f7e25..57ba024c3 100644 --- a/public/locales/nl/modules/dns-hole-summary.json +++ b/public/locales/nl/modules/dns-hole-summary.json @@ -20,9 +20,9 @@ "card": { "metrics": { "domainsOnAdlist": "Domeinen op adlists", - "queriesToday": "Vragen vandaag", - "queriesBlockedTodayPercentage": "", - "queriesBlockedToday": "" + "queriesToday": "Queries vandaag", + "queriesBlockedTodayPercentage": "Vandaag geblokkeerd", + "queriesBlockedToday": "Vandaag geblokkeerd" } } } diff --git a/public/locales/nl/modules/docker.json b/public/locales/nl/modules/docker.json index f7520eb7f..cddb32123 100644 --- a/public/locales/nl/modules/docker.json +++ b/public/locales/nl/modules/docker.json @@ -1,7 +1,7 @@ { "descriptor": { "name": "Docker", - "description": "Hiermee kunt u gemakkelijk al uw Docker Containers zien en beheren." + "description": "Geeft de mogelijkheid om al je Docker Containers gemakkelijk te zien en beheren." }, "search": { "placeholder": "Zoek op container of afbeeldingsnaam" @@ -41,7 +41,7 @@ "title": "Gegevens vernieuwen" }, "remove": { - "title": "Verwijder" + "title": "Verwijderen" }, "addToHomarr": { "title": "Toevoegen aan Homarr" @@ -53,7 +53,7 @@ "end": "Gestart" }, "stop": { - "start": "Bezig met Stoppen", + "start": "Bezig met stoppen", "end": "Gestopt" }, "restart": { @@ -68,7 +68,7 @@ "errors": { "integrationFailed": { "title": "Docker integratie mislukt", - "message": "Bent u vergeten de dokter-socket te koppelen?" + "message": "Ben je vergeten de docker-socket te koppelen?" }, "unknownError": { "title": "Er is een fout opgetreden" diff --git a/public/locales/nl/modules/health-monitoring.json b/public/locales/nl/modules/health-monitoring.json index dd45386b4..88e3a4a27 100644 --- a/public/locales/nl/modules/health-monitoring.json +++ b/public/locales/nl/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { + "label": "", "load": "", - "minute": "" - }, - "memory": { + "minute": "", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { + "info": "" + }, + "defaultViewState": { "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "data": { + "none": "Geen", + "node": "", + "vm": "", + "lxc": "", + "storage": "Opslagruimte" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "", + "minute": "" + }, + "memory": { + "label": "", + "totalMem": "", + "available": "" + }, + "fileSystem": { + "label": "", + "available": "" + }, + "info": { + "uptime": "", + "uptimeFormat": "", + "updates": "", + "reboot": "" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "Opslagruimte" + } + }, + "table": { + "header": { + "name": "Naam", + "cpu": "CPU", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Beschrijving", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/nl/modules/iframe.json b/public/locales/nl/modules/iframe.json index 180dd961b..c83087b17 100644 --- a/public/locales/nl/modules/iframe.json +++ b/public/locales/nl/modules/iframe.json @@ -39,7 +39,7 @@ "title": "Ongeldige URL", "text": "Zorg ervoor dat je een geldig adres hebt ingevoerd in de configuratie van je widget" }, - "browserSupport": "Uw browser ondersteunt geen iframes. Update uw browser." + "browserSupport": "Je browser ondersteunt geen iframes. Update je browser." } } } diff --git a/public/locales/nl/modules/media-requests-list.json b/public/locales/nl/modules/media-requests-list.json index 33383b2e0..279dbdcda 100644 --- a/public/locales/nl/modules/media-requests-list.json +++ b/public/locales/nl/modules/media-requests-list.json @@ -12,13 +12,13 @@ } } }, - "noRequests": "Geen verzoeken gevonden. Zorg ervoor dat u uw apps correct hebt geconfigureerd.", + "noRequests": "Geen verzoeken gevonden. Zorg ervoor dat je je apps correct hebt geconfigureerd.", "state": { "approved": "Goedgekeurd", "pendingApproval": "In afwachting van goedkeuring", "declined": "Afgewezen", "available": "", - "partial": "" + "partial": "Gedeeltelijk" }, "tooltips": { "approve": "Verzoeken goedkeuren", diff --git a/public/locales/nl/modules/media-server.json b/public/locales/nl/modules/media-server.json index 71b5472de..691d5d3f7 100644 --- a/public/locales/nl/modules/media-server.json +++ b/public/locales/nl/modules/media-server.json @@ -1,7 +1,7 @@ { "descriptor": { "name": "Media Server", - "description": "Interageer met uw Jellyfin of Plex mediaserver", + "description": "Interageer met je Jellyfin of Plex mediaserver", "settings": { "title": "Instellingen voor media server widget" } diff --git a/public/locales/nl/modules/media-transcoding.json b/public/locales/nl/modules/media-transcoding.json new file mode 100644 index 000000000..b6d1cc9e3 --- /dev/null +++ b/public/locales/nl/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Wachtrij", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "ETA", + "progress": "Voortgang" + }, + "empty": "Leeg", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Grootte" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Leeg", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Leeg", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Fout", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Wachtrij", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/nl/modules/notebook.json b/public/locales/nl/modules/notebook.json index 4e6d52923..cd011572e 100644 --- a/public/locales/nl/modules/notebook.json +++ b/public/locales/nl/modules/notebook.json @@ -17,11 +17,11 @@ }, "card": { "controls": { - "bold": "", - "italic": "", - "strikethrough": "", - "underline": "", - "colorText": "", + "bold": "Vetgedrukt", + "italic": "Schuingedrukt", + "strikethrough": "Doorgestreept", + "underline": "Onderstreept", + "colorText": "Kleur tekst", "colorHighlight": "", "code": "", "clear": "", @@ -29,17 +29,17 @@ "align": "", "blockquote": "", "horizontalLine": "", - "bulletList": "", + "bulletList": "Opsommingslijst", "orderedList": "", "checkList": "", "increaseIndent": "", "decreaseIndent": "", - "link": "", - "unlink": "", - "image": "", - "addTable": "", - "deleteTable": "", - "colorCell": "", + "link": "Link", + "unlink": "Link verwijderen", + "image": "Afbeelding insluiten", + "addTable": "Tabel toevoegen", + "deleteTable": "Tabel verwijderen", + "colorCell": "Kleur cel", "mergeCell": "", "addColumnLeft": "", "addColumnRight": "", diff --git a/public/locales/nl/modules/overseerr.json b/public/locales/nl/modules/overseerr.json index a8b92c2aa..70abc7e14 100644 --- a/public/locales/nl/modules/overseerr.json +++ b/public/locales/nl/modules/overseerr.json @@ -1,13 +1,13 @@ { "descriptor": { "name": "Overseerr", - "description": "Hiermee kunt u media zoeken en toevoegen vanuit Overseerr of Jellyseerr." + "description": "Hiermee kan je media zoeken en toevoegen vanuit Overseerr of Jellyseerr." }, "popup": { "item": { "buttons": { "askFor": "Vraag naar {{title}}", - "cancel": "Annuleer", + "cancel": "Annuleren", "request": "Aanvraag" }, "alerts": { @@ -18,7 +18,7 @@ } }, "seasonSelector": { - "caption": "Selecteer de seizoenen die u wilt downloaden", + "caption": "Selecteer de seizoenen die je wilt downloaden", "table": { "header": { "season": "Seizoen", diff --git a/public/locales/nl/modules/ping.json b/public/locales/nl/modules/ping.json index d95664309..bfbf8ff3f 100644 --- a/public/locales/nl/modules/ping.json +++ b/public/locales/nl/modules/ping.json @@ -1,7 +1,7 @@ { "descriptor": { "name": "Ping", - "description": "Toont een statusindicator afhankelijk van de HTTP-antwoordcode van een bepaalde URL." + "description": "Toont een statusindicator afhankelijk van de HTTP response code van een bepaalde URL." }, "states": { "online": "Online {{response}}", diff --git a/public/locales/nl/modules/search.json b/public/locales/nl/modules/search.json index dae9a0474..ca94fd822 100644 --- a/public/locales/nl/modules/search.json +++ b/public/locales/nl/modules/search.json @@ -25,6 +25,6 @@ "description": "Zoek naar Films en TV-series op Overseerr" } }, - "tip": "U kunt de zoekbalk selecteren met de sneltoets ", + "tip": "Je kan de zoekbalk selecteren met de sneltoets ", "switchedSearchEngine": "Omgeschakeld naar zoeken met {{searchEngine}}" } diff --git a/public/locales/nl/modules/smart-home/entity-state.json b/public/locales/nl/modules/smart-home/entity-state.json index 75dd923c8..45587f0a5 100644 --- a/public/locales/nl/modules/smart-home/entity-state.json +++ b/public/locales/nl/modules/smart-home/entity-state.json @@ -23,7 +23,12 @@ "displayFriendlyName": { "label": "", "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/nl/modules/torrents-status.json b/public/locales/nl/modules/torrents-status.json index 49083d16a..02aeec058 100644 --- a/public/locales/nl/modules/torrents-status.json +++ b/public/locales/nl/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "", "info": "" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "Down", + "up": "Up", + "eta": "ETA", + "progress": "Voortgang" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -63,7 +82,7 @@ }, "body": { "nothingFound": "Geen torrents gevonden", - "filterHidingItems": "{{count}} items worden verborgen door uw filters" + "filterHidingItems": "{{count}} items worden verborgen door je filters" } }, "lineChart": { @@ -84,10 +103,6 @@ "text": "Kan niet communiceren met je Torrent-clients. Controleer je configuratie" } }, - "loading": { - "title": "Laden", - "description": "Verbinding maken" - }, "popover": { "introductionPrefix": "Beheerd door", "metrics": { diff --git a/public/locales/nl/modules/weather.json b/public/locales/nl/modules/weather.json index cfcdf2543..026b97b26 100644 --- a/public/locales/nl/modules/weather.json +++ b/public/locales/nl/modules/weather.json @@ -11,10 +11,10 @@ "label": "Plaatsnaam weergeven" }, "displayWeekly": { - "label": "" + "label": "Wekelijkse voorspelling weergeven" }, "forecastDays": { - "label": "" + "label": "Dagen om weer te geven" }, "location": { "label": "Weerslocatie" @@ -40,4 +40,4 @@ } }, "error": "Er is een fout opgetreden" -} +} \ No newline at end of file diff --git a/public/locales/nl/settings/common.json b/public/locales/nl/settings/common.json index 94b80067f..3f1371462 100644 --- a/public/locales/nl/settings/common.json +++ b/public/locales/nl/settings/common.json @@ -6,7 +6,7 @@ "customizations": "Aanpassingen" }, "tips": { - "configTip": "Upload uw configuratiebestand door het naar de pagina te slepen!" + "configTip": "Upload je configuratiebestand door het naar de pagina te slepen!" }, "credits": { "madeWithLove": "Gemaakt met ❤️ door @", @@ -22,7 +22,7 @@ "title": "Voorbeeld", "subtitle": "Wijzigingen worden automatisch opgeslagen" }, - "divider": "Layout opties", + "divider": "Lay-out opties", "main": "Algemeen", "sidebar": "Zijbalk", "cannotturnoff": "Kan niet worden uitgeschakeld", diff --git a/public/locales/nl/settings/customization/general.json b/public/locales/nl/settings/customization/general.json index c148b3223..a93f65a2b 100644 --- a/public/locales/nl/settings/customization/general.json +++ b/public/locales/nl/settings/customization/general.json @@ -1,5 +1,5 @@ { - "text": "Met aanpassingen kunt u uw ervaring met Homarr configureren en aanpassen aan uw voorkeuren.", + "text": "Met aanpassingen kan je je ervaring met Homarr configureren en aanpassen aan jouw voorkeuren.", "accordeon": { "layout": { "name": "Indeling", @@ -7,7 +7,7 @@ }, "gridstack": { "name": "Gridstack", - "description": "Het gedrag en de kolommen van uw dashboard aanpassen" + "description": "Pas het gedrag en de kolommen van uw dashboardgebied aan" }, "pageMetadata": { "name": "Pagina metadata", diff --git a/public/locales/nl/settings/customization/gridstack.json b/public/locales/nl/settings/customization/gridstack.json index cb2093431..adb548a83 100644 --- a/public/locales/nl/settings/customization/gridstack.json +++ b/public/locales/nl/settings/customization/gridstack.json @@ -4,7 +4,7 @@ "descriptionPreset": "Aantal kolommen wanneer het scherm minder dan {{pixels}} pixels breed is.", "descriptionExceedsPreset": "Aantal kolommen wanneer het scherm groter is dan {{pixels}} pixels" }, - "unsavedChanges": "U heeft niet opgeslagen wijzigingen. Klik op de knop Wijzigingen toepassen hieronder om ze toe te passen en op te slaan.", + "unsavedChanges": "Je hebt niet opgeslagen wijzigingen. Klik op de knop Wijzigingen toepassen hieronder om ze toe te passen en op te slaan.", "applyChanges": "Wijzigingen toepassen", "defaultValues": "Standaardwaarden" } \ No newline at end of file diff --git a/public/locales/nl/settings/customization/opacity-selector.json b/public/locales/nl/settings/customization/opacity-selector.json index db60e2158..fa7bd10f0 100644 --- a/public/locales/nl/settings/customization/opacity-selector.json +++ b/public/locales/nl/settings/customization/opacity-selector.json @@ -1,3 +1,3 @@ { - "label": "App Ondoorzichtigheid" + "label": "App opacity" } \ No newline at end of file diff --git a/public/locales/nl/settings/customization/page-appearance.json b/public/locales/nl/settings/customization/page-appearance.json index fd600c677..ca2b258ff 100644 --- a/public/locales/nl/settings/customization/page-appearance.json +++ b/public/locales/nl/settings/customization/page-appearance.json @@ -1,11 +1,11 @@ { "pageTitle": { "label": "Paginatitel", - "description": "De titel van het dashboard linksboven" + "description": "De dashboard titel linksboven" }, "metaTitle": { - "label": "Meta Titel", - "description": "De titel die wordt weergegeven in uw browsertabblad" + "label": "Meta titel", + "description": "De titel die wordt weergegeven in je browsertabblad" }, "logo": { "label": "Logo", @@ -13,7 +13,7 @@ }, "favicon": { "label": "Favicon", - "description": "Het pictogram dat wordt weergegeven in uw browsertabblad" + "description": "Het pictogram dat wordt weergegeven in je browsertabblad" }, "background": { "label": "Achtergrond" @@ -26,9 +26,9 @@ } }, "backgroundImageSize": { - "label": "", + "label": "Grootte achtergrondafbeelding", "options": { - "cover": "", + "cover": "Bedekken - Schaalt de afbeelding zo klein mogelijk om het hele venster te bedekken door overtollige ruimte bij te snijden. (aanbevolen)", "contain": "" } }, @@ -43,8 +43,8 @@ }, "customCSS": { "label": "Eigen CSS", - "description": "Pas uw dashboard verder aan met behulp van CSS, alleen aanbevolen voor ervaren gebruikers", + "description": "Pas je dashboard verder aan met behulp van CSS, alleen aanbevolen voor ervaren gebruikers", "placeholder": "Eigen CSS wordt als laatste toegepast", - "applying": "CSS toepassen..." + "applying": "CSS aan het toepassen..." } } diff --git a/public/locales/nl/user/preferences.json b/public/locales/nl/user/preferences.json index 3b17aafba..b3cb5c0fd 100644 --- a/public/locales/nl/user/preferences.json +++ b/public/locales/nl/user/preferences.json @@ -1,6 +1,6 @@ { "metaTitle": "Voorkeuren", - "pageTitle": "Uw voorkeuren", + "pageTitle": "Jouw voorkeuren", "boards": { "defaultBoard": { "label": "Standaardkaart" diff --git a/public/locales/nl/widgets/error-boundary.json b/public/locales/nl/widgets/error-boundary.json index 7d35409c0..b43207187 100644 --- a/public/locales/nl/widgets/error-boundary.json +++ b/public/locales/nl/widgets/error-boundary.json @@ -8,7 +8,7 @@ }, "modal": { "text": "", - "label": "Uw fout", + "label": "Je fout", "reportButton": "Deze fout melden" } } diff --git a/public/locales/no/authentication/login.json b/public/locales/no/authentication/login.json index ab0f3bbd4..382988f07 100644 --- a/public/locales/no/authentication/login.json +++ b/public/locales/no/authentication/login.json @@ -16,8 +16,8 @@ }, "afterLoginRedirection": "Etter pålogging blir du omdirigert til {{url}}", "providersEmpty": { - "title": "", - "message": "" + "title": "Feil ved Auth leverandør", + "message": "Leverandøren(e) er ikke angitt, sjekk loggene dine for mer informasjon." } }, "alert": "Påloggingsinformasjonen din er feil eller denne kontoen eksisterer ikke. Vennligst prøv på nytt." diff --git a/public/locales/no/modules/health-monitoring.json b/public/locales/no/modules/health-monitoring.json index dd45386b4..30e8e1f61 100644 --- a/public/locales/no/modules/health-monitoring.json +++ b/public/locales/no/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Systemhelseovervåking", + "description": "Viser informasjon som viser helsen og statusen til systemet(e).", + "settings": { + "title": "Innstillinger for systemhelseovervåking", + "fahrenheit": { + "label": "CPU-temp i Fahrenheit" + }, + "cpu": { + "label": "Vis CPU-info", "load": "", - "minute": "" - }, - "memory": { - "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { - "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "minute": "", + "minutes": "{{minutes}} minutter" + }, + "memory": { + "label": "Vis minneinfo" + }, + "fileSystem": { + "label": "Vis filsysteminfo" + }, + "node": { + "label": "Filtrer etter nodenavn", + "info": "Skriv inn Proxmox-nodenavnet ditt for kun å vise beregninger for den noden. Som standard vises hele klyngen." + }, + "defaultViewState": { + "label": "Seksjon åpen som standard", + "data": { + "none": "Ingen", + "node": "Noder", + "vm": "VM-er", + "lxc": "LXC-er", + "storage": "Lagring" } + }, + "defaultTabState": { + "label": "Fane åpen som standard", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "", + "minute": "" + }, + "memory": { + "label": "", + "totalMem": "", + "available": "" + }, + "fileSystem": { + "label": "", + "available": "" + }, + "info": { + "uptime": "", + "uptimeFormat": "", + "updates": "", + "reboot": "" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Noder", + "vms": "VM-er", + "lxcs": "LXC-er", + "storage": "Lagring" + } + }, + "table": { + "header": { + "name": "Navn", + "cpu": "CPU", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Detaljer", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/no/modules/media-transcoding.json b/public/locales/no/modules/media-transcoding.json new file mode 100644 index 000000000..b43b081a4 --- /dev/null +++ b/public/locales/no/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Kø", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "Gjenstående tid (estimat)", + "progress": "Fremgang" + }, + "empty": "Tøm", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Størrelse" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Tøm", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Tøm", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Feil", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Kø", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/no/modules/smart-home/entity-state.json b/public/locales/no/modules/smart-home/entity-state.json index b48f3453f..267ba75b6 100644 --- a/public/locales/no/modules/smart-home/entity-state.json +++ b/public/locales/no/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Vis brukervennlig navn", - "info": "Vis brukervennlig navn fra Home Assistant i stedet for visningsnavn" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/no/modules/torrents-status.json b/public/locales/no/modules/torrents-status.json index e8e00479a..1adff6a26 100644 --- a/public/locales/no/modules/torrents-status.json +++ b/public/locales/no/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Vis filtrerte torrents listeforhold", "info": "Hvis deaktivert, vil bare det globale forholdet vises. Det globale forholdet vil fortsatt bruke etikettene hvis angitt" + }, + "columnOrdering": { + "label": "Aktiver omorganisering av kolonnene" + }, + "rowSorting": { + "label": "Aktiver sortering av radene" + }, + "columns": { + "label": "Velg kolonner som skal vises", + "data": { + "date": "Dato lagt til", + "down": "Ned", + "up": "Opp", + "eta": "Gjenstående tid (estimat)", + "progress": "Fremgang" + } + }, + "nameColumnSize": { + "label": "Endre størrelsen på navnekolonnen" } } }, @@ -47,7 +66,7 @@ "size": "Størrelse", "download": "Ned", "upload": "Opp", - "estimatedTimeOfArrival": "Gjenstående tid (estimat)", + "estimatedTimeOfArrival": "ETA", "progress": "Fremgang", "totalUploaded": "Total opplasting", "totalDownloaded": "Totalt nedlasting", @@ -84,10 +103,6 @@ "text": "Kan ikke kommunisere med Torrent-klientene dine. Vennligst sjekk konfigurasjonen din" } }, - "loading": { - "title": "Laster", - "description": "Etablerer en forbindelse" - }, "popover": { "introductionPrefix": "Administrert av", "metrics": { diff --git a/public/locales/no/modules/weather.json b/public/locales/no/modules/weather.json index 4a6df5ba2..45f7b9d9d 100644 --- a/public/locales/no/modules/weather.json +++ b/public/locales/no/modules/weather.json @@ -11,10 +11,10 @@ "label": "Vis bynavn" }, "displayWeekly": { - "label": "" + "label": "Vis ukentlig Værmelding" }, "forecastDays": { - "label": "" + "label": "Dager å vise" }, "location": { "label": "Vær plassering" @@ -40,4 +40,4 @@ } }, "error": "En feil oppstod" -} +} \ No newline at end of file diff --git a/public/locales/pl/modules/health-monitoring.json b/public/locales/pl/modules/health-monitoring.json index dd45386b4..0515aee8a 100644 --- a/public/locales/pl/modules/health-monitoring.json +++ b/public/locales/pl/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { + "label": "", "load": "", - "minute": "" - }, - "memory": { + "minute": "", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { + "info": "" + }, + "defaultViewState": { "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "data": { + "none": "Żaden", + "node": "", + "vm": "", + "lxc": "", + "storage": "Pamięć" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "", + "minute": "" + }, + "memory": { + "label": "", + "totalMem": "", + "available": "" + }, + "fileSystem": { + "label": "", + "available": "" + }, + "info": { + "uptime": "", + "uptimeFormat": "", + "updates": "", + "reboot": "" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "Pamięć" + } + }, + "table": { + "header": { + "name": "Nazwa", + "cpu": "CPU", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Szczegóły", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/pl/modules/media-transcoding.json b/public/locales/pl/modules/media-transcoding.json new file mode 100644 index 000000000..b00ab82fb --- /dev/null +++ b/public/locales/pl/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Kolejka", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "ETA", + "progress": "Postęp" + }, + "empty": "Puste", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Rozmiar" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Puste", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Puste", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Błąd", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Kolejka", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/pl/modules/smart-home/entity-state.json b/public/locales/pl/modules/smart-home/entity-state.json index 7f5fe40e1..91d4065b8 100644 --- a/public/locales/pl/modules/smart-home/entity-state.json +++ b/public/locales/pl/modules/smart-home/entity-state.json @@ -23,7 +23,12 @@ "displayFriendlyName": { "label": "", "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/pl/modules/torrents-status.json b/public/locales/pl/modules/torrents-status.json index 312785e3e..1863277a3 100644 --- a/public/locales/pl/modules/torrents-status.json +++ b/public/locales/pl/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Wyświetl współczynnik listy przefiltrowanych torrentów", "info": "Jeśli ta opcja jest wyłączona, wyświetlany będzie tylko współczynnik globalny. Współczynnik globalny będzie nadal używał etykiet, jeśli są ustawione" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "Pobieranie", + "up": "Udostępnianie", + "eta": "ETA", + "progress": "Postęp" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "Nie można połączyć się z klientami Torrent. Sprawdź konfigurację" } }, - "loading": { - "title": "Ładowanie", - "description": "Nawiązywanie połączenia" - }, "popover": { "introductionPrefix": "Zarządzany przez", "metrics": { diff --git a/public/locales/pt/authentication/login.json b/public/locales/pt/authentication/login.json index e0011a8db..d08a2c77c 100644 --- a/public/locales/pt/authentication/login.json +++ b/public/locales/pt/authentication/login.json @@ -1,7 +1,7 @@ { - "metaTitle": "Login", + "metaTitle": "“Login”", "title": "Bem-vindo de volta!", - "text": "Digite suas credenciais", + "text": "Por favor insira suas credenciais", "form": { "fields": { "username": { @@ -16,8 +16,8 @@ }, "afterLoginRedirection": "Após o login, você será redirecionado para {{url}}", "providersEmpty": { - "title": "", - "message": "" + "title": "Erro do provedor de autenticação", + "message": "O(s) provedo(s) não está(ão) definido(s). Por favor, verifique seus logs para mais informações." } }, "alert": "Suas credenciais estão incorretas ou esta conta não existe. Tente novamente." diff --git a/public/locales/pt/modules/health-monitoring.json b/public/locales/pt/modules/health-monitoring.json index bcd7ddacd..bd01b5577 100644 --- a/public/locales/pt/modules/health-monitoring.json +++ b/public/locales/pt/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Monitoramento da integridade do sistema", - "description": "Informações sobre o seu NAS", - "settings": { - "title": "Monitoramento da integridade do sistema", - "fahrenheit": { - "label": "Fahrenheit" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Monitoramento da integridade do sistema", + "description": "Exibe informações que mostram a saúde e status de seu(s) sistema(s).", + "settings": { + "title": "Configurações para monitoramento de saúde do sistema", + "fahrenheit": { + "label": "Temperatura da CPU em Fahrenheit" + }, + "cpu": { + "label": "Mostrar informações da CPU", "load": "Carga Média", - "minute": "{{minute}} minuto" - }, - "memory": { - "label": "Memória", - "totalMem": "Memória total: {{total}}GB", - "available": "Disponível: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "Sistema de arquivos", - "available": "Disponível: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "Tempo de Atividade", - "updates": "Atualizações", - "reboot": "Reiniciar" - }, - "errors": { - "general": { - "title": "Não foi possível encontrar seu NAS", - "text": "Ocorreu um problema na conexão com seu NAS. Verifique sua(s) configuração(ões)/integração(ões)." + "minute": "{{minute}} minuto", + "minutes": "{{minutes}} minutos" + }, + "memory": { + "label": "Mostrar informações da memória" + }, + "fileSystem": { + "label": "Mostrar informações do sistema de arquivos" + }, + "node": { + "label": "Filtrar por nome do nó", + "info": "Insira o nome do nó Proxmox para mostrar métricas desse nó. Por padrão, o cluster inteiro é mostrado." + }, + "defaultViewState": { + "label": "Seção aberta por padrão", + "data": { + "none": "Nenhum", + "node": "Nós", + "vm": "VMs", + "lxc": "LXCs", + "storage": "Armazenamento" } + }, + "defaultTabState": { + "label": "Aba aberta por padrão", + "info": "Aba aberta por padrão. Usado somente quando várias integrações estão disponíveis.", + "data": { + "system": "Sistema", + "cluster": "Cluster" + } + }, + "summary": { + "label": "Mostrar seção de resumo" + }, + "showNode": { + "label": "Mostrar seção de nós" + }, + "showVM": { + "label": "Mostrar seção de VMs" + }, + "showLXCs": { + "label": "Mostrar seção de LXCs" + }, + "showStorage": { + "label": "Mostrar seção de armazenamento" + }, + "sectionIndicatorColor": { + "label": "Requisito para o indicador de status de seção ser 'OK'", + "info": "'Todos' exige que todos os itens estejam online para que o indicador fique verde. 'Qualquer' requer que pelo menos um item esteja online.", + "data": { + "any": "Qualquer ativo", + "all": "Todos ativos" + } + }, + "ignoreCert": { + "label": "Ignorar erros de certificado", + "info": "Se ativado, o widget irá ignorar os erros de certificado ao acessar a API do Proxmox. Isso pode ser útil ao acessar o Proxmox por meio de HTTPS." + } } + }, + "cpu": { + "label": "CPU", + "load": "Carga Média", + "minute": "{{minute}} minuto" + }, + "memory": { + "label": "Memória", + "totalMem": "Memória total: {{total}}GB", + "available": "Disponível: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Sistema de arquivos", + "available": "Disponível: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Tempo de Atividade", + "uptimeFormat": "{{days}} dias, {{hours}} horas", + "updates": "Atualizações disponíveis", + "reboot": "Reiniciar" + }, + "errors": { + "general": { + "title": "Não foi possível localizar seu(s) sistema(s).", + "text": "Ocorreu um problema na conexão com seu sistema. Verifique sua(s) configuração(ões)/integração(ões)." + } + }, + "headings": { + "system": "Sistema", + "cluster": "Cluster" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Nós", + "vms": "VMs", + "lxcs": "LXCs", + "storage": "Armazenamento" + } + }, + "table": { + "header": { + "name": "Nome", + "cpu": "CPU", + "ram": "RAM", + "node": "Nó" + } + }, + "popover": { + "node": "Nó", + "vmid": "VMID", + "details": "Detalhes", + "cores": "Núcleos - {{maxCpu}}", + "memSize": "Memória - {{maxMem}}", + "memRatio": "Memória - {{usedMem}} / {{maxMem}}", + "diskSize": "Disco - {{maxDisk}}", + "diskRatio": "Disco - {{usedDisk}} / {{maxDisk}}", + "uptime": "Tempo de atividade - {{uptime}}", + "plugin": "Extensão", + "ha": "Estado HA - {{haState}}", + "sharedStorage": "Armazenamento Compartilhado", + "localStorage": "Armazenamento Local", + "na": "N/D" + } + } } \ No newline at end of file diff --git a/public/locales/pt/modules/media-transcoding.json b/public/locales/pt/modules/media-transcoding.json new file mode 100644 index 000000000..d4b8a9838 --- /dev/null +++ b/public/locales/pt/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Transcodificação de mídia", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Fila", + "statistics": "Estatísticas" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "Ficheiro", + "eta": "TED", + "progress": "Progresso" + }, + "empty": "Vazio", + "tooltip": { + "transcode": "Transcodificar", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "Ficheiro", + "size": "Tamanho" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Vazio", + "tooltip": { + "transcode": "Transcodificar", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Vazio", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "Codecs", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Erro", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Fila", + "statistics": "Estatísticas" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/pt/modules/smart-home/entity-state.json b/public/locales/pt/modules/smart-home/entity-state.json index ba2f751dc..db3dbbf9b 100644 --- a/public/locales/pt/modules/smart-home/entity-state.json +++ b/public/locales/pt/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Exibir nome amigável", - "info": "Exibir nome amigável do Home Assistant em vez do nome de exibição" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/pt/modules/torrents-status.json b/public/locales/pt/modules/torrents-status.json index 7fa0e918f..77865361a 100644 --- a/public/locales/pt/modules/torrents-status.json +++ b/public/locales/pt/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Exibir proporção da lista de torrents filtrados", "info": "Se estiver desativado, somente a proporção global será exibida. A proporção global ainda usará os rótulos se estiver definida" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "Selecione colunas para exibir", + "data": { + "date": "", + "down": "Para baixo", + "up": "Para cima", + "eta": "TED", + "progress": "Progresso" + } + }, + "nameColumnSize": { + "label": "Alterar o tamanho da coluna do nome" } } }, @@ -84,10 +103,6 @@ "text": "Não é possível se comunicar com seus clientes Torrent. Verifique sua configuração" } }, - "loading": { - "title": "Carregamento", - "description": "Estabelecimento de uma conexão" - }, "popover": { "introductionPrefix": "Gerido por", "metrics": { diff --git a/public/locales/pt/modules/weather.json b/public/locales/pt/modules/weather.json index 389d90f89..df8d043f1 100644 --- a/public/locales/pt/modules/weather.json +++ b/public/locales/pt/modules/weather.json @@ -11,10 +11,10 @@ "label": "Exibir nome da cidade" }, "displayWeekly": { - "label": "" + "label": "Exibir previsão semanal" }, "forecastDays": { - "label": "" + "label": "Dias a exibir" }, "location": { "label": "Localização do tempo" @@ -40,4 +40,4 @@ } }, "error": "Ocorreu um erro" -} +} \ No newline at end of file diff --git a/public/locales/ro/authentication/invite.json b/public/locales/ro/authentication/invite.json new file mode 100644 index 000000000..b392a1744 --- /dev/null +++ b/public/locales/ro/authentication/invite.json @@ -0,0 +1,35 @@ +{ + "metaTitle": "Creare cont", + "title": "Creare cont", + "text": "Vă rugam să introduceți datele de conectare mai jos", + "form": { + "fields": { + "username": { + "label": "Utilizator" + }, + "password": { + "label": "Parola" + }, + "passwordConfirmation": { + "label": "Confirmare parola" + } + }, + "buttons": { + "submit": "Creare cont" + } + }, + "notifications": { + "loading": { + "title": "Contul se creează", + "text": "Vă rugăm așteptați" + }, + "success": { + "title": "Contul a fost creat", + "text": "Contul tău a fost creat cu succes" + }, + "error": { + "title": "Eroare", + "text": "A apărut o eroare, ai primit următoarea eroare: {{error}}" + } + } +} \ No newline at end of file diff --git a/public/locales/ro/authentication/login.json b/public/locales/ro/authentication/login.json new file mode 100644 index 000000000..4d33fc6ec --- /dev/null +++ b/public/locales/ro/authentication/login.json @@ -0,0 +1,24 @@ +{ + "metaTitle": "Utilizator", + "title": "Bine ați revenit!", + "text": "Vă rugăm să introduceți datele de conectare", + "form": { + "fields": { + "username": { + "label": "Utilizator" + }, + "password": { + "label": "Parola" + } + }, + "buttons": { + "submit": "Conectare" + }, + "afterLoginRedirection": "După conectare, veți fi redirecționat către {{url}}", + "providersEmpty": { + "title": "Eroare autentificare cu furnizorul", + "message": "Furnizorul (furnizorii) nu sunt setați, vă rugăm să verificați log-urile pentru mai multe informații." + } + }, + "alert": "Datele de conectare sunt incorecte sau acest cont nu există. Vă rugăm să încercați din nou." +} \ No newline at end of file diff --git a/public/locales/ro/boards/common.json b/public/locales/ro/boards/common.json new file mode 100644 index 000000000..bd90c85a3 --- /dev/null +++ b/public/locales/ro/boards/common.json @@ -0,0 +1,5 @@ +{ + "header": { + "customize": "Personalizați planșa" + } +} \ No newline at end of file diff --git a/public/locales/ro/boards/customize.json b/public/locales/ro/boards/customize.json new file mode 100644 index 000000000..0269ef94e --- /dev/null +++ b/public/locales/ro/boards/customize.json @@ -0,0 +1,29 @@ +{ + "metaTitle": "Personalizați planșa {{name}}", + "pageTitle": "Personalizări pentru planșa {{name}}", + "backToBoard": "Înapoi la planșă", + "settings": { + "appearance": { + "primaryColor": "Culoare de bază", + "secondaryColor": "Culoare secundară" + } + }, + "save": { + "button": "Salvați schimbările", + "note": "Atenție, aveți schimbări nesalvate!" + }, + "notifications": { + "pending": { + "title": "Se salvează personalizările", + "message": "Vă rugăm să așteptați pană salvăm personalizările" + }, + "success": { + "title": "Personalizările au fost salvate", + "message": "Personalizări au fost salvate cu succes" + }, + "error": { + "title": "Eroare", + "message": "Schimbările nu au putut fi salvate" + } + } +} \ No newline at end of file diff --git a/public/locales/ro/common.json b/public/locales/ro/common.json new file mode 100644 index 000000000..7c60b4ee9 --- /dev/null +++ b/public/locales/ro/common.json @@ -0,0 +1,58 @@ +{ + "save": "Salvează", + "apply": "Aplică", + "insert": "Introdu", + "about": "Despre", + "cancel": "Anulează", + "close": "Închide", + "back": "Înapoi", + "delete": "Șterge", + "ok": "OK", + "edit": "Editare", + "next": "Următorul", + "previous": "Anteriorul", + "confirm": "Confirma", + "enabled": "Activat", + "duplicate": "Duplicare", + "disabled": "Dezactivat", + "enableAll": "Activați toate", + "disableAll": "Dezactivaţi toate", + "version": "Versiune", + "changePosition": "Schimbă locația", + "remove": "Elimină", + "removeConfirm": "Sunteți sigur că doriți să eliminați {{item}}?", + "createItem": "+ creează {{item}}", + "sections": { + "settings": "Setări", + "dangerZone": "Zonă periculoasă" + }, + "secrets": { + "apiKey": "Cheie API", + "username": "Utilizator", + "password": "Parola" + }, + "tip": "Pont: ", + "time": { + "seconds": "secunde", + "minutes": "minute", + "hours": "ore" + }, + "loading": "Se încarcă...", + "breakPoints": { + "small": "mic", + "medium": "mediu", + "large": "mare" + }, + "seeMore": "Vezi mai mult...", + "position": { + "left": "Stânga", + "center": "Centru", + "right": "Dreapta" + }, + "attributes": { + "width": "Lățime", + "height": "Înălțime" + }, + "public": "Public", + "restricted": "Restricţionat" +} \ No newline at end of file diff --git a/public/locales/ro/layout/common.json b/public/locales/ro/layout/common.json new file mode 100644 index 000000000..1c9b026cd --- /dev/null +++ b/public/locales/ro/layout/common.json @@ -0,0 +1,25 @@ +{ + "modals": { + "blockedPopups": { + "title": "Popup-uri blocate", + "text": "Browser-ul dumneavoastră a blocat Homarr in a accesa API-ului său. Acest lucru este cel mai frecvent cauzat de blocatoare de anunțuri (ca AdBlockers) sau permisiuni refuzate. Homarr nu poate solicita automat permisiuni.", + "list": { + "browserPermission": "Faceți clic pe pictogramă de lângă adresa URL și verificați permisiunile. Permiteți accesul la Popup-uri și ferestre noi", + "adBlockers": "Dezactivați blocatoarele de anunțuri și instrumentele de securitate din browser", + "otherBrowser": "Încercați un alt browser" + } + } + }, + "actions": { + "category": { + "openAllInNewTab": "Deschide toate în pagină nouă" + } + }, + "menu": { + "moveUp": "Mută în sus", + "moveDown": "Mută în jos", + "addCategory": "Adaugă categorie {{location}}", + "addAbove": "deasupra", + "addBelow": "dedesubt" + } +} \ No newline at end of file diff --git a/public/locales/ro/layout/element-selector/selector.json b/public/locales/ro/layout/element-selector/selector.json new file mode 100644 index 000000000..9ded34c79 --- /dev/null +++ b/public/locales/ro/layout/element-selector/selector.json @@ -0,0 +1,26 @@ +{ + "modal": { + "title": "Adaugă un nou indicator", + "text": "Indicatoarele sunt elementul principal ale Homarr-ului. Acestea sunt folosite pentru a vă afișa aplicațiile și alte informații. Puteți adăuga câte indicatoare doriți." + }, + "widgetDescription": "Widget-urile interacționează cu aplicațiile dvs., pentru a vă oferi mai mult control asupra aplicațiilor dvs. De obicei, acestea necesită o configurație suplimentară înainte de prima utilizare.", + "goBack": "Reveniți la pasul anterior", + "actionIcon": { + "tooltip": "Adaugă un indicator" + }, + "apps": "Aplicații", + "app": { + "defaultName": "Aplicația ta" + }, + "widgets": "Widget-uri", + "categories": "Categorii", + "category": { + "newName": "Denumirea noi categorii", + "defaultName": "Categorie nouă", + "created": { + "title": "Categorie creată", + "message": "Categoria {{name}} a fost creată cu succes" + } + }, + "importFromDocker": "Importa din Docker" +} diff --git a/public/locales/ro/layout/errors/access-denied.json b/public/locales/ro/layout/errors/access-denied.json new file mode 100644 index 000000000..1083da2f0 --- /dev/null +++ b/public/locales/ro/layout/errors/access-denied.json @@ -0,0 +1,5 @@ +{ + "title": "Acces refuzat", + "text": "Nu aveți permisiuni suficiente pentru a accesa această pagină. Dacă credeți că acest lucru nu este intenționat, vă rugăm să contactați administratorul.", + "switchAccount": "Schimbați contul" +} \ No newline at end of file diff --git a/public/locales/ro/layout/errors/not-found.json b/public/locales/ro/layout/errors/not-found.json new file mode 100644 index 000000000..2fc0358d0 --- /dev/null +++ b/public/locales/ro/layout/errors/not-found.json @@ -0,0 +1,5 @@ +{ + "title": "Pagina nu a fost găsită", + "text": "Această pagină nu a putut fi găsită. Este posibil ca adresa URL a acestei pagini să fi expirat, adresa URL să fie incorectă sau să nu aveți permisiunile necesare pentru a accesa această resursă.", + "button": "Întoarcere la pagina principală" +} \ No newline at end of file diff --git a/public/locales/ro/layout/header.json b/public/locales/ro/layout/header.json new file mode 100644 index 000000000..7cc316b36 --- /dev/null +++ b/public/locales/ro/layout/header.json @@ -0,0 +1,27 @@ +{ + "search": { + "label": "Caută", + "engines": { + "web": "Caută {{query}} pe web", + "youtube": "Caută {{query}} pe YouTube", + "torrent": "Caută {{query}} in torrente", + "movie": "Caută {{query}} in {{app}}" + } + }, + "actions": { + "avatar": { + "switchTheme": "Schimbă tema", + "preferences": "Preferințele utilizatorului", + "defaultBoard": "Planșa de bază", + "manage": "Gestionați", + "logout": "Deconectarea utilizatorului {{username}}", + "login": "Utilizator" + } + }, + "modals": { + "movie": { + "title": "", + "topResults": "Primele {{count}} rezultate pentru căutarea: {{search}}." + } + } +} \ No newline at end of file diff --git a/public/locales/ro/layout/header/actions/toggle-edit-mode.json b/public/locales/ro/layout/header/actions/toggle-edit-mode.json new file mode 100644 index 000000000..048ba7f47 --- /dev/null +++ b/public/locales/ro/layout/header/actions/toggle-edit-mode.json @@ -0,0 +1,12 @@ +{ + "description": "În modul editare, puteți ajusta indicatorii și configura aplicații. Modificările nu sunt salvate până când nu ieșiți din modul editare.", + "button": { + "disabled": "Întrare in modul editare", + "enabled": "Salvați modificările și ieșiți" + }, + "popover": { + "title": "Modul editare este activat pentru mărimea {{size}}", + "text": "Puteți ajusta și personaliza aplicațiile acum. Modificările nu sunt salvate până când ieșiți din modul editare" + }, + "unloadEvent": "Ieșiți din modul editare pentru a salva schimbările" +} diff --git a/public/locales/ro/layout/manage.json b/public/locales/ro/layout/manage.json new file mode 100644 index 000000000..bf23af368 --- /dev/null +++ b/public/locales/ro/layout/manage.json @@ -0,0 +1,36 @@ +{ + "navigation": { + "home": { + "title": "Acasă" + }, + "boards": { + "title": "Planșe" + }, + "users": { + "title": "Utilizatori", + "items": { + "manage": "Gestionați", + "invites": "Invitații" + } + }, + "help": { + "title": "Ajutor", + "items": { + "documentation": "Documentație", + "report": "Raportați o problemă / un bug", + "discord": "Comunitatea Discord", + "contribute": "Contribuie" + } + }, + "tools": { + "title": "Unelte", + "items": { + "docker": "Docker", + "api": "API" + } + }, + "about": { + "title": "Despre" + } + } +} \ No newline at end of file diff --git a/public/locales/ro/layout/mobile/drawer.json b/public/locales/ro/layout/mobile/drawer.json new file mode 100644 index 000000000..a59f6fd7e --- /dev/null +++ b/public/locales/ro/layout/mobile/drawer.json @@ -0,0 +1,3 @@ +{ + "title": "{{position}} bară laterală" +} diff --git a/public/locales/ro/layout/modals/about.json b/public/locales/ro/layout/modals/about.json new file mode 100644 index 000000000..34092de20 --- /dev/null +++ b/public/locales/ro/layout/modals/about.json @@ -0,0 +1,30 @@ +{ + "description": "Homarr este o planșă elegantă și modernă care vă pune toate aplicațiile și serviciile la îndemână. Cu Homarr, puteți accesa și controla totul dintr-o singură locație convenabilă. Homarr se integrează perfect cu aplicațiile pe care le-ați adăugat, oferindu-vă informații valoroase și oferindu-vă control complet. Instalarea este facilă, iar Homarr acceptă o gamă largă de implementari.", + "addToDashboard": "Adaugă în planșă", + "tip": "Mod se referă la tasta modificator, ca tasta Ctrl sau Command/Super/Windows", + "key": "Combinație taste pentru acces rapid", + "action": "Acțiune", + "keybinds": "Legături taste", + "translators": "Traducători ({{count}})", + "translatorsDescription": "Mulțumită acestor persoane, Homarr este disponibil în {{languages}} limbi! Vrei să ajuți să traduci Homarr în limba ta? Citește aici cum să faci acest lucru.", + "contributors": "Contribuitori ({{count}})", + "contributorsDescription": "Acești oameni au construit codul sursă care face ca Homarr să funcționeze! Vrei să ajuți la construirea lui Homarr? Citește aici cum să faci acest lucru", + "actions": { + "toggleTheme": "Comută între tema luminoasă/inchisă", + "focusSearchBar": "Accesați bara de căutare", + "openDocker": "Deschide widget-ul Docker", + "toggleEdit": "Comută în modul editare" + }, + "metrics": { + "configurationSchemaVersion": "Versiunea schemei de configurare", + "version": "Versiune", + "nodeEnvironment": "Tipul sistemului", + "i18n": "Limbi pentru traduceri încărcate de tip I18n", + "locales": "Traduceri de tip I18n configurate", + "experimental_disableEditMode": "EXPERIMENTAL: Dezactivează modul editare" + }, + "version": { + "new": "Nou: {{newVersion}}", + "dropdown": "Versiunea {{newVersion}} este disponibilă! Versiunea curentă este {{currentVersion}}" + } +} \ No newline at end of file diff --git a/public/locales/ro/layout/modals/add-app.json b/public/locales/ro/layout/modals/add-app.json new file mode 100644 index 000000000..2cf647ee5 --- /dev/null +++ b/public/locales/ro/layout/modals/add-app.json @@ -0,0 +1,128 @@ +{ + "tabs": { + "general": "General", + "behaviour": "Comportament", + "network": "Rețea", + "appearance": "Aspect", + "integration": "Integrare" + }, + "general": { + "appname": { + "label": "Numele aplicației", + "description": "Text folosit pentru a fi afișat numele aplicației pe planșă." + }, + "internalAddress": { + "label": "Adresa internă", + "description": "Adresa IP internă a aplicației.", + "troubleshoot": { + "label": "Întâmpinați probleme?", + "header": "Iată o listă de greșeli frecvente și sugestii de depanare:", + "lines": { + "nothingAfterPort": "Ar trebui, în cele mai multe cazuri, să nu introduceți nici o cale după port. (Chiar și '/admin' pentru Pi-hole sau '/web' pentru Plex)", + "protocolCheck": "Asigurați-vă întotdeauna că adresa URL are prefixul de http sau https, și asigurați-vă că utilizați adresa corectă.", + "preferIP": "Este recomandat să utilizați IP-ul direct al echipamentului sau containerului cu care încercați să comunicați.", + "enablePings": "Verificați dacă IP-ul este corect prin activarea ping-urilor. Personalizați Planșă -> Aspect -> Activați ping. Un mic indicator roșu sau verde va apărea in imaginea aplicației iar la trecerea cu mouse-ul peste vă va arăta codul de răspuns (un indicator verde pentru cod 200 este de așteptat în majoritatea cazurilor).", + "wget": "Pentru a vă asigura că Homarr poate comunica cu celelalte aplicații, folosiți unelte ca wget/curl/ping cu destinația IP-ul aplicației:port-ul.", + "iframe": "Când vine vorba de iframe, acestea ar trebui sa folosească întotdeauna același protocol (http/s) ca Homarr.", + "clearCache": "Unele informații sunt înregistrate în memoria cache, astfel o integrare ar putea să nu funcționeze decât după ce ștergeți memoria cache în opțiunile generale ale Homarr." + }, + "footer": "Pentru ajutor și alte sugestii de depanări cereți ajutor pe {{discord}}." + } + }, + "externalAddress": { + "label": "Adresa externă", + "description": "Adresa URL-ul care va fi deschisă atunci când faceți clic pe aplicație." + } + }, + "behaviour": { + "isOpeningNewTab": { + "label": "Deschideți într-o pagină nouă", + "description": "Deschideți aplicația într-o pagină nouă in loc de pagina curentă." + }, + "tooltipDescription": { + "label": "Descrierea aplicației", + "description": "Textul pe care îl introduceți aici va apărea atunci când treceți cu mouse-ul peste aplicație.\nUtilizați acestă secțiune pentru a oferi utilizatorilor mai multe detalii despre aplicație sau lăsați câmpul gol pentru a nu avea nimic." + }, + "customProtocolWarning": "Utilizarea unui protocol non-standard. Acest lucru poate necesita aplicații preinstalate și poate introduce riscuri de securitate. Asigurați-vă că adresa dumneavoastră este sigură și de încredere." + }, + "network": { + "statusChecker": { + "label": "Verifică starea", + "description": "Verifică dacă aplicația ta este online folosind o simplă cerere de tip HTTP(S)." + }, + "statusCodes": { + "label": "Coduri de răspuns HTTP", + "description": "Coduri de răspuns HTTP care sunt considerate a fi online." + } + }, + "appearance": { + "icon": { + "label": "Pictograma aplicației", + "description": "Începeți să tastați pentru a găsi o pictogramă. De asemenea puteți introduce o adresă URL a unei imagini pentru a o utiliza ca pictogramă personalizată.", + "autocomplete": { + "title": "Nici un rezultat găsit", + "text": "Încercați să utilizați un termen de căutare mai specific. Dacă nu găsiți pictograma dorită, puteți introduce adresa URL a imaginii in bara de mai sus pentru a o utiliza ca pictogramă personalizată" + }, + "noItems": { + "title": "Se încarcă pictograme externe", + "text": "Acestă activitate poate dura câteva secunde" + } + }, + "appNameFontSize": { + "label": "Mărimea textului numelui aplicației", + "description": "Alegeți mărimea textului pentru când se afișează numele aplicației in indicator." + }, + "appNameStatus": { + "label": "Starea numelui aplicației", + "description": "Alegeți unde doriți să apară numele aplicației, sau chiar deloc.", + "dropdown": { + "normal": "Afișați doar numele aplicației pe indicator", + "hover": "Afișați numele aplicației doar la trecerea mouse-ului peste", + "hidden": "Nu arăta deloc" + } + }, + "positionAppName": { + "label": "Poziționarea numelui aplicației", + "description": "Poziționarea numelui aplicației in raport cu pictograma.", + "dropdown": { + "top": "Sus", + "right": "Dreapta", + "bottom": "Jos", + "left": "Stânga" + } + }, + "lineClampAppName": { + "label": "Liniile numelui aplicație", + "description": "Definește câte linii ar trebui să se potrivească numele aplicație ca maxim. Setați 0 pentru nelimitat." + } + }, + "integration": { + "type": { + "label": "Configurarea integrării", + "description": "Configurația de integrare care va fi utilizată pentru a se conecta la aplicația dumneavoastră.", + "placeholder": "Alegeți o integrare", + "defined": "Definit", + "undefined": "Nedefinit", + "public": "Public", + "private": "Privat", + "explanationPrivate": "Un secret privat va fi trimis către server o singură dată. Odată ce browser-ul a reîmprospătat pagina, aceasta nu va mai fi trimis niciodată.", + "explanationPublic": "Un secret public va fi întotdeauna trimis clientului și este accesibil prin API. Nu ar trebui să conțină valori confidențiale, cum ar fi nume de utilizatori, parole, tokens, certificate și altele similare!" + }, + "secrets": { + "description": "Pentru a actualiza un secret, introduceți o valoare și faceți clic pe butonul de salvare. Pentru a elimina un secret, utilizați butonul de ștergere.", + "warning": "Datele dvs. de conectare acționează ca acces pentru integrările dvs. și nu ar trebui să e distribuiți niciodată cu nimeni altcineva. Echipa Homarr nu va cere niciodată datele dvs de conectare. Asigurați-vă că stocați și gestionați secretele în siguranță.", + "clear": "Ștergeți secretul", + "save": "Salvați secretul", + "update": "Actualizați secretul" + } + }, + "validation": { + "popover": "Formularul conține date invalide. Prin urmare, acesta nu poate fi salvat. Vă rugăm să corectați toate problemele și să faceți din nou clic pe acest buton pentru a salva modificările", + "name": "Numele este obligatoriu", + "noUrl": "Adresa URL este obligatorie", + "invalidUrl": "Textul introdus nu este o adresă URL validă", + "noIconUrl": "Acest câmp este obligatoriu", + "noExternalUri": "Adresa URL externă este necesară", + "invalidExternalUri": "Adresa URL externă nu este validă" + } +} diff --git a/public/locales/ro/layout/modals/change-position.json b/public/locales/ro/layout/modals/change-position.json new file mode 100644 index 000000000..de53e182d --- /dev/null +++ b/public/locales/ro/layout/modals/change-position.json @@ -0,0 +1,8 @@ +{ + "xPosition": "Poziționare pe axa X", + "width": "Lățime", + "height": "Înălțime", + "yPosition": "Poziționare pe axa Y", + "zeroOrHigher": "0 sau mai mare", + "betweenXandY": "Între {{min}} și {{max}}" +} \ No newline at end of file diff --git a/public/locales/ro/manage/boards.json b/public/locales/ro/manage/boards.json new file mode 100644 index 000000000..892c2f1ab --- /dev/null +++ b/public/locales/ro/manage/boards.json @@ -0,0 +1,57 @@ +{ + "metaTitle": "Planșe", + "pageTitle": "Planșe", + "cards": { + "statistics": { + "apps": "Aplicații", + "widgets": "Widget-uri", + "categories": "Categorii" + }, + "buttons": { + "view": "Vezi planșa" + }, + "menu": { + "setAsDefault": "Alege planșa de bază", + "delete": { + "label": "Șterge definitiv", + "disabled": "Ștergere dezactivată, deoarece componentele Homarr mai vechi nu permit ștergerea configurației implicite. Ștergerea va fi posibilă în viitor." + }, + "duplicate": "Duplicare", + "rename": { + "label": "Redenumire", + "modal": { + "title": "Redenumiți planșa {{name}}", + "fields": { + "name": { + "label": "Nume nou", + "placeholder": "Noul nume de planșă" + } + } + } + } + }, + "badges": { + "fileSystem": "Fișier de sistem", + "default": "Implicit" + } + }, + "buttons": { + "create": "Creează o nouă planșă" + }, + "modals": { + "delete": { + "title": "Șterge planșa", + "text": "Sunteți sigur că doriți să ștergeți această planșă? Această acțiune nu poate fi anulată iar datele dvs. vor fi pierdute definitiv." + }, + "create": { + "title": "Creează planșă", + "text": "Numele nu poate fi schimbat după ce planșa a fost creată.", + "form": { + "name": { + "label": "Nume" + }, + "submit": "Creează" + } + } + } +} \ No newline at end of file diff --git a/public/locales/ro/manage/index.json b/public/locales/ro/manage/index.json new file mode 100644 index 000000000..94e14f99b --- /dev/null +++ b/public/locales/ro/manage/index.json @@ -0,0 +1,23 @@ +{ + "metaTitle": "Gestionați", + "hero": { + "title": "Bine ai revenit, {{username}}", + "fallbackUsername": "Anonim", + "subtitle": "Bine ai venit la centrul dumneavoastră de aplicații. Organizați, optimizați și cuceriți!" + }, + "quickActions": { + "title": "Acțiuni rapide", + "boards": { + "title": "Planșele dumneavoastră", + "subtitle": "Creați și gestionați planșele dumneavoastră" + }, + "inviteUsers": { + "title": "Invitați un nou utilizator", + "subtitle": "Creați și trimiteți o invitație pentru înregistrare" + }, + "manageUsers": { + "title": "Gestionați utilizatorii", + "subtitle": "Ștergeți și gestionați utilizatorii" + } + } +} \ No newline at end of file diff --git a/public/locales/ro/manage/users.json b/public/locales/ro/manage/users.json new file mode 100644 index 000000000..9260abdb2 --- /dev/null +++ b/public/locales/ro/manage/users.json @@ -0,0 +1,44 @@ +{ + "metaTitle": "Utilizatori", + "pageTitle": "Gestionați utilizatorii", + "buttons": { + "create": "Creează" + }, + "filter": { + "roles": { + "all": "Tot", + "normal": "Normal", + "admin": "Administrator", + "owner": "Proprietar" + } + }, + "table": { + "header": { + "user": "Utilizator", + "email": "E-mail" + } + }, + "tooltips": { + "deleteUser": "Șterge utilizator", + "demoteAdmin": "Demiterea administratorului", + "promoteToAdmin": "Promovează ca administrator" + }, + "modals": { + "delete": { + "title": "Șterge utilizator {{name}}", + "text": "Sunteți sigur că doriți să ștergeți utilizatorul {{name}}? Acest lucru va șterge datele asociate cu acest cont, dar nu și planșele create de acest utilizator." + }, + "change-role": { + "promote": { + "title": "Promovați utilizatorul {{name}} ca administrator", + "text": "Sunteți sigur că doriți să promovați utilizatorul {{name}} la funcția de administrator? Acest lucru îi va oferi utilizatorului acces la toate resursele din instanța Homarr." + }, + "demote": { + "title": "Demiterea utilizatorul {{name}} la funcția de utilizator", + "text": "Sunteți sigur că doriți să demiteți utilizatorul {{name}} la funcția de utilizator? Acest lucru va elimina accesul utilizatorului la toate resursele din instanța Homarr." + }, + "confirm": "Confirma" + } + }, + "searchDoesntMatch": "Căutarea nu a întors nici un rezultat. Încercați cu un alt filtru." +} \ No newline at end of file diff --git a/public/locales/ro/manage/users/create.json b/public/locales/ro/manage/users/create.json new file mode 100644 index 000000000..354c01cde --- /dev/null +++ b/public/locales/ro/manage/users/create.json @@ -0,0 +1,52 @@ +{ + "metaTitle": "Creează utilizator", + "steps": { + "account": { + "title": "Pasul unu", + "text": "Creare cont", + "username": { + "label": "Utilizator" + }, + "email": { + "label": "E-mail" + } + }, + "security": { + "title": "Pasul doi", + "text": "Parola", + "password": { + "label": "Parola" + } + }, + "finish": { + "title": "Confirmare", + "text": "Salvați în baza de date", + "card": { + "title": "Revizuiți datele introduse", + "text": "După înregistrarea datelor în baza de date utilizatorul se va putea conecta. Sunteți sigur că doriți să stocați acest utilizator în baza de date și să activați autentificarea?" + }, + "table": { + "header": { + "property": "Câmp", + "value": "Valoare", + "username": "Utilizator", + "email": "E-mail", + "password": "Parola" + }, + "notSet": "Nesetat", + "valid": "Valid" + }, + "failed": "Crearea utilizatorului a eșuat: {{error}}" + }, + "completed": { + "alert": { + "title": "Utilizatorul a fost creat", + "text": "Utilizatorul a fost creat în baza de date. Acum se pot conecta." + } + } + }, + "buttons": { + "generateRandomPassword": "Generează o parolă aleatorie", + "createAnother": "Creează un alt utilizator" + } +} \ No newline at end of file diff --git a/public/locales/ro/manage/users/edit.json b/public/locales/ro/manage/users/edit.json new file mode 100644 index 000000000..8edaf1d07 --- /dev/null +++ b/public/locales/ro/manage/users/edit.json @@ -0,0 +1,55 @@ +{ + "metaTitle": "Utilizator {{username}}", + "back": "Înapoi la gestionarea utilizatorilor", + "sections": { + "general": { + "title": "General", + "inputs": { + "username": { + "label": "Utilizator" + }, + "eMail": { + "label": "E-mail" + } + } + }, + "security": { + "title": "Securitate", + "inputs": { + "password": { + "label": "Parolă nouă" + }, + "terminateExistingSessions": { + "label": "Închide sesiunile existente", + "description": "Forțează utilizatorul să se reconecteze pe dispozitivele sale" + }, + "confirm": { + "label": "Confirma", + "description": "Parola va fi actualizată. Această acțiune nu poate fi inversată." + } + } + }, + "roles": { + "title": "Roluri", + "currentRole": "Rol curent: ", + "badges": { + "owner": "Proprietar", + "admin": "Administrator", + "normal": "Normal" + } + }, + "deletion": { + "title": "Ștergerea contului", + "inputs": { + "confirmUsername": { + "label": "Confirmă utilizatorul", + "description": "Scrie numele utilizatorului pentru a confirma ștergerea" + }, + "confirm": { + "label": "Șterge definitiv", + "description": "Sunt conștient de faptul că această acțiune este permanentă și toate datele contului vor fi pierdute." + } + } + } + } +} \ No newline at end of file diff --git a/public/locales/ro/manage/users/invites.json b/public/locales/ro/manage/users/invites.json new file mode 100644 index 000000000..a2947cc6b --- /dev/null +++ b/public/locales/ro/manage/users/invites.json @@ -0,0 +1,48 @@ +{ + "metaTitle": "Invitațiile utilizatorilor", + "pageTitle": "Gestionează invitațiile utilizatorului", + "description": "Folosind invitații, puteți invita utilizatorii la instanța dvs. Homarr. Invitația va fi valabilă numai pentru o anumită perioadă și poate fi utilizată o singură dată. Expirarea invitației poate să fie setată între 5 minute și 12 luni de la creare.", + "button": { + "createInvite": "Creați o invitație", + "deleteInvite": "Șterge invitație" + }, + "table": { + "header": { + "id": "ID", + "creator": "Creator", + "expires": "Când expiră", + "action": "Acțiuni" + }, + "data": { + "expiresAt": "a expirat {{at}}", + "expiresIn": "în {{in}}" + } + }, + "modals": { + "create": { + "title": "Creați o invitație", + "description": "După expirare, invitația nu va mai fi valabilă iar destinatarul invitației nu va mai putea crea un cont.", + "form": { + "expires": "Data expirării", + "submit": "Creează" + } + }, + "copy": { + "title": "Copiază invitația", + "description": "Invitația a fost generată. După închiderea acestei ferestre nu veți mai putea copia acest link. Dacă nu mai doriți să invitați persoana respectivă, puteți șterge această invitație oricând.", + "invitationLink": "Link de invitație", + "details": { + "id": "ID", + "token": "Token" + }, + "button": { + "close": "Copiază si închide" + } + }, + "delete": { + "title": "Șterge invitație", + "description": "Sunteți sigur că doriți să ștergeți această invitație? Utilizatorii care au acest link nu vor mai putea crea un cont folosind acest link." + } + }, + "noInvites": "Nu aveți invitații încă." +} \ No newline at end of file diff --git a/public/locales/ro/modules/bookmark.json b/public/locales/ro/modules/bookmark.json new file mode 100644 index 000000000..2d06d29fe --- /dev/null +++ b/public/locales/ro/modules/bookmark.json @@ -0,0 +1,43 @@ +{ + "descriptor": { + "name": "Marcaj", + "description": "Afișează o listă statică de caractere sau link-uri", + "settings": { + "title": "Setări pentru marcaje", + "name": { + "label": "Titlu Widget", + "info": "Lăsați gol pentru a păstra titlul ascuns." + }, + "items": { + "label": "Elemente" + }, + "layout": { + "label": "Aspect", + "data": { + "autoGrid": "Grilă automată", + "horizontal": "Orizontal", + "vertical": "Vertical" + } + } + } + }, + "card": { + "noneFound": { + "title": "Lista de marcaje este goală", + "text": "Adăugați noi elemente la această listă în modul de editare" + } + }, + "item": { + "validation": { + "length": "Lungimea trebuie să fie între {{shortest}} și {{longest}}", + "invalidLink": "Nu este un link valid", + "errorMsg": "Nu s-a salvat, deoarece au existat erori de validare. Te rugăm să corectezi textele introduse" + }, + "name": "Nume", + "url": "Adresa URL", + "newTab": "Deschideți într-o pagină nouă", + "hideHostname": "Ascunde numele de gazdă", + "hideIcon": "Ascunde pictograma", + "delete": "Șterge" + } +} diff --git a/public/locales/ro/modules/calendar.json b/public/locales/ro/modules/calendar.json new file mode 100644 index 000000000..21f6a645f --- /dev/null +++ b/public/locales/ro/modules/calendar.json @@ -0,0 +1,33 @@ +{ + "descriptor": { + "name": "Calendar", + "description": "Afișează un calendar cu evenimente viitoare, din integrările acceptate.", + "settings": { + "title": "Setări pentru Widget-ul Calendar", + "radarrReleaseType": { + "label": "Tip de evenimente ale Radarr", + "data": { + "inCinemas": "În cinematografe", + "physicalRelease": "În format fizic", + "digitalRelease": "În format digital" + } + }, + "hideWeekDays": { + "label": "Ascunde zilele săptămânii" + }, + "showUnmonitored": { + "label": "Arată elementele nemonitorizate" + }, + "fontSize": { + "label": "Mărime textului", + "data": { + "xs": "Foarte mic", + "sm": "Mic", + "md": "Mediu", + "lg": "Mare", + "xl": "Foarte mare" + } + } + } + } +} \ No newline at end of file diff --git a/public/locales/ro/modules/common-media-cards.json b/public/locales/ro/modules/common-media-cards.json new file mode 100644 index 000000000..d46e8695a --- /dev/null +++ b/public/locales/ro/modules/common-media-cards.json @@ -0,0 +1,6 @@ +{ + "buttons": { + "play": "Redare", + "request": "Cerere" + } +} \ No newline at end of file diff --git a/public/locales/ro/modules/common.json b/public/locales/ro/modules/common.json new file mode 100644 index 000000000..122ec6bc8 --- /dev/null +++ b/public/locales/ro/modules/common.json @@ -0,0 +1,10 @@ +{ + "settings": { + "label": "Setări" + }, + "errors": { + "unmappedOptions": { + "text": "" + } + } +} diff --git a/public/locales/ro/modules/dashdot.json b/public/locales/ro/modules/dashdot.json new file mode 100644 index 000000000..c3e840ecb --- /dev/null +++ b/public/locales/ro/modules/dashdot.json @@ -0,0 +1,118 @@ +{ + "descriptor": { + "name": "Dash.", + "description": "Afișează elementele graficele ale Dash-ului extern. Instanță în interiorul Homarr.", + "settings": { + "title": "Setări pentru Widget-ul Dash.", + "dashName": { + "label": "Numele Dash." + }, + "url": { + "label": "Adresa URL pentru Dash." + }, + "usePercentages": { + "label": "Afișează procente" + }, + "columns": { + "label": "Afişează coloanele" + }, + "graphHeight": { + "label": "Înălțimea graficelor" + }, + "graphsOrder": { + "label": "Grafice (Ordine)", + "storage": { + "label": "Spațiu de stocare", + "enabled": { + "label": "Afișați în Widget" + }, + "span": { + "label": "Interval de coloană" + }, + "compactView": { + "label": "Afișați ca text (compact)" + }, + "multiView": { + "label": "Afișați ca multi-drive-view" + } + }, + "network": { + "label": "Rețea", + "enabled": { + "label": "Afișați în Widget" + }, + "span": { + "label": "Interval de coloană" + }, + "compactView": { + "label": "Afișați ca text (compact)" + } + }, + "cpu": { + "label": "Procesor", + "enabled": { + "label": "Afișați în Widget" + }, + "span": { + "label": "Interval de coloană" + }, + "multiView": { + "label": "Afișați ca multi-core-view" + } + }, + "ram": { + "label": "Memorie RAM", + "enabled": { + "label": "Afișați în Widget" + }, + "span": { + "label": "Interval de coloană" + } + }, + "gpu": { + "label": "Procesor grafic", + "enabled": { + "label": "Afișați în Widget" + }, + "span": { + "label": "Interval de coloană" + } + } + } + } + }, + "card": { + "title": "Dash.", + "errors": { + "noService": "Serviciul Dash. nu a fost găsit. Vă rugăm să adăugați unul in planșa dvs. sau setați un adresa URL a Dash.-ul în opțiunile modulului", + "noInformation": "Nu se pot obține informații de la Dash. - aveți cea mai recentă versiune?", + "protocolDowngrade": { + "title": "S-a detectat o reducere de protocol", + "text": "Conexiunea cu instanța Dash. utilizează HTTP. Acest lucru reprezintă un risc de securitate, deoarece HTTP nu este criptat și atacatorii ar putea abuza de această conexiune. Asigurați-vă că Dash. utilizează HTTPS sau reduceți Homarr la HTTP (nerecomandat)." + } + }, + "graphs": { + "storage": { + "title": "Spațiu de stocare", + "label": "Spațiu de stocare:" + }, + "network": { + "title": "Rețea", + "label": "Rețea:", + "metrics": { + "download": "În jos", + "upload": "În sus" + } + }, + "cpu": { + "title": "Procesor" + }, + "ram": { + "title": "Memorie RAM" + }, + "gpu": { + "title": "Procesor grafic" + } + } + } +} diff --git a/public/locales/ro/modules/date.json b/public/locales/ro/modules/date.json new file mode 100644 index 000000000..fa0f99315 --- /dev/null +++ b/public/locales/ro/modules/date.json @@ -0,0 +1,34 @@ +{ + "descriptor": { + "name": "Data și ora", + "description": "Afișează data și ora curentă.", + "settings": { + "title": "Setări pentru widget-ul Data și ora", + "timezone": { + "label": "Fus orar", + "info": "Selectați numele fusului orar, găsiți-l pe al dvs. aici: " + }, + "customTitle": { + "label": "Numele orașului sau titlul personalizat" + }, + "display24HourFormat": { + "label": "Afișează ora întreagă (24 de ore)" + }, + "dateFormat": { + "label": "Tipul de afișare a datei", + "data": { + "hide": "Ascunde data" + } + }, + "titleState": { + "label": "Titlul ceasului", + "info": "Titlul personalizat și codul fusului orar pot fi afișate pe widget.
Poți, de asemenea, să arăți orașul singur, să nu afișezi nimic,
sau chiar afișezi fusul orar singur atunci când ambele sunt selectate, dar nici un titlu nu este furnizat.", + "data": { + "both": "Titlu și fus orar", + "city": "Doar titlu", + "none": "Nimic" + } + } + } + } +} diff --git a/public/locales/ro/modules/dlspeed.json b/public/locales/ro/modules/dlspeed.json new file mode 100644 index 000000000..a6c19c068 --- /dev/null +++ b/public/locales/ro/modules/dlspeed.json @@ -0,0 +1,35 @@ +{ + "descriptor": { + "name": "Viteza de descărcare", + "description": "Afișează viteza de descărcare și încărcare a integrărilor care suportată această funcție." + }, + "card": { + "table": { + "header": { + "name": "Nume", + "size": "Mărime", + "download": "În jos", + "upload": "În sus", + "estimatedTimeOfArrival": "Timp rămas estimat", + "progress": "Progres" + }, + "body": { + "nothingFound": "Nici un torrent găsit" + } + }, + "lineChart": { + "title": "Viteza actuală de descărcare", + "download": "Descărcare: {{download}}", + "upload": "Încărcare: {{upload}}", + "timeSpan": "acum {{seconds}} secunde", + "totalDownload": "Descărcare: {{download}}/s", + "totalUpload": "Încărcare: {{upload}}/s" + }, + "errors": { + "noDownloadClients": { + "title": "Nu au fost găsiți clienți de descărcare suportați!", + "text": "Adăugați un serviciu de descărcare pentru a vizualiza descărcările curente" + } + } + } +} diff --git a/public/locales/ro/modules/dns-hole-controls.json b/public/locales/ro/modules/dns-hole-controls.json new file mode 100644 index 000000000..39ff87c0d --- /dev/null +++ b/public/locales/ro/modules/dns-hole-controls.json @@ -0,0 +1,18 @@ +{ + "descriptor": { + "name": "Comenzi de hole-DNS", + "description": "Controlați PiHole sau AdGuard din planșa dvs.", + "settings": { + "title": "Setări de control al hole-DNS", + "showToggleAllButtons": { + "label": "Afișați butoanele „Activați/Dezactivați toate”" + } + }, + "errors": { + "general": { + "title": "Nu se poate găsi hole-DNS", + "text": "A apărut o problemă la conectarea la hole-DNS. Vă rugăm să verificați configurația/integrarea (integrările)." + } + } + } +} \ No newline at end of file diff --git a/public/locales/ro/modules/dns-hole-summary.json b/public/locales/ro/modules/dns-hole-summary.json new file mode 100644 index 000000000..552e13f07 --- /dev/null +++ b/public/locales/ro/modules/dns-hole-summary.json @@ -0,0 +1,28 @@ +{ + "descriptor": { + "name": "Rezumatul hole-DNS", + "description": "Afișează date importante de la PiHole sau AdGuard", + "settings": { + "title": "Setări pentru rezumatul hole-DNS", + "usePiHoleColors": { + "label": "Folosiți culori de la PiHole" + }, + "layout": { + "label": "Aspect", + "data": { + "grid": "2 pe 2", + "row": "Orizontal", + "column": "Vertical" + } + } + } + }, + "card": { + "metrics": { + "domainsOnAdlist": "Domenii pe liste de anunțuri", + "queriesToday": "Interogări astăzi", + "queriesBlockedTodayPercentage": "Blocate astăzi", + "queriesBlockedToday": "Blocate astăzi" + } + } +} diff --git a/public/locales/ro/modules/docker.json b/public/locales/ro/modules/docker.json new file mode 100644 index 000000000..1c9e9d59d --- /dev/null +++ b/public/locales/ro/modules/docker.json @@ -0,0 +1,83 @@ +{ + "descriptor": { + "name": "Docker", + "description": "Vă permite vizualizarea și gestionarea cu ușurință a tuturor containerele Docker." + }, + "search": { + "placeholder": "Căutare după numele containerului sau al imaginii" + }, + "table": { + "header": { + "name": "Nume", + "image": "Imagine", + "ports": "Porturi", + "state": "Stare" + }, + "body": { + "portCollapse": "{{ports}} mai multe" + }, + "states": { + "running": "Rulează", + "created": "Creat", + "stopped": "Oprit", + "unknown": "Necunoscut" + } + }, + "actionBar": { + "addService": { + "title": "Adaugă aplicație", + "message": "Adaugă aplicația în Homarr" + }, + "restart": { + "title": "Repornește" + }, + "stop": { + "title": "Opreşte" + }, + "start": { + "title": "Pornește" + }, + "refreshData": { + "title": "Actualizează datele" + }, + "remove": { + "title": "Elimină" + }, + "addToHomarr": { + "title": "Adaugă în Homarr" + } + }, + "actions": { + "start": { + "start": "Începe", + "end": "A început" + }, + "stop": { + "start": "Opresc", + "end": "Oprit" + }, + "restart": { + "start": "Repornire", + "end": "Repornit" + }, + "remove": { + "start": "Eliminare", + "end": "Eliminat" + } + }, + "errors": { + "integrationFailed": { + "title": "Integrarea Docker a eșuat", + "message": "Ai uitat să asociați socket-ul de Docker?" + }, + "unknownError": { + "title": "A apărut o eroare" + }, + "oneServiceAtATime": { + "title": "Vă rugăm să adăugați o singură aplicație sau serviciu o dată!" + } + }, + "actionIcon": { + "tooltip": "Docker" + } +} diff --git a/public/locales/ro/modules/health-monitoring.json b/public/locales/ro/modules/health-monitoring.json new file mode 100644 index 000000000..8111caeaf --- /dev/null +++ b/public/locales/ro/modules/health-monitoring.json @@ -0,0 +1,141 @@ +{ + "descriptor": { + "name": "Monitorizarea sănătății sistemului", + "description": "Afișează informații care arată starea de sănătate și statistica sistemului (sistemelor) dumneavoastră.", + "settings": { + "title": "Setări pentru monitorizarea sănătății sistemului", + "fahrenheit": { + "label": "Temperatura procesorului în Fahrenheit" + }, + "cpu": { + "label": "Afișare informații procesor", + "load": "Utilizare medie", + "minute": "{{minute}} minute", + "minutes": "{{minutes}} minute" + }, + "memory": { + "label": "Afișare informații memorie" + }, + "fileSystem": { + "label": "Afișare informații despre sistemul de fișiere" + }, + "node": { + "label": "Filtrați după numele nodului", + "info": "Introduceți numele nodului dvs. Proxmox pentru a afișa numai valorile acestui nod. În mod implicit, este afișat întregul grup." + }, + "defaultViewState": { + "label": "Secțiune deschisă în mod implicit", + "data": { + "none": "Nimic", + "node": "Noduri", + "vm": "Masini Virtuale", + "lxc": "LXC-uri", + "storage": "Spațiu de stocare" + } + }, + "defaultTabState": { + "label": "Pagină deschisă implicit", + "info": "Pagină deschis implicit. Se utilizează numai atunci când sunt disponibile mai multe integrări.", + "data": { + "system": "Sistem", + "cluster": "Grupuri" + } + }, + "summary": { + "label": "Afișare secțiune sumar" + }, + "showNode": { + "label": "Afișare secțiune noduri" + }, + "showVM": { + "label": "Afișare secțiune mașini virtuale" + }, + "showLXCs": { + "label": "Afișare secțiune LXC-uri" + }, + "showStorage": { + "label": "Afișare secțiune de stocare" + }, + "sectionIndicatorColor": { + "label": "Cerința ca indicatorul de stare a secțiunii să fie „OK”", + "info": "„Toate” necesită ca toate articolele să fie online pentru ca indicatorul să fie verde. „Orice” necesită ca cel puțin un articol să fie online.", + "data": { + "any": "Oricare activ", + "all": "Toate active" + } + }, + "ignoreCert": { + "label": "Ignoră erorile certificatului", + "info": "Dacă este activat, Widget-ul va ignora erorile de certificat la accesarea API-ului Proxmox. Acest lucru poate fi util când accesați Proxmox prin HTTPS." + } + } + }, + "cpu": { + "label": "Procesor", + "load": "Utilizare medie", + "minute": "{{minute}} minute" + }, + "memory": { + "label": "Memorie RAM", + "totalMem": "Total memorie: {{total}}GB", + "available": "Disponibil: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Fișiere de sistem", + "available": "Disponibil: {{available}}- {{percentage}}%" + }, + "info": { + "uptime": "Timp de funcționare", + "uptimeFormat": "{{days}} zile, {{hours}} ore", + "updates": "Actualizări disponibile", + "reboot": "Repornire" + }, + "errors": { + "general": { + "title": "Nu a putut găsi sistemul (sistemele) dumneavoastră.", + "text": "A existat o problemă la conectarea la sistemul dvs. Vă rugăm să vă verificați configurația/integrarea (integrările)." + } + }, + "headings": { + "system": "Sistem", + "cluster": "Grupuri" + }, + "cluster": { + "summary": { + "cpu": "Procesor", + "ram": "Memorie RAM" + }, + "accordion": { + "title": { + "nodes": "Noduri", + "vms": "Masini Virtuale", + "lxcs": "LXC-uri", + "storage": "Spațiu de stocare" + } + }, + "table": { + "header": { + "name": "Nume", + "cpu": "Procesor", + "ram": "Memorie RAM", + "node": "Nod" + } + }, + "popover": { + "node": "Nod", + "vmid": "VMID", + "details": "Detalii", + "cores": "Nucelee - {{maxCpu}}", + "memSize": "Memorie RAM - {{maxMem}}", + "memRatio": "Memorie RAM - {{usedMem}} / {{maxMem}}", + "diskSize": "Disc - {{maxDisk}}", + "diskRatio": "Disc - {{usedDisk}} / {{maxDisk}}", + "uptime": "Timp de funcționare - {{uptime}}", + "plugin": "Extensii", + "ha": "Stare HA - {{haState}}", + "sharedStorage": "Stocare partajată", + "localStorage": "Stocare locală", + "na": "Indisponibil" + } + } +} \ No newline at end of file diff --git a/public/locales/ro/modules/iframe.json b/public/locales/ro/modules/iframe.json new file mode 100644 index 000000000..eea8475bb --- /dev/null +++ b/public/locales/ro/modules/iframe.json @@ -0,0 +1,45 @@ +{ + "descriptor": { + "name": "iFrame", + "description": "Încorporați orice conținut de pe internet. Unele site-uri web pot restricționa accesul.", + "settings": { + "title": "Setări iFrame", + "embedUrl": { + "label": "Încorporați adresa URL" + }, + "allowFullScreen": { + "label": "Permiteți ecranul complet" + }, + "allowTransparency": { + "label": "Permiteți transparența" + }, + "allowScrolling": { + "label": "Permiteți derularea" + }, + "allowPayment": { + "label": "Permiteți plata" + }, + "allowAutoPlay": { + "label": "Permiteți redarea automată" + }, + "allowMicrophone": { + "label": "Permiteți microfonul" + }, + "allowCamera": { + "label": "Permiteți camera" + }, + "allowGeolocation": { + "label": "Permiteți geolocalizarea" + } + } + }, + "card": { + "errors": { + "noUrl": { + "title": "Adresă URL invalidă", + "text": "Asigurați-vă că ați introdus o adresă validă în configurația Widget-ului dvs" + }, + "browserSupport": "Browser-ul tău nu acceptă iFrames. Te rugăm să actualizezi browser-ul." + } + } +} diff --git a/public/locales/ro/modules/indexer-manager.json b/public/locales/ro/modules/indexer-manager.json new file mode 100644 index 000000000..fd7c90f3d --- /dev/null +++ b/public/locales/ro/modules/indexer-manager.json @@ -0,0 +1,19 @@ +{ + "descriptor": { + "name": "Starea managerului de clasificare", + "description": "Statistici despre clasificatoarele dvs.", + "settings": { + "title": "Starea managerului de clasificare" + } + }, + "indexersStatus": { + "title": "Manager de clasificare", + "testAllButton": "Verifică toate" + }, + "errors": { + "general": { + "title": "Nu s-a găsit nici un manager de clasificare", + "text": "A apărut o problemă la conectarea la managerul de clasificare. Vă rugăm să vă verificați configurația/integrarea (integrările)." + } + } +} \ No newline at end of file diff --git a/public/locales/ro/modules/media-requests-list.json b/public/locales/ro/modules/media-requests-list.json new file mode 100644 index 000000000..b94c46184 --- /dev/null +++ b/public/locales/ro/modules/media-requests-list.json @@ -0,0 +1,35 @@ +{ + "descriptor": { + "name": "Cereri media", + "description": "Vezi o listă cu toate cererile media de la instanțele Overseerr sau Jellyseerr", + "settings": { + "title": "Listă cu cereri media", + "replaceLinksWithExternalHost": { + "label": "Înlocuiți link-urile cu o gazdă externă" + }, + "openInNewTab": { + "label": "Deschide link-ul într-o pagină nouă" + } + } + }, + "noRequests": "Nici o cerere găsită. Asigurați-vă că ați configurat corect aplicațiile.", + "state": { + "approved": "Aprobat", + "pendingApproval": "În curs de aprobare", + "declined": "Refuzat", + "available": "Disponibil", + "partial": "Parțial" + }, + "tooltips": { + "approve": "Aprobă cererile", + "decline": "Refuză cererile", + "approving": "Aprobă cererile..." + }, + "mutation": { + "approving": "Aprobare", + "declining": "Refuz", + "request": "cerere...", + "approved": "Cererea a fost aprobata!", + "declined": "Cererea a fost refuzată!" + } +} diff --git a/public/locales/ro/modules/media-requests-stats.json b/public/locales/ro/modules/media-requests-stats.json new file mode 100644 index 000000000..e6ce570af --- /dev/null +++ b/public/locales/ro/modules/media-requests-stats.json @@ -0,0 +1,27 @@ +{ + "descriptor": { + "name": "Situația cererilor media", + "description": "Statistici despre solicitările dvs. media", + "settings": { + "title": "Situația cererilor media", + "replaceLinksWithExternalHost": { + "label": "Înlocuiți link-urile cu o gazdă externă" + }, + "openInNewTab": { + "label": "Deschide link-ul într-o pagină nouă" + } + } + }, + "mediaStats": { + "title": "Situația media", + "pending": "În curs de aprobare", + "tvRequests": "Cereri seriale TV", + "movieRequests": "Cereri filme", + "approved": "Deja aprobat", + "totalRequests": "Total" + }, + "userStats": { + "title": "Top utilizatori", + "requests": "Cereri: {{number}}" + } +} diff --git a/public/locales/ro/modules/media-server.json b/public/locales/ro/modules/media-server.json new file mode 100644 index 000000000..5918ad621 --- /dev/null +++ b/public/locales/ro/modules/media-server.json @@ -0,0 +1,25 @@ +{ + "descriptor": { + "name": "Server-ul media", + "description": "Interacționați cu server-ul dvs. media Jellyfin sau Plex", + "settings": { + "title": "Setări pentru widget-ul server-ului media" + } + }, + "loading": "Se încarcă stream-urile", + "card": { + "table": { + "header": { + "session": "Sesiune", + "user": "Utilizator", + "currentlyPlaying": "În acest moment se redă" + } + }, + "errors": { + "general": { + "title": "Nu se poate încărca conținutul", + "text": "Nu s-au putut obține informații de la server. Verificați log-urile pentru mai multe detalii" + } + } + } +} \ No newline at end of file diff --git a/public/locales/ro/modules/media-transcoding.json b/public/locales/ro/modules/media-transcoding.json new file mode 100644 index 000000000..f519604b0 --- /dev/null +++ b/public/locales/ro/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Transcrieri media", + "description": "Afișează informații despre transcrierea media", + "settings": { + "title": "Setări ale transcrieri media", + "appId": { + "label": "Alegeți o aplicație" + }, + "defaultView": { + "label": "Afișare implicită", + "data": { + "workers": "Lucrători", + "queue": "Listă de așteptare", + "statistics": "Statistici" + } + }, + "showHealthCheck": { + "label": "Afișați indicatorul Health Check" + }, + "showHealthChecksInQueue": { + "label": "Afișați indicatorul Stare de sănătate in așteptare" + }, + "queuePageSize": { + "label": "În așteptare: elemente pe pagină" + }, + "showAppIcon": { + "label": "Afișați pictograma aplicației în colțul din dreapta jos" + } + } + }, + "noAppSelected": "Vă rugăm să selectați o aplicație în setările widget-ului", + "views": { + "workers": { + "table": { + "header": { + "name": "Fișier", + "eta": "Timp rămas estimat", + "progress": "Progres" + }, + "empty": "Gol", + "tooltip": { + "transcode": "Transcriere", + "healthCheck": "Stare de sănătate" + } + } + }, + "queue": { + "table": { + "header": { + "name": "Fișier", + "size": "Mărime" + }, + "footer": { + "currentIndex": "{{start}}-{{end}} din {{total}}" + }, + "empty": "Gol", + "tooltip": { + "transcode": "Transcriere", + "healthCheck": "Stare de sănătate" + } + } + }, + "statistics": { + "empty": "Gol", + "box": { + "transcodes": "Transcrieri: {{value}}", + "healthChecks": "Stări de sănătate: {{value}}", + "files": "Fișiere: {{value}}", + "spaceSaved": "Salvat: {{value}}" + }, + "pies": { + "transcodes": "Transcrieri", + "healthChecks": "Health Checks", + "videoCodecs": "Codec-uri", + "videoContainers": "Containere", + "videoResolutions": "Rezoluţie" + } + } + }, + "error": { + "title": "Eroare", + "message": "A apărut o eroare la preluarea datelor de la aplicația Tdarr." + }, + "tabs": { + "workers": "Lucrători", + "queue": "Listă de așteptare", + "statistics": "Statistici" + }, + "healthCheckStatus": { + "title": "Stare de sănătate", + "queued": "Pus în așteptare", + "healthy": "Sănătos", + "unhealthy": "Nesănătos" + } +} diff --git a/public/locales/ro/modules/notebook.json b/public/locales/ro/modules/notebook.json new file mode 100644 index 000000000..4571406e9 --- /dev/null +++ b/public/locales/ro/modules/notebook.json @@ -0,0 +1,59 @@ +{ + "descriptor": { + "name": "Agendă", + "description": "Un widget interactiv de tip markdown pentru a vă nota ideile dvs!", + "settings": { + "title": "Setări pentru widget-ul agendă", + "showToolbar": { + "label": "Arată bara de instrumente pentru a te ajuta să notezi în tip markdown" + }, + "allowReadOnlyCheck": { + "label": "Permite verificarea în modul numai-citire" + }, + "content": { + "label": "Conținutul agendei" + } + } + }, + "card": { + "controls": { + "bold": "Îngroșat", + "italic": "Cursiv", + "strikethrough": "Tăiat cu o linie", + "underline": "Subliniat", + "colorText": "Culoare text", + "colorHighlight": "Text colorat pentru evidențiere", + "code": "Cod", + "clear": "Curăță formatul", + "heading": "Rubrica {{level}}", + "align": "Așezați textul: {{position}}", + "blockquote": "Citat", + "horizontalLine": "Linie orizontală", + "bulletList": "Listă cu puncte", + "orderedList": "Listă ordonată", + "checkList": "Lista de verificare cu bifă", + "increaseIndent": "Mărește spațierea", + "decreaseIndent": "Scade spațierea", + "link": "Link", + "unlink": "Șterge link-ul", + "image": "Încorporează imagine", + "addTable": "Adaugă tabelă", + "deleteTable": "Șterge tabelă", + "colorCell": "Culoare celulă", + "mergeCell": "Comută îmbinarea celulelor", + "addColumnLeft": "Adaugă o coloană în fată", + "addColumnRight": "Adaugă o coloană după", + "deleteColumn": "Șterge coloană", + "addRowTop": "Adaugă un rând înainte", + "addRowBelow": "Adaugă un rând după", + "deleteRow": "Șterge rând" + }, + "modals": { + "clearColor": "Șterge culoarea", + "source": "Sursă", + "widthPlaceholder": "Valoare exprimată în % sau pixeli", + "columns": "Coloane", + "rows": "Rânduri" + } + } +} \ No newline at end of file diff --git a/public/locales/ro/modules/overseerr.json b/public/locales/ro/modules/overseerr.json new file mode 100644 index 000000000..7a313d83d --- /dev/null +++ b/public/locales/ro/modules/overseerr.json @@ -0,0 +1,30 @@ +{ + "descriptor": { + "name": "Overseerr", + "description": "Vă permite să căutați și să adăugați conținut media din aplicațiile Overseerr sau Jellyseerr." + }, + "popup": { + "item": { + "buttons": { + "askFor": "Cere {{title}}", + "cancel": "Anulează", + "request": "Cerere" + }, + "alerts": { + "automaticApproval": { + "title": "Folosind cheia API", + "text": "Această solicitare va fi aprobată automat" + } + } + }, + "seasonSelector": { + "caption": "Bifați sezonul pe care doriți să îl descărcați", + "table": { + "header": { + "season": "Sezon", + "numberOfEpisodes": "Număr de episoade" + } + } + } + } +} diff --git a/public/locales/ro/modules/ping.json b/public/locales/ro/modules/ping.json new file mode 100644 index 000000000..2e715b7c3 --- /dev/null +++ b/public/locales/ro/modules/ping.json @@ -0,0 +1,11 @@ +{ + "descriptor": { + "name": "Ping", + "description": "Afișează un indicator de stare în funcție de codul de răspuns HTTP al unei adrese URL date." + }, + "states": { + "online": "Online {{response}}", + "offline": "Offline {{response}}", + "loading": "Se încarcă..." + } +} diff --git a/public/locales/ro/modules/rss.json b/public/locales/ro/modules/rss.json new file mode 100644 index 000000000..a76dc5170 --- /dev/null +++ b/public/locales/ro/modules/rss.json @@ -0,0 +1,40 @@ +{ + "descriptor": { + "name": "Widget RSS", + "description": "Widget-ul RSS vă permite să afișați feed-urile RSS pe planșă.", + "settings": { + "title": "Setări pentru Widget-ul RSS", + "rssFeedUrl": { + "label": "Adrese URL ale feed-urilor RSS", + "description": "Adresele URL ale feed-urilor RSS pe care doriți să le afișați." + }, + "refreshInterval": { + "label": "Interval de actualizare (în minute)" + }, + "dangerousAllowSanitizedItemContent": { + "label": "Permiteți formatarea de tip HTML (Periculos)", + "info": "Permiterea formatării de tip HTML din exterior ar putea fi periculoasă.
Vă rugăm să vă asigurați că feed-ul provine dintr-o sursă de încredere." + }, + "textLinesClamp": { + "label": "Fixarea liniilor de text" + }, + "sortByPublishDateAscending": { + "label": "Sortează după data publicării (ascendent)" + }, + "sortPostsWithoutPublishDateToTheTop": { + "label": "Așează postări fără data publicării în partea de sus" + }, + "maximumAmountOfPosts": { + "label": "Numărul maxim de postări" + } + }, + "card": { + "errors": { + "general": { + "title": "Nu se poate prelua feed-ul RSS", + "text": "A apărut o problemă la accesarea feed-ului RSS. Asigură-te că ai configurat corect feed-ul RSS folosind o adresa URL validă. Adresele URL-urile ar trebui să corespundă specificațiilor oficiale. După actualizarea feed-ului, ar putea fi necesar să reactualizați planșă." + } + } + } + } +} diff --git a/public/locales/ro/modules/search.json b/public/locales/ro/modules/search.json new file mode 100644 index 000000000..69dba7753 --- /dev/null +++ b/public/locales/ro/modules/search.json @@ -0,0 +1,30 @@ +{ + "descriptor": { + "name": "Bară de căutare", + "description": "O bară de căutare care vă permite să căutați motorul dvs. de căutare personalizat, YouTube, și integrări suportate." + }, + "input": { + "placeholder": "Căutați pe internet..." + }, + "switched-to": "Comută la", + "searchEngines": { + "search": { + "name": "Internet", + "description": "Căutare..." + }, + "youtube": { + "name": "YouTube", + "description": "Caută pe YouTube" + }, + "torrents": { + "name": "Torrent", + "description": "Caută in torrente" + }, + "overseerr": { + "name": "Overseerr", + "description": "Căutați filme și seriale TV in Overseerr" + } + }, + "tip": "Puteți selecta bara de căutare cu ajutorul comenzii rapide ", + "switchedSearchEngine": "A trecut la căutarea cu {{searchEngine}}" +} diff --git a/public/locales/ro/modules/smart-home/entity-state.json b/public/locales/ro/modules/smart-home/entity-state.json new file mode 100644 index 000000000..3d826fbe3 --- /dev/null +++ b/public/locales/ro/modules/smart-home/entity-state.json @@ -0,0 +1,34 @@ +{ + "entityNotFound": "Entitatea nu a fost găsită", + "descriptor": { + "name": "Entitate Home Assistant", + "description": "Starea actuală a unei entități în Home Assistant", + "settings": { + "title": "Starea entității", + "entityId": { + "label": "Identificator entitate", + "info": "Identificatorul unic al entității în Home Assistant. Copiați făcând clic pe entitate > Faceți clic pe pictograma cu rotiță > Faceți clic pe butonul de copiere la \"Entity ID\". Este posibil ca unele entități personalizate să nu fie acceptate." + }, + "appendUnit": { + "label": "Adăugați unitatea de măsură", + "info": "Adăugați atributul unității de măsură la starea entității." + }, + "automationId": { + "label": "Identificator automatizare opțional", + "info": "Identificatorul dvs. unic de automatizare. Întotdeauna începe cu automation.XXXXX. Dacă nu este setat, Widget-ul nu va putea fi accesat și va afișa doar starea. După ce se face clic, starea entității va fi reîmprospătată." + }, + "displayName": { + "label": "Nume afișat" + }, + "displayFriendlyName": { + "label": "Afișează un nume prietenos", + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" + } + } + } +} + diff --git a/public/locales/ro/modules/smart-home/trigger-automation.json b/public/locales/ro/modules/smart-home/trigger-automation.json new file mode 100644 index 000000000..1c498018b --- /dev/null +++ b/public/locales/ro/modules/smart-home/trigger-automation.json @@ -0,0 +1,16 @@ +{ + "descriptor": { + "name": "Automatizare Home Assistant", + "description": "Executați o automatizare", + "settings": { + "title": "Executați o automatizare", + "automationId": { + "label": "Identificator automatizare", + "info": "Identificatorul dvs. unic de automatizare. Întotdeauna începe cu automation.XXXXX." + }, + "displayName": { + "label": "Nume afișat" + } + } + } +} \ No newline at end of file diff --git a/public/locales/ro/modules/torrents-status.json b/public/locales/ro/modules/torrents-status.json new file mode 100644 index 000000000..2f3e3c86b --- /dev/null +++ b/public/locales/ro/modules/torrents-status.json @@ -0,0 +1,118 @@ +{ + "descriptor": { + "name": "Torrent", + "description": "Afişează o listă de torente de la clienţii compatibili cu Torrente.", + "settings": { + "title": "Setări pentru Widget-ul Torrent", + "refreshInterval": { + "label": "Interval de actualizare (în secunde)" + }, + "displayCompletedTorrents": { + "label": "Afișare torente finalizate" + }, + "displayActiveTorrents": { + "label": "Afișare torente active" + }, + "speedLimitOfActiveTorrents": { + "label": "Viteza de încărcare pentru a considera un torent activ (kB/s)" + }, + "displayStaleTorrents": { + "label": "Afișare torente fără surse" + }, + "labelFilterIsWhitelist": { + "label": "Lista de etichete este o listă albă (în loc de lista neagră)" + }, + "labelFilter": { + "label": "Lista de etichete", + "description": "Când este bifat „listă albă”, aceasta va acționa ca o listă albă. Dacă nu este bifată, aceasta este o listă neagră. Nu va face nimic când este gol" + }, + "displayRatioWithFilter": { + "label": "Afișează raportul listei de torente filtrate", + "info": "Dacă este dezactivat, va fi afișat doar raportul global. Raportul global va folosi în continuare etichetele dacă este setat" + }, + "columnOrdering": { + "label": "Permite reordonarea coloanelor" + }, + "rowSorting": { + "label": "Permiteți sortarea rândurilor" + }, + "columns": { + "label": "Selectați coloanele pentru afișare", + "data": { + "date": "Data adăugării", + "down": "În jos", + "up": "În sus", + "eta": "Timp rămas estimat", + "progress": "Progres" + } + }, + "nameColumnSize": { + "label": "Schimbă dimensiunea coloanei pentru nume" + } + } + }, + "card": { + "footer": { + "error": "Eroare", + "lastUpdated": "Ultima actualizare acum {{time}}", + "ratioGlobal": "Raport global", + "ratioWithFilter": "Raport cu filtru" + }, + "table": { + "header": { + "isCompleted": "Descărcare", + "name": "Nume", + "dateAdded": "Adăugat la data", + "size": "Mărime", + "download": "În jos", + "upload": "În sus", + "estimatedTimeOfArrival": "Timp rămas estimat", + "progress": "Progres", + "totalUploaded": "Total încărcări", + "totalDownloaded": "Total descărcări", + "ratio": "Raport", + "seeds": "Seed-eri (conectat)", + "peers": "Parteneri (conectat)", + "label": "Etichetă", + "state": "Stare", + "stateMessage": "Mesaj de stare" + }, + "item": { + "text": "Gestionat de {{appName}}, {{ratio}} raport" + }, + "body": { + "nothingFound": "Nici un torrent găsit", + "filterHidingItems": "{{count}} intrări sunt ascunse de filtrele dvs." + } + }, + "lineChart": { + "title": "Viteza actuală de descărcare", + "download": "Descărcare: {{download}}", + "upload": "Încărcare: {{upload}}", + "timeSpan": "acum {{seconds}} secunde", + "totalDownload": "Descărcare: {{download}}/s", + "totalUpload": "Încărcare: {{upload}}/s" + }, + "errors": { + "noDownloadClients": { + "title": "Nu au fost găsiți clienți de torente!", + "text": "Adaugă un client de Torrent acceptat pentru a vizualiza descărcările curente" + }, + "generic": { + "title": "A apărut o eroare neașteptată", + "text": "Nu se poate comunica cu clienții dvs. Torrent. Vă rugăm să vă verificați configurația" + } + }, + "popover": { + "introductionPrefix": "Gestionat de", + "metrics": { + "queuePosition": "Poziție în așteptare - {{position}}", + "progress": "Progres - {{progress}}%", + "totalSelectedSize": "Total - {{totalSize}}", + "state": "Stare - {{state}}", + "ratio": "Raport -", + "completed": "Finalizat" + } + } + } +} diff --git a/public/locales/ro/modules/usenet.json b/public/locales/ro/modules/usenet.json new file mode 100644 index 000000000..5d5b58d0f --- /dev/null +++ b/public/locales/ro/modules/usenet.json @@ -0,0 +1,49 @@ +{ + "descriptor": { + "name": "Usenet", + "description": "Vă permite să vizualizați și să vă gestionați instanța dvs. Usenet." + }, + "card": { + "errors": { + "noDownloadClients": { + "title": "Nu au fost găsiți clienți de descărcare suportați!", + "text": "Adaugă un client de descărcare Usenet acceptat pentru a vizualiza descărcările curente" + } + } + }, + "tabs": { + "queue": "Listă de așteptare", + "history": "Istoric" + }, + "info": { + "sizeLeft": "Rest", + "paused": "În pauză" + }, + "queue": { + "header": { + "name": "Nume", + "size": "Mărime", + "eta": "Timp rămas estimat", + "progress": "Progres" + }, + "empty": "Gol", + "error": { + "title": "Eroare", + "message": "A apărut o eroare" + }, + "paused": "În pauză" + }, + "history": { + "header": { + "name": "Nume", + "size": "Mărime", + "duration": "Durată" + }, + "empty": "Gol", + "error": { + "title": "Eroare", + "message": "Eroare la încărcarea istoricului" + }, + "paused": "În pauză" + } +} \ No newline at end of file diff --git a/public/locales/ro/modules/video-stream.json b/public/locales/ro/modules/video-stream.json new file mode 100644 index 000000000..b99d2f694 --- /dev/null +++ b/public/locales/ro/modules/video-stream.json @@ -0,0 +1,24 @@ +{ + "descriptor": { + "name": "Stream video", + "description": "Încorporează un steam video sau video-ul dintr-o cameră sau un site web", + "settings": { + "title": "Setări pentru Widget-ul Stream video", + "FeedUrl": { + "label": "Adresa URL a feed-ului" + }, + "autoPlay": { + "label": "Redare automată" + }, + "muted": { + "label": "Dezactivare sunet" + }, + "controls": { + "label": "Comenzi player video" + } + } + }, + "errors": { + "invalidStream": "Stream invalid" + } +} \ No newline at end of file diff --git a/public/locales/ro/modules/weather.json b/public/locales/ro/modules/weather.json new file mode 100644 index 000000000..c6237bfc0 --- /dev/null +++ b/public/locales/ro/modules/weather.json @@ -0,0 +1,43 @@ +{ + "descriptor": { + "name": "Meteo", + "description": "Afișează informațiile meteo curente ale unei locații stabilite.", + "settings": { + "title": "Setări pentru Widget-ul Meteo", + "displayInFahrenheit": { + "label": "Afișează în Fahrenheit" + }, + "displayCityName": { + "label": "Afișează numele orașului" + }, + "displayWeekly": { + "label": "Afișează prognoza săptămânală" + }, + "forecastDays": { + "label": "Zile de afișat" + }, + "location": { + "label": "Locație meteo" + } + } + }, + "card": { + "weatherDescriptions": { + "clear": "Senin", + "mainlyClear": "Parțial noros", + "fog": "Ceață", + "drizzle": "Burniță", + "freezingDrizzle": "Chiciură", + "rain": "Ploaie", + "freezingRain": "Polei", + "snowFall": "Ninsoare", + "snowGrains": "Fulgi de Zăpadă", + "rainShowers": "Averse de ploaie", + "snowShowers": "Averse de ninsoare", + "thunderstorm": "Furtună", + "thunderstormWithHail": "Furtună cu grindină", + "unknown": "Necunoscut" + } + }, + "error": "A aparut o eroare" +} diff --git a/public/locales/ro/password-requirements.json b/public/locales/ro/password-requirements.json new file mode 100644 index 000000000..1b25c2487 --- /dev/null +++ b/public/locales/ro/password-requirements.json @@ -0,0 +1,7 @@ +{ + "number": "Să includă cifre", + "lowercase": "Să includă litere mici", + "uppercase": "Să includă litere mari", + "special": "Să includă caractere speciale", + "length": "Să includă cel puțin {{count}} caractere" +} \ No newline at end of file diff --git a/public/locales/ro/settings/common.json b/public/locales/ro/settings/common.json new file mode 100644 index 000000000..6818b0167 --- /dev/null +++ b/public/locales/ro/settings/common.json @@ -0,0 +1,38 @@ +{ + "title": "Setări", + "tooltip": "Setări", + "tabs": { + "common": "Comun", + "customizations": "Personalizări" + }, + "tips": { + "configTip": "Încărcați fișierul de configurare prin tragere și plasare acestuia pe pagină!" + }, + "credits": { + "madeWithLove": "Realizat cu ❤️ de @", + "thirdPartyContent": "Vezi conținutul terților", + "thirdPartyContentTable": { + "dependencyName": "Dependență", + "dependencyVersion": "Versiune" + } + }, + "grow": "Mărește grilă (ocupă tot spațiul)", + "layout": { + "preview": { + "title": "Previzualizare", + "subtitle": "Modificările vor fi salvate automat" + }, + "divider": "Opțiuni de aspect", + "main": "Principal", + "sidebar": "Bara laterală", + "cannotturnoff": "Nu se poate dezactiva", + "dashboardlayout": "Aspectul planșei", + "enablersidebar": "Activează bara laterală în dreapta", + "enablelsidebar": "Activează bara laterală în stânga", + "enablesearchbar": "Activează bara de căutare", + "enabledocker": "Activează integrarea cu Docker", + "enableping": "Activează ping", + "enablelsidebardesc": "Opțional. Poate fi folosit numai pentru aplicații și integrări", + "enablersidebardesc": "Opțional. Poate fi folosit numai pentru aplicații și integrări" + } +} diff --git a/public/locales/ro/settings/customization/access.json b/public/locales/ro/settings/customization/access.json new file mode 100644 index 000000000..8731fea29 --- /dev/null +++ b/public/locales/ro/settings/customization/access.json @@ -0,0 +1,6 @@ +{ + "allowGuests": { + "label": "Permite accesul anonim", + "description": "Permiteți utilizatorilor care nu sunt autentificați să vă vadă planșa" + } +} \ No newline at end of file diff --git a/public/locales/ro/settings/customization/general.json b/public/locales/ro/settings/customization/general.json new file mode 100644 index 000000000..762454a5b --- /dev/null +++ b/public/locales/ro/settings/customization/general.json @@ -0,0 +1,29 @@ +{ + "text": "Personalizările vă permit să configurați și să ajustați experiența dumneavoastră cu Homarr în funcție de preferințele dumneavoastră.", + "accordeon": { + "layout": { + "name": "Aspect", + "description": "Activați și dezactivați elementele din antetul pagini și din indicatori planșei" + }, + "gridstack": { + "name": "Grilaj", + "description": "Personalizați comportamentul și coloanele din zona planșei" + }, + "pageMetadata": { + "name": "Metadatele paginii", + "description": "Ajustați titlurile, sigla și PWA" + }, + "appereance": { + "name": "Aspect", + "description": "Personalizați aspectul fundalului, culorilor și aplicațiilor" + }, + "accessibility": { + "name": "Accesibilitate", + "description": "Configurați Homarr pentru utilizatorii cu dizabilități și persoane cu handicap" + }, + "access": { + "name": "Acces", + "description": "Configurați cine are acces la planșa dvs." + } + } +} diff --git a/public/locales/ro/settings/customization/gridstack.json b/public/locales/ro/settings/customization/gridstack.json new file mode 100644 index 000000000..a59045c29 --- /dev/null +++ b/public/locales/ro/settings/customization/gridstack.json @@ -0,0 +1,10 @@ +{ + "columnsCount": { + "labelPreset": "Coloane cu dimensiunea {{size}}", + "descriptionPreset": "Numărul de coloane când ecranul este mai mic decât {{pixels}} pixeli lăţime", + "descriptionExceedsPreset": "Numărul de coloane când dimensiunea ecranului depășește {{pixels}} pixeli" + }, + "unsavedChanges": "Aveți modificări nesalvate. Apăsați butonul Aplică modificările de mai jos pentru a aplica și salva.", + "applyChanges": "Aplică modificările", + "defaultValues": "Valori implicite" +} \ No newline at end of file diff --git a/public/locales/ro/settings/customization/opacity-selector.json b/public/locales/ro/settings/customization/opacity-selector.json new file mode 100644 index 000000000..2a332539f --- /dev/null +++ b/public/locales/ro/settings/customization/opacity-selector.json @@ -0,0 +1,3 @@ +{ + "label": "Opacitatea aplicației" +} \ No newline at end of file diff --git a/public/locales/ro/settings/customization/page-appearance.json b/public/locales/ro/settings/customization/page-appearance.json new file mode 100644 index 000000000..3cf725477 --- /dev/null +++ b/public/locales/ro/settings/customization/page-appearance.json @@ -0,0 +1,50 @@ +{ + "pageTitle": { + "label": "Titlu pagină", + "description": "Numele planșei în stânga sus" + }, + "metaTitle": { + "label": "Titlu Meta", + "description": "Titlul afișat în pagina browserului dvs" + }, + "logo": { + "label": "Siglă", + "description": "Sigla afișată în stânga sus" + }, + "favicon": { + "label": "Favicon", + "description": "Pictograma afișată în pagina browserului dvs" + }, + "background": { + "label": "Fundal" + }, + "backgroundImageAttachment": { + "label": "Atașare imagine de fundal", + "options": { + "fixed": "Fix - imaginea de fundal rămâne în aceeași poziție (recomandat)", + "scroll": "Derulare - derulează imaginea de fundal cu mouse-ul tău" + } + }, + "backgroundImageSize": { + "label": "Dimensiunea imaginii de fundal", + "options": { + "cover": "Cover (Acoperire) - Redimensionează imaginea cât mai mult posibil pentru a acoperi întreaga fereastră prin decuparea spațiului excesiv. (recomandat)", + "contain": "Conținut - Redimensionează imaginea cât mai mare posibil în container, fără a decupa sau a întinde imaginea." + } + }, + "backgroundImageRepeat": { + "label": "Atașare imagine de fundal", + "options": { + "repeat": "Repetare - Imaginea este repetată atât cât este necesar pentru a acoperi întreaga zonă de pictură a imaginii de fundal.", + "no-repeat": "Fără repetare - Imaginea nu se repetă și este posibil să nu umple întreg spațiul (recomandat)", + "repeat-x": "Repetă X - La fel ca „Repetă”, dar numai pe axa orizontală.", + "repeat-y": "Repetă Y - La fel ca „Repetă”, dar numai pe axa verticala." + } + }, + "customCSS": { + "label": "CSS personalizat", + "description": "În plus, personalizați-vă planșa folosind CSS, recomandat doar pentru utilizatorii experimentați", + "placeholder": "Personalizare CSS va fi aplicată ultima", + "applying": "Se aplică CSS..." + } +} diff --git a/public/locales/ro/settings/customization/shade-selector.json b/public/locales/ro/settings/customization/shade-selector.json new file mode 100644 index 000000000..44de22679 --- /dev/null +++ b/public/locales/ro/settings/customization/shade-selector.json @@ -0,0 +1,3 @@ +{ + "label": "Nuante" +} \ No newline at end of file diff --git a/public/locales/ro/tools/docker.json b/public/locales/ro/tools/docker.json new file mode 100644 index 000000000..37bfe18d7 --- /dev/null +++ b/public/locales/ro/tools/docker.json @@ -0,0 +1,32 @@ +{ + "title": "Docker", + "alerts": { + "notConfigured": { + "text": "Instanța Homarr nu are configurat Docker sau nu a reușit să preia containere. Vă rugăm să verificați documentația privind modul de configurare a integrării." + } + }, + "modals": { + "selectBoard": { + "title": "Alege o planșă", + "text": "Alegeți planșa în care doriți să adăugați aplicațiile pentru containerele Docker selectate.", + "form": { + "board": { + "label": "Planșă" + }, + "submit": "Adăugați aplicații" + } + } + }, + "notifications": { + "selectBoard": { + "success": { + "title": "Aplicații adăugate în planșă", + "message": "Aplicațiile pentru containerele Docker selectate au fost adăugate în planșă." + }, + "error": { + "title": "Nu s-a reușit adăugarea aplicațiilor in planșă", + "message": "Aplicațiile pentru containerele Docker selectate nu au putut fi adăugate în planșă." + } + } + } +} \ No newline at end of file diff --git a/public/locales/ro/user/preferences.json b/public/locales/ro/user/preferences.json new file mode 100644 index 000000000..628ec1852 --- /dev/null +++ b/public/locales/ro/user/preferences.json @@ -0,0 +1,48 @@ +{ + "metaTitle": "Preferințe", + "pageTitle": "Preferințele dvs.", + "boards": { + "defaultBoard": { + "label": "Planșă de bază" + } + }, + "accessibility": { + "title": "Accesibilitate", + "disablePulse": { + "label": "Dezactivați ping", + "description": "În mod implicit, indicatorii de ping din Homarr vor pulsa. Acest lucru poate fi iritant. Acest buton va dezactiva animația" + }, + "replaceIconsWithDots": { + "label": "Înlocuiți punctele de ping cu pictograme", + "description": "Pentru utilizatorii daltoniști, punctele ping pot fi de nerecunoscut. Acest lucru va înlocui punctele cu pictograme" + } + }, + "localization": { + "language": { + "label": "Limbă" + }, + "firstDayOfWeek": { + "label": "Prima zi a săptămâni", + "options": { + "monday": "Luni", + "saturday": "Sâmbătă", + "sunday": "Duminică" + } + } + }, + "searchEngine": { + "title": "Motor de căutare", + "custom": "Personalizat", + "newTab": { + "label": "Deschideți rezultatele căutării într-o pagina nouă" + }, + "autoFocus": { + "label": "Focalizează bara de căutare la încărcarea paginii.", + "description": "Acest lucru va focaliza automat bara de căutare, atunci când navigați la paginile planșei. Funcționează doar pe dispozitive de tip desktop." + }, + "template": { + "label": "Adresa URL a căutări", + "description": "Folosește %s ca înlocuitor pentru textul căutare" + } + } +} \ No newline at end of file diff --git a/public/locales/ro/widgets/draggable-list.json b/public/locales/ro/widgets/draggable-list.json new file mode 100644 index 000000000..aff09df1e --- /dev/null +++ b/public/locales/ro/widgets/draggable-list.json @@ -0,0 +1,7 @@ +{ + "noEntries": { + "title": "Nici o intrare", + "text": "Utilizați butoanele de mai jos pentru a adăuga mai multe intrări" + }, + "buttonAdd": "Adaugă" +} diff --git a/public/locales/ro/widgets/error-boundary.json b/public/locales/ro/widgets/error-boundary.json new file mode 100644 index 000000000..4fbe140b6 --- /dev/null +++ b/public/locales/ro/widgets/error-boundary.json @@ -0,0 +1,14 @@ +{ + "card": { + "title": "Hopa, a apărut o eroare!", + "buttons": { + "details": "Detalii", + "tryAgain": "Încearcă din nou" + } + }, + "modal": { + "text": "", + "label": "Eroare dvs.", + "reportButton": "Raportați această eroare" + } +} diff --git a/public/locales/ro/zod.json b/public/locales/ro/zod.json new file mode 100644 index 000000000..d8d455751 --- /dev/null +++ b/public/locales/ro/zod.json @@ -0,0 +1,22 @@ +{ + "errors": { + "default": "Acest câmp nu este valid", + "required": "Acest câmp este obligatoriu", + "string": { + "startsWith": "Acest câmp trebuie să înceapă cu {{startsWith}}", + "endsWith": "Acest câmp trebuie să se termine cu {{endsWith}}", + "includes": "Acest câmp trebuie să includă {{includes}}" + }, + "tooSmall": { + "string": "Acest câmp trebuie să aibă cel puțin {{minimum}} caractere", + "number": "Acest câmp trebuie să fie mai mare sau egal cu {{minimum}}" + }, + "tooBig": { + "string": "Acest câmp trebuie să aibă cel mult {{maximum}} caractere", + "number": "Acest câmp trebuie să fie mai mic sau egal cu {{maximum}}" + }, + "custom": { + "passwordMatch": "Parolele trebuie să fie identice" + } + } +} \ No newline at end of file diff --git a/public/locales/ru/modules/health-monitoring.json b/public/locales/ru/modules/health-monitoring.json index 3a55ed03f..720834f33 100644 --- a/public/locales/ru/modules/health-monitoring.json +++ b/public/locales/ru/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Мониторинг состояния системы", - "description": "Информация о вашем NAS", - "settings": { - "title": "Мониторинг состояния системы", - "fahrenheit": { - "label": "По Фаренгейту" - } - } - }, - "cpu": { - "label": "ЦПУ", + "descriptor": { + "name": "Мониторинг состояния системы", + "description": "Информация о вашем NAS", + "settings": { + "title": "", + "fahrenheit": { + "label": "По Фаренгейту" + }, + "cpu": { + "label": "", "load": "Средняя загрузка", - "minute": "{{minute}} минута" - }, - "memory": { - "label": "Память", - "totalMem": "Общий объем памяти: {{total}}Гб", - "available": "Доступно: {{available}}Гб - {{percentage}}%" - }, - "fileSystem": { - "label": "Файловая система", - "available": "Доступно: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "Время работы", - "updates": "Обновления", - "reboot": "Перезагрузка" - }, - "errors": { - "general": { - "title": "Не удалось найти ваш NAS", - "text": "Проблема с подключением к вашему NAS. Пожалуйста, проверьте свою конфигурацию/интеграцию." + "minute": "{{minute}} минута", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { + "label": "", + "info": "" + }, + "defaultViewState": { + "label": "", + "data": { + "none": "Ничего", + "node": "", + "vm": "", + "lxc": "", + "storage": "Хранилище" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "ЦПУ", + "load": "Средняя загрузка", + "minute": "{{minute}} минута" + }, + "memory": { + "label": "Память", + "totalMem": "Общий объем памяти: {{total}}Гб", + "available": "Доступно: {{available}}Гб - {{percentage}}%" + }, + "fileSystem": { + "label": "Файловая система", + "available": "Доступно: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Время работы", + "uptimeFormat": "", + "updates": "Обновления", + "reboot": "Перезагрузка" + }, + "errors": { + "general": { + "title": "Не удалось найти ваш NAS", + "text": "Проблема с подключением к вашему NAS. Пожалуйста, проверьте свою конфигурацию/интеграцию." + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "ЦПУ", + "ram": "ОЗУ" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "Хранилище" + } + }, + "table": { + "header": { + "name": "Имя", + "cpu": "ЦПУ", + "ram": "ОЗУ", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Подробности", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/ru/modules/media-transcoding.json b/public/locales/ru/modules/media-transcoding.json new file mode 100644 index 000000000..dafb09a3f --- /dev/null +++ b/public/locales/ru/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Очередь", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "Осталось", + "progress": "Прогресс" + }, + "empty": "Пусто", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Размер" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Пусто", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Пусто", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Ошибка", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Очередь", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/ru/modules/smart-home/entity-state.json b/public/locales/ru/modules/smart-home/entity-state.json index eb48be315..5f4e5bd52 100644 --- a/public/locales/ru/modules/smart-home/entity-state.json +++ b/public/locales/ru/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Показать собственное имя", - "info": "Показывать собственное имя Home Assistant вместо отображаемого имени" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/ru/modules/torrents-status.json b/public/locales/ru/modules/torrents-status.json index 7d8108498..472c90779 100644 --- a/public/locales/ru/modules/torrents-status.json +++ b/public/locales/ru/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Отображать рейтинг для отфильтрованных торрентов", "info": "Если отключено, будет отображаться только общий рейтинг. Общий рейтинг все равно будет использовать метки, если они заданы" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "Загрузка", + "up": "Отдача", + "eta": "Осталось", + "progress": "Прогресс" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "Невозможно установить связь с Torrent-клиентами. Пожалуйста, проверьте настройки" } }, - "loading": { - "title": "Загрузка", - "description": "Установка соединения" - }, "popover": { "introductionPrefix": "Под управлением", "metrics": { diff --git a/public/locales/sk/authentication/login.json b/public/locales/sk/authentication/login.json index a4235f571..409418179 100644 --- a/public/locales/sk/authentication/login.json +++ b/public/locales/sk/authentication/login.json @@ -16,8 +16,8 @@ }, "afterLoginRedirection": "Po prihlásení budete presmerovaní na stránku {{url}}", "providersEmpty": { - "title": "", - "message": "" + "title": "Chyba poskytovateľa autorizácie", + "message": "Poskytovateľ(-lia) nie je(sú) nastavený(-í), ďalšie informácie nájdete v záznamoch." } }, "alert": "Vaše poverovacie údaje sú nesprávne alebo toto konto neexistuje. Skúste to prosím znova." diff --git a/public/locales/sk/modules/health-monitoring.json b/public/locales/sk/modules/health-monitoring.json index 1019267ae..f8dca0773 100644 --- a/public/locales/sk/modules/health-monitoring.json +++ b/public/locales/sk/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Monitorovanie stavu systému", - "description": "Informácie o vašom NAS", - "settings": { - "title": "Monitorovanie stavu systému", - "fahrenheit": { - "label": "Fahrenheit" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Monitorovanie stavu systému", + "description": "Zobrazuje informácie o stave a kondícii vášho systému.", + "settings": { + "title": "Nastavenia pre monitorovanie stavu systému", + "fahrenheit": { + "label": "Teplota CPU v stupňoch Fahrenheita" + }, + "cpu": { + "label": "Zobrazenie informácií o CPU", "load": "Priemerná záťaž", - "minute": "{minutes} min." - }, - "memory": { - "label": "Pamäť", - "totalMem": "Celková pamäť: {{total}}GB", - "available": "K dispozícii: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "Súborový systém", - "available": "K dispozícii: {{available}}GB - {{percentage}}%" - }, - "info": { - "uptime": "Čas prevádzky", - "updates": "Aktualizácie", - "reboot": "Reštartovať" - }, - "errors": { - "general": { - "title": "Nemožno nájsť váš NAS", - "text": "Nastal problém s pripojením k vášmu NAS. Skontrolujte prosím svoju konfiguráciu/integráciu." + "minute": "{minutes} min.", + "minutes": "{minutess} min" + }, + "memory": { + "label": "Zobraziť informácie o pamäti" + }, + "fileSystem": { + "label": "Zobraziť informácie o súborovom systéme" + }, + "node": { + "label": "Filtrujte podľa názvu uzla", + "info": "Zadajte názov uzla Proxmox, aby sa zobrazili len metriky pre tento uzol. V predvolenom nastavení sa zobrazuje celý klaster." + }, + "defaultViewState": { + "label": "Predvolene otvorená sekcia", + "data": { + "none": "Žiadne", + "node": "Uzly", + "vm": "VM", + "lxc": "LXCs", + "storage": "Úložisko" } + }, + "defaultTabState": { + "label": "Predvolene otvorená karta", + "info": "Predvolene otvorená karta. Používa sa len vtedy, keď je k dispozícii viacero integrácií.", + "data": { + "system": "Systém", + "cluster": "Cluster" + } + }, + "summary": { + "label": "Zobraziť sekciu súhrnu" + }, + "showNode": { + "label": "Zobraziť sekciu uzlov" + }, + "showVM": { + "label": "Zobraziť sekciu VM" + }, + "showLXCs": { + "label": "Zobraziť sekciu LXC" + }, + "showStorage": { + "label": "Zobraziť sekciu úložiska" + }, + "sectionIndicatorColor": { + "label": "Požiadavka, aby bol indikátor stavu sekcie „OK“", + "info": "„Všetko“ vyžaduje, aby boli všetky položky online, aby bol indikátor zelený. Možnosť „Akýkoľvek“ vyžaduje, aby bola online aspoň jedna položka.", + "data": { + "any": "Akýkoľvek aktívny", + "all": "Všetky aktívne" + } + }, + "ignoreCert": { + "label": "Ignorovať chyby certifikátu", + "info": "Ak je táto možnosť povolená, widget bude pri prístupe k rozhraniu API Proxmox ignorovať chyby certifikátu. To môže byť užitočné pri prístupe k Proxmox cez HTTPS." + } } + }, + "cpu": { + "label": "CPU", + "load": "Priemerná záťaž", + "minute": "{minutes} min." + }, + "memory": { + "label": "Pamäť", + "totalMem": "Celková pamäť: {{total}}GB", + "available": "K dispozícii: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Súborový systém", + "available": "K dispozícii: {{available}}GB - {{percentage}}%" + }, + "info": { + "uptime": "Čas prevádzky", + "uptimeFormat": "{{days}} dní, {{hours}} hodín", + "updates": "Dostupné aktualizácie", + "reboot": "Reštartovať" + }, + "errors": { + "general": { + "title": "Nie je možné nájsť váš systém (systémy).", + "text": "Nastal problém s pripojením k vášmu systému. Skontrolujte prosím svoju konfiguráciu/integráciu." + } + }, + "headings": { + "system": "Systém", + "cluster": "Cluster" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "Uzly", + "vms": "VM", + "lxcs": "LXCs", + "storage": "Úložisko" + } + }, + "table": { + "header": { + "name": "Názov", + "cpu": "CPU", + "ram": "RAM", + "node": "Uzol" + } + }, + "popover": { + "node": "Uzol", + "vmid": "VMID", + "details": "Detaily", + "cores": "Jadrá - {{maxCpu}}", + "memSize": "Pamäť - {{maxMem}}", + "memRatio": "Pamäť - {{usedMem}} / {{maxMem}}", + "diskSize": "Disk - {{maxDisk}}", + "diskRatio": "Disk - {{usedDisk}} / {{maxDisk}}", + "uptime": "Prevádzková doba - {{uptime}}", + "plugin": "Plugin", + "ha": "HA Stav - {{haState}}", + "sharedStorage": "Zdieľané úložisko", + "localStorage": "Lokálne úložisko", + "na": "N/A" + } + } } \ No newline at end of file diff --git a/public/locales/sk/modules/media-transcoding.json b/public/locales/sk/modules/media-transcoding.json new file mode 100644 index 000000000..e5ae57c7c --- /dev/null +++ b/public/locales/sk/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Prekódovanie médií", + "description": "Zobrazí informácie o prekódovaní médií", + "settings": { + "title": "Nastavenia prekódovania médií", + "appId": { + "label": "Vyberte aplikáciu" + }, + "defaultView": { + "label": "Predvolené zobrazenie", + "data": { + "workers": "Pracovníci", + "queue": "Fronta", + "statistics": "Statistiky" + } + }, + "showHealthCheck": { + "label": "Zobraziť indikátor stavu" + }, + "showHealthChecksInQueue": { + "label": "Zobraziť kontroly stavu vo fronte" + }, + "queuePageSize": { + "label": "Fronta: Položky na stránku" + }, + "showAppIcon": { + "label": "Zobraziť ikonu aplikácie v pravom dolnom rohu" + } + } + }, + "noAppSelected": "Vyberte aplikáciu v nastaveniach miniaplikácie", + "views": { + "workers": { + "table": { + "header": { + "name": "Súbor", + "eta": "Odhad", + "progress": "Stav" + }, + "empty": "Prázdny", + "tooltip": { + "transcode": "Transkodér", + "healthCheck": "Kontrola stavu" + } + } + }, + "queue": { + "table": { + "header": { + "name": "Súbor", + "size": "Veľkosť" + }, + "footer": { + "currentIndex": "{{start}}-{{end}} z {{total}}" + }, + "empty": "Prázdny", + "tooltip": { + "transcode": "Transkodér", + "healthCheck": "Kontrola stavu" + } + } + }, + "statistics": { + "empty": "Prázdny", + "box": { + "transcodes": "Prekódovanie: {{value}}", + "healthChecks": "Zdravotné kontroly: {{value}}", + "files": "Súbory: {{value}}", + "spaceSaved": "Uložené: {{value}}" + }, + "pies": { + "transcodes": "Transkodér", + "healthChecks": "Kontrola stavu", + "videoCodecs": "Kodeky", + "videoContainers": "Kontajnery", + "videoResolutions": "Rozlíšenie" + } + } + }, + "error": { + "title": "Chyba", + "message": "Pri načítavaní údajov z Tdarr došlo k chybe." + }, + "tabs": { + "workers": "Pracovníci", + "queue": "Fronta", + "statistics": "Statistiky" + }, + "healthCheckStatus": { + "title": "Kontrola stavu", + "queued": "V poradí", + "healthy": "Zdravý", + "unhealthy": "Nezdravý" + } +} diff --git a/public/locales/sk/modules/smart-home/entity-state.json b/public/locales/sk/modules/smart-home/entity-state.json index c3eccddb4..e41822b83 100644 --- a/public/locales/sk/modules/smart-home/entity-state.json +++ b/public/locales/sk/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Zobraziť priateľské meno", - "info": "Namiesto zobrazovaného mena zobraziť popisný názov z Home Assistant" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/sk/modules/torrents-status.json b/public/locales/sk/modules/torrents-status.json index 251957716..b1a8179cd 100644 --- a/public/locales/sk/modules/torrents-status.json +++ b/public/locales/sk/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Zobraziť pomer zoznamu filtrovaných torrentov", "info": "Ak je vypnutý, zobrazí sa iba globálny pomer. Globálny pomer bude stále používať štítky, ak je nastavený" + }, + "columnOrdering": { + "label": "Povoliť zmenu poradia stĺpcov" + }, + "rowSorting": { + "label": "Povoliť triedenie riadkov" + }, + "columns": { + "label": "Vyberte stĺpce na zobrazenie", + "data": { + "date": "Dátum pridania", + "down": "Dole", + "up": "Hore", + "eta": "Odhad", + "progress": "Stav" + } + }, + "nameColumnSize": { + "label": "Zmena veľkosti stĺpca s názvom" } } }, @@ -84,10 +103,6 @@ "text": "Nieje možné komunikovať s klientmi Torrent. Skontrolujte prosím svoju konfiguráciu" } }, - "loading": { - "title": "Načítavanie", - "description": "Nadväzovanie spojenia..." - }, "popover": { "introductionPrefix": "Spravovaný", "metrics": { diff --git a/public/locales/sk/modules/weather.json b/public/locales/sk/modules/weather.json index 50ffe08a5..cb86dcaee 100644 --- a/public/locales/sk/modules/weather.json +++ b/public/locales/sk/modules/weather.json @@ -11,10 +11,10 @@ "label": "Zobrazenie názvu mesta" }, "displayWeekly": { - "label": "" + "label": "Zobraziť týždennú predpoveď" }, "forecastDays": { - "label": "" + "label": "Dni na zobrazenie" }, "location": { "label": "Poloha počasia" @@ -40,4 +40,4 @@ } }, "error": "Vyskytla sa chyba" -} +} \ No newline at end of file diff --git a/public/locales/sl/modules/health-monitoring.json b/public/locales/sl/modules/health-monitoring.json index dd45386b4..4f471bf8f 100644 --- a/public/locales/sl/modules/health-monitoring.json +++ b/public/locales/sl/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { + "label": "", "load": "", - "minute": "" - }, - "memory": { + "minute": "", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { + "info": "" + }, + "defaultViewState": { "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "data": { + "none": "Ni", + "node": "", + "vm": "", + "lxc": "", + "storage": "Shramba" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "", + "minute": "" + }, + "memory": { + "label": "", + "totalMem": "", + "available": "" + }, + "fileSystem": { + "label": "", + "available": "" + }, + "info": { + "uptime": "", + "uptimeFormat": "", + "updates": "", + "reboot": "" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "Shramba" + } + }, + "table": { + "header": { + "name": "Ime", + "cpu": "CPU", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Podrobnosti", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/sl/modules/media-transcoding.json b/public/locales/sl/modules/media-transcoding.json new file mode 100644 index 000000000..cfbd9215c --- /dev/null +++ b/public/locales/sl/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Čakalna vrsta", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "ETA", + "progress": "Napredek" + }, + "empty": "Prazno", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Velikost" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Prazno", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Prazno", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Napaka", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Čakalna vrsta", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/sl/modules/smart-home/entity-state.json b/public/locales/sl/modules/smart-home/entity-state.json index e3b2b290b..307d85c52 100644 --- a/public/locales/sl/modules/smart-home/entity-state.json +++ b/public/locales/sl/modules/smart-home/entity-state.json @@ -23,7 +23,12 @@ "displayFriendlyName": { "label": "", "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/sl/modules/torrents-status.json b/public/locales/sl/modules/torrents-status.json index eebdf5408..6a1158936 100644 --- a/public/locales/sl/modules/torrents-status.json +++ b/public/locales/sl/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Prikaz razmerja filtriranega seznama torrentov", "info": "Če je onemogočeno, se prikaže samo globalno razmerje. Če je nastavljeno globalno razmerje, se bodo še vedno uporabljale oznake." + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "Dol", + "up": "Gor", + "eta": "ETA", + "progress": "Napredek" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "Ne morete komunicirati z odjemalci Torrent. Preverite svojo konfiguracijo." } }, - "loading": { - "title": "Nalaganje", - "description": "Vzpostavitev povezave" - }, "popover": { "introductionPrefix": "Upravlja jo", "metrics": { diff --git a/public/locales/sv/authentication/login.json b/public/locales/sv/authentication/login.json index d433b9488..0586554e3 100644 --- a/public/locales/sv/authentication/login.json +++ b/public/locales/sv/authentication/login.json @@ -16,7 +16,7 @@ }, "afterLoginRedirection": "Efter inloggningen kommer du att omdirigeras till {{url}}", "providersEmpty": { - "title": "", + "title": "Fel vid autentiseringsfel", "message": "" } }, diff --git a/public/locales/sv/modules/health-monitoring.json b/public/locales/sv/modules/health-monitoring.json index de23c2466..bad4ee1f5 100644 --- a/public/locales/sv/modules/health-monitoring.json +++ b/public/locales/sv/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Övervakning av systemhälsan", - "description": "Information om din NAS", - "settings": { - "title": "Övervakning av systemhälsan", - "fahrenheit": { - "label": "Fahrenheit" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Övervakning av systemhälsan", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { + "label": "", "load": "Genomsnittlig belastning", - "minute": "{{minute}} minut" - }, - "memory": { - "label": "Minne", - "totalMem": "Totalt minne: {{total}}GB", - "available": "Tillgängligt: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "Filsystem", - "available": "Tillgängligt: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "Drifttid", - "updates": "Uppdateringar", - "reboot": "Omstart" - }, - "errors": { - "general": { - "title": "Det gick inte att hitta din NAS", - "text": "Det gick inte att ansluta till din NAS. Vänligen verifiera din konfiguration/integration(er)." + "minute": "{{minute}} minut", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { + "label": "", + "info": "" + }, + "defaultViewState": { + "label": "", + "data": { + "none": "Ingen", + "node": "", + "vm": "", + "lxc": "", + "storage": "Lagring" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "Genomsnittlig belastning", + "minute": "{{minute}} minut" + }, + "memory": { + "label": "Minne", + "totalMem": "Totalt minne: {{total}}GB", + "available": "Tillgängligt: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Filsystem", + "available": "Tillgängligt: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Drifttid", + "uptimeFormat": "", + "updates": "", + "reboot": "Omstart" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "Lagring" + } + }, + "table": { + "header": { + "name": "Namn", + "cpu": "CPU", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Detaljer", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/sv/modules/media-transcoding.json b/public/locales/sv/modules/media-transcoding.json new file mode 100644 index 000000000..0dca284da --- /dev/null +++ b/public/locales/sv/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Kö", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "Beräknad sluttid", + "progress": "Förlopp" + }, + "empty": "Tom", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Storlek" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Tom", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Tom", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Fel", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Kö", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/sv/modules/smart-home/entity-state.json b/public/locales/sv/modules/smart-home/entity-state.json index 75dd923c8..45587f0a5 100644 --- a/public/locales/sv/modules/smart-home/entity-state.json +++ b/public/locales/sv/modules/smart-home/entity-state.json @@ -23,7 +23,12 @@ "displayFriendlyName": { "label": "", "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/sv/modules/torrents-status.json b/public/locales/sv/modules/torrents-status.json index cec2ed889..f27db998b 100644 --- a/public/locales/sv/modules/torrents-status.json +++ b/public/locales/sv/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Visa filtrerade torrents listförhållande", "info": "Om inaktiverat visas endast det globala förhållandet. Det globala förhållandet kommer fortfarande att använda etiketterna om det är inställt" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "Ned", + "up": "Upp", + "eta": "Beräknad sluttid", + "progress": "Förlopp" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "Homarr kunde inte kommunicera med dina torrent-klienter. Vänligen kontrollera din konfiguration" } }, - "loading": { - "title": "Laddar", - "description": "Upprättar en anslutning" - }, "popover": { "introductionPrefix": "Förvaltas av", "metrics": { diff --git a/public/locales/sv/modules/weather.json b/public/locales/sv/modules/weather.json index 61942dace..4929a6ed0 100644 --- a/public/locales/sv/modules/weather.json +++ b/public/locales/sv/modules/weather.json @@ -11,10 +11,10 @@ "label": "Visa stadens namn" }, "displayWeekly": { - "label": "" + "label": "Visa veckovis prognos" }, "forecastDays": { - "label": "" + "label": "Dagar att visa" }, "location": { "label": "Plats för väder" @@ -40,4 +40,4 @@ } }, "error": "Ett fel uppstod" -} +} \ No newline at end of file diff --git a/public/locales/tr/modules/health-monitoring.json b/public/locales/tr/modules/health-monitoring.json index 330a479d8..a9fec5688 100644 --- a/public/locales/tr/modules/health-monitoring.json +++ b/public/locales/tr/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Sistem Sağlığı İzleme", - "description": "NAS'ınız hakkında bilgi", - "settings": { - "title": "Sistem Sağlığı İzleme", - "fahrenheit": { - "label": "Fahrenayt" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Sistem Sağlığı İzleme", + "description": "Sistem(ler)inizin sağlığını ve durumunu gösteren bilgileri görüntüler.", + "settings": { + "title": "Sistem durumu izleme ayarları", + "fahrenheit": { + "label": "Fahrenheit cinsinden CPU Sıcaklığı" + }, + "cpu": { + "label": "CPU Bilgilerini Göster", "load": "Yük Ortalaması", - "minute": "{{minute}} dakika" - }, - "memory": { - "label": "Bellek", - "totalMem": "Toplam bellek: {{total}}GB", - "available": "Mevcut: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "Dosya Sistemi", - "available": "Mevcut: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "Çalışma süresi", - "updates": "Güncellemeler", - "reboot": "Yeniden başlat" - }, - "errors": { - "general": { - "title": "NAS'ınız bulunamıyor", - "text": "NAS'ınıza bağlanırken bir sorun oluştu. Lütfen yapılandırmanızı/entegrasyonlarınızı kontrol edin." + "minute": "{{minute}} dakika", + "minutes": "{{minutes}} dakika" + }, + "memory": { + "label": "Bellek Bilgilerini Göster" + }, + "fileSystem": { + "label": "Dosya Sistemi Bilgilerini Göster" + }, + "node": { + "label": "Node adına göre filtrele", + "info": "Yalnızca söz konusu node'e ilişkin ölçümleri göstermek için Proxmox node'nizin adını girin. Varsayılan olarak kümenin tamamı gösterilir." + }, + "defaultViewState": { + "label": "Bölüm varsayılan olarak açık", + "data": { + "none": "Hiçbiri", + "node": "Node'lar", + "vm": "VM'ler", + "lxc": "LXC'ler", + "storage": "Depolama" } + }, + "defaultTabState": { + "label": "Sekme varsayılan olarak açık", + "info": "Sekme varsayılan olarak açıktır. Yalnızca birden fazla entegrasyon mevcut olduğunda kullanılır.", + "data": { + "system": "Sistem", + "cluster": "Küme" + } + }, + "summary": { + "label": "Özet bölümünü göster" + }, + "showNode": { + "label": "Node bölümünü göster" + }, + "showVM": { + "label": "VM bölümünü göster" + }, + "showLXCs": { + "label": "LXC bölümünü göster" + }, + "showStorage": { + "label": "Depolama bölümünü göster" + }, + "sectionIndicatorColor": { + "label": "Bölüm durum göstergesinin 'Tamam' olması gerekliliği", + "info": "'Tümü' göstergenin yeşil olması için tüm öğelerin çevrimiçi olmasını gerektirir. 'Herhangi' en az bir öğenin çevrimiçi olmasını gerektirir.", + "data": { + "any": "Herhangi Aktif", + "all": "Tümü Aktif" + } + }, + "ignoreCert": { + "label": "Sertifika Hatalarını Yoksay", + "info": "Etkinleştirilirse widget, Proxmox API'sine erişirken sertifika hatalarını yok sayar. Bu, Proxmox'a HTTPS aracılığıyla erişirken yararlı olabilir." + } } + }, + "cpu": { + "label": "CPU", + "load": "Yük Ortalaması", + "minute": "{{minute}} dakika" + }, + "memory": { + "label": "Bellek", + "totalMem": "Toplam bellek: {{total}}GB", + "available": "Mevcut: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Dosya Sistemi", + "available": "Mevcut: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Çalışma süresi", + "uptimeFormat": "{{days}} gün, {{hours}} saat", + "updates": "Güncellemeler mevcut", + "reboot": "Yeniden başlat" + }, + "errors": { + "general": { + "title": "Sistem(ler)iniz bulunamadı.", + "text": "Sisteminize bağlanırken bir sorun oluştu. Lütfen yapılandırmanızı/entegrasyonlarınızı kontrol edin." + } + }, + "headings": { + "system": "Sistem", + "cluster": "Küme" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "Ram" + }, + "accordion": { + "title": { + "nodes": "Node'lar", + "vms": "VM'ler", + "lxcs": "LXC'ler", + "storage": "Depolama" + } + }, + "table": { + "header": { + "name": "İsim", + "cpu": "CPU", + "ram": "Ram", + "node": "Node" + } + }, + "popover": { + "node": "Node", + "vmid": "VMID", + "details": "Detaylar", + "cores": "Çekirdekler - {{maxCpu}}", + "memSize": "Bellek - {{maxMem}}", + "memRatio": "Bellek - {{usedMem}} / {{maxMem}}", + "diskSize": "Disk - {{maxDisk}}", + "diskRatio": "Disk - {{usedDisk}} / {{maxDisk}}", + "uptime": "Çalışma süresi - {{uptime}}", + "plugin": "Eklenti", + "ha": "HA Durumu - {{haState}}", + "sharedStorage": "Paylaşılan depolama alanı", + "localStorage": "Yerel depolama", + "na": "Yok" + } + } } \ No newline at end of file diff --git a/public/locales/tr/modules/media-requests-stats.json b/public/locales/tr/modules/media-requests-stats.json index 346d1c09d..e08ec0a23 100644 --- a/public/locales/tr/modules/media-requests-stats.json +++ b/public/locales/tr/modules/media-requests-stats.json @@ -14,10 +14,10 @@ }, "mediaStats": { "title": "Medya İstatistikleri", - "pending": "Bekleyen Onaylar", + "pending": "Onay bekleyen", "tvRequests": "Dizi talepleri", "movieRequests": "Film talepleri", - "approved": "Zaten onaylandı", + "approved": "Onaylanan", "totalRequests": "Toplam" }, "userStats": { diff --git a/public/locales/tr/modules/media-transcoding.json b/public/locales/tr/modules/media-transcoding.json new file mode 100644 index 000000000..0969a497b --- /dev/null +++ b/public/locales/tr/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "Medya Kod Dönüştürme", + "description": "Medya kod dönüştürmeyle ilgili bilgileri görüntüler", + "settings": { + "title": "Medya Kod Dönüştürme Ayarları", + "appId": { + "label": "Bir uygulama seçin" + }, + "defaultView": { + "label": "Varsayılan görünüm", + "data": { + "workers": "İşçiler", + "queue": "Kuyruk", + "statistics": "İstatistik" + } + }, + "showHealthCheck": { + "label": "Durum Kontrolü göstergesini göster" + }, + "showHealthChecksInQueue": { + "label": "Durum Denetimlerini kuyrukta göster" + }, + "queuePageSize": { + "label": "Kuyruk: Sayfa başına öğe sayısı" + }, + "showAppIcon": { + "label": "Uygulama simgesini sağ alt köşede göster" + } + } + }, + "noAppSelected": "Lütfen widget ayarlarından bir uygulama seçin", + "views": { + "workers": { + "table": { + "header": { + "name": "Dosya", + "eta": "ETA (Kalan Süre)", + "progress": "İlerleme" + }, + "empty": "Boş", + "tooltip": { + "transcode": "Kod dönüştürme", + "healthCheck": "Sağlık kontrolü" + } + } + }, + "queue": { + "table": { + "header": { + "name": "Dosya", + "size": "Boyut" + }, + "footer": { + "currentIndex": "{{start}} - {{end}} üzerinden {{total}}" + }, + "empty": "Boş", + "tooltip": { + "transcode": "Kod dönüştürme", + "healthCheck": "Sağlık kontrolü" + } + } + }, + "statistics": { + "empty": "Boş", + "box": { + "transcodes": "Kod dönüştürmeler: {{value}}", + "healthChecks": "Sağlık Kontrolleri: {{value}}", + "files": "Dosyalar: {{value}}", + "spaceSaved": "Kaydedildi: {{value}}" + }, + "pies": { + "transcodes": "Kod dönüştürmeler", + "healthChecks": "Sağlık kontrolleri", + "videoCodecs": "Kodek'ler", + "videoContainers": "Konteyner", + "videoResolutions": "Çözünürlükler" + } + } + }, + "error": { + "title": "Hata", + "message": "Tdarr'dan veri alınırken bir hata oluştu." + }, + "tabs": { + "workers": "İşçiler", + "queue": "Kuyruk", + "statistics": "İstatistik" + }, + "healthCheckStatus": { + "title": "Sağlık kontrolü", + "queued": "Sıraya alındı", + "healthy": "Sağlıklı", + "unhealthy": "Sağlıksız" + } +} diff --git a/public/locales/tr/modules/smart-home/entity-state.json b/public/locales/tr/modules/smart-home/entity-state.json index 8e104239d..8a7e29bbd 100644 --- a/public/locales/tr/modules/smart-home/entity-state.json +++ b/public/locales/tr/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Kolay adı görüntüle", - "info": "Görünen ad yerine Home Assistant'ın kolay adını görüntüler" + "info": "Görünen ad yerine Home Assistant'ın kolay adını görüntüler." + }, + "genericToggle": { + "label": "Varlık geçişi", + "info": "Tıklandığında varlık üzerinde genel bir Home Assistant geçiş eylemi gerçekleştirir." } } } -} \ No newline at end of file +} + diff --git a/public/locales/tr/modules/torrents-status.json b/public/locales/tr/modules/torrents-status.json index 6e61b7c34..4a488e5af 100644 --- a/public/locales/tr/modules/torrents-status.json +++ b/public/locales/tr/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Filtrelenmiş torrent listesi ratio oranını görüntüle", "info": "Devre dışı bırakılırsa, yalnızca genel ratio görüntülenir. Genel ratio, ayarlanmışsa etiketleri kullanmaya devam edecektir" + }, + "columnOrdering": { + "label": "Sütunların yeniden sıralanmasını etkinleştir" + }, + "rowSorting": { + "label": "Satırları sıralamayı etkinleştir" + }, + "columns": { + "label": "Görüntülenecek sütunları seçin", + "data": { + "date": "Ekleme Tarihi", + "down": "İndirme", + "up": "Yükleme", + "eta": "ETA (Kalan Süre)", + "progress": "İlerleme" + } + }, + "nameColumnSize": { + "label": "Ad sütunun boyutunu değiştirme" } } }, @@ -84,10 +103,6 @@ "text": "Torrent istemcilerinizle iletişim kuramadı. Lütfen yapılandırmanızı kontrol edin" } }, - "loading": { - "title": "Yükleniyor", - "description": "Bağlantı kur" - }, "popover": { "introductionPrefix": "Tarafından yönetilen", "metrics": { diff --git a/public/locales/tw/authentication/login.json b/public/locales/tw/authentication/login.json index c71cb2b6c..9fa33391a 100644 --- a/public/locales/tw/authentication/login.json +++ b/public/locales/tw/authentication/login.json @@ -16,8 +16,8 @@ }, "afterLoginRedirection": "登入後,您將進入 {{url}}", "providersEmpty": { - "title": "", - "message": "" + "title": "驗證提供錯誤", + "message": "驗證伺服器未設定,請檢察您的日誌內容" } }, "alert": "您的憑證不正確或此帳號不存在,請重試" diff --git a/public/locales/tw/modules/health-monitoring.json b/public/locales/tw/modules/health-monitoring.json index 915360b65..baa53ad9b 100644 --- a/public/locales/tw/modules/health-monitoring.json +++ b/public/locales/tw/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } + "descriptor": { + "name": "系統健康監控", + "description": "顯示系統運行健康、狀態訊息", + "settings": { + "title": "設定系統健康監測", + "fahrenheit": { + "label": "CPU溫度 (華氏度)" + }, + "cpu": { + "label": "顯示 CPU 訊息", + "load": "平均負載", + "minute": "{{minute}} 分鐘", + "minutes": "{{minutes}} 分鐘" + }, + "memory": { + "label": "顯示記憶體訊息" + }, + "fileSystem": { + "label": "顯示檔案系統訊息" + }, + "node": { + "label": "按節點名稱篩選", + "info": "輸入您的 Proxmox 節點名稱,預設顯示全部集群" + }, + "defaultViewState": { + "label": "預設開啟", + "data": { + "none": "無", + "node": "節點", + "vm": "虛擬機", + "lxc": "LXCs", + "storage": "儲存設備" } - }, - "cpu": { - "label": "處理器", - "load": "", - "minute": "" - }, - "memory": { - "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { - "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + }, + "defaultTabState": { + "label": "預設開啟", + "info": "預設開啟,當多個集成可用時才使用", + "data": { + "system": "系統", + "cluster": "集群" } + }, + "summary": { + "label": "顯示摘要" + }, + "showNode": { + "label": "顯示節點" + }, + "showVM": { + "label": "顯示虛擬機" + }, + "showLXCs": { + "label": "顯示 LXCs" + }, + "showStorage": { + "label": "顯示儲存" + }, + "sectionIndicatorColor": { + "label": "要求部分指示器為\"OK\"", + "info": "需要全部項目都在線,指標才會成為綠色,至少需要一個項目在線", + "data": { + "any": "任何活動", + "all": "全部活動" + } + }, + "ignoreCert": { + "label": "忽略證書錯誤", + "info": "如果啟用,小工具在訪問 Proxmox API ,這對於 HTTPS 訪問 Proxmox 時很有幫助" + } } + }, + "cpu": { + "label": "處理器", + "load": "平均負載", + "minute": "{{minute}} 分鐘" + }, + "memory": { + "label": "記憶體", + "totalMem": "總記憶體: {{total}} GB", + "available": "可用: {{available}} GB - {{percentage}} %" + }, + "fileSystem": { + "label": "檔案系統", + "available": "可用: {{available}} - {{percentage}} %" + }, + "info": { + "uptime": "運行時間", + "uptimeFormat": "{{days}} 天,{{hours}} 小時", + "updates": "可用更新", + "reboot": "重新啟動" + }, + "errors": { + "general": { + "title": "無法找到系統", + "text": "連接系統時出現問題,請檢查配置/集成" + } + }, + "headings": { + "system": "系統", + "cluster": "集群" + }, + "cluster": { + "summary": { + "cpu": "處理器", + "ram": "記憶體" + }, + "accordion": { + "title": { + "nodes": "節點", + "vms": "虛擬機", + "lxcs": "LXCs", + "storage": "儲存設備" + } + }, + "table": { + "header": { + "name": "名稱", + "cpu": "處理器", + "ram": "記憶體", + "node": "節點" + } + }, + "popover": { + "node": "節點", + "vmid": "VMID", + "details": "詳情", + "cores": "核心 - {{maxCpu}}", + "memSize": "記憶體 - {{maxMem}}", + "memRatio": "記憶體 - {{usedMem}} / {{maxMem}}", + "diskSize": "硬碟 - {{maxDisk}}", + "diskRatio": "硬碟 - {{usedDisk}} / {{maxDisk}}", + "uptime": "運行時間 - {{uptime}}", + "plugin": "插件", + "ha": "狀態 - {{haState}}", + "sharedStorage": "共享儲存", + "localStorage": "本地儲存", + "na": "不可用" + } + } } \ No newline at end of file diff --git a/public/locales/tw/modules/media-transcoding.json b/public/locales/tw/modules/media-transcoding.json new file mode 100644 index 000000000..a31546f69 --- /dev/null +++ b/public/locales/tw/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "媒體轉碼", + "description": "顯示有關媒體轉碼的訊息", + "settings": { + "title": "媒體轉碼設定", + "appId": { + "label": "選擇一個應用" + }, + "defaultView": { + "label": "預設視圖", + "data": { + "workers": "工作種", + "queue": "隊列", + "statistics": "統計" + } + }, + "showHealthCheck": { + "label": "顯示現康檢查指示器" + }, + "showHealthChecksInQueue": { + "label": "在隊列中顯示健康檢查" + }, + "queuePageSize": { + "label": "隊獵:每頁項目數" + }, + "showAppIcon": { + "label": "在右下角顯示應用程式圖標" + } + } + }, + "noAppSelected": "請在小組件設置中選擇一個應用程式", + "views": { + "workers": { + "table": { + "header": { + "name": "檔案", + "eta": "剩餘時間", + "progress": "進度" + }, + "empty": "空", + "tooltip": { + "transcode": "轉碼", + "healthCheck": "健康檢查" + } + } + }, + "queue": { + "table": { + "header": { + "name": "檔案", + "size": "大小" + }, + "footer": { + "currentIndex": "{{start}}{{end}} 共 {{total}}" + }, + "empty": "空", + "tooltip": { + "transcode": "轉碼", + "healthCheck": "健康檢查" + } + } + }, + "statistics": { + "empty": "空", + "box": { + "transcodes": "轉碼:{{value}}", + "healthChecks": "健康檢查:{{value}}", + "files": "檔案:{{value}}", + "spaceSaved": "已儲存:{{value}}" + }, + "pies": { + "transcodes": "轉碼", + "healthChecks": "健康檢查", + "videoCodecs": "編碼", + "videoContainers": "容器", + "videoResolutions": "解析度" + } + } + }, + "error": { + "title": "錯誤", + "message": "從 Tdarr 獲取數據時發生錯誤" + }, + "tabs": { + "workers": "工作種", + "queue": "隊列", + "statistics": "統計" + }, + "healthCheckStatus": { + "title": "健康檢查", + "queued": "隊列", + "healthy": "健康", + "unhealthy": "不良" + } +} diff --git a/public/locales/tw/modules/smart-home/entity-state.json b/public/locales/tw/modules/smart-home/entity-state.json index dd0561c30..c62e72bd9 100644 --- a/public/locales/tw/modules/smart-home/entity-state.json +++ b/public/locales/tw/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "顯示友好名稱", - "info": "顯示來自 Home Assistant 的友好名稱,而不是顯示名稱" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/tw/modules/torrents-status.json b/public/locales/tw/modules/torrents-status.json index c44a9aa5c..3d25408f0 100644 --- a/public/locales/tw/modules/torrents-status.json +++ b/public/locales/tw/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "顯示過濾後的 Torrents 列表比例", "info": "如果禁用,則只會顯示全局比率,而全局比率仍將使用標籤" + }, + "columnOrdering": { + "label": "啟用重新排序列" + }, + "rowSorting": { + "label": "啟用行排列" + }, + "columns": { + "label": "選擇要顯示的列", + "data": { + "date": "日期已添加", + "down": "下載", + "up": "上傳", + "eta": "剩餘時間", + "progress": "進度" + } + }, + "nameColumnSize": { + "label": "更改名稱列大小" } } }, @@ -84,10 +103,6 @@ "text": "無法與您的 Torrent 客戶端交互,請檢查您的設定" } }, - "loading": { - "title": "載入中", - "description": "建立連接中" - }, "popover": { "introductionPrefix": "管理方:", "metrics": { diff --git a/public/locales/tw/modules/weather.json b/public/locales/tw/modules/weather.json index 77f5d1484..a14c25360 100644 --- a/public/locales/tw/modules/weather.json +++ b/public/locales/tw/modules/weather.json @@ -11,10 +11,10 @@ "label": "顯示城市名稱" }, "displayWeekly": { - "label": "" + "label": "顯示每周預測" }, "forecastDays": { - "label": "" + "label": "顯示天數" }, "location": { "label": "天氣位置" @@ -40,4 +40,4 @@ } }, "error": "出現錯誤" -} +} \ No newline at end of file diff --git a/public/locales/uk/authentication/invite.json b/public/locales/uk/authentication/invite.json index b18d900e8..4a245224e 100644 --- a/public/locales/uk/authentication/invite.json +++ b/public/locales/uk/authentication/invite.json @@ -21,7 +21,7 @@ "notifications": { "loading": { "title": "Створення облікового запису", - "text": "Будь ласка, зачекайте." + "text": "Будь ласка, зачекайте" }, "success": { "title": "Обліковий запис створено", diff --git a/public/locales/uk/modules/health-monitoring.json b/public/locales/uk/modules/health-monitoring.json index 43dc6133b..b7cc6023a 100644 --- a/public/locales/uk/modules/health-monitoring.json +++ b/public/locales/uk/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "", - "description": "", - "settings": { - "title": "", - "fahrenheit": { - "label": "" - } - } - }, - "cpu": { - "label": "Процесор", + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { + "label": "", "load": "", - "minute": "" - }, - "memory": { + "minute": "", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { "label": "", - "totalMem": "", - "available": "" - }, - "fileSystem": { + "info": "" + }, + "defaultViewState": { "label": "", - "available": "" - }, - "info": { - "uptime": "", - "updates": "", - "reboot": "" - }, - "errors": { - "general": { - "title": "", - "text": "" + "data": { + "none": "Нема", + "node": "", + "vm": "", + "lxc": "", + "storage": "Диск" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "Процесор", + "load": "", + "minute": "" + }, + "memory": { + "label": "", + "totalMem": "", + "available": "" + }, + "fileSystem": { + "label": "", + "available": "" + }, + "info": { + "uptime": "", + "uptimeFormat": "", + "updates": "", + "reboot": "" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "Процесор", + "ram": "Оперативна пам'ять" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "Диск" + } + }, + "table": { + "header": { + "name": "Ім’я", + "cpu": "Процесор", + "ram": "Оперативна пам'ять", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Деталі", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/uk/modules/media-transcoding.json b/public/locales/uk/modules/media-transcoding.json new file mode 100644 index 000000000..a64f7d57a --- /dev/null +++ b/public/locales/uk/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Черга", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "Залишилося", + "progress": "Прогрес" + }, + "empty": "Пусто", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Розмір" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Пусто", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Пусто", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Помилка", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Черга", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/uk/modules/smart-home/entity-state.json b/public/locales/uk/modules/smart-home/entity-state.json index 75dd923c8..45587f0a5 100644 --- a/public/locales/uk/modules/smart-home/entity-state.json +++ b/public/locales/uk/modules/smart-home/entity-state.json @@ -23,7 +23,12 @@ "displayFriendlyName": { "label": "", "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/uk/modules/torrents-status.json b/public/locales/uk/modules/torrents-status.json index 1af6bd391..54b97c370 100644 --- a/public/locales/uk/modules/torrents-status.json +++ b/public/locales/uk/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "", "info": "" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "Завантаження", + "up": "Віддача", + "eta": "Залишилося", + "progress": "Прогрес" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "Не вдається зв'язатися з вашими Torrent-клієнтами. Будь ласка, перевірте вашу конфігурацію" } }, - "loading": { - "title": "Завантаження", - "description": "Встановлення з'єднання" - }, "popover": { "introductionPrefix": "Керується", "metrics": { diff --git a/public/locales/vi/modules/health-monitoring.json b/public/locales/vi/modules/health-monitoring.json index f3849cb90..243f2bb26 100644 --- a/public/locales/vi/modules/health-monitoring.json +++ b/public/locales/vi/modules/health-monitoring.json @@ -1,37 +1,141 @@ { - "descriptor": { - "name": "Giám sát tình trạng hệ thống", - "description": "Cung cấp thông tin về NAS của bạn", - "settings": { - "title": "Giám sát tình trạng hệ thống", - "fahrenheit": { - "label": "Độ F" - } - } - }, - "cpu": { - "label": "CPU", + "descriptor": { + "name": "Giám sát tình trạng hệ thống", + "description": "", + "settings": { + "title": "", + "fahrenheit": { + "label": "" + }, + "cpu": { + "label": "", "load": "Tải trung bình", - "minute": "{{minute}} phút" - }, - "memory": { - "label": "Bộ nhớ", - "totalMem": "Tổng bộ nhớ: {{total}}GB", - "available": "Có sẵn: {{available}}GB - {{percentage}}%" - }, - "fileSystem": { - "label": "Hệ thống tập tin", - "available": "Có sẵn: {{available}} - {{percentage}}%" - }, - "info": { - "uptime": "Thời gian hoạt động", - "updates": "Cập nhật", - "reboot": "Khởi động lại" - }, - "errors": { - "general": { - "title": "Không thể tìm thấy NAS của bạn", - "text": "Đã xảy ra sự cố khi kết nối với NAS của bạn. Vui lòng xác minh (các) cấu hình/tích hợp của bạn." + "minute": "{{minute}} phút", + "minutes": "" + }, + "memory": { + "label": "" + }, + "fileSystem": { + "label": "" + }, + "node": { + "label": "", + "info": "" + }, + "defaultViewState": { + "label": "", + "data": { + "none": "Không hiển thị", + "node": "", + "vm": "", + "lxc": "", + "storage": "Bộ nhớ" } + }, + "defaultTabState": { + "label": "", + "info": "", + "data": { + "system": "", + "cluster": "" + } + }, + "summary": { + "label": "" + }, + "showNode": { + "label": "" + }, + "showVM": { + "label": "" + }, + "showLXCs": { + "label": "" + }, + "showStorage": { + "label": "" + }, + "sectionIndicatorColor": { + "label": "", + "info": "", + "data": { + "any": "", + "all": "" + } + }, + "ignoreCert": { + "label": "", + "info": "" + } } + }, + "cpu": { + "label": "CPU", + "load": "Tải trung bình", + "minute": "{{minute}} phút" + }, + "memory": { + "label": "Bộ nhớ", + "totalMem": "Tổng bộ nhớ: {{total}}GB", + "available": "Có sẵn: {{available}}GB - {{percentage}}%" + }, + "fileSystem": { + "label": "Hệ thống tập tin", + "available": "Có sẵn: {{available}} - {{percentage}}%" + }, + "info": { + "uptime": "Thời gian hoạt động", + "uptimeFormat": "", + "updates": "", + "reboot": "Khởi động lại" + }, + "errors": { + "general": { + "title": "", + "text": "" + } + }, + "headings": { + "system": "", + "cluster": "" + }, + "cluster": { + "summary": { + "cpu": "CPU", + "ram": "RAM" + }, + "accordion": { + "title": { + "nodes": "", + "vms": "", + "lxcs": "", + "storage": "Bộ nhớ" + } + }, + "table": { + "header": { + "name": "Tên", + "cpu": "CPU", + "ram": "RAM", + "node": "" + } + }, + "popover": { + "node": "", + "vmid": "", + "details": "Chi tiết", + "cores": "", + "memSize": "", + "memRatio": "", + "diskSize": "", + "diskRatio": "", + "uptime": "", + "plugin": "", + "ha": "", + "sharedStorage": "", + "localStorage": "", + "na": "" + } + } } \ No newline at end of file diff --git a/public/locales/vi/modules/media-transcoding.json b/public/locales/vi/modules/media-transcoding.json new file mode 100644 index 000000000..49357230f --- /dev/null +++ b/public/locales/vi/modules/media-transcoding.json @@ -0,0 +1,96 @@ +{ + "descriptor": { + "name": "", + "description": "", + "settings": { + "title": "", + "appId": { + "label": "" + }, + "defaultView": { + "label": "", + "data": { + "workers": "", + "queue": "Chờ", + "statistics": "" + } + }, + "showHealthCheck": { + "label": "" + }, + "showHealthChecksInQueue": { + "label": "" + }, + "queuePageSize": { + "label": "" + }, + "showAppIcon": { + "label": "" + } + } + }, + "noAppSelected": "", + "views": { + "workers": { + "table": { + "header": { + "name": "", + "eta": "Thời gian dự kiến", + "progress": "Tiến độ" + }, + "empty": "Trống", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "queue": { + "table": { + "header": { + "name": "", + "size": "Kích cỡ" + }, + "footer": { + "currentIndex": "" + }, + "empty": "Trống", + "tooltip": { + "transcode": "", + "healthCheck": "" + } + } + }, + "statistics": { + "empty": "Trống", + "box": { + "transcodes": "", + "healthChecks": "", + "files": "", + "spaceSaved": "" + }, + "pies": { + "transcodes": "", + "healthChecks": "", + "videoCodecs": "", + "videoContainers": "", + "videoResolutions": "" + } + } + }, + "error": { + "title": "Lỗi", + "message": "" + }, + "tabs": { + "workers": "", + "queue": "Chờ", + "statistics": "" + }, + "healthCheckStatus": { + "title": "", + "queued": "", + "healthy": "", + "unhealthy": "" + } +} diff --git a/public/locales/vi/modules/smart-home/entity-state.json b/public/locales/vi/modules/smart-home/entity-state.json index 2898301b2..dbe4a23ea 100644 --- a/public/locales/vi/modules/smart-home/entity-state.json +++ b/public/locales/vi/modules/smart-home/entity-state.json @@ -22,8 +22,13 @@ }, "displayFriendlyName": { "label": "Hiển thị tên thân thiện", - "info": "Hiển thị tên thân thiện từ Home Assistant thay vì tên hiển thị" + "info": "" + }, + "genericToggle": { + "label": "", + "info": "" } } } -} \ No newline at end of file +} + diff --git a/public/locales/vi/modules/torrents-status.json b/public/locales/vi/modules/torrents-status.json index 89c48877b..bca83f78c 100644 --- a/public/locales/vi/modules/torrents-status.json +++ b/public/locales/vi/modules/torrents-status.json @@ -29,6 +29,25 @@ "displayRatioWithFilter": { "label": "Hiển thị tỷ lệ danh sách torrent sau lọc", "info": "Nếu tắt, chỉ tỉ lệ chung sẽ được hiển thị. Tỉ lệ chung sẽ vẫn sử dụng nhãn nếu được đặt" + }, + "columnOrdering": { + "label": "" + }, + "rowSorting": { + "label": "" + }, + "columns": { + "label": "", + "data": { + "date": "", + "down": "Tải xuống", + "up": "Tải lên", + "eta": "Thời gian dự kiến", + "progress": "Tiến độ" + } + }, + "nameColumnSize": { + "label": "" } } }, @@ -84,10 +103,6 @@ "text": "Không thể liên lạc với khách hàng Torrent của bạn. Vui lòng kiểm tra cấu hình của bạn" } }, - "loading": { - "title": "Đang tải", - "description": "Thiết lập kết nối" - }, "popover": { "introductionPrefix": "Quản lý bởi", "metrics": { diff --git a/src/components/Board/Customize/Appearance/AppearanceCustomization.tsx b/src/components/Board/Customize/Appearance/AppearanceCustomization.tsx index 4f1411124..ee595a55c 100644 --- a/src/components/Board/Customize/Appearance/AppearanceCustomization.tsx +++ b/src/components/Board/Customize/Appearance/AppearanceCustomization.tsx @@ -16,7 +16,11 @@ import { useTranslation } from 'next-i18next'; import { highlight, languages } from 'prismjs'; import Editor from 'react-simple-code-editor'; import { useColorTheme } from '~/tools/color'; -import { BackgroundImageAttachment, BackgroundImageRepeat, BackgroundImageSize } from '~/types/settings'; +import { + BackgroundImageAttachment, + BackgroundImageRepeat, + BackgroundImageSize, +} from '~/types/settings'; import { useBoardCustomizationFormContext } from '../form'; diff --git a/src/components/Board/Customize/Layout/LayoutPreview.tsx b/src/components/Board/Customize/Layout/LayoutPreview.tsx index ecae8cc6f..9f771a31d 100644 --- a/src/components/Board/Customize/Layout/LayoutPreview.tsx +++ b/src/components/Board/Customize/Layout/LayoutPreview.tsx @@ -114,6 +114,7 @@ const PlaceholderElement = ({ height, width, showPing, index }: PlaceholderEleme size={5} offset={10} color={index % 4 === 0 ? 'red' : 'green'} + zIndex={0} > diff --git a/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx b/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx index 7b5010604..f9ba29e04 100644 --- a/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx @@ -75,7 +75,11 @@ export const EditAppModal = ({ return t('validation.noExternalUri'); } - if (!url.match(appUrlWithAnyProtocolRegex)) { + if ( + !url.match(appUrlWithAnyProtocolRegex) && + !url.startsWith('[homarr_base]') && + !url.startsWith('[homarr_protocol]://') + ) { return t('validation.invalidExternalUri'); } @@ -110,7 +114,7 @@ export const EditAppModal = ({ // also close the parent modal context.closeAll(); - umami.track('Add app', { name: values.name }); + umami.track('Add app', { name: values.name }); }; const [activeTab, setActiveTab] = useState('general'); diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx index b1a6e80fe..ee9b6e25a 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx @@ -1,4 +1,4 @@ -import { Flex, NumberInput, Select, Stack, Switch, Tabs } from '@mantine/core'; +import { Flex, NumberInput, Select, Stack, Tabs } from '@mantine/core'; import { UseFormReturnType } from '@mantine/form'; import { useDebouncedValue } from '@mantine/hooks'; import { useTranslation } from 'next-i18next'; @@ -18,14 +18,13 @@ export const AppearanceTab = ({ allowAppNamePropagation, }: AppearanceTabProps) => { const iconSelectorRef = useRef(); - const [debouncedValue] = useDebouncedValue(form.values.name, 500); + const [debouncedValue] = useDebouncedValue(form.values.name, 2 * 1000); // 2 seconds debounce const { t } = useTranslation('layout/modals/add-app'); useEffect(() => { if (allowAppNamePropagation !== true) { return; } - if (!iconSelectorRef.current) { return; } diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx index 3e7806159..a1a833197 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx @@ -3,6 +3,7 @@ import { UseFormReturnType } from '@mantine/form'; import { useDisclosure } from '@mantine/hooks'; import { IconClick, IconCursorText, IconLink } from '@tabler/icons-react'; import { useTranslation } from 'next-i18next'; +import { InfoCard } from '~/components/InfoCard/InfoCard'; import { AppType } from '~/types/app'; import { EditAppModalTab } from '../type'; @@ -50,14 +51,21 @@ export const GeneralTab = ({ form, openTab }: GeneralTabProps) => { form.setFieldValue('url', e.target.value); }} /> - } - label={t('general.externalAddress.label')} - description={t('general.externalAddress.description')} - placeholder="https://homarr.mywebsite.com/" - variant="default" - {...form.getInputProps('behaviour.externalUrl')} - /> + + + + {t('general.externalAddress.label')} + + + + } + description={t('general.externalAddress.description')} + placeholder="https://homarr.mywebsite.com/" + variant="default" + {...form.getInputProps('behaviour.externalUrl')} + /> + @@ -81,7 +89,9 @@ export const GeneralTab = ({ form, openTab }: GeneralTabProps) => { {!form.values.behaviour.externalUrl.startsWith('https://') && - !form.values.behaviour.externalUrl.startsWith('http://') && ( + !form.values.behaviour.externalUrl.startsWith('http://') && + !form.values.behaviour.externalUrl.startsWith('[homarr_base]') && + !form.values.behaviour.externalUrl.startsWith('[homarr_protocol]://') && ( {t('behaviour.customProtocolWarning')} diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/InputElements/IntegrationSelector.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/InputElements/IntegrationSelector.tsx index bedb543a2..515c4b467 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/InputElements/IntegrationSelector.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/InputElements/IntegrationSelector.tsx @@ -198,4 +198,14 @@ export const availableIntegrations = [ image: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/openmediavault.png', label: 'OpenMediaVault', }, + { + value: 'proxmox', + image: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/proxmox.png', + label: 'Proxmox', + }, + { + value: 'tdarr', + image: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/tdarr.png', + label: 'Tdarr', + } ] as const satisfies Readonly; diff --git a/src/components/Dashboard/Tiles/Apps/AppTile.tsx b/src/components/Dashboard/Tiles/Apps/AppTile.tsx index da4ee649e..e9fa7dc01 100644 --- a/src/components/Dashboard/Tiles/Apps/AppTile.tsx +++ b/src/components/Dashboard/Tiles/Apps/AppTile.tsx @@ -1,7 +1,7 @@ -import { Affix, Box, Text, Tooltip, UnstyledButton } from '@mantine/core'; +import { Box, Text, Tooltip, UnstyledButton } from '@mantine/core'; import { createStyles, useMantineTheme } from '@mantine/styles'; import { motion } from 'framer-motion'; -import Link from 'next/link'; +import { useExternalUrl } from '~/hooks/useExternalUrl'; import { AppType } from '~/types/app'; import { useEditModeStore } from '../../Views/useEditModeStore'; @@ -26,6 +26,7 @@ export const AppTile = ({ className, app }: AppTileProps) => { .join(': '); const isRow = app.appearance.positionAppName.includes('row'); + const href = useExternalUrl(app); function Inner() { return ( @@ -88,7 +89,7 @@ export const AppTile = ({ className, app }: AppTileProps) => { 0 ? app.behaviour.externalUrl : app.url} + href={href} target={app.behaviour.isOpeningNewTab ? '_blank' : '_self'} className={`${classes.button} ${classes.base}`} > diff --git a/src/components/Dashboard/Tiles/Widgets/Inputs/LocationSelection.tsx b/src/components/Dashboard/Tiles/Widgets/Inputs/LocationSelection.tsx index 7218196a0..f60a59fe0 100644 --- a/src/components/Dashboard/Tiles/Widgets/Inputs/LocationSelection.tsx +++ b/src/components/Dashboard/Tiles/Widgets/Inputs/LocationSelection.tsx @@ -169,11 +169,7 @@ const CitySelectModal = ({ opened, closeModal, query, onCitySelected }: CitySele if (isError === true) return ( - {t('modal.title')} - {query} - - } + title={t('modal.title') + ' - ' + query} size="xl" opened={opened} onClose={closeModal} @@ -193,11 +189,7 @@ const CitySelectModal = ({ opened, closeModal, query, onCitySelected }: CitySele return ( - {t('modal.title')} - {query} - - } + title={t('modal.title') + ' - ' + query} size="xl" opened={opened} onClose={closeModal} diff --git a/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx b/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx index 6b6e11e1a..f2a2a15dc 100644 --- a/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx +++ b/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx @@ -85,7 +85,7 @@ export const WidgetsEditModal = ({ return ( - {items.map(([key, _], index) => { + {items.map(([key], index) => { const option = (currentWidgetDefinition as any).options[key] as IWidgetOptionValue; const value = moduleProperties[key] ?? option.defaultValue; @@ -395,6 +395,7 @@ const WidgetOptionTypeSwitch: FC<{ ); + /* eslint-enable no-case-declarations */ default: return null; diff --git a/src/components/Dashboard/Tiles/Widgets/WidgetsMenu.tsx b/src/components/Dashboard/Tiles/Widgets/WidgetsMenu.tsx index 88dfc827d..36d544827 100644 --- a/src/components/Dashboard/Tiles/Widgets/WidgetsMenu.tsx +++ b/src/components/Dashboard/Tiles/Widgets/WidgetsMenu.tsx @@ -1,4 +1,3 @@ -import { Title } from '@mantine/core'; import { useTranslation } from 'next-i18next'; import { openContextModalGeneric } from '~/tools/mantineModalManagerExtensions'; import { IWidget } from '~/widgets/widgets'; @@ -38,7 +37,7 @@ export const WidgetsMenu = ({ integration, widget }: WidgetsMenuProps) => { const handleDeleteClick = () => { openContextModalGeneric({ modal: 'integrationRemove', - title: {t('common:remove')}, + title: t('common:remove'), innerProps: { widgetId: widget.id, widgetType: integration, @@ -63,7 +62,7 @@ export const WidgetsMenu = ({ integration, widget }: WidgetsMenuProps) => { const handleEditClick = () => { openContextModalGeneric({ modal: 'integrationOptions', - title: {t('descriptor.settings.title')}, + title: t('descriptor.settings.title'), innerProps: { widgetId: widget.id, widgetType: integration, diff --git a/src/components/Dashboard/Wrappers/Category/Category.tsx b/src/components/Dashboard/Wrappers/Category/Category.tsx index 72d162c49..e7115d4a5 100644 --- a/src/components/Dashboard/Wrappers/Category/Category.tsx +++ b/src/components/Dashboard/Wrappers/Category/Category.tsx @@ -14,6 +14,7 @@ import { modals } from '@mantine/modals'; import { IconDotsVertical, IconShare3 } from '@tabler/icons-react'; import { useTranslation } from 'next-i18next'; import { useConfigContext } from '~/config/provider'; +import { useGetExternalUrl } from '~/hooks/useExternalUrl'; import { CategoryType } from '~/types/category'; import { useCardStyles } from '../../../layout/Common/useCardStyles'; @@ -33,6 +34,7 @@ export const DashboardCategory = ({ category }: DashboardCategoryProps) => { const { classes: cardClasses, cx } = useCardStyles(true); const { classes } = useStyles(); const { t } = useTranslation(['layout/common', 'common']); + const getAppUrl = useGetExternalUrl(); const categoryList = config?.categories.map((x) => x.name) ?? []; const [toggledCategories, setToggledCategories] = useLocalStorage({ @@ -44,7 +46,8 @@ export const DashboardCategory = ({ category }: DashboardCategoryProps) => { const handleMenuClick = () => { for (let i = 0; i < apps.length; i += 1) { const app = apps[i]; - const popUp = window.open(app.url, app.id); + const appUrl = getAppUrl(app); + const popUp = window.open(appUrl, app.id); if (popUp === null) { modals.openConfirmModal({ @@ -98,10 +101,10 @@ export const DashboardCategory = ({ category }: DashboardCategoryProps) => { > - }> + {category.name} - {!isEditMode && ( + {!isEditMode ? ( @@ -114,6 +117,8 @@ export const DashboardCategory = ({ category }: DashboardCategoryProps) => { + ) : ( + )} diff --git a/src/components/Manage/Board/create-board.modal.tsx b/src/components/Manage/Board/create-board.modal.tsx index 0f440f0bc..90fd32052 100644 --- a/src/components/Manage/Board/create-board.modal.tsx +++ b/src/components/Manage/Board/create-board.modal.tsx @@ -1,4 +1,4 @@ -import { Button, Group, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Button, Group, Stack, Text, TextInput } from '@mantine/core'; import { useForm } from '@mantine/form'; import { ContextModalProps, modals } from '@mantine/modals'; import { Trans, useTranslation } from 'next-i18next'; @@ -80,11 +80,7 @@ export const CreateBoardModal = ({ id }: ContextModalProps<{}>) => { export const openCreateBoardModal = () => { modals.openContextModal({ modal: 'createBoardModal', - title: ( - - <Trans i18nKey="manage/boards:modals.create.title" /> - - ), + title: , innerProps: {}, }); }; diff --git a/src/components/Manage/Board/delete-board.modal.tsx b/src/components/Manage/Board/delete-board.modal.tsx index cddb7c9bb..ce9521780 100644 --- a/src/components/Manage/Board/delete-board.modal.tsx +++ b/src/components/Manage/Board/delete-board.modal.tsx @@ -1,4 +1,4 @@ -import { Button, Group, Stack, Text, Title } from '@mantine/core'; +import { Button, Group, Stack, Text } from '@mantine/core'; import { ContextModalProps, modals } from '@mantine/modals'; import { Trans, useTranslation } from 'next-i18next'; import { api } from '~/utils/api'; @@ -51,11 +51,7 @@ export const DeleteBoardModal = ({ id, innerProps }: ContextModalProps { modals.openContextModal({ modal: 'deleteBoardModal', - title: ( - - <Trans i18nKey="manage/boards:modals.delete.title" /> - - ), + title: , innerProps, }); }; diff --git a/src/components/Manage/Tools/Docker/docker-select-board.modal.tsx b/src/components/Manage/Tools/Docker/docker-select-board.modal.tsx index 688c6796c..590393e23 100644 --- a/src/components/Manage/Tools/Docker/docker-select-board.modal.tsx +++ b/src/components/Manage/Tools/Docker/docker-select-board.modal.tsx @@ -1,4 +1,4 @@ -import { Button, Group, Select, Stack, Text, Title } from '@mantine/core'; +import { Button, Group, Select, Stack, Text } from '@mantine/core'; import { useForm } from '@mantine/form'; import { ContextModalProps, modals } from '@mantine/modals'; import { showNotification } from '@mantine/notifications'; @@ -132,11 +132,7 @@ export const DockerSelectBoardModal = ({ id, innerProps }: ContextModalProps { modals.openContextModal({ modal: 'dockerSelectBoardModal', - title: ( - - <Trans i18nKey="tools/docker:modals.selectBoard.title" /> - - ), + title: , innerProps, }); umami.track('Add to homarr modal'); diff --git a/src/components/Manage/User/Invite/copy-invite.modal.tsx b/src/components/Manage/User/Invite/copy-invite.modal.tsx index 44551e6b1..efa318fb1 100644 --- a/src/components/Manage/User/Invite/copy-invite.modal.tsx +++ b/src/components/Manage/User/Invite/copy-invite.modal.tsx @@ -1,4 +1,4 @@ -import { Button, CopyButton, Mark, Stack, Text, Title } from '@mantine/core'; +import { Button, CopyButton, Mark, Stack, Text } from '@mantine/core'; import { ContextModalProps, modals } from '@mantine/modals'; import { Trans, useTranslation } from 'next-i18next'; import Link from 'next/link'; @@ -65,11 +65,7 @@ const useInviteUrl = (id: string, token: string) => { export const openCopyInviteModal = (data: InnerProps) => { modals.openContextModal({ modal: 'copyInviteModal', - title: ( - - <Trans i18nKey="manage/users/invites:modals.copy.title" /> - - ), + title: , innerProps: data, }); }; diff --git a/src/components/Manage/User/Invite/create-invite.modal.tsx b/src/components/Manage/User/Invite/create-invite.modal.tsx index 972a210a2..386e5df69 100644 --- a/src/components/Manage/User/Invite/create-invite.modal.tsx +++ b/src/components/Manage/User/Invite/create-invite.modal.tsx @@ -1,4 +1,4 @@ -import { Button, Group, Stack, Text, Title } from '@mantine/core'; +import { Button, Group, Stack, Text } from '@mantine/core'; import { DateTimePicker } from '@mantine/dates'; import { useForm } from '@mantine/form'; import { ContextModalProps, modals } from '@mantine/modals'; @@ -79,11 +79,7 @@ export const CreateInviteModal = ({ id }: ContextModalProps<{}>) => { export const openCreateInviteModal = () => { modals.openContextModal({ modal: 'createInviteModal', - title: ( - - <Trans i18nKey="manage/users/invites:modals.create.title" /> - - ), + title: , innerProps: {}, }); }; diff --git a/src/components/Manage/User/change-user-role.modal.tsx b/src/components/Manage/User/change-user-role.modal.tsx index 97c2efc36..a5c691e93 100644 --- a/src/components/Manage/User/change-user-role.modal.tsx +++ b/src/components/Manage/User/change-user-role.modal.tsx @@ -1,4 +1,4 @@ -import { Button, Group, Stack, Text, Title } from '@mantine/core'; +import { Button, Group, Stack, Text } from '@mantine/core'; import { ContextModalProps, modals } from '@mantine/modals'; import { Trans, useTranslation } from 'next-i18next'; import { api } from '~/utils/api'; @@ -48,12 +48,10 @@ export const openRoleChangeModal = (user: InnerProps) => { modals.openContextModal({ modal: 'changeUserRoleModal', title: ( - - <Trans - i18nKey={`manage/users:modals.change-role.${user.type}.title`} - values={{ name: user.name }} - /> - + ), innerProps: user, }); diff --git a/src/components/Manage/User/delete-user.modal.tsx b/src/components/Manage/User/delete-user.modal.tsx index adbeae1ce..3f6287c96 100644 --- a/src/components/Manage/User/delete-user.modal.tsx +++ b/src/components/Manage/User/delete-user.modal.tsx @@ -1,4 +1,4 @@ -import { Button, Group, Stack, Text, Title } from '@mantine/core'; +import { Button, Group, Stack, Text } from '@mantine/core'; import { ContextModalProps, modals } from '@mantine/modals'; import { Trans, useTranslation } from 'next-i18next'; import { api } from '~/utils/api'; @@ -46,11 +46,7 @@ export const DeleteUserModal = ({ id, innerProps }: ContextModalProps { modals.openContextModal({ modal: 'deleteUserModal', - title: ( - - <Trans i18nKey="manage/users:modals.delete.title" values={{ name: user.name }} /> - - ), + title: , innerProps: user, }); }; diff --git a/src/components/layout/Templates/BoardLayout.tsx b/src/components/layout/Templates/BoardLayout.tsx index 0e7f82609..0fdbc1f43 100644 --- a/src/components/layout/Templates/BoardLayout.tsx +++ b/src/components/layout/Templates/BoardLayout.tsx @@ -285,6 +285,7 @@ const BackgroundVideo = ({videoSource, videoFormat}: BackgroundVideoProps) => { autoPlay muted loop + playsInline style={{ position: 'fixed', width: '100vw', diff --git a/src/components/layout/header/AvatarMenu.tsx b/src/components/layout/header/AvatarMenu.tsx index f9d6b4d0d..485c9bb35 100644 --- a/src/components/layout/header/AvatarMenu.tsx +++ b/src/components/layout/header/AvatarMenu.tsx @@ -14,6 +14,7 @@ import { signOut, useSession } from 'next-auth/react'; import { useTranslation } from 'next-i18next'; import Link from 'next/link'; import { forwardRef } from 'react'; +import { useLogoutUrl } from '~/hooks/custom-session-provider'; import { useColorScheme } from '~/hooks/use-colorscheme'; import { useBoardLink } from '../Templates/BoardLayout'; @@ -26,65 +27,65 @@ export const AvatarMenu = () => { const Icon = colorScheme === 'dark' ? IconSun : IconMoonStars; const defaultBoardHref = useBoardLink('/board'); + const logoutUrl = useLogoutUrl(); + return ( - - - + + + - - - } - onClick={toggleColorScheme} - > - {t('actions.avatar.switchTheme')} - - {sessionData?.user && ( - <> - } - > - {t('actions.avatar.preferences')} - - } - > - {t('actions.avatar.defaultBoard')} - - }> - {t('actions.avatar.manage')} - - - - )} - {sessionData?.user ? ( + + + + } onClick={toggleColorScheme}> + {t('actions.avatar.switchTheme')} + + {sessionData?.user && ( + <> } - color="red" - onClick={() => - signOut({ - redirect: false, - }).then(() => window.location.reload()) - } + component={Link} + passHref + href="/user/preferences" + icon={} > - {t('actions.avatar.logout', { - username: sessionData.user.name, - })} + {t('actions.avatar.preferences')} - ) : ( - } component={Link} href="/auth/login"> - {t('actions.avatar.login')} + } + > + {t('actions.avatar.defaultBoard')} - )} - - - + }> + {t('actions.avatar.manage')} + + + + )} + {sessionData?.user ? ( + } + color="red" + onClick={() => { + signOut({ + redirect: false, + }).then(() => + logoutUrl ? window.location.assign(logoutUrl) : window.location.reload() + ); + }} + > + {t('actions.avatar.logout', { + username: sessionData.user.name, + })} + + ) : ( + } component={Link} href="/auth/login"> + {t('actions.avatar.login')} + + )} + + ); }; @@ -92,10 +93,10 @@ type CurrentUserAvatarProps = { user: User | null; }; -const getGravatar = (email?: string | undefined | null) => { +const getAvatarLink = (email?: string | undefined | null) => { if (!email) return null; const emailHash = createHash('sha256').update(email.trim().toLowerCase()).digest('hex'); - return `https://gravatar.com/avatar/${emailHash}?d=null`; + return `https://seccdn.libravatar.org/avatar/${emailHash}?d=404`; }; const CurrentUserAvatar = forwardRef( @@ -104,18 +105,16 @@ const CurrentUserAvatar = forwardRef( const { fn } = useMantineTheme(); const border = fn.variant({ variant: 'default' }).border; - if (!user) - return ; - return ( - {user.name?.slice(0, 2).toUpperCase()} + {user?.name?.slice(0, 2).toUpperCase()} ); } diff --git a/src/components/layout/header/Header.tsx b/src/components/layout/header/Header.tsx index a584e7e64..baedc29a8 100644 --- a/src/components/layout/header/Header.tsx +++ b/src/components/layout/header/Header.tsx @@ -1,5 +1,4 @@ import { - Anchor, Box, Center, Flex, @@ -8,11 +7,11 @@ import { Text, Title, UnstyledButton, - useMantineTheme, + useMantineTheme } from '@mantine/core'; import { useMediaQuery } from '@mantine/hooks'; import { IconAlertTriangle } from '@tabler/icons-react'; -import { Trans, useTranslation } from 'next-i18next'; +import { useTranslation } from 'next-i18next'; import { Logo } from '../Common/Logo'; import { AvatarMenu } from './AvatarMenu'; @@ -44,7 +43,7 @@ export const MainHeader = ({ : headerBaseHeight; return ( -
+
{leftIcon} diff --git a/src/env.js b/src/env.js index 203a48be9..ef6039f9b 100644 --- a/src/env.js +++ b/src/env.js @@ -12,6 +12,12 @@ const zodParsedBoolean = () => .default('false') .transform((value) => trueStrings.includes(value)); +const numberSchema = z + .string() + .regex(/\d*/) + .transform((value) => (value === undefined ? undefined : Number(value))) + .optional(); + const portSchema = z .string() .regex(/\d*/) @@ -43,6 +49,12 @@ const env = createEnv({ DEMO_MODE: z.string().optional(), HOSTNAME: z.string().optional(), + //regex allows number with extra letter as time multiplier, applied with secondsFromTimeString + AUTH_SESSION_EXPIRY_TIME: z + .string() + .regex(/^\d+[smhd]?$/) + .optional(), + // Authentication AUTH_PROVIDER: z .string() @@ -71,9 +83,12 @@ const env = createEnv({ AUTH_LDAP_BASE: z.string(), AUTH_LDAP_SEARCH_SCOPE: z.enum(['base', 'one', 'sub']).default('base'), AUTH_LDAP_USERNAME_ATTRIBUTE: z.string().default('uid'), + AUTH_LDAP_USER_MAIL_ATTRIBUTE: z.string().default('mail'), + AUTH_LDAP_USERNAME_FILTER_EXTRA_ARG: z.string().optional(), AUTH_LDAP_GROUP_CLASS: z.string().default('groupOfUniqueNames'), AUTH_LDAP_GROUP_MEMBER_ATTRIBUTE: z.string().default('member'), AUTH_LDAP_GROUP_MEMBER_USER_ATTRIBUTE: z.string().default('dn'), + AUTH_LDAP_GROUP_FILTER_EXTRA_ARG: z.string().optional(), AUTH_LDAP_ADMIN_GROUP: z.string().default('admin'), AUTH_LDAP_OWNER_GROUP: z.string().default('admin'), } @@ -90,6 +105,7 @@ const env = createEnv({ AUTH_OIDC_OWNER_GROUP: z.string().default('admin'), AUTH_OIDC_AUTO_LOGIN: zodParsedBoolean(), AUTH_OIDC_SCOPE_OVERWRITE: z.string().default('openid email profile groups'), + AUTH_OIDC_TIMEOUT: numberSchema.default(3500), } : {}), }, @@ -111,6 +127,7 @@ const env = createEnv({ .optional() .default('light'), NEXT_PUBLIC_DOCKER_HOST: z.string().optional(), + AUTH_LOGOUT_REDIRECT_URL: z.string().optional(), }, /** * You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g. @@ -135,9 +152,12 @@ const env = createEnv({ AUTH_LDAP_BASE: process.env.AUTH_LDAP_BASE, AUTH_LDAP_SEARCH_SCOPE: process.env.AUTH_LDAP_SEARCH_SCOPE?.toLowerCase(), AUTH_LDAP_USERNAME_ATTRIBUTE: process.env.AUTH_LDAP_USERNAME_ATTRIBUTE, + AUTH_LDAP_USER_MAIL_ATTRIBUTE: process.env.AUTH_LDAP_USER_MAIL_ATTRIBUTE, + AUTH_LDAP_USERNAME_FILTER_EXTRA_ARG: process.env.AUTH_LDAP_USERNAME_FILTER_EXTRA_ARG, AUTH_LDAP_GROUP_CLASS: process.env.AUTH_LDAP_GROUP_CLASS, AUTH_LDAP_GROUP_MEMBER_ATTRIBUTE: process.env.AUTH_LDAP_GROUP_MEMBER_ATTRIBUTE, AUTH_LDAP_GROUP_MEMBER_USER_ATTRIBUTE: process.env.AUTH_LDAP_GROUP_MEMBER_USER_ATTRIBUTE, + AUTH_LDAP_GROUP_FILTER_EXTRA_ARG: process.env.AUTH_LDAP_GROUP_FILTER_EXTRA_ARG, AUTH_LDAP_ADMIN_GROUP: process.env.AUTH_LDAP_ADMIN_GROUP, AUTH_LDAP_OWNER_GROUP: process.env.AUTH_LDAP_OWNER_GROUP, AUTH_OIDC_CLIENT_ID: process.env.AUTH_OIDC_CLIENT_ID, @@ -149,6 +169,9 @@ const env = createEnv({ AUTH_OIDC_OWNER_GROUP: process.env.AUTH_OIDC_OWNER_GROUP, AUTH_OIDC_AUTO_LOGIN: process.env.AUTH_OIDC_AUTO_LOGIN, AUTH_OIDC_SCOPE_OVERWRITE: process.env.AUTH_OIDC_SCOPE_OVERWRITE, + AUTH_OIDC_TIMEOUT: process.env.AUTH_OIDC_TIMEOUT, + AUTH_LOGOUT_REDIRECT_URL: process.env.AUTH_LOGOUT_REDIRECT_URL, + AUTH_SESSION_EXPIRY_TIME: process.env.AUTH_SESSION_EXPIRY_TIME, DEMO_MODE: process.env.DEMO_MODE, }, skipValidation: !!process.env.SKIP_ENV_VALIDATION, diff --git a/src/hooks/custom-session-provider.tsx b/src/hooks/custom-session-provider.tsx new file mode 100644 index 000000000..0bd1cc5b5 --- /dev/null +++ b/src/hooks/custom-session-provider.tsx @@ -0,0 +1,44 @@ +import dayjs from 'dayjs'; +import { Session } from 'next-auth'; +import { SessionProvider, signIn } from 'next-auth/react'; +import { createContext, useContext, useEffect } from 'react'; + +interface CustomSessionProviderProps { + session: Session; + children: React.ReactNode; + logoutUrl?: string; +} + +export const CustomSessionProvider = ({ + session, + children, + logoutUrl, +}: CustomSessionProviderProps) => { + //Automatically redirect to the login page after a session expires or after 24 days + useEffect(() => { + if (!session) return () => {}; + //setTimeout doesn't allow for a number higher than 2147483647 (2³¹-1 , or roughly 24 days) + const timeout = setTimeout(signIn, Math.min(dayjs(session.expires).diff(), 2147483647)); + return () => clearTimeout(timeout); + }, [session]); + + return ( + + {children} + + ); +}; + +interface SessionContextProps { + logoutUrl?: string; +} + +const SessionContext = createContext(null); + +export function useLogoutUrl() { + const context = useContext(SessionContext); + if (!context) { + throw new Error('You cannot use logoutUrl outside of session context.'); + } + return context.logoutUrl; +} diff --git a/src/hooks/useExternalUrl.ts b/src/hooks/useExternalUrl.ts new file mode 100644 index 000000000..bbd774220 --- /dev/null +++ b/src/hooks/useExternalUrl.ts @@ -0,0 +1,39 @@ +import { useCallback, useMemo } from 'react'; +import * as tldts from 'tldts'; +import { AppType } from '~/types/app'; + +export const useGetExternalUrl = () => { + const parsedUrl = useMemo(() => { + try { + return tldts.parse(window.location.toString()); + } catch { + return null; + } + }, [window.location]); + + const getHref = useCallback( + (appType: AppType) => { + if (appType.behaviour.externalUrl.length > 0) { + return appType.behaviour.externalUrl + .replace('[homarr_base]', `${window.location.protocol}//${window.location.hostname}`) + .replace('[homarr_hostname]', parsedUrl?.hostname ?? '') + .replace('[homarr_domain]', parsedUrl?.domain ?? '') + .replace('[homarr_protocol]', window.location.protocol.replace(':', '')); + } + return appType.url; + }, + [parsedUrl] + ); + + return getHref; +}; + +export const useExternalUrl = (app: AppType) => { + const getHref = useGetExternalUrl(); + + const href = useMemo(() => { + return getHref(app); + }, [app, getHref]); + + return href; +}; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 1795ac8e1..d3296d752 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -10,7 +10,7 @@ import utc from 'dayjs/plugin/utc'; import 'flag-icons/css/flag-icons.min.css'; import { GetServerSidePropsContext } from 'next'; import { Session } from 'next-auth'; -import { getSession, SessionProvider } from 'next-auth/react'; +import { getSession } from 'next-auth/react'; import { appWithTranslation } from 'next-i18next'; import { AppProps } from 'next/app'; import Script from 'next/script'; @@ -19,12 +19,16 @@ import 'video.js/dist/video-js.css'; import { CommonHead } from '~/components/layout/Meta/CommonHead'; import { ConfigProvider } from '~/config/provider'; import { env } from '~/env.js'; +import { CustomSessionProvider } from '~/hooks/custom-session-provider'; import { ColorSchemeProvider } from '~/hooks/use-colorscheme'; import { modals } from '~/modals'; import { usePackageAttributesStore } from '~/tools/client/zustands/usePackageAttributesStore'; import { ColorTheme } from '~/tools/color'; import { getLanguageByCode } from '~/tools/language'; -import { getServiceSidePackageAttributes, ServerSidePackageAttributesType } from '~/tools/server/getPackageVersion'; +import { + ServerSidePackageAttributesType, + getServiceSidePackageAttributes, +} from '~/tools/server/getPackageVersion'; import { theme } from '~/tools/server/theme/theme'; import { ConfigType } from '~/types/config'; import { api } from '~/utils/api'; @@ -44,6 +48,7 @@ function App( environmentColorScheme: MantineColorScheme; packageAttributes: ServerSidePackageAttributesType; editModeEnabled: boolean; + logoutUrl?: string; analyticsEnabled: boolean; config?: ConfigType; primaryColor?: MantineTheme['primaryColor']; @@ -111,7 +116,7 @@ function App( strategy="lazyOnload" /> )} - + {(colorScheme) => ( @@ -151,7 +156,7 @@ function App( )} - + ); } @@ -177,6 +182,7 @@ App.getInitialProps = async ({ ctx }: { ctx: GetServerSidePropsContext }) => { pageProps: { ...getActiveColorScheme(session, ctx), packageAttributes: getServiceSidePackageAttributes(), + logoutUrl: env.AUTH_LOGOUT_REDIRECT_URL, analyticsEnabled, session, locale: ctx.locale ?? 'en', diff --git a/src/pages/auth/login.tsx b/src/pages/auth/login.tsx index 19b8442f2..8bc5c0d9f 100644 --- a/src/pages/auth/login.tsx +++ b/src/pages/auth/login.tsx @@ -49,6 +49,7 @@ export default function LoginPage({ validateInputOnChange: true, validateInputOnBlur: true, validate: i18nZodResolver(signInSchemaWithProvider), + initialValues: { name: '', password: '', provider: '' }, }); const handleSubmit = (values: z.infer) => { diff --git a/src/server/api/root.ts b/src/server/api/root.ts index 2f12f6a37..98f0ee68f 100644 --- a/src/server/api/root.ts +++ b/src/server/api/root.ts @@ -8,13 +8,13 @@ import { dashDotRouter } from './routers/dash-dot'; import { dnsHoleRouter } from './routers/dns-hole/router'; import { dockerRouter } from './routers/docker/router'; import { downloadRouter } from './routers/download'; +import { healthMonitoringRouter } from './routers/health-monitoring/router'; import { iconRouter } from './routers/icon'; import { indexerManagerRouter } from './routers/indexer-manager'; import { inviteRouter } from './routers/invite/invite-router'; import { mediaRequestsRouter } from './routers/media-request'; import { mediaServerRouter } from './routers/media-server'; import { notebookRouter } from './routers/notebook'; -import { openmediavaultRouter } from './routers/openmediavault'; import { overseerrRouter } from './routers/overseerr'; import { passwordRouter } from './routers/password'; import { rssRouter } from './routers/rss'; @@ -22,6 +22,7 @@ import { smartHomeEntityStateRouter } from './routers/smart-home/entity-state'; import { usenetRouter } from './routers/usenet/router'; import { userRouter } from './routers/user'; import { weatherRouter } from './routers/weather'; +import { tdarrRouter } from '~/server/api/routers/tdarr'; /** * This is the primary router for your server. @@ -50,7 +51,8 @@ export const rootRouter = createTRPCRouter({ password: passwordRouter, notebook: notebookRouter, smartHomeEntityState: smartHomeEntityStateRouter, - openmediavault: openmediavaultRouter, + healthMonitoring: healthMonitoringRouter, + tdarr: tdarrRouter, }); // export type definition of API diff --git a/src/server/api/routers/health-monitoring/openmediavault.ts b/src/server/api/routers/health-monitoring/openmediavault.ts new file mode 100644 index 000000000..dbfb8f87a --- /dev/null +++ b/src/server/api/routers/health-monitoring/openmediavault.ts @@ -0,0 +1,134 @@ +import axios from 'axios'; +import Consola from 'consola'; +import { checkIntegrationsType, findAppProperty } from '~/tools/client/app-properties'; +import { getConfig } from '~/tools/config/getConfig'; +import { ConfigAppType } from '~/types/app'; + +let sessionId: string | null = null; +let loginToken: string | null = null; + +async function makeOpenMediaVaultRPCCall( + serviceName: string, + method: string, + params: Record, + headers: Record, + input: { configName: string } +) { + const config = getConfig(input.configName); + const app = config.apps.find((app) => checkIntegrationsType(app.integration, ['openmediavault'])); + + if (!app) { + Consola.error(`App 'openmediavault' not found for configName '${input.configName}'`); + return null; + } + + const appUrl = new URL(app.url); + const response = await axios.post( + `${appUrl.origin}/rpc.php`, + { + service: serviceName, + method: method, + params: params, + }, + { + headers: { + 'Content-Type': 'application/json', + ...headers, + }, + } + ); + return response; +} + +export async function makeOpenMediaVaultCalls(app: ConfigAppType, input: any) { + let authResponse: any = null; + + if (!sessionId || !loginToken) { + if (!app) { + Consola.error( + `Failed to process request to app 'openmediavault'. Please check username & password` + ); + return null; + } + + authResponse = await makeOpenMediaVaultRPCCall( + 'session', + 'login', + { + username: findAppProperty(app, 'username'), + password: findAppProperty(app, 'password'), + }, + {}, + input + ); + + if (authResponse.data.response.sessionid) { + sessionId = authResponse.data.response.sessionid; + } else { + const cookies = authResponse.headers['set-cookie'] || []; + sessionId = cookies + .find( + (cookie: any) => + cookie.includes('X-OPENMEDIAVAULT-SESSIONID') || + cookie.includes('OPENMEDIAVAULT-SESSIONID') + ) + ?.split(';')[0]; + + loginToken = cookies + .find( + (cookie: any) => + cookie.includes('X-OPENMEDIAVAULT-LOGIN') || cookie.includes('OPENMEDIAVAULT-LOGIN') + ) + ?.split(';')[0]; + } + + const responses = await Promise.allSettled([ + makeOpenMediaVaultRPCCall( + 'system', + 'getInformation', + {}, + loginToken + ? { Cookie: `${loginToken};${sessionId}` } + : { 'X-OPENMEDIAVAULT-SESSIONID': sessionId as string }, + input + ), + makeOpenMediaVaultRPCCall( + 'filesystemmgmt', + 'enumerateMountedFilesystems', + { includeroot: true }, + loginToken + ? { Cookie: `${loginToken};${sessionId}` } + : { 'X-OPENMEDIAVAULT-SESSIONID': sessionId as string }, + input + ), + makeOpenMediaVaultRPCCall( + 'cputemp', + 'get', + {}, + loginToken + ? { Cookie: `${loginToken};${sessionId}` } + : { 'X-OPENMEDIAVAULT-SESSIONID': sessionId as string }, + input + ), + ]); + + const systemInfoResponse = + responses[0].status === 'fulfilled' && responses[0].value + ? responses[0].value.data?.response + : null; + const fileSystemResponse = + responses[1].status === 'fulfilled' && responses[1].value + ? responses[1].value.data?.response + : null; + const cpuTempResponse = + responses[2].status === 'fulfilled' && responses[2].value + ? responses[2].value.data?.response + : null; + + return { + systemInfo: systemInfoResponse, + fileSystem: fileSystemResponse, + cpuTemp: cpuTempResponse, + }; + } +} diff --git a/src/server/api/routers/health-monitoring/proxmox.ts b/src/server/api/routers/health-monitoring/proxmox.ts new file mode 100644 index 000000000..0a7673b75 --- /dev/null +++ b/src/server/api/routers/health-monitoring/proxmox.ts @@ -0,0 +1,109 @@ +import axios from 'axios'; +import Consola from 'consola'; +import https from 'https'; +import { findAppProperty } from '~/tools/client/app-properties'; +import { ConfigAppType } from '~/types/app'; +import { ResourceData, ResourceSummary } from '~/widgets/health-monitoring/cluster/types'; + +export async function makeProxmoxStatusAPICall(app: ConfigAppType, input: any) { + if (!app) { + Consola.error(`App 'proxmox' not found for configName '${input.configName}'`); + return null; + } + + const apiKey = findAppProperty(app, 'apiKey'); + if (!apiKey) { + Consola.error(`'proxmox': Missing API key. Please check the configuration.`); + return null; + } + + const appUrl = new URL('api2/json/cluster/resources', app.url); + const agent = input.ignoreCerts + ? new https.Agent({ rejectUnauthorized: false, requestCert: false }) + : new https.Agent(); + + const result = await axios + .get(appUrl.toString(), { + headers: { + Authorization: `PVEAPIToken=${apiKey}`, + }, + httpsAgent: agent, + }) + .catch((error) => { + Consola.error( + `'proxmox': Error accessing service API: '${appUrl}'. The following error was returned: ${error}` + ); + return null; + }) + .then((res) => { + let resources: ResourceSummary = { vms: [], lxcs: [], nodes: [], storage: [] }; + + if (!res) return null; + + res.data.data.forEach((item: any) => { + if (input.filterNode === '' || input.filterNode === item.node) { + let resource: ResourceData = { + id: item.id, + cpu: item.cpu ? item.cpu : 0, + maxCpu: item.maxcpu ? item.maxcpu : 0, + maxMem: item.maxmem ? item.maxmem : 0, + mem: item.mem ? item.mem : 0, + name: item.name, + node: item.node, + status: item.status, + running: false, + type: item.type, + uptime: item.uptime, + vmId: item.vmid, + netIn: item.netin, + netOut: item.netout, + diskRead: item.diskread, + diskWrite: item.diskwrite, + disk: item.disk, + maxDisk: item.maxdisk, + haState: item.hastate, + storagePlugin: item.plugintype, + storageShared: item.shared == 1, + }; + if (item.template == 0) { + if (item.type === 'qemu') { + resource.running = resource.status === 'running'; + resources.vms.push(resource); + } else if (item.type === 'lxc') { + resource.running = resource.status === 'running'; + resources.lxcs.push(resource); + } + } else if (item.type === 'node') { + resource.name = item.node; + resource.running = resource.status === 'online'; + resources.nodes.push(resource); + } else if (item.type === 'storage') { + resource.name = item.storage; + resource.running = resource.status === 'available'; + resources.storage.push(resource); + } + } + }); + + // results must be sorted; proxmox api result order can change dynamically, + // so sort the data to keep the item positions consistent + const sorter = (a: ResourceData, b: ResourceData) => { + if (a.id < b.id) { + return -1; + } + if (a.id > b.id) { + return 1; + } + return 0; + }; + + resources.nodes.sort(sorter); + resources.lxcs.sort(sorter); + resources.storage.sort(sorter); + resources.vms.sort(sorter); + + return resources; + }); + + return result; +} diff --git a/src/server/api/routers/health-monitoring/router.ts b/src/server/api/routers/health-monitoring/router.ts new file mode 100644 index 000000000..35213302a --- /dev/null +++ b/src/server/api/routers/health-monitoring/router.ts @@ -0,0 +1,77 @@ +import Consola from 'consola'; +import { z } from 'zod'; +import { checkIntegrationsType } from '~/tools/client/app-properties'; +import { getConfig } from '~/tools/config/getConfig'; + +import { createTRPCRouter, publicProcedure } from '../../trpc'; +import { makeOpenMediaVaultCalls } from './openmediavault'; +import { makeProxmoxStatusAPICall } from './proxmox'; + +export const healthMonitoringRouter = createTRPCRouter({ + integrations: publicProcedure + .input( + z.object({ + configName: z.string(), + }) + ) + .query(async ({ input }) => { + const config = getConfig(input.configName); + const apps = config.apps.map((app) => { + if (checkIntegrationsType(app.integration, ['proxmox', 'openmediavault'])) { + return app.integration.type; + } + }); + + return apps; + }), + fetchData: publicProcedure + .input( + z.object({ + configName: z.string(), + filterNode: z.string(), + ignoreCerts: z.boolean(), + }) + ) + .query(async ({ input }) => { + const config = getConfig(input.configName); + const omvApp = config.apps.find((app) => + checkIntegrationsType(app.integration, ['openmediavault']) + ); + const proxApp = config.apps.find((app) => + checkIntegrationsType(app.integration, ['proxmox']) + ); + + if (!omvApp && !proxApp) { + Consola.error(`No valid integrations found for health monitoring in '${input.configName}'`); + return null; + } + + let systemData: any; + let clusterData: any; + + try { + const results = await Promise.all([ + omvApp ? makeOpenMediaVaultCalls(omvApp, input) : null, + proxApp ? makeProxmoxStatusAPICall(proxApp, input) : null, + ]); + + for (const response of results) { + if (response) { + if ('systemInfo' in response && response.systemInfo != null) { + systemData = response; + } else if ('nodes' in response) { + clusterData = response; + } + } + } + } catch (error) { + Consola.error(`Error executing health monitoring requests(s): ${error}`); + return null; + } + + return { + system: systemData, + cluster: clusterData, + }; + }), +}); diff --git a/src/server/api/routers/media-request.ts b/src/server/api/routers/media-request.ts index 8ced548e8..43c6cf220 100644 --- a/src/server/api/routers/media-request.ts +++ b/src/server/api/routers/media-request.ts @@ -164,7 +164,7 @@ const retrieveDetailsForItem = async ( name: series.name, airDate: series.firstAirDate, backdropPath: series.backdropPath, - posterPath: series.backdropPath, + posterPath: series.posterPath ?? series.backdropPath, }; } @@ -175,7 +175,7 @@ const retrieveDetailsForItem = async ( const movie = (await movieResponse.json()) as OverseerrMovie; return { - name: movie.originalTitle, + name: movie.title, airDate: movie.releaseDate, backdropPath: movie.backdropPath, posterPath: movie.posterPath, @@ -190,7 +190,7 @@ type GenericOverseerrItem = { }; type OverseerrMovie = { - originalTitle: string; + title: string; releaseDate: string; backdropPath: string; posterPath: string; diff --git a/src/server/api/routers/openmediavault.ts b/src/server/api/routers/openmediavault.ts deleted file mode 100644 index 3d42ad4fd..000000000 --- a/src/server/api/routers/openmediavault.ts +++ /dev/null @@ -1,126 +0,0 @@ -import axios from 'axios'; -import Consola from 'consola'; -import { z } from 'zod'; -import { checkIntegrationsType, findAppProperty } from '~/tools/client/app-properties'; -import { getConfig } from '~/tools/config/getConfig'; - -import { createTRPCRouter, publicProcedure } from '../trpc'; - -let sessionId: string | null = null; -let loginToken: string | null = null; - -async function makeOpenMediaVaultRPCCall( - serviceName: string, - method: string, - params: Record, - headers: Record, - input: { configName: string } -) { - const config = getConfig(input.configName); - const app = config.apps.find((app) => checkIntegrationsType(app.integration, ['openmediavault'])); - - if (!app) { - Consola.error(`App not found for configName '${input.configName}'`); - return null; - } - - const appUrl = new URL(app.url); - const response = await axios.post( - `${appUrl.origin}/rpc.php`, - { - service: serviceName, - method: method, - params: params, - }, - { - headers: { - 'Content-Type': 'application/json', - ...headers, - }, - } - ); - return response; -} - -export const openmediavaultRouter = createTRPCRouter({ - fetchData: publicProcedure - .input( - z.object({ - configName: z.string(), - }) - ) - .query(async ({ input }) => { - let authResponse: any = null; - let app: any; - - if (!sessionId || !loginToken) { - app = getConfig(input.configName)?.apps.find((app) => - checkIntegrationsType(app.integration, ['openmediavault']) - ); - - if (!app) { - Consola.error( - `Failed to process request to app '${app.integration}' (${app.id}). Please check username & password` - ); - return null; - } - - authResponse = await makeOpenMediaVaultRPCCall( - 'session', - 'login', - { - username: findAppProperty(app, 'username'), - password: findAppProperty(app, 'password'), - }, - {}, - input - ); - - const cookies = authResponse.headers['set-cookie'] || []; - sessionId = cookies - .find( - (cookie: any) => - cookie.includes('X-OPENMEDIAVAULT-SESSIONID') || - cookie.includes('OPENMEDIAVAULT-SESSIONID') - ) - ?.split(';')[0]; - loginToken = cookies - .find( - (cookie: any) => - cookie.includes('X-OPENMEDIAVAULT-LOGIN') || cookie.includes('OPENMEDIAVAULT-LOGIN') - ) - ?.split(';')[0]; - } - - const [systemInfoResponse, fileSystemResponse, cpuTempResponse] = await Promise.all([ - makeOpenMediaVaultRPCCall( - 'system', - 'getInformation', - {}, - { Cookie: `${loginToken};${sessionId}` }, - input - ), - makeOpenMediaVaultRPCCall( - 'filesystemmgmt', - 'enumerateMountedFilesystems', - { includeroot: true }, - { Cookie: `${loginToken};${sessionId}` }, - input - ), - makeOpenMediaVaultRPCCall( - 'cputemp', - 'get', - {}, - { Cookie: `${loginToken};${sessionId}` }, - input - ), - ]); - - return { - authenticated: authResponse ? authResponse.data.response.authenticated : true, - systemInfo: systemInfoResponse?.data.response, - fileSystem: fileSystemResponse?.data.response, - cpuTemp: cpuTempResponse?.data.response, - }; - }), -}); diff --git a/src/server/api/routers/smart-home/entity-state.ts b/src/server/api/routers/smart-home/entity-state.ts index fdc204f16..e9d974f3a 100644 --- a/src/server/api/routers/smart-home/entity-state.ts +++ b/src/server/api/routers/smart-home/entity-state.ts @@ -88,6 +88,36 @@ export const smartHomeEntityStateRouter = createTRPCRouter({ } } + return false; + }), + triggerToggle: protectedProcedure + .input(z.object({ + widgetId: z.string(), + configName: z.string() + })).mutation(async ({ input }) => { + const config = getConfig(input.configName); + const widget = config.widgets.find(widget => widget.id === input.widgetId) as ISmartHomeEntityStateWidget | null; + + if (!widget) { + Consola.error(`Referenced widget ${input.widgetId} does not exist on backend.`); + throw new TRPCError({ + code: 'CONFLICT', + message: 'Referenced widget does not exist on backend', + }); + } + + const instances = config.apps.filter((app) => app.integration?.type == 'homeAssistant'); + + for (const instance of instances) { + const url = new URL(instance.url); + const client = HomeAssistantSingleton.getOrSet(url, findAppProperty(instance, 'apiKey')); + const state = await client.triggerToggle(widget.properties.entityId); + + if (state) { + return true; + } + } + return false; }), }); diff --git a/src/server/api/routers/tdarr.ts b/src/server/api/routers/tdarr.ts new file mode 100644 index 000000000..892464d0d --- /dev/null +++ b/src/server/api/routers/tdarr.ts @@ -0,0 +1,356 @@ +import { TRPCError } from '@trpc/server'; +import axios from 'axios'; +import { z } from 'zod'; +import { checkIntegrationsType } from '~/tools/client/app-properties'; +import { getConfig } from '~/tools/config/getConfig'; +import { ConfigAppType } from '~/types/app'; + +import { createTRPCRouter, publicProcedure } from '../trpc'; +import { TdarrQueue, TdarrStatistics, TdarrWorker } from '~/types/api/tdarr'; + +const getStatisticsSchema = z.object({ + totalFileCount: z.number(), + totalTranscodeCount: z.number(), + totalHealthCheckCount: z.number(), + table3Count: z.number(), + table6Count: z.number(), + table1Count: z.number(), + table4Count: z.number(), + pies: z.array( + z.tuple([ + z.string(), // Library Name + z.string(), // Library ID + z.number(), // File count + z.number(), // Number of transcodes + z.number(), // Space saved (in GB) + z.number(), // Number of health checks + z.array( + z.object({ + // Transcode Status (Pie segments) + name: z.string(), + value: z.number(), + }) + ), + z.array( + z.object({ + // Health Status (Pie segments) + name: z.string(), + value: z.number(), + }) + ), + z.array( + z.object({ + // Video files - Codecs (Pie segments) + name: z.string(), + value: z.number(), + }) + ), + z.array( + z.object({ + // Video files - Containers (Pie segments) + name: z.string(), + value: z.number(), + }) + ), + z.array( + z.object({ + // Video files - Resolutions (Pie segments) + name: z.string(), + value: z.number(), + }) + ), + z.array( + z.object({ + // Audio files - Codecs (Pie segments) + name: z.string(), + value: z.number(), + }) + ), + z.array( + z.object({ + // Audio files - Containers (Pie segments) + name: z.string(), + value: z.number(), + }) + ), + ]) + ), +}); + +const getNodesResponseSchema = z.record( + z.string(), + z.object({ + _id: z.string(), + nodeName: z.string(), + nodePaused: z.boolean(), + workers: z.record( + z.string(), + z.object({ + _id: z.string(), + file: z.string(), + fps: z.number(), + percentage: z.number(), + ETA: z.string(), + job: z.object({ + type: z.string(), + }), + status: z.string(), + lastPluginDetails: z + .object({ + number: z.string().optional(), + }) + .optional(), + originalfileSizeInGbytes: z.number(), + estSize: z.number().optional(), + outputFileSizeInGbytes: z.number().optional(), + workerType: z.string(), + }) + ), + }) +); + +const getStatusTableSchema = z.object({ + array: z.array( + z.object({ + _id: z.string(), + HealthCheck: z.string(), + TranscodeDecisionMaker: z.string(), + file: z.string(), + file_size: z.number(), + container: z.string(), + video_codec_name: z.string(), + video_resolution: z.string(), + }) + ), + totalCount: z.number(), +}); + +export const tdarrRouter = createTRPCRouter({ + statistics: publicProcedure + .input(z.object({ + appId: z.string(), + configName: z.string(), + })) + .query(async ({ input }): Promise => { + const app = getTdarrApp(input.appId, input.configName); + const appUrl = new URL('api/v2/cruddb', app.url); + + const body = { + data: { + collection: 'StatisticsJSONDB', + mode: 'getById', + docID: 'statistics', + }, + }; + + const res = await axios.post(appUrl.toString(), body); + const data: z.infer = res.data; + + const zodRes = getStatisticsSchema.safeParse(data); + if (!zodRes.success) { + /* + * Tdarr's API is not documented and had to be reverse engineered. To account for mistakes in the type + * definitions, we assume the best case scenario and log any parsing errors to aid in fixing the types. + */ + console.error(zodRes.error); + } + + return { + totalFileCount: data.totalFileCount, + totalTranscodeCount: data.totalTranscodeCount, + totalHealthCheckCount: data.totalHealthCheckCount, + failedTranscodeCount: data.table3Count, + failedHealthCheckCount: data.table6Count, + stagedTranscodeCount: data.table1Count, + stagedHealthCheckCount: data.table4Count, + pies: data.pies.map((pie) => ({ + libraryName: pie[0], + libraryId: pie[1], + totalFiles: pie[2], + totalTranscodes: pie[3], + savedSpace: pie[4] * 1_000_000_000, // file_size is in GB, convert to bytes, + totalHealthChecks: pie[5], + transcodeStatus: pie[6], + healthCheckStatus: pie[7], + videoCodecs: pie[8], + videoContainers: pie[9], + videoResolutions: pie[10], + audioCodecs: pie[11], + audioContainers: pie[12], + })), + }; + }), + + workers: publicProcedure + .input(z.object({ + appId: z.string(), + configName: z.string(), + })).query(async ({ input }): Promise => { + const app = getTdarrApp(input.appId, input.configName); + const appUrl = new URL('api/v2/get-nodes', app.url); + + const res = await axios.get(appUrl.toString()); + const data: z.infer = res.data; + + const zodRes = getNodesResponseSchema.safeParse(data); + if (!zodRes.success) { + /* + * Tdarr's API is not documented and had to be reverse engineered. To account for mistakes in the type + * definitions, we assume the best case scenario and log any parsing errors to aid in fixing the types. + */ + console.error(zodRes.error); + } + + const nodes = Object.values(data); + const workers = nodes.flatMap((node) => { + return Object.values(node.workers); + }); + + return workers.map((worker) => ({ + id: worker._id, + filePath: worker.file, + fps: worker.fps, + percentage: worker.percentage, + ETA: worker.ETA, + jobType: worker.job.type, + status: worker.status, + step: worker.lastPluginDetails?.number ?? '', + originalSize: worker.originalfileSizeInGbytes * 1_000_000_000, // file_size is in GB, convert to bytes, + estimatedSize: worker.estSize ? worker.estSize * 1_000_000_000 : null, // file_size is in GB, convert to bytes, + outputSize: worker.outputFileSizeInGbytes ? worker.outputFileSizeInGbytes * 1_000_000_000 : null, // file_size is in GB, convert to bytes, + })); + }), + + queue: publicProcedure + .input(z.object({ + appId: z.string(), + configName: z.string(), + showHealthChecksInQueue: z.boolean(), + pageSize: z.number(), + page: z.number(), + })) + .query(async ({ input }): Promise => { + const app = getTdarrApp(input.appId, input.configName); + + const appUrl = new URL('api/v2/client/status-tables', app.url); + + const { page, pageSize, showHealthChecksInQueue } = input; + + const firstItemIndex = page * pageSize; + + const transcodeQueueBody = { + data: { + start: firstItemIndex, + pageSize: pageSize, + filters: [], + sorts: [], + opts: { + table: 'table1', + }, + }, + }; + + const transcodeQueueRes = await axios.post(appUrl.toString(), transcodeQueueBody); + const transcodeQueueData: z.infer = transcodeQueueRes.data; + + const transcodeQueueZodRes = getStatusTableSchema.safeParse(transcodeQueueData); + if (!transcodeQueueZodRes.success) { + /* + * Tdarr's API is not documented and had to be reverse engineered. To account for mistakes in the type + * definitions, we assume the best case scenario and log any parsing errors to aid in fixing the types. + */ + console.error(transcodeQueueZodRes.error); + } + + const transcodeQueueResult = { + array: transcodeQueueData.array.map((item) => ({ + id: item._id, + healthCheck: item.HealthCheck, + transcode: item.TranscodeDecisionMaker, + filePath: item.file, + fileSize: item.file_size * 1_000_000, // file_size is in MB, convert to bytes + container: item.container, + codec: item.video_codec_name, + resolution: item.video_resolution, + type: 'transcode' as const, + })), + totalCount: transcodeQueueData.totalCount, + startIndex: firstItemIndex, + endIndex: firstItemIndex + transcodeQueueData.array.length - 1, + }; + + if (!showHealthChecksInQueue) { + return transcodeQueueResult; + } + + const healthCheckQueueBody = { + data: { + start: Math.max(firstItemIndex - transcodeQueueData.totalCount, 0), + pageSize: pageSize, + filters: [], + sorts: [], + opts: { + table: 'table4', + }, + }, + }; + + const healthCheckQueueRes = await axios.post(appUrl.toString(), healthCheckQueueBody); + const healthCheckQueueData: z.infer = healthCheckQueueRes.data; + + const healthCheckQueueZodRes = getStatusTableSchema.safeParse(healthCheckQueueData); + if (!healthCheckQueueZodRes.success) { + /* + * Tdarr's API is not documented and had to be reverse engineered. To account for mistakes in the type + * definitions, we assume the best case scenario and log any parsing errors to aid in fixing the types. + */ + console.error(healthCheckQueueZodRes.error); + } + + const healthCheckResultArray = healthCheckQueueData.array.map((item) => ({ + id: item._id, + healthCheck: item.HealthCheck, + transcode: item.TranscodeDecisionMaker, + filePath: item.file, + fileSize: item.file_size * 1_000_000, // file_size is in MB, convert to bytes + container: item.container, + codec: item.video_codec_name, + resolution: item.video_resolution, + type: 'health check' as const, + })); + + const combinedArray = [...transcodeQueueResult.array, ...healthCheckResultArray].slice( + 0, + pageSize + ); + + return { + array: combinedArray, + totalCount: transcodeQueueData.totalCount + healthCheckQueueData.totalCount, + startIndex: firstItemIndex, + endIndex: firstItemIndex + combinedArray.length - 1, + }; + }), +}); + +function getTdarrApp(appId: string, configName: string): ConfigAppType { + const config = getConfig(configName); + + const app = config.apps.find((x) => x.id === appId); + + if (!app) { + throw new TRPCError({ + code: 'BAD_REQUEST', + message: `[Tdarr integration] App with ID "${appId}" could not be found.`, + }); + } + + if (!checkIntegrationsType(app.integration, ['tdarr'])) { + throw new TRPCError({ + code: 'BAD_REQUEST', + message: `[Tdarr integration] App with ID "${appId}" is not using the Tdarr integration.`, + }); + } + + return app; +} diff --git a/src/server/auth.ts b/src/server/auth.ts index 380940378..5f56c5c66 100644 --- a/src/server/auth.ts +++ b/src/server/auth.ts @@ -4,6 +4,8 @@ import { type GetServerSidePropsContext, type NextApiRequest, type NextApiRespon import { type NextAuthOptions, getServerSession } from 'next-auth'; import { Adapter } from 'next-auth/adapters'; import { decode, encode } from 'next-auth/jwt'; +import { env } from '~/env'; +import { secondsFromTimeString } from '~/tools/client/parseDuration'; import { adapter, getProviders, onCreateUser } from '~/utils/auth'; import { createRedirectUri } from '~/utils/auth/oidc'; import EmptyNextAuthProvider from '~/utils/empty-provider'; @@ -13,7 +15,8 @@ import { colorSchemeParser } from '~/validations/user'; import { db } from './db'; import { users } from './db/schema'; -const sessionMaxAgeInSeconds = 30 * 24 * 60 * 60; // 30 days +const sessionMaxAgeInSeconds = + secondsFromTimeString(env.AUTH_SESSION_EXPIRY_TIME) ?? 30 * 24 * 60 * 60; // 30 days /** * Options for NextAuth.js used to configure adapters, providers, callbacks, etc. diff --git a/src/styles/global.scss b/src/styles/global.scss index 05e137588..6be988fc9 100644 --- a/src/styles/global.scss +++ b/src/styles/global.scss @@ -140,6 +140,11 @@ background-size: 60px 60px; } +.mantine-Modal-title { + font-size: 1.375rem; + font-weight: 700; +} + .tiptap { hr { border-top-style: double; diff --git a/src/tools/client/parseDuration.ts b/src/tools/client/parseDuration.ts index d59de519a..4c0171e89 100644 --- a/src/tools/client/parseDuration.ts +++ b/src/tools/client/parseDuration.ts @@ -18,3 +18,32 @@ export const parseDuration = (time: number, t: TFunction): string => { return eta; }; + +export const secondsFromTimeString = (time: string | undefined): number | undefined => { + if (!time) { + return undefined; + } + const lastChar = time[time.length - 1]; + if (!isNaN(+lastChar)) { + return Number(time); + } + + const numTime = +time.substring(0, time.length - 1); + switch (lastChar.toLowerCase()) { + case 's': { + return numTime; + } + case 'm': { + return numTime * 60; + } + case 'h': { + return numTime * 60 * 60; + } + case 'd': { + return numTime * 24 * 60 * 60; + } + default: { + return undefined; + } + } +}; diff --git a/src/tools/language.ts b/src/tools/language.ts index 4fba03a99..0b4b4c626 100644 --- a/src/tools/language.ts +++ b/src/tools/language.ts @@ -254,6 +254,14 @@ export const languages = [ country: 'LT', locale: 'lt', dayJsLocale: 'lt' + }, + { + shortName: 'ro', + originalName: 'Românesc', + translatedName: 'Romanian', + country: 'RO', + locale: 'ro', + dayJsLocale: 'ro' } ] as const satisfies Readonly; diff --git a/src/tools/server/sdk/homeassistant/HomeAssistant.ts b/src/tools/server/sdk/homeassistant/HomeAssistant.ts index 1a317772c..2f443edd6 100644 --- a/src/tools/server/sdk/homeassistant/HomeAssistant.ts +++ b/src/tools/server/sdk/homeassistant/HomeAssistant.ts @@ -56,4 +56,28 @@ export class HomeAssistant { return false; } } + + /** + * Triggers a toggle action for a specific entity. + * + * @param entityId - The ID of the entity to toggle. + * @returns A boolean indicating whether the toggle action was successful. + */ + async triggerToggle(entityId: string) { + try { + const response = await fetch(appendPath(this.basePath, `/services/homeassistant/toggle`), { + headers: { + 'Authorization': `Bearer ${this.token}`, + }, + body: JSON.stringify({ + 'entity_id': entityId, + }), + method: 'POST' + }); + return response.ok; + } catch (err) { + Consola.error(`Failed to fetch from '${this.basePath}': ${err}`); + return false; + } + } } diff --git a/src/tools/server/translation-namespaces.ts b/src/tools/server/translation-namespaces.ts index fe698859f..eeeeacc8d 100644 --- a/src/tools/server/translation-namespaces.ts +++ b/src/tools/server/translation-namespaces.ts @@ -34,6 +34,7 @@ export const boardNamespaces = [ 'modules/notebook', 'modules/smart-home/entity-state', 'modules/smart-home/trigger-automation', + 'modules/media-transcoding', 'widgets/error-boundary', 'widgets/draggable-list', 'widgets/location', diff --git a/src/types/api/tdarr.ts b/src/types/api/tdarr.ts new file mode 100644 index 000000000..751611b40 --- /dev/null +++ b/src/types/api/tdarr.ts @@ -0,0 +1,60 @@ +export type TdarrPieSegment = { + name: string; + value: number; +}; + +export type TdarrStatistics = { + totalFileCount: number; + totalTranscodeCount: number; + totalHealthCheckCount: number; + failedTranscodeCount: number; + failedHealthCheckCount: number; + stagedTranscodeCount: number; + stagedHealthCheckCount: number; + pies: { + libraryName: string; + libraryId: string; + totalFiles: number; + totalTranscodes: number; + savedSpace: number; + totalHealthChecks: number; + transcodeStatus: TdarrPieSegment[]; + healthCheckStatus: TdarrPieSegment[]; + videoCodecs: TdarrPieSegment[]; + videoContainers: TdarrPieSegment[]; + videoResolutions: TdarrPieSegment[]; + audioCodecs: TdarrPieSegment[]; + audioContainers: TdarrPieSegment[]; + }[]; +}; + +export type TdarrWorker = { + id: string; + filePath: string; + fps: number; + percentage: number; + ETA: string; + jobType: string; + status: string; + step: string; + originalSize: number; + estimatedSize: number | null; + outputSize: number | null; +}; + +export type TdarrQueue = { + array: { + id: string; + healthCheck: string; + transcode: string; + filePath: string; + fileSize: number; + container: string; + codec: string; + resolution: string; + type: 'transcode' | 'health check'; + }[]; + totalCount: number; + startIndex: number; + endIndex: number; +}; \ No newline at end of file diff --git a/src/types/app.ts b/src/types/app.ts index ec3e4848a..60f0093e9 100644 --- a/src/types/app.ts +++ b/src/types/app.ts @@ -58,7 +58,9 @@ export type IntegrationType = | 'pihole' | 'adGuardHome' | 'homeAssistant' - | 'openmediavault'; + | 'openmediavault' + | 'proxmox' + | 'tdarr'; export type AppIntegrationType = { type: IntegrationType | null; @@ -103,6 +105,8 @@ export const integrationFieldProperties: { adGuardHome: ['username', 'password'], homeAssistant: ['apiKey'], openmediavault: ['username', 'password'], + proxmox: ['apiKey'], + tdarr: [], }; export type IntegrationFieldDefinitionType = { diff --git a/src/utils/auth/ldap.ts b/src/utils/auth/ldap.ts index 879e0ccd8..e8ba1dd0c 100644 --- a/src/utils/auth/ldap.ts +++ b/src/utils/auth/ldap.ts @@ -1,6 +1,7 @@ import Consola from 'consola'; import ldap from 'ldapjs'; import Credentials from 'next-auth/providers/credentials'; +import { z } from 'zod'; import { env } from '~/env'; import { signInSchema } from '~/validations/user'; @@ -61,6 +62,15 @@ const ldapSearch = async < reject('error: ' + err.message); }); res.on('searchEntry', (entry) => { + let userDn; + try { + //dn is the only attribute returned with special characters formatted in UTF-8 (Bad for any letters with an accent) + //Regex replaces any backslash followed by 2 hex characters with a percentage unless said backslash is preceded by another backslash. + //That can then be processed by decodeURIComponent which will turn back characters to normal. + userDn = decodeURIComponent( + entry.pojo.objectName.replace(/(?>( (obj, attr) => { @@ -70,7 +80,10 @@ const ldapSearch = async < : attr.values[0]; return obj; }, - { dn: entry.pojo.objectName } + { + // Assume userDn since there's a reject if not set + dn: userDn!, + } ) as SearchResult ); }); @@ -95,27 +108,47 @@ export default Credentials({ try { const data = await signInSchema.parseAsync(credentials); - Consola.log(`user ${data.name} is trying to log in using LDAP. Signing in...`); + Consola.log(`user ${data.name} is trying to log in using LDAP. Connecting to LDAP server...`); const client = await ldapLogin(env.AUTH_LDAP_BIND_DN, env.AUTH_LDAP_BIND_PASSWORD); + Consola.log(`Connection established. Searching User...`); const ldapUser = ( await ldapSearch(client, env.AUTH_LDAP_BASE, { - filter: `(uid=${data.name})`, + filter: env.AUTH_LDAP_USERNAME_FILTER_EXTRA_ARG + ? `(&(${env.AUTH_LDAP_USERNAME_ATTRIBUTE}=${data.name})${env.AUTH_LDAP_USERNAME_FILTER_EXTRA_ARG})` + : `(${env.AUTH_LDAP_USERNAME_ATTRIBUTE}=${data.name})`, scope: env.AUTH_LDAP_SEARCH_SCOPE, // as const for inference - attributes: ['uid', 'mail'] as const, + attributes: [ + env.AUTH_LDAP_USERNAME_ATTRIBUTE, + env.AUTH_LDAP_USER_MAIL_ATTRIBUTE, + ] as const, }) )[0]; if (!ldapUser) throw new Error('User not found in LDAP'); + try { + z.string().email().parse(ldapUser[env.AUTH_LDAP_USER_MAIL_ATTRIBUTE]); + } catch { + throw new Error( + `User found but with invalid or non-existing Email. Not Supported: "${ + ldapUser[env.AUTH_LDAP_USER_MAIL_ATTRIBUTE] ?? ' ' + }"` + ); + } + + Consola.log(`User found. Logging in...`); await ldapLogin(ldapUser.dn, data.password).then((client) => client.destroy()); + Consola.log(`User logged in. Retrieving groups...`); const userGroups = ( await ldapSearch(client, env.AUTH_LDAP_BASE, { - filter: `(&(objectclass=${env.AUTH_LDAP_GROUP_CLASS})(${ + filter: `(&(objectClass=${env.AUTH_LDAP_GROUP_CLASS})(${ env.AUTH_LDAP_GROUP_MEMBER_ATTRIBUTE - }=${ldapUser[env.AUTH_LDAP_GROUP_MEMBER_USER_ATTRIBUTE as 'dn' | 'uid']}))`, + }=${ldapUser[env.AUTH_LDAP_GROUP_MEMBER_USER_ATTRIBUTE as 'dn' | 'uid']})${ + env.AUTH_LDAP_GROUP_FILTER_EXTRA_ARG ?? '' + })`, scope: env.AUTH_LDAP_SEARCH_SCOPE, // as const for inference attributes: 'cn', @@ -126,15 +159,15 @@ export default Credentials({ Consola.log(`user ${data.name} successfully authorized`); - let user = await adapter.getUserByEmail!(ldapUser.mail); - const isAdmin = userGroups.includes(env.AUTH_LDAP_ADMIN_GROUP); + let user = await adapter.getUserByEmail!(ldapUser[env.AUTH_LDAP_USER_MAIL_ATTRIBUTE]); const isOwner = userGroups.includes(env.AUTH_LDAP_OWNER_GROUP); + const isAdmin = isOwner || userGroups.includes(env.AUTH_LDAP_ADMIN_GROUP); if (!user) { // CreateUser will create settings in event - user = await adapter.createUser({ - name: ldapUser.uid, - email: ldapUser.mail, + user = adapter.createUser({ + name: ldapUser[env.AUTH_LDAP_USERNAME_ATTRIBUTE], + email: ldapUser[env.AUTH_LDAP_USER_MAIL_ATTRIBUTE], emailVerified: new Date(), // assume ldap email is verified isAdmin: isAdmin, isOwner: isOwner, @@ -153,7 +186,7 @@ export default Credentials({ return { id: user?.id || ldapUser.dn, - name: user?.name || ldapUser.uid, + name: user?.name || ldapUser[env.AUTH_LDAP_USERNAME_ATTRIBUTE], isAdmin: isAdmin, isOwner: isOwner, }; diff --git a/src/utils/auth/oidc.ts b/src/utils/auth/oidc.ts index f1d3e58a9..ead2268d7 100644 --- a/src/utils/auth/oidc.ts +++ b/src/utils/auth/oidc.ts @@ -50,6 +50,9 @@ const createProvider = (headers: OidcRedirectCallbackHeaders): OAuthConfig { color: 'teal', }, { - label: `${t('cpu.minute', { minute: 5 })}`, + label: `${t('cpu.minutes', { minutes: 5 })}`, stats: info.loadAverage['5min'], progress: info.loadAverage['5min'], color: 'blue', }, { - label: `${t('cpu.minute', { minute: 15 })}`, + label: `${t('cpu.minutes', { minutes: 15 })}`, stats: info.loadAverage['15min'], progress: info.loadAverage['15min'], color: 'red', @@ -40,12 +40,12 @@ const HealthMonitoringCpu = ({ info, cpuTemp, fahrenheit }: any) => { {info.cpuUtilization.toFixed(2)}% - + @@ -83,27 +83,29 @@ const HealthMonitoringCpu = ({ info, cpuTemp, fahrenheit }: any) => { }, ]} /> - - {fahrenheit ? `${toFahrenheit(cpuTemp.cputemp)}°F` : `${cpuTemp.cputemp}°C`} - - - } - sections={[ - { - value: cpuTemp.cputemp, - color: cpuTemp.cputemp < 60 ? 'green' : 'red', - }, - ]} - /> + {cpuTemp && ( + + {fahrenheit ? `${toFahrenheit(cpuTemp.cputemp)}°F` : `${cpuTemp.cputemp}°C`} + + + } + sections={[ + { + value: cpuTemp.cputemp, + color: cpuTemp.cputemp < 60 ? 'green' : 'red', + }, + ]} + /> + )} ); }; diff --git a/src/widgets/health-monitoring/HealthMonitoringFileSystem.tsx b/src/widgets/health-monitoring/HealthMonitoringFileSystem.tsx index 0efa59070..5462ab85a 100644 --- a/src/widgets/health-monitoring/HealthMonitoringFileSystem.tsx +++ b/src/widgets/health-monitoring/HealthMonitoringFileSystem.tsx @@ -15,6 +15,10 @@ const HealthMonitoringFileSystem = ({ fileSystem }: any) => { available: number; } + const sortedFileSystem = fileSystem.slice().sort((a: FileSystemDisk, b: FileSystemDisk) => { + return a.devicename.localeCompare(b.devicename); + }); + return ( { gap={{ base: 'sm', sm: 'lg' }} justify={{ sm: 'center' }} > - {fileSystem.map((disk: FileSystemDisk) => ( + {sortedFileSystem.map((disk: FileSystemDisk) => ( {disk.devicename} - + diff --git a/src/widgets/health-monitoring/HealthMonitoringMemory.tsx b/src/widgets/health-monitoring/HealthMonitoringMemory.tsx index 8da67b772..7243ac2cb 100644 --- a/src/widgets/health-monitoring/HealthMonitoringMemory.tsx +++ b/src/widgets/health-monitoring/HealthMonitoringMemory.tsx @@ -16,12 +16,12 @@ const HealthMonitoringMemory = ({ info }: any) => { {usedMemoryGB}GiB - + diff --git a/src/widgets/health-monitoring/HealthMonitoringTile.tsx b/src/widgets/health-monitoring/HealthMonitoringTile.tsx index 251936bc6..71bddeeed 100644 --- a/src/widgets/health-monitoring/HealthMonitoringTile.tsx +++ b/src/widgets/health-monitoring/HealthMonitoringTile.tsx @@ -1,5 +1,6 @@ -import { Card, Divider, Flex, Group, ScrollArea, Text } from '@mantine/core'; +import { Card, Center, Divider, Group, ScrollArea, Stack, Tabs, Text, Title } from '@mantine/core'; import { + IconAlertTriangle, IconCloudDownload, IconHeartRateMonitor, IconInfoSquare, @@ -15,6 +16,16 @@ import { IWidget } from '../widgets'; import HealthMonitoringCpu from './HealthMonitoringCpu'; import HealthMonitoringFileSystem from './HealthMonitoringFileSystem'; import HealthMonitoringMemory from './HealthMonitoringMemory'; +import { ClusterStatusTile } from './cluster/HealthMonitoringClusterTile'; + +const defaultViewStates = ['none', 'node', 'vm', 'lxc', 'storage'] as const; +type DefaultViewState = (typeof defaultViewStates)[number]; + +const indicatorColorControls = ['all', 'any'] as const; +type IndicatorColorControl = (typeof indicatorColorControls)[number]; + +const defaultTabStates = ['system', 'cluster'] as const; +type DefaultTabStates = (typeof defaultTabStates)[number]; const definition = defineWidget({ id: 'health-monitoring', @@ -36,12 +47,59 @@ const definition = defineWidget({ type: 'switch', defaultValue: true, }, + defaultTabState: { + type: 'select', + defaultValue: 'system' as DefaultTabStates, + data: defaultTabStates.map((stateValue) => ({ value: stateValue })), + info: true, + }, + node: { + type: 'text', + defaultValue: '', + info: true, + }, + defaultViewState: { + type: 'select', + defaultValue: 'none' as DefaultViewState, + data: defaultViewStates.map((stateValue) => ({ value: stateValue })), + }, + summary: { + type: 'switch', + defaultValue: true, + }, + showNode: { + type: 'switch', + defaultValue: true, + }, + showVM: { + type: 'switch', + defaultValue: true, + }, + showLXCs: { + type: 'switch', + defaultValue: true, + }, + showStorage: { + type: 'switch', + defaultValue: true, + }, + sectionIndicatorColor: { + type: 'select', + defaultValue: 'all' as IndicatorColorControl, + data: indicatorColorControls.map((sectionColor) => ({ value: sectionColor })), + info: true, + }, + ignoreCert: { + type: 'switch', + defaultValue: true, + info: true, + }, }, gridstack: { - minWidth: 1, - minHeight: 1, - maxWidth: 6, - maxHeight: 6, + minWidth: 2, + minHeight: 2, + maxWidth: 12, + maxHeight: 12, }, component: HealthMonitoringWidgetTile, }); @@ -53,60 +111,127 @@ interface HealthMonitoringWidgetProps { } function HealthMonitoringWidgetTile({ widget }: HealthMonitoringWidgetProps) { const { t } = useTranslation('modules/health-monitoring'); - const { isInitialLoading, data } = useOpenmediavaultQuery(); + let { data, isInitialLoading, isError } = useStatusQuery( + widget.properties.node, + widget.properties.ignoreCert + ); - if (isInitialLoading || !data) { + if (isInitialLoading) { return ; } + if (isError || !data) { + return ( +
+ + + {t('errors.general.title')} + {t('errors.general.text')} + +
+ ); + } + + if (data.system && data.cluster) { + return ( + + + + + {t('headings.system')} + + + {t('headings.cluster')} + + + + + + + + + + + ); + } else { + return ( + + {data.system && } + {data.cluster && } + + ); + } +} + +const SystemStatusTile = ({ data, properties }: { data: any; properties: any }) => { + const { t } = useTranslation('modules/health-monitoring'); + const formatUptime = (uptime: number) => { const days = Math.floor(uptime / (60 * 60 * 24)); const remainingHours = Math.floor((uptime % (60 * 60 * 24)) / 3600); - return `${days} days, ${remainingHours} hours`; + return t('info.uptimeFormat', { days: days, hours: remainingHours}) }; return ( - - - - - - - {t('info.uptime')}: -
- {formatUptime(data.systemInfo.uptime)} -
- - {data.systemInfo.availablePkgUpdates === 0 ? ( - '' - ) : ( - - )} - {data.systemInfo.rebootRequired ? : ''} - -
-
- + + - {widget?.properties.cpu && ( - - )} - {widget?.properties.memory && } + + + {t('info.uptime')}: +
+ {formatUptime(data.systemInfo.uptime)} +
+ + {data.systemInfo.availablePkgUpdates === 0 ? ( + '' + ) : ( + + )} + {data.systemInfo.rebootRequired ? : ''} +
- {widget?.properties.fileSystem && ( - <> - - - +
+ + + {properties.cpu && ( + )} -
-
+ {properties.memory && } +
+ {properties.fileSystem && ( + <> + + + + )} + ); -} +}; export const ringColor = (percentage: number) => { if (percentage < 30) return 'green'; @@ -115,9 +240,9 @@ export const ringColor = (percentage: number) => { else return 'red'; }; -export const useOpenmediavaultQuery = () => { +export const getIntegrations = () => { const { name: configName } = useConfigContext(); - return api.openmediavault.fetchData.useQuery( + return api.healthMonitoring.integrations.useQuery( { configName: configName!, }, @@ -127,4 +252,19 @@ export const useOpenmediavaultQuery = () => { ); }; +const useStatusQuery = (node: string, ignoreCerts: boolean) => { + const { name: configName } = useConfigContext(); + + return api.healthMonitoring.fetchData.useQuery( + { + configName: configName!, + filterNode: node!, + ignoreCerts: ignoreCerts!, + }, + { + refetchInterval: 5000, + } + ); +}; + export default definition; diff --git a/src/widgets/health-monitoring/cluster/HealthMonitoringClusterDetailPopover.tsx b/src/widgets/health-monitoring/cluster/HealthMonitoringClusterDetailPopover.tsx new file mode 100644 index 000000000..4e8be016e --- /dev/null +++ b/src/widgets/health-monitoring/cluster/HealthMonitoringClusterDetailPopover.tsx @@ -0,0 +1,232 @@ +import { + Badge, + Center, + Divider, + Flex, + Group, + List, + RingProgress, + Stack, + Text, +} from '@mantine/core'; +import { + IconArrowNarrowDown, + IconArrowNarrowUp, + IconBrain, + IconClockHour3, + IconCpu, + IconCube, + IconDatabase, + IconDeviceLaptop, + IconHeartBolt, + IconNetwork, + IconServer, +} from '@tabler/icons-react'; +import dayjs from 'dayjs'; +import duration from 'dayjs/plugin/duration'; +import { useTranslation } from 'react-i18next'; +import { humanFileSize } from '~/tools/humanFileSize'; +import { ResourceData } from '~/widgets/health-monitoring/cluster/types'; + +dayjs.extend(duration); + +export const ResourceTypeEntryDetails = ({ entry }: { entry: ResourceData }) => { + const { t } = useTranslation('modules/health-monitoring'); + return ( + + + + + + + {entry.name} + + {capitalize(entry.status)} + + + + {entry.type !== 'node' && ( + + + {t('cluster.popover.node')} + + + {entry.node} + + + )} + {(entry.type === 'lxc' || entry.type === 'vm') && ( + + + {t('cluster.popover.vmid')} + + + {entry.vmId} + + + )} + {entry.type === 'storage' && ( + + + {t('cluster.popover.plugin')} + + + {entry.storagePlugin} + + + )} + + + + {entry.type !== 'storage' && } + {entry.type === 'storage' && } + + ); +}; + +const ComputeResourceDetails = ({ entry }: { entry: ResourceData }) => { + const { t } = useTranslation('modules/health-monitoring'); + return ( + + }> + {t('cluster.popover.cores', { maxCpu: entry.maxCpu })} + + }>{displayMemoryText(entry)} + }>{displayDiskText(entry)} + }> + {t('cluster.popover.uptime', { uptime: formatUptime(entry) })} + + {entry.haState && ( + }> + {t('cluster.popover.ha', { haState: capitalize(entry.haState) })} + + )} + + + + ); +}; + +const StorageResourceDetails = ({ entry }: { entry: ResourceData }) => { + const storagePercent = entry.maxDisk ? (entry.disk / entry.maxDisk) * 100 : 0; + return ( + +
+ {storagePercent.toFixed(1)}%} + sections={[{ value: storagePercent, color: storagePercent > 75 ? 'orange' : 'green' }]} + /> + + {displayDiskText(entry, false)} + +
+ + + +
+ ); +}; + +const DiskStats = ({ entry }: { entry: ResourceData }) => { + if (!entry.diskWrite || !entry.diskRead) { + return null; + } + return ( + }> + + + {humanFileSize(entry.diskWrite, false)} + + + + {humanFileSize(entry.diskRead, false)} + + + + + ); +}; + +const NetStats = ({ entry }: { entry: ResourceData }) => { + if (!entry.netIn || !entry.netOut) { + return null; + } + return ( + }> + + + {humanFileSize(entry.netIn, false)} + + + + {humanFileSize(entry.netOut, false)} + + + + + ); +}; + +const StorageType = ({ entry }: { entry: ResourceData }) => { + const { t } = useTranslation('modules/health-monitoring'); + if (entry.storageShared) { + return {t('cluster.popover.sharedStorage')}; + } else { + return {t('cluster.popover.localStorage')}; + } +}; + +const capitalize = (input: string) => { + return input[0].toUpperCase() + input.slice(1); +}; + +const ResourceIcon = ({ entry, size }: { entry: ResourceData; size: number }) => { + if (entry.type === 'node') { + return ; + } else if (entry.type === 'qemu') { + return ; + } else if (entry.type === 'storage') { + return ; + } else { + return ; + } +}; + +const displayMemoryText = (entry: ResourceData) => { + const { t } = useTranslation('modules/health-monitoring'); + if (!entry.maxMem) { + return t('cluster.popover.memSize', { maxMem: humanFileSize(0, false) }); + } else if (!entry.mem) { + return t('cluster.popover.memSize', { maxMem: humanFileSize(entry.maxMem, false) }); + } else { + return t('cluster.popover.memRatio', { + usedMem: humanFileSize(entry.mem, false), + maxMem: humanFileSize(entry.maxMem, false), + }); + } +}; + +const displayDiskText = (entry: ResourceData, useTrans: boolean = true) => { + const { t } = useTranslation('modules/health-monitoring'); + const maxDisk = !entry.maxDisk ? humanFileSize(0, false) : humanFileSize(entry.maxDisk, false); + const disk = !entry.disk ? humanFileSize(0, false) : humanFileSize(entry.disk, false); + + if (!entry.maxDisk || !entry.disk) { + return useTrans ? t('cluster.popover.diskSize', { maxDisk: maxDisk }) : maxDisk; + } else { + return useTrans + ? t('cluster.popover.diskRatio', { usedDisk: disk, maxDisk: maxDisk }) + : disk + ' / ' + maxDisk; + } +}; + +const formatUptime = (entry: ResourceData) => { + const { t } = useTranslation('modules/health-monitoring'); + if (entry.uptime > 0) { + return dayjs.duration(entry.uptime * 1000).humanize(); + } + return t('cluster.popover.na'); +}; diff --git a/src/widgets/health-monitoring/cluster/HealthMonitoringClusterResourceRow.tsx b/src/widgets/health-monitoring/cluster/HealthMonitoringClusterResourceRow.tsx new file mode 100644 index 000000000..0ac96e447 --- /dev/null +++ b/src/widgets/health-monitoring/cluster/HealthMonitoringClusterResourceRow.tsx @@ -0,0 +1,112 @@ +import { Accordion, Badge, Group, Indicator, Popover, Table, Text } from '@mantine/core'; +import { TablerIconsProps } from '@tabler/icons-react'; +import { useTranslation } from 'react-i18next'; +import { ResourceTypeEntryDetails } from '~/widgets/health-monitoring/cluster/HealthMonitoringClusterDetailPopover'; +import { ResourceData } from '~/widgets/health-monitoring/cluster/types'; + +interface ResourceType { + data: ResourceData[]; + icon: (props: TablerIconsProps) => JSX.Element; + title: string; + count: number; + length: number; + indicatorColorControl: string; +} + +interface ResourceTypeProps { + item: ResourceType; + id: string; + include: boolean; + tableConfig: TableViewConfig; +} + +interface TableViewConfig { + showCpu: boolean; + showRam: boolean; + showNode: boolean; +} + +const indicatorColorControl = (entry: ResourceType) => { + return (entry.indicatorColorControl === 'all' && entry.count == entry.length) || + (entry.indicatorColorControl === 'any' && entry.count > 0) + ? 'green' + : 'orange'; +}; + +export const ResourceType = ({ item, id, include, tableConfig }: ResourceTypeProps) => { + const { t } = useTranslation('modules/health-monitoring'); + if (!include) { + return null; + } + return ( + + }> + + {item.title} + + {item.count} / {item.length} + + + + + + + + + {tableConfig.showCpu && } + {tableConfig.showRam && } + {tableConfig.showNode && } + + + + {item.data.map((data) => { + return ; + })} + +
{t('cluster.table.header.name')}{t('cluster.table.header.cpu')}{t('cluster.table.header.ram')}{t('cluster.table.header.node')}
+
+
+ ); +}; + +interface ResourceTypeEntryProps { + entry: ResourceData; + tableConfig: TableViewConfig; +} + +const ResourceTypeEntry = ({ entry, tableConfig }: ResourceTypeEntryProps) => { + return ( + + + + + + + {entry.name} + + + {tableConfig.showCpu && ( + {(entry.cpu * 100).toFixed(1)}% + )} + {tableConfig.showRam && ( + + {(entry.maxMem ? (entry.mem / entry.maxMem) * 100 : 0).toFixed(1)}% + + )} + {tableConfig.showNode && {entry.node}} + + + + + + + ); +}; diff --git a/src/widgets/health-monitoring/cluster/HealthMonitoringClusterTile.tsx b/src/widgets/health-monitoring/cluster/HealthMonitoringClusterTile.tsx new file mode 100644 index 000000000..2ad96cb40 --- /dev/null +++ b/src/widgets/health-monitoring/cluster/HealthMonitoringClusterTile.tsx @@ -0,0 +1,169 @@ +import { Accordion, Center, Flex, Group, RingProgress, Stack, Text } from '@mantine/core'; +import { + IconBrain, + IconCpu, + IconCube, + IconDatabase, + IconDeviceLaptop, + IconServer, +} from '@tabler/icons-react'; +import { useTranslation } from 'react-i18next'; +import { ResourceData, ResourceSummary } from '~/widgets/health-monitoring/cluster/types'; + +import { ResourceType } from './HealthMonitoringClusterResourceRow'; + +export const ClusterStatusTile = ({ + data, + properties, +}: { + data: ResourceSummary; + properties: any; +}) => { + const { t } = useTranslation('modules/health-monitoring'); + + const running = (total: number, current: ResourceData) => { + return current.running ? total + 1 : total; + }; + + const activeNodes = data.nodes.reduce(running, 0); + const activeVMs = data.vms.reduce(running, 0); + const activeLXCs = data.lxcs.reduce(running, 0); + const activeStorage = data.storage.reduce(running, 0); + + const usedMem = data.nodes.reduce( + (sum: number, item: ResourceData) => (item.running ? item.mem + sum : sum), + 0 + ); + const maxMem = data.nodes.reduce( + (sum: number, item: ResourceData) => (item.running ? item.maxMem + sum : sum), + 0 + ); + const maxCpu = data.nodes.reduce( + (sum: number, item: ResourceData) => (item.running ? item.maxCpu + sum : sum), + 0 + ); + const usedCpu = data.nodes.reduce( + (sum: number, item: ResourceData) => (item.running ? item.cpu * item.maxCpu + sum : sum), + 0 + ); + + const cpuPercent = (usedCpu / maxCpu) * 100; + const memPercent = (usedMem / maxMem) * 100; + + return ( + + + + + + + + + + ); +}; + +interface SummaryHeaderProps { + cpu: number; + memory: number; + include: boolean; +} + +const SummaryHeader = ({ cpu, memory, include }: SummaryHeaderProps) => { + const { t } = useTranslation('modules/health-monitoring'); + if (!include) { + return null; + } + return ( +
+ + + + +
+ } + sections={[{ value: cpu, color: cpu > 75 ? 'orange' : 'green' }]} + /> + + {t('cluster.summary.cpu')} + {cpu.toFixed(1)}% + +
+ + + + + } + sections={[{ value: memory, color: memory > 75 ? 'orange' : 'green' }]} + /> + + {t('cluster.summary.ram')} + {memory.toFixed(1)}% + + +
+ + ); +}; diff --git a/src/widgets/health-monitoring/cluster/types.ts b/src/widgets/health-monitoring/cluster/types.ts new file mode 100644 index 000000000..eff55a46f --- /dev/null +++ b/src/widgets/health-monitoring/cluster/types.ts @@ -0,0 +1,30 @@ +export type ResourceSummary = { + vms: ResourceData[]; + lxcs: ResourceData[]; + nodes: ResourceData[]; + storage: ResourceData[]; +}; + +export type ResourceData = { + id: string; + cpu: number; + maxCpu: number; + maxMem: number; + mem: number; + name: string; + node: string; + status: string; + running: boolean; + type: string; + uptime: number; + vmId: number; + netIn: number; + netOut: number; + diskRead: number; + diskWrite: number; + disk: number; + maxDisk: number; + haState: string; + storagePlugin: string; + storageShared: boolean; +}; \ No newline at end of file diff --git a/src/widgets/index.ts b/src/widgets/index.ts index 1666722bf..69ed3a316 100644 --- a/src/widgets/index.ts +++ b/src/widgets/index.ts @@ -15,6 +15,7 @@ import notebook from './notebook/NotebookWidgetTile'; import rss from './rss/RssWidgetTile'; import smartHomeEntityState from './smart-home/entity-state/entity-state.widget'; import smartHomeTriggerAutomation from './smart-home/trigger-automation/trigger-automation.widget'; +import mediaTranscoding from '~/widgets/media-transcoding/MediaTranscodingTile'; import torrent from './torrent/TorrentTile'; import usenet from './useNet/UseNetTile'; import videoStream from './video/VideoStreamTile'; @@ -42,4 +43,5 @@ export default { 'smart-home/entity-state': smartHomeEntityState, 'smart-home/trigger-automation': smartHomeTriggerAutomation, 'health-monitoring': healthMonitoring, + 'media-transcoding': mediaTranscoding, }; diff --git a/src/widgets/media-requests/MediaRequestStatsTile.tsx b/src/widgets/media-requests/MediaRequestStatsTile.tsx index d1a692460..155eef8d0 100644 --- a/src/widgets/media-requests/MediaRequestStatsTile.tsx +++ b/src/widgets/media-requests/MediaRequestStatsTile.tsx @@ -156,6 +156,7 @@ function MediaRequestStatsTile({ widget }: MediaRequestStatsWidgetProps) { left={8} size={15} ml={-5} + zIndex={1} color={user.app === 'overseerr' ? '#ECB000' : '#6677CC'} processing={mediaFetching || usersFetching} children diff --git a/src/widgets/media-transcoding/HealthCheckStatus.tsx b/src/widgets/media-transcoding/HealthCheckStatus.tsx new file mode 100644 index 000000000..4bf91baa8 --- /dev/null +++ b/src/widgets/media-transcoding/HealthCheckStatus.tsx @@ -0,0 +1,90 @@ +import { + Divider, + Group, + HoverCard, + Indicator, + MantineColor, + RingProgress, + Stack, + Text, +} from '@mantine/core'; +import { IconHeartbeat } from '@tabler/icons-react'; +import { useTranslation } from 'next-i18next'; +import { useColorScheme } from '~/hooks/use-colorscheme'; + +import { TdarrStatistics } from '~/types/api/tdarr'; + +interface StatisticsBadgeProps { + statistics?: TdarrStatistics; +} + +export function HealthCheckStatus(props: StatisticsBadgeProps) { + const { statistics } = props; + + const { colorScheme } = useColorScheme(); + const { t } = useTranslation('modules/media-transcoding'); + + if (!statistics) { + return ; + } + + const indicatorColor = statistics.failedHealthCheckCount + ? 'red' + : statistics.stagedHealthCheckCount + ? 'yellow' + : 'green'; + + return ( + + + + + + + + + + + {t(`healthCheckStatus.title`)} + + + + + + + {statistics.stagedHealthCheckCount} + + {t(`healthCheckStatus.queued`)} + + + + {statistics.totalHealthCheckCount} + + {t(`healthCheckStatus.healthy`)} + + + + {statistics.failedHealthCheckCount} + + {t(`healthCheckStatus.unhealthy`)} + + + + + + ); +} + +function textColor(color: MantineColor, theme: 'light' | 'dark') { + return `${color}.${theme === 'light' ? 8 : 5}`; +} diff --git a/src/widgets/media-transcoding/MediaTranscodingTile.tsx b/src/widgets/media-transcoding/MediaTranscodingTile.tsx new file mode 100644 index 000000000..b388e7e0c --- /dev/null +++ b/src/widgets/media-transcoding/MediaTranscodingTile.tsx @@ -0,0 +1,265 @@ +import { + Alert, + Center, + Code, + Divider, + Group, + List, + Pagination, + SegmentedControl, + Stack, + Text, + Title, + Tooltip, +} from '@mantine/core'; +import { + IconAlertCircle, + IconClipboardList, + IconCpu2, + IconReportAnalytics, IconTransform, +} from '@tabler/icons-react'; +import { useTranslation } from 'next-i18next'; +import { useState } from 'react'; +import { z } from 'zod'; +import { AppAvatar } from '~/components/AppAvatar'; +import { useConfigContext } from '~/config/provider'; +import { api } from '~/utils/api'; +import { HealthCheckStatus } from '~/widgets/media-transcoding/HealthCheckStatus'; +import { QueuePanel } from '~/widgets/media-transcoding/QueuePanel'; +import { StatisticsPanel } from '~/widgets/media-transcoding/StatisticsPanel'; +import { WorkersPanel } from '~/widgets/media-transcoding/WorkersPanel'; + +import { defineWidget } from '../helper'; +import { IWidget } from '../widgets'; + +const definition = defineWidget({ + id: 'media-transcoding', + icon: IconTransform, + options: { + defaultView: { + type: 'select', + data: [ + { + value: 'workers', + }, + { + value: 'queue', + }, + { + value: 'statistics', + }, + ], + defaultValue: 'workers', + }, + showHealthCheck: { + type: 'switch', + defaultValue: true, + }, + showHealthChecksInQueue: { + type: 'switch', + defaultValue: true, + }, + queuePageSize: { + type: 'number', + defaultValue: 10, + }, + showAppIcon: { + type: 'switch', + defaultValue: true, + }, + }, + gridstack: { + minWidth: 3, + minHeight: 2, + maxWidth: 12, + maxHeight: 6, + }, + component: MediaTranscodingTile, +}); + +export type TdarrWidget = IWidget<(typeof definition)['id'], typeof definition>; + +interface TdarrQueueTileProps { + widget: TdarrWidget; +} + +function MediaTranscodingTile({ widget }: TdarrQueueTileProps) { + const { t } = useTranslation('modules/media-transcoding'); + const { config, name: configName } = useConfigContext(); + + const appId = config?.apps.find( + (app) => app.integration.type === 'tdarr', + )?.id; + const app = config?.apps.find((app) => app.id === appId); + const { defaultView, showHealthCheck, showHealthChecksInQueue, queuePageSize, showAppIcon } = + widget.properties; + + const [view, setView] = useState<'workers' | 'queue' | 'statistics'>( + viewSchema.parse(defaultView) + ); + + const [queuePage, setQueuePage] = useState(1); + + const workers = api.tdarr.workers.useQuery( + { + appId: app?.id!, + configName: configName!, + }, + { enabled: !!app?.id && !!configName && view === 'workers', refetchInterval: 2000 } + ); + + const statistics = api.tdarr.statistics.useQuery( + { + appId: app?.id!, + configName: configName!, + }, + { enabled: !!app?.id && !!configName, refetchInterval: 10000 } + ); + + const queue = api.tdarr.queue.useQuery( + { + appId: app?.id!, + configName: configName!, + pageSize: queuePageSize, + page: queuePage - 1, + showHealthChecksInQueue, + }, + { + enabled: !!app?.id && !!configName && view === 'queue', + refetchInterval: 2000, + } + ); + + if (statistics.isError || workers.isError || queue.isError) { + return ( + + } + my="lg" + title={t('error.title')} + color="red" + radius="md" + > + {t('error.message')} + + {statistics.isError && ( + + {statistics.error.message} + + )} + {workers.isError && ( + + {workers.error.message} + + )} + {queue.isError && ( + + {queue.error.message} + + )} + + + + ); + } + + if (!app) { + return ( + +
+ {t('noAppSelected')} +
+
+ ); + } + + const totalQueuePages = Math.ceil((queue.data?.totalCount || 1) / queuePageSize); + + return ( + + {view === 'workers' ? ( + + ) : view === 'queue' ? ( + + ) : ( + + )} + + + + + + {t('tabs.workers')} + + + ), + value: 'workers', + }, + { + label: ( +
+ + + {t('tabs.queue')} + +
+ ), + value: 'queue', + }, + { + label: ( +
+ + + {t('tabs.statistics')} + +
+ ), + value: 'statistics', + }, + ]} + value={view} + onChange={(value) => setView(viewSchema.parse(value))} + size="xs" + /> + {view === 'queue' && !!queue.data && ( + <> + + + + + + + + + + {t('views.queue.table.footer.currentIndex', { + start: queue.data.startIndex + 1, + end: queue.data.endIndex + 1, + total: queue.data.totalCount, + })} + + + )} + + {showHealthCheck && statistics.data && } + {showAppIcon && ( + +
+ +
+
+ )} +
+
+
+ ); +} + +const viewSchema = z.enum(['workers', 'queue', 'statistics']); + +export default definition; diff --git a/src/widgets/media-transcoding/QueuePanel.tsx b/src/widgets/media-transcoding/QueuePanel.tsx new file mode 100644 index 000000000..bb7a1c5ed --- /dev/null +++ b/src/widgets/media-transcoding/QueuePanel.tsx @@ -0,0 +1,69 @@ +import { Center, Group, ScrollArea, Table, Text, Title, Tooltip } from '@mantine/core'; +import { IconHeartbeat, IconTransform } from '@tabler/icons-react'; +import { useTranslation } from 'next-i18next'; +import { humanFileSize } from '~/tools/humanFileSize'; +import { WidgetLoading } from '~/widgets/loading'; +import { TdarrQueue } from '~/types/api/tdarr'; + +interface QueuePanelProps { + queue: TdarrQueue | undefined; + isLoading: boolean; +} + +export function QueuePanel(props: QueuePanelProps) { + const { queue, isLoading } = props; + + const { t } = useTranslation('modules/media-transcoding'); + + if (isLoading) { + return ; + } + + if (!queue?.array.length) { + return ( +
+ {t('views.queue.table.empty')} +
+ ); + } + + return ( + + + + + + + + + + {queue.array.map((item) => ( + + + + + ))} + +
{t('views.queue.table.header.name')}{t('views.queue.table.header.size')}
+ +
+ {item.type === 'transcode' ? ( + + + + ) : ( + + + + )} +
+ {item.filePath.split('\\').pop()?.split('/').pop() ?? item.filePath} +
+
+ {humanFileSize(item.fileSize)} +
+
+ ); +} diff --git a/src/widgets/media-transcoding/StatisticsPanel.tsx b/src/widgets/media-transcoding/StatisticsPanel.tsx new file mode 100644 index 000000000..3a1564369 --- /dev/null +++ b/src/widgets/media-transcoding/StatisticsPanel.tsx @@ -0,0 +1,167 @@ +import { + Box, + Center, + Grid, + Group, + MantineColor, + RingProgress, + RingProgressProps, + Stack, + Text, + Title, +} from '@mantine/core'; +import { + IconDatabaseHeart, + IconFileDescription, + IconHeartbeat, + IconTransform, +} from '@tabler/icons-react'; +import { useTranslation } from 'next-i18next'; +import { ReactNode } from 'react'; +import { humanFileSize } from '~/tools/humanFileSize'; +import { WidgetLoading } from '~/widgets/loading'; +import { TdarrPieSegment, TdarrStatistics } from '~/types/api/tdarr'; + +const PIE_COLORS: MantineColor[] = ['cyan', 'grape', 'gray', 'orange', 'pink']; + +interface StatisticsPanelProps { + statistics: TdarrStatistics | undefined; + isLoading: boolean; +} + +export function StatisticsPanel(props: StatisticsPanelProps) { + const { statistics, isLoading } = props; + + const { t } = useTranslation('modules/media-transcoding'); + + if (isLoading) { + return ; + } + + const allLibs = statistics?.pies.find((pie) => pie.libraryName === 'All'); + + if (!statistics || !allLibs) { + return ( +
+ {t('views.statistics.empty')} +
+ ); + } + + return ( + + + + + {t('views.statistics.pies.transcodes')} + + + + } + label={t('views.statistics.box.transcodes', { + value: statistics.totalTranscodeCount + })} + /> + + + } + label={t('views.statistics.box.healthChecks', { + value: statistics.totalHealthCheckCount + })} + /> + + + } + label={t('views.statistics.box.files', { + value: statistics.totalFileCount + })} + /> + + + } + label={t('views.statistics.box.spaceSaved', { + value: allLibs?.savedSpace ? humanFileSize(allLibs.savedSpace) : '-' + })} + /> + + + + + {t('views.statistics.pies.healthChecks')} + + + + + + {t('views.statistics.pies.videoCodecs')} + + + + {t('views.statistics.pies.videoContainers')} + + + + {t('views.statistics.pies.videoResolutions')} + + + + ); +} + +function toRingProgressSections(segments: TdarrPieSegment[]): RingProgressProps['sections'] { + const total = segments.reduce((prev, curr) => prev + curr.value , 0); + return segments.map((segment, index) => ({ + value: (segment.value * 100) / total, + tooltip: `${segment.name}: ${segment.value}`, + color: PIE_COLORS[index % PIE_COLORS.length], // Ensures a valid color in the case that index > PIE_COLORS.length + })); +} + +type StatBoxProps = { + icon: ReactNode; + label: string; +}; + +function StatBox(props: StatBoxProps) { + const { icon, label } = props; + return ( + ({ + padding: theme.spacing.xs, + border: '1px solid', + borderRadius: theme.radius.md, + borderColor: theme.colorScheme === 'dark' ? theme.colors.dark[3] : theme.colors.gray[1], + })} + > + + {icon} + + {label} + + + + ); +} diff --git a/src/widgets/media-transcoding/WorkersPanel.tsx b/src/widgets/media-transcoding/WorkersPanel.tsx new file mode 100644 index 000000000..b07250969 --- /dev/null +++ b/src/widgets/media-transcoding/WorkersPanel.tsx @@ -0,0 +1,94 @@ +import { + Center, + Group, + Progress, + ScrollArea, + Table, + Text, + Title, + Tooltip, +} from '@mantine/core'; +import { IconHeartbeat, IconTransform } from '@tabler/icons-react'; +import { useTranslation } from 'next-i18next'; +import { WidgetLoading } from '~/widgets/loading'; +import { TdarrWorker } from '~/types/api/tdarr'; + +interface WorkersPanelProps { + workers: TdarrWorker[] | undefined; + isLoading: boolean; +} + +export function WorkersPanel(props: WorkersPanelProps) { + const { workers, isLoading } = props; + + const { t } = useTranslation('modules/media-transcoding'); + + if (isLoading) { + return ; + } + + if (!workers?.length) { + return ( +
+ {t('views.workers.table.empty')} +
+ ); + } + + return ( + + + + + + + + + + + {workers.map((worker) => ( + + + + + + ))} + +
{t('views.workers.table.header.name')}{t('views.workers.table.header.eta')}{t('views.workers.table.header.progress')}
+ +
+ {worker.jobType === 'transcode' ? ( + + + + ) : ( + + + + )} +
+ {worker.filePath.split('\\').pop()?.split('/').pop() ?? worker.filePath} +
+
+ + {worker.ETA.startsWith('0:') ? worker.ETA.substring(2) : worker.ETA} + + + + {worker.step} + + {Math.round(worker.percentage)}% + +
+
+ ); +} diff --git a/src/widgets/smart-home/entity-state/entity-state.widget.tsx b/src/widgets/smart-home/entity-state/entity-state.widget.tsx index e448fd235..f2d3c8993 100644 --- a/src/widgets/smart-home/entity-state/entity-state.widget.tsx +++ b/src/widgets/smart-home/entity-state/entity-state.widget.tsx @@ -21,6 +21,11 @@ const definition = defineWidget({ defaultValue: false, info: true, }, + genericToggle: { + type: 'switch', + defaultValue: false, + info: true, + }, automationId: { type: 'text', info: true, @@ -82,15 +87,26 @@ function EntityStateTile({ widget }: SmartHomeEntityStateWidgetProps) { }, }); - const handleClick = async () => { - if (!widget.properties.automationId) { - return; - } + const { mutateAsync: mutateTriggerToggleSync } = api.smartHomeEntityState.triggerToggle.useMutation({ + onSuccess: () => { + void utils.smartHomeEntityState.invalidate(); + }, + }); - await mutateTriggerAutomationAsync({ - configName: configName as string, - widgetId: widget.id, - }); + const handleClick = async () => { + if (widget.properties.genericToggle) { + await mutateTriggerToggleSync({ + configName: configName as string, + widgetId: widget.id, + }); + } + + if (widget.properties.automationId) { + await mutateTriggerAutomationAsync({ + configName: configName as string, + widgetId: widget.id, + }); + } }; let dataComponent = null; diff --git a/src/widgets/torrent/TorrentTile.spec.ts b/src/widgets/torrent/TorrentTile.spec.ts index 9854c45af..a56334962 100644 --- a/src/widgets/torrent/TorrentTile.spec.ts +++ b/src/widgets/torrent/TorrentTile.spec.ts @@ -24,6 +24,8 @@ describe('TorrentTile', () => { speedLimitOfActiveTorrents: 10, displayStaleTorrents: false, displayRatioWithFilter: false, + columns: [], + nameColumnSize: 0, }, }; const torrents: NormalizedTorrent[] = [ @@ -62,6 +64,8 @@ describe('TorrentTile', () => { speedLimitOfActiveTorrents: 10, displayStaleTorrents: true, displayRatioWithFilter: false, + columns: [], + nameColumnSize: 0, }, }; const torrents: NormalizedTorrent[] = [ @@ -100,6 +104,8 @@ describe('TorrentTile', () => { speedLimitOfActiveTorrents: 10, displayStaleTorrents: true, displayRatioWithFilter: false, + columns: [], + nameColumnSize: 0, }, }; const torrents: NormalizedTorrent[] = [ @@ -138,6 +144,8 @@ describe('TorrentTile', () => { speedLimitOfActiveTorrents: 10, displayStaleTorrents: true, displayRatioWithFilter: false, + columns: [], + nameColumnSize: 0, }, }; const torrents: NormalizedTorrent[] = [ @@ -192,6 +200,8 @@ describe('TorrentTile', () => { speedLimitOfActiveTorrents: 10, displayStaleTorrents: true, displayRatioWithFilter: false, + columns: [], + nameColumnSize: 0, }, }; const torrents: NormalizedTorrent[] = [ @@ -230,6 +240,8 @@ describe('TorrentTile', () => { speedLimitOfActiveTorrents: 10, displayStaleTorrents: true, displayRatioWithFilter: false, + columns: [], + nameColumnSize: 0, }, }; const torrents: NormalizedTorrent[] = [ @@ -268,6 +280,8 @@ describe('TorrentTile', () => { speedLimitOfActiveTorrents: 10, displayStaleTorrents: true, displayRatioWithFilter: false, + columns: [], + nameColumnSize: 0, }, }; const torrents: NormalizedTorrent[] = [constructTorrent('HH', 'I am completed', true, 0, 0)]; diff --git a/src/widgets/torrent/TorrentTile.tsx b/src/widgets/torrent/TorrentTile.tsx index 19921f6ce..4111489b4 100644 --- a/src/widgets/torrent/TorrentTile.tsx +++ b/src/widgets/torrent/TorrentTile.tsx @@ -3,7 +3,6 @@ import { Center, Flex, Group, - Loader, Popover, Progress, Stack, @@ -16,9 +15,9 @@ import { IconFileDownload } from '@tabler/icons-react'; import dayjs from 'dayjs'; import duration from 'dayjs/plugin/duration'; import relativeTime from 'dayjs/plugin/relativeTime'; -import { MRT_TableContainer, useMantineReactTable, type MRT_ColumnDef } from 'mantine-react-table'; +import { type MRT_ColumnDef, MRT_TableContainer, useMantineReactTable } from 'mantine-react-table'; import { useTranslation } from 'next-i18next'; -import { useMemo } from 'react'; +import { useMemo, useState } from 'react'; import { MIN_WIDTH_MOBILE } from '~/constants/constants'; import { calculateETA } from '~/tools/client/calculateEta'; import { humanFileSize } from '~/tools/humanFileSize'; @@ -29,6 +28,7 @@ import { import { useGetDownloadClientsQueue } from '../download-speed/useGetNetworkSpeed'; import { defineWidget } from '../helper'; +import { WidgetLoading } from '../loading'; import { IWidget } from '../widgets'; import { TorrentQueuePopover } from './TorrentQueueItem'; @@ -69,6 +69,32 @@ const definition = defineWidget({ defaultValue: true, info: true, }, + columnOrdering: { + type: 'switch', + defaultValue: true, + }, + rowSorting: { + type: 'switch', + defaultValue: true, + }, + columns: { + type: 'multi-select', + defaultValue: ['up', 'down', 'eta', 'progress'], + data: [ + { value: 'up' }, + { value: 'down' }, + { value: 'eta' }, + { value: 'progress' }, + { value: 'date' }, + ], + }, + nameColumnSize: { + type: 'slider', + defaultValue: 2, + min: 1, + max: 4, + step: 1, + }, }, gridstack: { minWidth: 2, @@ -115,12 +141,20 @@ function TorrentTile({ widget }: TorrentTileProps) { const ratioGlobal = getTorrentsRatio(widget, torrents, false); const ratioWithFilter = getTorrentsRatio(widget, torrents, true); + const [opened, setOpened] = useState(-1); + const columns = useMemo[]>( () => [ { id: 'dateAdded', accessorFn: (row) => new Date(row.dateAdded), - header: 'dateAdded', + Cell: ({ cell }) => ( + + {dayjs(cell.getValue() as Date).format('YYYY/MM/DD')} + {dayjs(cell.getValue() as Date).format('HH:mm')} + + ), + header: t('card.table.header.dateAdded'), maxSize: 1, }, { @@ -135,6 +169,8 @@ function TorrentTile({ widget }: TorrentTileProps) { transitionProps={{ transition: 'pop', }} + opened={opened === row.index} + onChange={(o) => setOpened(() => (o ? row.index : -1))} > @@ -146,8 +182,7 @@ function TorrentTile({ widget }: TorrentTileProps) { ), - maxSize: 1, - size: 1, + maxSize: widget.properties.nameColumnSize, }, { accessorKey: 'totalSelected', @@ -182,9 +217,9 @@ function TorrentTile({ widget }: TorrentTileProps) { header: t('card.table.header.progress'), maxSize: 1, Cell: ({ cell, row }) => ( - + - {(Number(cell.getValue()) * 100).toFixed(1)}% + {(Number(cell.getValue()) * 100).toPrecision(3)}% - , ), sortDescFirst: true, }, ], - [] + [opened] ); const torrentsTable = useMantineReactTable({ @@ -217,9 +251,19 @@ function TorrentTile({ widget }: TorrentTileProps) { enableColumnFilters: false, enableRowVirtualization: true, rowVirtualizerProps: { overscan: 20 }, - mantineTableContainerProps: { sx: { scrollbarWidth: 'none' } }, - enableColumnOrdering: true, - enableSorting: true, + mantineTableContainerProps: { sx: { scrollbarWidth: 'none', flex: '1', borderRadius: '0.5rem' } }, + mantineTableBodyCellProps: { style: { background: 'transparent' } }, + mantineTableHeadCellProps: { + style: { borderTopLeftRadius: '0.5rem', borderTopRightRadius: '0.5rem' }, + }, + mantineTableHeadRowProps: { + style: { borderTopLeftRadius: '0.5rem', borderTopRightRadius: '0.5rem' }, + }, + mantineTableBodyRowProps: ({ row }) => ({ + onClick: () => setOpened((o) => (o === row.index ? -1 : row.index)), + }), + enableColumnOrdering: widget.properties.columnOrdering, + enableSorting: widget.properties.rowSorting, initialState: { showColumnFilters: false, showGlobalFilter: false, @@ -239,10 +283,11 @@ function TorrentTile({ widget }: TorrentTileProps) { density: 'xs', columnVisibility: { isCompleted: false, - dateAdded: false, - uploadSpeed: width > MIN_WIDTH_MOBILE, - downloadSpeed: width > MIN_WIDTH_MOBILE, - eta: width > MIN_WIDTH_MOBILE, + dateAdded: widget.properties.columns.includes('date') && width > MIN_WIDTH_MOBILE, + uploadSpeed: widget.properties.columns.includes('up') && width > MIN_WIDTH_MOBILE, + downloadSpeed: widget.properties.columns.includes('down') && width > MIN_WIDTH_MOBILE, + eta: widget.properties.columns.includes('eta') && width > MIN_WIDTH_MOBILE, + progress: widget.properties.columns.includes('progress'), }, }, }); @@ -259,21 +304,7 @@ function TorrentTile({ widget }: TorrentTileProps) { } if (isInitialLoading || !data) { - return ( - - - - {t('card.loading.title')} - {t('card.loading.description')} - - - ); + return ; } if (data.apps.length === 0) { diff --git a/src/widgets/weather/WeatherTile.tsx b/src/widgets/weather/WeatherTile.tsx index 91b8311a9..2adf2d172 100644 --- a/src/widgets/weather/WeatherTile.tsx +++ b/src/widgets/weather/WeatherTile.tsx @@ -63,7 +63,11 @@ interface WeatherTileProps { } function WeatherTile({ widget }: WeatherTileProps) { - const { data: weather, isLoading, isError } = api.weather.at.useQuery(widget.properties.location); + const { + data: weather, + isLoading, + isError, + } = api.weather.at.useQuery(widget.properties.location, { refetchInterval: 1000 * 60 * 30 }); const { width, ref } = useElementSize(); const { t } = useTranslation('modules/weather'); diff --git a/src/widgets/widgets.ts b/src/widgets/widgets.ts index b77a9251c..5cff6af0a 100644 --- a/src/widgets/widgets.ts +++ b/src/widgets/widgets.ts @@ -8,6 +8,7 @@ import { } from '@mantine/core'; import { Icon } from '@tabler/icons-react'; import React from 'react'; +import { IntegrationType } from '~/types/app'; import { AreaType } from '~/types/area'; import { ShapeType } from '~/types/shape'; diff --git a/yarn.lock b/yarn.lock index 26f58fa16..c9d89b889 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7495,6 +7495,7 @@ __metadata: sabnzbd-api: ^1.5.0 sass: ^1.56.1 swagger-ui-react: ^5.11.0 + tldts: ^6.1.18 trpc-openapi: ^1.2.0 ts-node: latest turbo: ^1.10.12 @@ -11885,6 +11886,24 @@ __metadata: languageName: node linkType: hard +"tldts-core@npm:^6.1.18": + version: 6.1.18 + resolution: "tldts-core@npm:6.1.18" + checksum: 392d490c04aca5b40f16666fb6cbc9d7ef6df42884b1ac196736ffdeeb378019962dbc04ee00a2a85ce61944a0692c1f1cd8b64896277949906991146830314f + languageName: node + linkType: hard + +"tldts@npm:^6.1.18": + version: 6.1.18 + resolution: "tldts@npm:6.1.18" + dependencies: + tldts-core: ^6.1.18 + bin: + tldts: bin/cli.js + checksum: 04ec7d6a5ad42ddedd9dd250d9cde37608b09bf28eecb94bad8c49d65225d861e0bddc6e1cea3253baf8fc96722e0d2fc1e926eb73b7a35396c77346efaf70f0 + languageName: node + linkType: hard + "tmp@npm:^0.0.33": version: 0.0.33 resolution: "tmp@npm:0.0.33"