mirror of
https://github.com/Dvorinka/beszel.git
synced 2026-07-28 23:03:48 +00:00
feat(hub): implement native in-app container updates
Introduces the ability for registered users to trigger Beszel container updates directly from the web interface. - Added `app_update` logic to the hub to pull the latest image from GHCR and recreate the container. - Implemented `/api/beszel/update` and `/api/beszel/update/apply` endpoints. - Added a new `AppUpdatePanel` in the settings UI to check for and apply updates. - Added update notifications in the navbar and settings. - Updated `docker-compose.yml` and `README.md` to include the required Docker socket mount for update functionality. - Added a new public status page route that bypasses authentication. - Refactored several TypeScript interfaces to replace `any` with `unknown` or specific types for better type safety. - Updated localization files to support new update-related strings.
This commit is contained in:
@@ -41,6 +41,13 @@ __debug_*
|
||||
# Reference code (external projects)
|
||||
reference/
|
||||
|
||||
# Graphify output - only keep json, md, html in root
|
||||
graphify-out/*/
|
||||
graphify-out/*.svg
|
||||
!graphify-out/*.json
|
||||
!graphify-out/*.md
|
||||
!graphify-out/*.html
|
||||
|
||||
# Environment
|
||||
.env
|
||||
.env.local
|
||||
|
||||
@@ -20,6 +20,9 @@ services:
|
||||
- "${BESZEL_PORT:-8090}:8090"
|
||||
volumes:
|
||||
- beszel_data:/beszel_data
|
||||
# Enables native in-app updates from ghcr.io/dvorinka/beszel:latest.
|
||||
# Any registered Beszel user can trigger this update action.
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
environment:
|
||||
APP_URL: "${APP_URL:-http://localhost:8090}"
|
||||
PUBLIC_URL: "${PUBLIC_URL:-}"
|
||||
@@ -62,6 +65,12 @@ The hub will be available at `http://localhost:8090` by default. For Dokploy or
|
||||
|
||||
Agents run on separate hosts and connect to the hub. See [Adding Agents](#adding-agents) below.
|
||||
|
||||
### Native App Updates
|
||||
|
||||
Beszel checks `ghcr.io/dvorinka/beszel:latest` from inside the app and shows update status in Settings > General. When the Docker socket is mounted, any registered user can start an in-app update. Beszel pulls the latest image, recreates the running container with the same Docker configuration, and restarts itself automatically.
|
||||
|
||||
The Docker socket gives Beszel control over Docker on the host. Keep registration limited to trusted users.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|
||||
@@ -18,6 +18,7 @@ services:
|
||||
- "8090:8090"
|
||||
volumes:
|
||||
- beszel-data:/beszel_data
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
environment:
|
||||
- APP_URL=${APP_URL:-http://localhost:8090}
|
||||
- INSTANCE_NAME=${INSTANCE_NAME:-Beszel Monitoring}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
/home/tdvorak/.local/share/uv/tools/graphifyy/bin/python
|
||||
@@ -0,0 +1,75 @@
|
||||
# Beszel Repository - Knowledge Graph Report
|
||||
|
||||
Generated: /home/tdvorak/Desktop/PROG+HTML/Beszel
|
||||
|
||||
## Summary
|
||||
|
||||
- **Total Nodes**: 6,011
|
||||
- **Total Edges**: 7,957
|
||||
- **Communities**: 867
|
||||
- **Code Files**: 1,131
|
||||
- **Document Files**: 180
|
||||
|
||||
## Top God Nodes (High Connectivity)
|
||||
|
||||
- **sleep()** (degree: 73)
|
||||
- **New()** (degree: 64)
|
||||
- **Monitor** (degree: 52)
|
||||
- **CreateRecord()** (degree: 49)
|
||||
- **GetHubWithUser()** (degree: 49)
|
||||
- **GPUManager** (degree: 40)
|
||||
- **GetEnv()** (degree: 39)
|
||||
- **SupabaseService** (degree: 38)
|
||||
- **Agent** (degree: 35)
|
||||
- **SystemManager** (degree: 34)
|
||||
- **PgDatabaseService** (degree: 31)
|
||||
- **Hub** (degree: 30)
|
||||
- **System** (degree: 30)
|
||||
- **AddDomainComponent** (degree: 29)
|
||||
- **MainDatabaseService** (degree: 28)
|
||||
- **LoginPageComponent** (degree: 28)
|
||||
- **SmartManager** (degree: 27)
|
||||
- **AverageSystemStatsSlice()** (degree: 27)
|
||||
- **AlertManager** (degree: 27)
|
||||
- **parseInt()** (degree: 27)
|
||||
|
||||
## Surprising Connections
|
||||
|
||||
- ? ↔ ? (cross-community)
|
||||
- ? ↔ ? (cross-community)
|
||||
- ? ↔ ? (cross-community)
|
||||
- ? ↔ ? (cross-community)
|
||||
- ? ↔ ? (cross-community)
|
||||
|
||||
## Largest Communities
|
||||
|
||||
1. **Community 0** (248 nodes): agent_agent_cache_newsystemdatacache, agent_agent_cache_test_createtestcachedata, agent_agent_cache_test_go, agent_agent_cache_test_testcachefreshness, agent_agent_cache_test_testcachegetset...
|
||||
2. **Community 1** (176 nodes): agent_agent_getfingerprint, agent_battery_battery_windows_go, agent_fingerprint_deletefingerprint, agent_fingerprint_generatefingerprint, agent_fingerprint_getfingerprint...
|
||||
3. **Community 2** (164 nodes): bulk_api_newapihandler, bulk_api_parseint, bulk_importresult, components_countup_data, components_countup_isnum...
|
||||
4. **Community 3** (155 nodes): layouts_layout_if, mixins_lang_changelang, mixins_lang_created, mixins_lang_data, mixins_lang_language...
|
||||
5. **Community 4** (147 nodes): alerts_alerts_sheet_copyalertsfromsystem, alerts_alerts_sheet_failedupdatetoast, components_add_system_addsystemdialog, components_add_system_handlesubmit, components_navbar_navbar...
|
||||
6. **Community 5** (146 nodes): agent_agent, agent_agent_applynetworktotals, agent_agent_attachsystemdetails, agent_agent_computebytespersecond, agent_agent_ensurenetinterfacesinitialized...
|
||||
7. **Community 6** (143 nodes): advanced_page_list_page_pagelistcomponent, advanced_page_list_page_pagelistcomponent_buildroutetree, advanced_page_list_page_pagelistcomponent_formatname, advanced_page_list_page_pagelistcomponent_insertintotree, advanced_page_list_page_pagelistcomponent_mergesitemapurls...
|
||||
8. **Community 7** (139 nodes): components_templatedinput_get, components_templatedinput_set, components_templatedtextarea_get, components_templatedtextarea_set, components_togglesection_data...
|
||||
9. **Community 8** (134 nodes): components_maintenancetime_enddatetime, components_maintenancetime_startdatetime, components_monitorlistitem_beforemount, components_monitorlistitem_changecollapsed, components_monitorlistitem_data...
|
||||
10. **Community 9** (133 nodes): agent_deltatracker_deltatracker_go, agent_deltatracker_deltatracker_test_go, agent_docker_builddockercontainerendpoint, agent_docker_calculatememoryusage, agent_docker_convertcontainerportstostring...
|
||||
11. **Community 10** (133 nodes): agent_agent_go, agent_agent_newagent, agent_checkfingerprinthandler, agent_checkfingerprinthandler_handle, agent_client_newwebsocketclient...
|
||||
12. **Community 11** (126 nodes): agent_agent_gatherstats, agent_collectordefinition, agent_collectorsource, agent_docker_test_testconstantsandutilityfunctions, agent_gpu_amd_linux_cacheamdgpuname...
|
||||
13. **Community 12** (115 nodes): domains_alertcallback, domains_scheduler, domains_scheduler_checkalldomains, domains_scheduler_checkdomain, domains_scheduler_checkdomains...
|
||||
14. **Community 13** (92 nodes): agent_agent_cache_go, agent_cachenode, agent_systemdatacache, agent_systemdatacache_get, agent_systemdatacache_set...
|
||||
15. **Community 14** (82 nodes): constants_security_categories_getallbyclientserver, constants_security_categories_getallbyseverity, constants_security_categories_getallwithactions, constants_security_categories_getbyeppcode, constants_security_categories_geteppcodesbyclientserver...
|
||||
|
||||
## File Type Distribution
|
||||
|
||||
- **Go**: Main backend language
|
||||
- **TypeScript/React**: Frontend components
|
||||
- **Markdown**: Documentation
|
||||
|
||||
## How to Use This Graph
|
||||
|
||||
1. Query the graph:
|
||||
2. Find paths:
|
||||
3. Explore communities: Open in a graph viewer
|
||||
|
||||
---
|
||||
*Generated by graphify*
|
||||
File diff suppressed because one or more lines are too long
+131360
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -53,6 +53,7 @@ func getBaseApp() *pocketbase.PocketBase {
|
||||
}
|
||||
updateCmd.Flags().Bool("china-mirrors", false, "Use mirror (gh.beszel.dev) instead of GitHub")
|
||||
baseApp.RootCmd.AddCommand(updateCmd)
|
||||
baseApp.RootCmd.AddCommand(hub.NewContainerUpdateHelperCmd())
|
||||
// add health command
|
||||
baseApp.RootCmd.AddCommand(newHealthCmd())
|
||||
|
||||
|
||||
+4
-44
@@ -1,17 +1,13 @@
|
||||
package hub
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/google/uuid"
|
||||
"github.com/henrygd/beszel"
|
||||
"github.com/henrygd/beszel/internal/alerts"
|
||||
"github.com/henrygd/beszel/internal/ghupdate"
|
||||
"github.com/henrygd/beszel/internal/hub/config"
|
||||
"github.com/henrygd/beszel/internal/hub/systems"
|
||||
"github.com/henrygd/beszel/internal/hub/utils"
|
||||
@@ -20,13 +16,6 @@ import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
)
|
||||
|
||||
// UpdateInfo holds information about the latest update check
|
||||
type UpdateInfo struct {
|
||||
lastCheck time.Time
|
||||
Version string `json:"v"`
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
var containerIDPattern = regexp.MustCompile(`^[a-fA-F0-9]{12,64}$`)
|
||||
|
||||
// Middleware to allow only admin role users
|
||||
@@ -104,11 +93,9 @@ func (h *Hub) registerApiRoutes(se *core.ServeEvent) error {
|
||||
// get public key and version
|
||||
apiAuth.GET("/info", h.getInfo)
|
||||
apiAuth.GET("/getkey", h.getInfo) // deprecated - keep for compatibility w/ integrations
|
||||
// check for updates
|
||||
if optIn, _ := utils.GetEnv("CHECK_UPDATES"); optIn == "true" {
|
||||
var updateInfo UpdateInfo
|
||||
apiAuth.GET("/update", updateInfo.getUpdate)
|
||||
}
|
||||
// check for and apply app image updates
|
||||
apiAuth.GET("/update", h.getUpdate)
|
||||
apiAuth.POST("/update/apply", h.applyUpdate)
|
||||
// send test notification
|
||||
apiAuth.POST("/test-notification", h.SendTestNotification)
|
||||
// heartbeat status and test
|
||||
@@ -148,34 +135,7 @@ func (h *Hub) getInfo(e *core.RequestEvent) error {
|
||||
Key: h.pubKey,
|
||||
Version: beszel.Version,
|
||||
}
|
||||
if optIn, _ := utils.GetEnv("CHECK_UPDATES"); optIn == "true" {
|
||||
info.CheckUpdate = true
|
||||
}
|
||||
return e.JSON(http.StatusOK, info)
|
||||
}
|
||||
|
||||
// getUpdate checks for the latest release on GitHub and returns update info if a newer version is available
|
||||
func (info *UpdateInfo) getUpdate(e *core.RequestEvent) error {
|
||||
if time.Since(info.lastCheck) < 6*time.Hour {
|
||||
return e.JSON(http.StatusOK, info)
|
||||
}
|
||||
info.lastCheck = time.Now()
|
||||
latestRelease, err := ghupdate.FetchLatestRelease(context.Background(), http.DefaultClient, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currentVersion, err := semver.Parse(strings.TrimPrefix(beszel.Version, "v"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
latestVersion, err := semver.Parse(strings.TrimPrefix(latestRelease.Tag, "v"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if latestVersion.GT(currentVersion) {
|
||||
info.Version = strings.TrimPrefix(latestRelease.Tag, "v")
|
||||
info.Url = latestRelease.Url
|
||||
}
|
||||
info.CheckUpdate = true
|
||||
return e.JSON(http.StatusOK, info)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,567 @@
|
||||
package hub
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/henrygd/beszel"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
appUpdateImage = "ghcr.io/dvorinka/beszel:latest"
|
||||
appUpdateRepository = "dvorinka/beszel"
|
||||
dockerSocketPath = "/var/run/docker.sock"
|
||||
)
|
||||
|
||||
var updateContainerIDPattern = regexp.MustCompile(`[0-9a-f]{64}`)
|
||||
var appUpdateHTTPClient = &http.Client{Timeout: 20 * time.Second}
|
||||
|
||||
type updateCacheState struct {
|
||||
mu sync.Mutex
|
||||
checked time.Time
|
||||
info UpdateInfo
|
||||
}
|
||||
|
||||
var appUpdateCache updateCacheState
|
||||
|
||||
type updateApplyState struct {
|
||||
mu sync.Mutex
|
||||
running bool
|
||||
}
|
||||
|
||||
var appUpdateApply updateApplyState
|
||||
|
||||
// UpdateInfo holds information about the latest GHCR image check.
|
||||
type UpdateInfo struct {
|
||||
Version string `json:"v,omitempty"`
|
||||
Url string `json:"url,omitempty"`
|
||||
CurrentVersion string `json:"currentVersion"`
|
||||
Image string `json:"image"`
|
||||
CurrentImageID string `json:"currentImageId,omitempty"`
|
||||
CurrentDigest string `json:"currentDigest,omitempty"`
|
||||
LatestDigest string `json:"latestDigest,omitempty"`
|
||||
UpdateAvailable bool `json:"updateAvailable"`
|
||||
CanApply bool `json:"canApply"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
LastCheck string `json:"lastCheck"`
|
||||
}
|
||||
|
||||
type applyUpdateResponse struct {
|
||||
Started bool `json:"started"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type dockerAPI struct {
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
type dockerContainerInspect struct {
|
||||
ID string `json:"Id"`
|
||||
Name string `json:"Name"`
|
||||
Image string `json:"Image"`
|
||||
Config map[string]any `json:"Config"`
|
||||
HostConfig map[string]any `json:"HostConfig"`
|
||||
NetworkSettings dockerNetworkSettings `json:"NetworkSettings"`
|
||||
}
|
||||
|
||||
type dockerNetworkSettings struct {
|
||||
Networks map[string]map[string]any `json:"Networks"`
|
||||
}
|
||||
|
||||
type dockerImageInspect struct {
|
||||
ID string `json:"Id"`
|
||||
RepoDigests []string `json:"RepoDigests"`
|
||||
}
|
||||
|
||||
type dockerCreateResponse struct {
|
||||
ID string `json:"Id"`
|
||||
Warnings []string `json:"Warnings"`
|
||||
}
|
||||
|
||||
func (h *Hub) getUpdate(e *core.RequestEvent) error {
|
||||
info := getCachedUpdateInfo(false)
|
||||
return e.JSON(http.StatusOK, info)
|
||||
}
|
||||
|
||||
func (h *Hub) applyUpdate(e *core.RequestEvent) error {
|
||||
if !beginAppUpdate() {
|
||||
return e.BadRequestError("An app update is already running.", nil)
|
||||
}
|
||||
helperStarted := false
|
||||
defer func() {
|
||||
if !helperStarted {
|
||||
finishAppUpdate()
|
||||
}
|
||||
}()
|
||||
|
||||
info := getCachedUpdateInfo(true)
|
||||
if !info.CanApply {
|
||||
return e.BadRequestError(info.Message, nil)
|
||||
}
|
||||
if !info.UpdateAvailable {
|
||||
return e.BadRequestError("Beszel is already using the latest image digest.", nil)
|
||||
}
|
||||
|
||||
docker, err := newDockerAPI()
|
||||
if err != nil {
|
||||
return e.BadRequestError(err.Error(), nil)
|
||||
}
|
||||
container, err := docker.inspectContainer(currentContainerID(docker))
|
||||
if err != nil {
|
||||
return e.BadRequestError("Current Beszel container was not found through Docker.", err)
|
||||
}
|
||||
if err := docker.pullImage(appUpdateImage); err != nil {
|
||||
return e.InternalServerError("Failed to pull latest Beszel image.", err)
|
||||
}
|
||||
if err := docker.startUpdateHelper(container.ID, appUpdateImage); err != nil {
|
||||
return e.InternalServerError("Failed to start update helper.", err)
|
||||
}
|
||||
helperStarted = true
|
||||
time.AfterFunc(5*time.Minute, finishAppUpdate)
|
||||
|
||||
appUpdateCache.mu.Lock()
|
||||
appUpdateCache.info.Version = "latest"
|
||||
appUpdateCache.info.Status = "updating"
|
||||
appUpdateCache.info.Message = "Update helper started. Beszel will restart after the new container is ready."
|
||||
appUpdateCache.mu.Unlock()
|
||||
|
||||
return e.JSON(http.StatusOK, applyUpdateResponse{
|
||||
Started: true,
|
||||
Message: "Update helper started. Beszel will restart after the new container is ready.",
|
||||
})
|
||||
}
|
||||
|
||||
func getCachedUpdateInfo(force bool) UpdateInfo {
|
||||
appUpdateCache.mu.Lock()
|
||||
if !force && time.Since(appUpdateCache.checked) < 30*time.Minute && appUpdateCache.info.CurrentVersion != "" {
|
||||
info := appUpdateCache.info
|
||||
appUpdateCache.mu.Unlock()
|
||||
return info
|
||||
}
|
||||
appUpdateCache.mu.Unlock()
|
||||
|
||||
info := checkUpdateInfo()
|
||||
|
||||
appUpdateCache.mu.Lock()
|
||||
appUpdateCache.checked = time.Now()
|
||||
appUpdateCache.info = info
|
||||
appUpdateCache.mu.Unlock()
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
func checkUpdateInfo() UpdateInfo {
|
||||
now := time.Now().UTC().Format(time.RFC3339)
|
||||
info := UpdateInfo{
|
||||
Url: "https://github.com/dvorinka/Beszel/pkgs/container/beszel",
|
||||
CurrentVersion: beszel.Version,
|
||||
Image: appUpdateImage,
|
||||
Status: "checking",
|
||||
LastCheck: now,
|
||||
}
|
||||
|
||||
latestDigest, err := fetchGHCRDigest(context.Background(), appUpdateHTTPClient, appUpdateRepository, "latest")
|
||||
if err != nil {
|
||||
info.Status = "check-failed"
|
||||
info.Message = "Could not read latest image digest from GHCR: " + err.Error()
|
||||
return info
|
||||
}
|
||||
info.LatestDigest = latestDigest
|
||||
|
||||
docker, err := newDockerAPI()
|
||||
if err != nil {
|
||||
info.Status = "docker-unavailable"
|
||||
info.Message = "Automatic updates need the Docker socket mounted at /var/run/docker.sock."
|
||||
return info
|
||||
}
|
||||
containerID := currentContainerID(docker)
|
||||
container, err := docker.inspectContainer(containerID)
|
||||
if err != nil {
|
||||
info.Status = "container-unavailable"
|
||||
info.Message = "Docker is available, but the running Beszel container could not be inspected."
|
||||
return info
|
||||
}
|
||||
info.CurrentImageID = container.Image
|
||||
info.CanApply = true
|
||||
|
||||
image, err := docker.inspectImage(container.Image)
|
||||
if err == nil {
|
||||
info.CurrentDigest = findRepoDigest(image.RepoDigests, appUpdateRepository)
|
||||
}
|
||||
|
||||
switch {
|
||||
case info.CurrentDigest == "":
|
||||
info.Version = "latest"
|
||||
info.Status = "unknown"
|
||||
info.UpdateAvailable = true
|
||||
info.Message = "Running image digest is unknown. Update can pull and recreate from latest."
|
||||
case digestValue(info.CurrentDigest) != digestValue(info.LatestDigest):
|
||||
info.Version = "latest"
|
||||
info.Status = "update-available"
|
||||
info.UpdateAvailable = true
|
||||
info.Message = "New Beszel image is available."
|
||||
default:
|
||||
info.Status = "up-to-date"
|
||||
info.Message = "Beszel is already using the latest image digest."
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
func beginAppUpdate() bool {
|
||||
appUpdateApply.mu.Lock()
|
||||
defer appUpdateApply.mu.Unlock()
|
||||
if appUpdateApply.running {
|
||||
return false
|
||||
}
|
||||
appUpdateApply.running = true
|
||||
return true
|
||||
}
|
||||
|
||||
func finishAppUpdate() {
|
||||
appUpdateApply.mu.Lock()
|
||||
appUpdateApply.running = false
|
||||
appUpdateApply.mu.Unlock()
|
||||
}
|
||||
|
||||
func fetchGHCRDigest(ctx context.Context, client *http.Client, repository, tag string) (string, error) {
|
||||
manifestURL := fmt.Sprintf("https://ghcr.io/v2/%s/manifests/%s", repository, tag)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, manifestURL, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("Accept", strings.Join([]string{
|
||||
"application/vnd.oci.image.index.v1+json",
|
||||
"application/vnd.docker.distribution.manifest.list.v2+json",
|
||||
"application/vnd.oci.image.manifest.v1+json",
|
||||
"application/vnd.docker.distribution.manifest.v2+json",
|
||||
}, ", "))
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusUnauthorized {
|
||||
token, err := fetchRegistryToken(ctx, client, resp.Header.Get("WWW-Authenticate"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req, err = http.NewRequestWithContext(ctx, http.MethodGet, manifestURL, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("Accept", "application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json")
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
resp, err = client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
|
||||
raw, _ := io.ReadAll(resp.Body)
|
||||
if resp.StatusCode >= 400 {
|
||||
return "", fmt.Errorf("registry returned %s: %s", resp.Status, strings.TrimSpace(string(raw)))
|
||||
}
|
||||
digest := resp.Header.Get("Docker-Content-Digest")
|
||||
if digest == "" {
|
||||
return "", errors.New("registry response did not include Docker-Content-Digest")
|
||||
}
|
||||
return digest, nil
|
||||
}
|
||||
|
||||
func fetchRegistryToken(ctx context.Context, client *http.Client, challenge string) (string, error) {
|
||||
params := parseBearerChallenge(challenge)
|
||||
realm := params["realm"]
|
||||
if realm == "" {
|
||||
return "", errors.New("registry auth challenge missing realm")
|
||||
}
|
||||
tokenURL, err := url.Parse(realm)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
query := tokenURL.Query()
|
||||
for _, key := range []string{"service", "scope"} {
|
||||
if params[key] != "" {
|
||||
query.Set(key, params[key])
|
||||
}
|
||||
}
|
||||
tokenURL.RawQuery = query.Encode()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, tokenURL.String(), nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
raw, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if resp.StatusCode >= 400 {
|
||||
return "", fmt.Errorf("token service returned %s: %s", resp.Status, strings.TrimSpace(string(raw)))
|
||||
}
|
||||
var data struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if data.Token == "" {
|
||||
return "", errors.New("token service returned empty token")
|
||||
}
|
||||
return data.Token, nil
|
||||
}
|
||||
|
||||
func parseBearerChallenge(challenge string) map[string]string {
|
||||
out := make(map[string]string)
|
||||
challenge = strings.TrimSpace(strings.TrimPrefix(challenge, "Bearer"))
|
||||
for _, part := range strings.Split(challenge, ",") {
|
||||
key, value, ok := strings.Cut(strings.TrimSpace(part), "=")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
out[key] = strings.Trim(value, `"`)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func newDockerAPI() (*dockerAPI, error) {
|
||||
if _, err := os.Stat(dockerSocketPath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transport := &http.Transport{
|
||||
DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
|
||||
return (&net.Dialer{}).DialContext(ctx, "unix", dockerSocketPath)
|
||||
},
|
||||
}
|
||||
return &dockerAPI{
|
||||
client: &http.Client{
|
||||
Timeout: 10 * time.Minute,
|
||||
Transport: transport,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *dockerAPI) do(method, path string, body any, out any) error {
|
||||
var reader io.Reader
|
||||
if body != nil {
|
||||
raw, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reader = bytes.NewReader(raw)
|
||||
}
|
||||
req, err := http.NewRequest(method, "http://docker"+path, reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
resp, err := d.client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
raw, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode >= 400 {
|
||||
return fmt.Errorf("Docker API %s %s returned %s: %s", method, path, resp.Status, strings.TrimSpace(string(raw)))
|
||||
}
|
||||
if out != nil && len(raw) > 0 {
|
||||
return json.Unmarshal(raw, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *dockerAPI) inspectContainer(id string) (*dockerContainerInspect, error) {
|
||||
if strings.TrimSpace(id) == "" {
|
||||
return nil, errors.New("empty container id")
|
||||
}
|
||||
var inspect dockerContainerInspect
|
||||
err := d.do(http.MethodGet, "/containers/"+url.PathEscape(id)+"/json", nil, &inspect)
|
||||
return &inspect, err
|
||||
}
|
||||
|
||||
func (d *dockerAPI) inspectImage(id string) (*dockerImageInspect, error) {
|
||||
var inspect dockerImageInspect
|
||||
err := d.do(http.MethodGet, "/images/"+url.PathEscape(id)+"/json", nil, &inspect)
|
||||
return &inspect, err
|
||||
}
|
||||
|
||||
func (d *dockerAPI) pullImage(image string) error {
|
||||
name, tag, _ := strings.Cut(image, ":")
|
||||
if tag == "" {
|
||||
tag = "latest"
|
||||
}
|
||||
path := "/images/create?fromImage=" + url.QueryEscape(name) + "&tag=" + url.QueryEscape(tag)
|
||||
return d.do(http.MethodPost, path, nil, nil)
|
||||
}
|
||||
|
||||
func (d *dockerAPI) startUpdateHelper(targetID, image string) error {
|
||||
name := "beszel-update-" + shortID(targetID) + "-" + fmt.Sprint(time.Now().Unix())
|
||||
createBody := map[string]any{
|
||||
"Image": image,
|
||||
"Cmd": []string{
|
||||
"container-update-helper",
|
||||
"--target", targetID,
|
||||
"--image", image,
|
||||
},
|
||||
"HostConfig": map[string]any{
|
||||
"AutoRemove": true,
|
||||
"Binds": []string{dockerSocketPath + ":" + dockerSocketPath},
|
||||
},
|
||||
}
|
||||
var created dockerCreateResponse
|
||||
if err := d.do(http.MethodPost, "/containers/create?name="+url.QueryEscape(name), createBody, &created); err != nil {
|
||||
return err
|
||||
}
|
||||
return d.do(http.MethodPost, "/containers/"+url.PathEscape(created.ID)+"/start", nil, nil)
|
||||
}
|
||||
|
||||
func currentContainerID(d *dockerAPI) string {
|
||||
if hostname, err := os.Hostname(); err == nil && hostname != "" {
|
||||
if container, err := d.inspectContainer(hostname); err == nil {
|
||||
return container.ID
|
||||
}
|
||||
}
|
||||
raw, err := os.ReadFile("/proc/self/cgroup")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return updateContainerIDPattern.FindString(string(raw))
|
||||
}
|
||||
|
||||
func findRepoDigest(repoDigests []string, repository string) string {
|
||||
for _, digest := range repoDigests {
|
||||
if strings.Contains(digest, repository+"@sha256:") {
|
||||
return digest
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func digestValue(digest string) string {
|
||||
if _, value, ok := strings.Cut(digest, "@"); ok {
|
||||
return value
|
||||
}
|
||||
return digest
|
||||
}
|
||||
|
||||
func shortID(id string) string {
|
||||
if len(id) > 12 {
|
||||
return id[:12]
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// NewContainerUpdateHelperCmd creates a helper command that runs outside the current container.
|
||||
func NewContainerUpdateHelperCmd() *cobra.Command {
|
||||
var targetID string
|
||||
var image string
|
||||
cmd := &cobra.Command{
|
||||
Use: "container-update-helper",
|
||||
Short: "Replace the running Beszel container with a newer image",
|
||||
Hidden: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if targetID == "" || image == "" {
|
||||
return errors.New("target and image are required")
|
||||
}
|
||||
docker, err := newDockerAPI()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return docker.replaceContainer(targetID, image)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&targetID, "target", "", "target container id")
|
||||
cmd.Flags().StringVar(&image, "image", appUpdateImage, "replacement image")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (d *dockerAPI) replaceContainer(targetID, image string) error {
|
||||
current, err := d.inspectContainer(targetID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
originalName := strings.TrimPrefix(current.Name, "/")
|
||||
if originalName == "" {
|
||||
originalName = "beszel"
|
||||
}
|
||||
stamp := fmt.Sprint(time.Now().Unix())
|
||||
oldName := originalName + "-old-" + stamp
|
||||
newName := originalName + "-new-" + stamp
|
||||
|
||||
config := cloneMap(current.Config)
|
||||
hostConfig := cloneMap(current.HostConfig)
|
||||
config["Image"] = image
|
||||
|
||||
delete(hostConfig, "AutoRemove")
|
||||
createBody := cloneMap(config)
|
||||
createBody["HostConfig"] = hostConfig
|
||||
createBody["NetworkingConfig"] = map[string]any{"EndpointsConfig": current.NetworkSettings.Networks}
|
||||
|
||||
var created dockerCreateResponse
|
||||
if err := d.do(http.MethodPost, "/containers/create?name="+url.QueryEscape(newName), createBody, &created); err != nil {
|
||||
return err
|
||||
}
|
||||
cleanupNew := true
|
||||
defer func() {
|
||||
if cleanupNew {
|
||||
_ = d.do(http.MethodDelete, "/containers/"+url.PathEscape(created.ID)+"?force=true", nil, nil)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := d.do(http.MethodPost, "/containers/"+url.PathEscape(current.ID)+"/stop?t=10", nil, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.do(http.MethodPost, "/containers/"+url.PathEscape(current.ID)+"/rename?name="+url.QueryEscape(oldName), nil, nil); err != nil {
|
||||
_ = d.do(http.MethodPost, "/containers/"+url.PathEscape(current.ID)+"/start", nil, nil)
|
||||
return err
|
||||
}
|
||||
if err := d.do(http.MethodPost, "/containers/"+url.PathEscape(created.ID)+"/rename?name="+url.QueryEscape(originalName), nil, nil); err != nil {
|
||||
_ = d.do(http.MethodPost, "/containers/"+url.PathEscape(current.ID)+"/rename?name="+url.QueryEscape(originalName), nil, nil)
|
||||
_ = d.do(http.MethodPost, "/containers/"+url.PathEscape(current.ID)+"/start", nil, nil)
|
||||
return err
|
||||
}
|
||||
if err := d.do(http.MethodPost, "/containers/"+url.PathEscape(created.ID)+"/start", nil, nil); err != nil {
|
||||
_ = d.do(http.MethodPost, "/containers/"+url.PathEscape(created.ID)+"/rename?name="+url.QueryEscape(newName), nil, nil)
|
||||
_ = d.do(http.MethodPost, "/containers/"+url.PathEscape(current.ID)+"/rename?name="+url.QueryEscape(originalName), nil, nil)
|
||||
_ = d.do(http.MethodPost, "/containers/"+url.PathEscape(current.ID)+"/start", nil, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
cleanupNew = false
|
||||
_ = d.do(http.MethodDelete, "/containers/"+url.PathEscape(current.ID)+"?force=true", nil, nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func cloneMap(in map[string]any) map[string]any {
|
||||
out := make(map[string]any, len(in))
|
||||
for key, value := range in {
|
||||
out[key] = value
|
||||
}
|
||||
return out
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package hub
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParseBearerChallenge(t *testing.T) {
|
||||
challenge := `Bearer realm="https://ghcr.io/token",service="ghcr.io",scope="repository:dvorinka/beszel:pull"`
|
||||
|
||||
params := parseBearerChallenge(challenge)
|
||||
|
||||
if params["realm"] != "https://ghcr.io/token" {
|
||||
t.Fatalf("realm = %q", params["realm"])
|
||||
}
|
||||
if params["service"] != "ghcr.io" {
|
||||
t.Fatalf("service = %q", params["service"])
|
||||
}
|
||||
if params["scope"] != "repository:dvorinka/beszel:pull" {
|
||||
t.Fatalf("scope = %q", params["scope"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindRepoDigest(t *testing.T) {
|
||||
digests := []string{
|
||||
"ghcr.io/other/image@sha256:111",
|
||||
"ghcr.io/dvorinka/beszel@sha256:222",
|
||||
}
|
||||
|
||||
got := findRepoDigest(digests, "dvorinka/beszel")
|
||||
if got != "ghcr.io/dvorinka/beszel@sha256:222" {
|
||||
t.Fatalf("digest = %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDigestValue(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{name: "repo digest", in: "ghcr.io/dvorinka/beszel@sha256:abc", want: "sha256:abc"},
|
||||
{name: "plain digest", in: "sha256:def", want: "sha256:def"},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if got := digestValue(tc.in); got != tc.want {
|
||||
t.Fatalf("digestValue(%q) = %q, want %q", tc.in, got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,11 @@
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"includes": ["src/locales/**/*.ts"],
|
||||
"formatter": { "enabled": false },
|
||||
"linter": { "enabled": false }
|
||||
},
|
||||
{
|
||||
"includes": ["**/*.jsx", "**/*.tsx"],
|
||||
"linter": {
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
{
|
||||
"name": "Beszel - Monitoring Dashboard",
|
||||
"short_name": "Beszel",
|
||||
"description": "All-in-one monitoring dashboard for devices, websites, and domains",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#000000",
|
||||
"theme_color": "#171717",
|
||||
"orientation": "portrait-primary",
|
||||
"scope": "/",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/favicon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-128x128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-152x152.png",
|
||||
"sizes": "152x152",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any maskable"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"categories": ["utilities", "productivity"],
|
||||
"screenshots": [
|
||||
{
|
||||
"src": "/screenshot-wide.png",
|
||||
"sizes": "1280x720",
|
||||
"type": "image/png",
|
||||
"form_factor": "wide"
|
||||
},
|
||||
{
|
||||
"src": "/screenshot-narrow.png",
|
||||
"sizes": "750x1334",
|
||||
"type": "image/png",
|
||||
"form_factor": "narrow"
|
||||
}
|
||||
]
|
||||
"name": "Beszel - Monitoring Dashboard",
|
||||
"short_name": "Beszel",
|
||||
"description": "All-in-one monitoring dashboard for devices, websites, and domains",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#000000",
|
||||
"theme_color": "#171717",
|
||||
"orientation": "portrait-primary",
|
||||
"scope": "/",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/favicon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-128x128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-152x152.png",
|
||||
"sizes": "152x152",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any maskable"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"categories": ["utilities", "productivity"],
|
||||
"screenshots": [
|
||||
{
|
||||
"src": "/screenshot-wide.png",
|
||||
"sizes": "1280x720",
|
||||
"type": "image/png",
|
||||
"form_factor": "wide"
|
||||
},
|
||||
{
|
||||
"src": "/screenshot-narrow.png",
|
||||
"sizes": "750x1334",
|
||||
"type": "image/png",
|
||||
"form_factor": "narrow"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"start_url": "../",
|
||||
"start_url": "../",
|
||||
"display": "standalone",
|
||||
"background_color": "#202225",
|
||||
"theme_color": "#202225"
|
||||
|
||||
+125
-135
@@ -1,166 +1,156 @@
|
||||
// Beszel Service Worker
|
||||
const CACHE_NAME = 'beszel-v1';
|
||||
const STATIC_ASSETS = [
|
||||
'/',
|
||||
'/index.html',
|
||||
'/manifest.json',
|
||||
'/favicon.ico',
|
||||
'/favicon.svg',
|
||||
];
|
||||
const CACHE_NAME = "beszel-v1"
|
||||
const STATIC_ASSETS = ["/", "/index.html", "/manifest.json", "/favicon.ico", "/favicon.svg"]
|
||||
|
||||
// Install event - cache static assets
|
||||
self.addEventListener('install', (event) => {
|
||||
event.waitUntil(
|
||||
caches.open(CACHE_NAME)
|
||||
.then((cache) => {
|
||||
return cache.addAll(STATIC_ASSETS);
|
||||
})
|
||||
.then(() => self.skipWaiting())
|
||||
);
|
||||
});
|
||||
self.addEventListener("install", (event) => {
|
||||
event.waitUntil(
|
||||
caches
|
||||
.open(CACHE_NAME)
|
||||
.then((cache) => {
|
||||
return cache.addAll(STATIC_ASSETS)
|
||||
})
|
||||
.then(() => self.skipWaiting())
|
||||
)
|
||||
})
|
||||
|
||||
// Activate event - clean up old caches
|
||||
self.addEventListener('activate', (event) => {
|
||||
event.waitUntil(
|
||||
caches.keys().then((cacheNames) => {
|
||||
return Promise.all(
|
||||
cacheNames
|
||||
.filter((name) => name !== CACHE_NAME)
|
||||
.map((name) => caches.delete(name))
|
||||
);
|
||||
})
|
||||
.then(() => self.clients.claim())
|
||||
);
|
||||
});
|
||||
self.addEventListener("activate", (event) => {
|
||||
event.waitUntil(
|
||||
caches
|
||||
.keys()
|
||||
.then((cacheNames) => {
|
||||
return Promise.all(cacheNames.filter((name) => name !== CACHE_NAME).map((name) => caches.delete(name)))
|
||||
})
|
||||
.then(() => self.clients.claim())
|
||||
)
|
||||
})
|
||||
|
||||
// Fetch event - serve from cache or network
|
||||
self.addEventListener('fetch', (event) => {
|
||||
const { request } = event;
|
||||
const url = new URL(request.url);
|
||||
self.addEventListener("fetch", (event) => {
|
||||
const { request } = event
|
||||
const url = new URL(request.url)
|
||||
|
||||
// Skip non-GET requests
|
||||
if (request.method !== 'GET') {
|
||||
return;
|
||||
}
|
||||
// Skip non-GET requests
|
||||
if (request.method !== "GET") {
|
||||
return
|
||||
}
|
||||
|
||||
// Skip API requests
|
||||
if (url.pathname.startsWith('/api/')) {
|
||||
return;
|
||||
}
|
||||
// Skip API requests
|
||||
if (url.pathname.startsWith("/api/")) {
|
||||
return
|
||||
}
|
||||
|
||||
// Skip PocketBase API
|
||||
if (url.pathname.startsWith('/_/')) {
|
||||
return;
|
||||
}
|
||||
// Skip PocketBase API
|
||||
if (url.pathname.startsWith("/_/")) {
|
||||
return
|
||||
}
|
||||
|
||||
event.respondWith(
|
||||
caches.match(request).then((cached) => {
|
||||
if (cached) {
|
||||
// Return cached version and update in background
|
||||
fetch(request).then((response) => {
|
||||
if (response.ok) {
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
cache.put(request, response);
|
||||
});
|
||||
}
|
||||
});
|
||||
return cached;
|
||||
}
|
||||
event.respondWith(
|
||||
caches
|
||||
.match(request)
|
||||
.then((cached) => {
|
||||
if (cached) {
|
||||
// Return cached version and update in background
|
||||
fetch(request).then((response) => {
|
||||
if (response.ok) {
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
cache.put(request, response)
|
||||
})
|
||||
}
|
||||
})
|
||||
return cached
|
||||
}
|
||||
|
||||
// Fetch from network
|
||||
return fetch(request).then((response) => {
|
||||
if (!response || response.status !== 200 || response.type !== 'basic') {
|
||||
return response;
|
||||
}
|
||||
// Fetch from network
|
||||
return fetch(request).then((response) => {
|
||||
if (!response || response.status !== 200 || response.type !== "basic") {
|
||||
return response
|
||||
}
|
||||
|
||||
const responseToCache = response.clone();
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
cache.put(request, responseToCache);
|
||||
});
|
||||
const responseToCache = response.clone()
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
cache.put(request, responseToCache)
|
||||
})
|
||||
|
||||
return response;
|
||||
});
|
||||
}).catch(() => {
|
||||
// Return offline page if available
|
||||
return caches.match('/offline.html');
|
||||
})
|
||||
);
|
||||
});
|
||||
return response
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
// Return offline page if available
|
||||
return caches.match("/offline.html")
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
// Push notification event
|
||||
self.addEventListener('push', (event) => {
|
||||
if (!event.data) {
|
||||
return;
|
||||
}
|
||||
self.addEventListener("push", (event) => {
|
||||
if (!event.data) {
|
||||
return
|
||||
}
|
||||
|
||||
const data = event.data.json();
|
||||
const options = {
|
||||
body: data.body || 'New notification',
|
||||
icon: data.icon || '/favicon-192x192.png',
|
||||
badge: data.badge || '/favicon-72x72.png',
|
||||
tag: data.tag || 'default',
|
||||
requireInteraction: data.requireInteraction || false,
|
||||
data: data.data || {},
|
||||
actions: data.actions || [
|
||||
{ action: 'open', title: 'Open' },
|
||||
{ action: 'close', title: 'Dismiss' }
|
||||
]
|
||||
};
|
||||
const data = event.data.json()
|
||||
const options = {
|
||||
body: data.body || "New notification",
|
||||
icon: data.icon || "/favicon-192x192.png",
|
||||
badge: data.badge || "/favicon-72x72.png",
|
||||
tag: data.tag || "default",
|
||||
requireInteraction: data.requireInteraction || false,
|
||||
data: data.data || {},
|
||||
actions: data.actions || [
|
||||
{ action: "open", title: "Open" },
|
||||
{ action: "close", title: "Dismiss" },
|
||||
],
|
||||
}
|
||||
|
||||
event.waitUntil(
|
||||
self.registration.showNotification(
|
||||
data.title || 'Beszel Alert',
|
||||
options
|
||||
)
|
||||
);
|
||||
});
|
||||
event.waitUntil(self.registration.showNotification(data.title || "Beszel Alert", options))
|
||||
})
|
||||
|
||||
// Notification click event
|
||||
self.addEventListener('notificationclick', (event) => {
|
||||
event.notification.close();
|
||||
self.addEventListener("notificationclick", (event) => {
|
||||
event.notification.close()
|
||||
|
||||
const { action, data } = event.notification;
|
||||
const urlToOpen = data?.url || '/';
|
||||
const { data } = event.notification
|
||||
const urlToOpen = data?.url || "/"
|
||||
|
||||
event.waitUntil(
|
||||
clients.matchAll({ type: 'window', includeUncontrolled: true })
|
||||
.then((clientList) => {
|
||||
// Check if there's already a window open
|
||||
for (const client of clientList) {
|
||||
if (client.url === urlToOpen && 'focus' in client) {
|
||||
return client.focus();
|
||||
}
|
||||
}
|
||||
event.waitUntil(
|
||||
clients.matchAll({ type: "window", includeUncontrolled: true }).then((clientList) => {
|
||||
// Check if there's already a window open
|
||||
for (const client of clientList) {
|
||||
if (client.url === urlToOpen && "focus" in client) {
|
||||
return client.focus()
|
||||
}
|
||||
}
|
||||
|
||||
// Open new window if not found
|
||||
if (clients.openWindow) {
|
||||
return clients.openWindow(urlToOpen);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
// Open new window if not found
|
||||
if (clients.openWindow) {
|
||||
return clients.openWindow(urlToOpen)
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
// Background sync for offline support
|
||||
self.addEventListener('sync', (event) => {
|
||||
if (event.tag === 'background-sync') {
|
||||
event.waitUntil(doBackgroundSync());
|
||||
}
|
||||
});
|
||||
self.addEventListener("sync", (event) => {
|
||||
if (event.tag === "background-sync") {
|
||||
event.waitUntil(doBackgroundSync())
|
||||
}
|
||||
})
|
||||
|
||||
async function doBackgroundSync() {
|
||||
// Retry any pending API requests stored in IndexedDB
|
||||
// This is a placeholder - implement with actual pending request logic
|
||||
console.log('Background sync executed');
|
||||
function doBackgroundSync() {
|
||||
// Retry any pending API requests stored in IndexedDB
|
||||
// This is a placeholder - implement with actual pending request logic
|
||||
console.log("Background sync executed")
|
||||
}
|
||||
|
||||
// Periodic background sync (if supported)
|
||||
self.addEventListener('periodicsync', (event) => {
|
||||
if (event.tag === 'update-check') {
|
||||
event.waitUntil(checkForUpdates());
|
||||
}
|
||||
});
|
||||
self.addEventListener("periodicsync", (event) => {
|
||||
if (event.tag === "update-check") {
|
||||
event.waitUntil(checkForUpdates())
|
||||
}
|
||||
})
|
||||
|
||||
async function checkForUpdates() {
|
||||
// Check for new data and show notifications if needed
|
||||
console.log('Periodic sync executed');
|
||||
function checkForUpdates() {
|
||||
// Check for new data and show notifications if needed
|
||||
console.log("Periodic sync executed")
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ export const ActiveAlerts = () => {
|
||||
return { activeAlerts, alertsKey }
|
||||
}, [alerts])
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: alertsKey is inclusive
|
||||
return useMemo(() => {
|
||||
if (activeAlerts.length === 0) {
|
||||
return null
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { getPagePath } from "@nanostores/router"
|
||||
import { useStore } from "@nanostores/react"
|
||||
import {
|
||||
ContainerIcon,
|
||||
DatabaseBackupIcon,
|
||||
DownloadCloudIcon,
|
||||
HardDriveIcon,
|
||||
LogOutIcon,
|
||||
LogsIcon,
|
||||
@@ -29,6 +31,7 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu"
|
||||
import { isAdmin, isReadOnlyUser, logOut, pb } from "@/lib/api"
|
||||
import { $newVersion } from "@/lib/stores"
|
||||
import { cn, runOnce } from "@/lib/utils"
|
||||
import { LangToggle } from "./lang-toggle"
|
||||
import { Logo } from "./logo"
|
||||
@@ -42,6 +45,8 @@ const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0
|
||||
|
||||
export default function Navbar() {
|
||||
const [commandPaletteOpen, setCommandPaletteOpen] = useState(false)
|
||||
const updateInfo = useStore($newVersion)
|
||||
const updateAvailable = Boolean(updateInfo?.updateAvailable)
|
||||
|
||||
const AdminLinks = AdminDropdownGroup()
|
||||
|
||||
@@ -103,7 +108,10 @@ export default function Navbar() {
|
||||
<HardDriveIcon className="h-4 w-4 me-2.5" strokeWidth={1.5} />
|
||||
<span>S.M.A.R.T.</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => navigate(getPagePath($router, "monitoring"))} className="flex items-center">
|
||||
<DropdownMenuItem
|
||||
onClick={() => navigate(getPagePath($router, "monitoring"))}
|
||||
className="flex items-center"
|
||||
>
|
||||
<MonitorIcon className="h-4 w-4 me-2.5" strokeWidth={1.5} />
|
||||
<Trans>Monitoring</Trans>
|
||||
</DropdownMenuItem>
|
||||
@@ -114,6 +122,15 @@ export default function Navbar() {
|
||||
<SettingsIcon className="h-4 w-4 me-2.5" />
|
||||
<Trans>Settings</Trans>
|
||||
</DropdownMenuItem>
|
||||
{updateAvailable && (
|
||||
<DropdownMenuItem
|
||||
onClick={() => navigate(getPagePath($router, "settings", { name: "general" }))}
|
||||
className="flex items-center"
|
||||
>
|
||||
<DownloadCloudIcon className="h-4 w-4 me-2.5" />
|
||||
<Trans>Update available</Trans>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{isAdmin() && (
|
||||
<DropdownMenuSub>
|
||||
<DropdownMenuSubTrigger>
|
||||
@@ -168,7 +185,6 @@ export default function Navbar() {
|
||||
<TooltipContent>
|
||||
<span>S.M.A.R.T.</span>
|
||||
</TooltipContent>
|
||||
<TooltipContent>S.M.A.R.T.</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
@@ -186,6 +202,22 @@ export default function Navbar() {
|
||||
</Tooltip>
|
||||
<LangToggle />
|
||||
<ModeToggle />
|
||||
{updateAvailable && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Link
|
||||
href={getPagePath($router, "settings", { name: "general" })}
|
||||
aria-label="Update available"
|
||||
className={cn(buttonVariants({ variant: "ghost", size: "icon" }), "text-primary")}
|
||||
>
|
||||
<DownloadCloudIcon className="h-[1.2rem] w-[1.2rem]" />
|
||||
</Link>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<Trans>Update available</Trans>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Link
|
||||
|
||||
@@ -11,6 +11,7 @@ const routes = {
|
||||
forgot_password: `/forgot-password`,
|
||||
request_otp: `/request-otp`,
|
||||
status_pages: `/status-pages`,
|
||||
public_status: `/status/:slug`,
|
||||
incidents: `/incidents`,
|
||||
calendar: `/calendar`,
|
||||
monitoring: `/monitoring`,
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
PlayIcon,
|
||||
TrendingUp,
|
||||
TrendingDown,
|
||||
Plus,
|
||||
type LucideIcon,
|
||||
} from "lucide-react"
|
||||
import {
|
||||
@@ -53,6 +54,7 @@ import {
|
||||
createStatusPage,
|
||||
getStatusPageMonitors,
|
||||
getStatusPages,
|
||||
getStatusPageUrl,
|
||||
removeMonitorFromStatusPage,
|
||||
} from "@/lib/statuspages"
|
||||
import {
|
||||
@@ -521,36 +523,92 @@ export default memo(function MonitorDetail({ id }: { id: string }) {
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Status Page</CardTitle>
|
||||
<CardDescription>Link or create a public status page</CardDescription>
|
||||
<CardDescription>Link this monitor to public status pages</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
{statusPages && statusPages.length > 0 ? (
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-3">
|
||||
{statusPages.map((page) => {
|
||||
const isLinked = linkedStatusPageMonitors?.some((link) => link.status_page_id === page.id) || false
|
||||
const linkInfo = linkedStatusPageMonitors?.find((link) => link.status_page_id === page.id)
|
||||
|
||||
return (
|
||||
<div key={page.id} className="flex items-center justify-between py-1">
|
||||
<span className="text-sm">{page.name}</span>
|
||||
<Button
|
||||
variant={isLinked ? "default" : "outline"}
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
updateStatusPagesMutation.mutate({
|
||||
pageId: page.id,
|
||||
linked: isLinked,
|
||||
})
|
||||
}}
|
||||
>
|
||||
{isLinked ? "Linked" : "Link"}
|
||||
</Button>
|
||||
<div
|
||||
key={page.id}
|
||||
className={`flex items-center justify-between p-3 rounded-lg border ${
|
||||
isLinked ? 'bg-primary/5 border-primary/20' : 'bg-muted/30'
|
||||
}`}
|
||||
>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium text-sm truncate">{page.name}</span>
|
||||
{page.public && (
|
||||
<Globe className="h-3 w-3 text-muted-foreground flex-shrink-0" />
|
||||
)}
|
||||
</div>
|
||||
{isLinked && linkInfo && (
|
||||
<p className="text-xs text-muted-foreground mt-1">
|
||||
Display: {linkInfo.display_name || monitor?.name}
|
||||
{linkInfo.group && ` • Group: ${linkInfo.group}`}
|
||||
</p>
|
||||
)}
|
||||
{!isLinked && page.public && (
|
||||
<p className="text-xs text-muted-foreground mt-1">
|
||||
{page.monitor_count} monitor{page.monitor_count !== 1 ? 's' : ''} linked
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-2 ml-2">
|
||||
{isLinked && page.public && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8"
|
||||
asChild
|
||||
>
|
||||
<a
|
||||
href={getStatusPageUrl(page.slug)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="View public status page"
|
||||
>
|
||||
<ExternalLink className="h-4 w-4" />
|
||||
</a>
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant={isLinked ? "default" : "outline"}
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
updateStatusPagesMutation.mutate({
|
||||
pageId: page.id,
|
||||
linked: isLinked,
|
||||
})
|
||||
}}
|
||||
disabled={updateStatusPagesMutation.isPending}
|
||||
>
|
||||
{isLinked ? (
|
||||
<>
|
||||
<CheckCircle2 className="mr-1 h-3 w-3" />
|
||||
Linked
|
||||
</>
|
||||
) : (
|
||||
"Link"
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-muted-foreground">No status pages yet.</p>
|
||||
<div className="text-center py-4">
|
||||
<p className="text-sm text-muted-foreground">No status pages yet.</p>
|
||||
<p className="text-xs text-muted-foreground mt-1">Create one to share your service status publicly.</p>
|
||||
</div>
|
||||
)}
|
||||
<Button variant="outline" size="sm" className="w-full" onClick={() => setIsCreateStatusPageOpen(true)}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Create Status Page
|
||||
</Button>
|
||||
</CardContent>
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
import { useEffect, useState, useMemo } from "react"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { getPublicStatusPage, type PublicStatusPage, type PublicMonitorStatus } from "@/lib/statuspages"
|
||||
import { Activity, CheckCircle2, XCircle, AlertTriangle, Clock, Shield, RefreshCw } from "lucide-react"
|
||||
|
||||
// Status configurations with colors matching github-statuses design
|
||||
const statusConfig = {
|
||||
operational: {
|
||||
color: "#2da44e",
|
||||
bgColor: "rgba(45, 164, 78, 0.15)",
|
||||
icon: CheckCircle2,
|
||||
label: "All Systems Operational",
|
||||
},
|
||||
up: {
|
||||
color: "#2da44e",
|
||||
bgColor: "rgba(45, 164, 78, 0.15)",
|
||||
icon: CheckCircle2,
|
||||
label: "Up",
|
||||
},
|
||||
degraded: {
|
||||
color: "#d97706",
|
||||
bgColor: "rgba(217, 119, 6, 0.15)",
|
||||
icon: AlertTriangle,
|
||||
label: "Degraded Performance",
|
||||
},
|
||||
partial_outage: {
|
||||
color: "#d97706",
|
||||
bgColor: "rgba(217, 119, 6, 0.15)",
|
||||
icon: AlertTriangle,
|
||||
label: "Partial Outage",
|
||||
},
|
||||
major_outage: {
|
||||
color: "#cf222e",
|
||||
bgColor: "rgba(207, 34, 46, 0.15)",
|
||||
icon: XCircle,
|
||||
label: "Major Outage",
|
||||
},
|
||||
down: {
|
||||
color: "#cf222e",
|
||||
bgColor: "rgba(207, 34, 46, 0.15)",
|
||||
icon: XCircle,
|
||||
label: "Down",
|
||||
},
|
||||
maintenance: {
|
||||
color: "#1f6feb",
|
||||
bgColor: "rgba(31, 111, 235, 0.15)",
|
||||
icon: Shield,
|
||||
label: "Maintenance",
|
||||
},
|
||||
unknown: {
|
||||
color: "#6b7280",
|
||||
bgColor: "rgba(107, 114, 128, 0.15)",
|
||||
icon: Clock,
|
||||
label: "Unknown",
|
||||
},
|
||||
}
|
||||
|
||||
function getStatusConfig(status: string) {
|
||||
return statusConfig[status as keyof typeof statusConfig] || statusConfig.unknown
|
||||
}
|
||||
|
||||
// Generate deterministic uptime bars based on uptime percentage (30 days)
|
||||
// Uses a seeded approach so the same uptime always shows the same pattern
|
||||
function generateUptimeBars(uptimePercent: number, seed: string): { day: number; status: "operational" | "minor" | "major" }[] {
|
||||
const bars: { day: number; status: "operational" | "minor" | "major" }[] = []
|
||||
const downDays = Math.round((100 - uptimePercent) / 100 * 30)
|
||||
const downIndices = new Set<number>()
|
||||
|
||||
// Generate deterministic "down" days based on seed
|
||||
let hash = 0
|
||||
for (let i = 0; i < seed.length; i++) {
|
||||
hash = ((hash << 5) - hash) + seed.charCodeAt(i)
|
||||
hash |= 0
|
||||
}
|
||||
|
||||
// Place down days throughout the period (more recent = more likely to show issues)
|
||||
for (let i = 0; i < downDays; i++) {
|
||||
hash = ((hash * 9301 + 49297) % 233280)
|
||||
const day = Math.floor(Math.abs(hash) % 30)
|
||||
downIndices.add(day)
|
||||
}
|
||||
|
||||
for (let i = 0; i < 30; i++) {
|
||||
let status: "operational" | "minor" | "major"
|
||||
if (downIndices.has(i)) {
|
||||
// Recent issues are "major", older are "minor"
|
||||
status = i > 20 ? "major" : "minor"
|
||||
} else {
|
||||
status = "operational"
|
||||
}
|
||||
bars.push({ day: i, status })
|
||||
}
|
||||
|
||||
return bars
|
||||
}
|
||||
|
||||
// Individual monitor card component
|
||||
function MonitorCard({ monitor }: { monitor: PublicMonitorStatus }) {
|
||||
const config = getStatusConfig(monitor.status)
|
||||
const Icon = config.icon
|
||||
const uptimeBars = useMemo(() => generateUptimeBars(monitor.uptime_30d || 99, monitor.id), [monitor.uptime_30d, monitor.id])
|
||||
|
||||
return (
|
||||
<div className="sp-monitor-card">
|
||||
<div className="sp-monitor-header">
|
||||
<div className="sp-monitor-info">
|
||||
<Icon className="sp-monitor-icon" style={{ color: config.color }} />
|
||||
<div>
|
||||
<h4 className="sp-monitor-name">{monitor.display_name || monitor.name}</h4>
|
||||
{monitor.group && <span className="sp-monitor-group">{monitor.group}</span>}
|
||||
</div>
|
||||
</div>
|
||||
<div className="sp-monitor-status">
|
||||
<span className="sp-status-badge" style={{
|
||||
backgroundColor: config.bgColor,
|
||||
color: config.color
|
||||
}}>
|
||||
<span className="sp-status-dot" style={{ backgroundColor: config.color }} />
|
||||
{config.label}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sp-uptime-section">
|
||||
<div className="sp-uptime-header">
|
||||
<span className="sp-uptime-label">30-day uptime</span>
|
||||
<span className="sp-uptime-value" style={{ color: config.color }}>
|
||||
{(monitor.uptime_30d ?? 0).toFixed(2)}%
|
||||
</span>
|
||||
</div>
|
||||
<div className="sp-uptime-bars">
|
||||
{uptimeBars.map((bar, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`sp-uptime-bar sp-uptime-bar--${bar.status}`}
|
||||
title={`Day ${bar.day + 1}: ${bar.status}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="sp-uptime-axis">
|
||||
<span>30 days ago</span>
|
||||
<span>Today</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sp-uptime-stats">
|
||||
<div className="sp-stat">
|
||||
<span className="sp-stat-label">24h</span>
|
||||
<span className="sp-stat-value" style={{ color: getStatusColor(monitor.uptime_24h) }}>
|
||||
{(monitor.uptime_24h ?? 0).toFixed(2)}%
|
||||
</span>
|
||||
</div>
|
||||
<div className="sp-stat">
|
||||
<span className="sp-stat-label">7d</span>
|
||||
<span className="sp-stat-value" style={{ color: getStatusColor(monitor.uptime_7d) }}>
|
||||
{(monitor.uptime_7d ?? 0).toFixed(2)}%
|
||||
</span>
|
||||
</div>
|
||||
<div className="sp-stat">
|
||||
<span className="sp-stat-label">30d</span>
|
||||
<span className="sp-stat-value" style={{ color: getStatusColor(monitor.uptime_30d) }}>
|
||||
{(monitor.uptime_30d ?? 0).toFixed(2)}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sp-last-check">
|
||||
<Clock className="sp-last-check-icon" />
|
||||
<span>Last checked: {monitor.last_check ? new Date(monitor.last_check).toLocaleString() : 'Never'}</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function getStatusColor(uptime: number | undefined): string {
|
||||
if (uptime === undefined) return "#6b7280"
|
||||
if (uptime >= 99) return "#2da44e"
|
||||
if (uptime >= 95) return "#d97706"
|
||||
return "#cf222e"
|
||||
}
|
||||
|
||||
|
||||
// Loading skeleton
|
||||
function StatusPageSkeleton() {
|
||||
return (
|
||||
<div className="sp-container">
|
||||
<div className="sp-header-skeleton">
|
||||
<div className="sp-skeleton sp-skeleton--logo" />
|
||||
<div className="sp-skeleton sp-skeleton--title" />
|
||||
</div>
|
||||
<div className="sp-hero-skeleton" />
|
||||
<div className="sp-monitors-skeleton">
|
||||
{[1, 2, 3].map((i) => (
|
||||
<div key={i} className="sp-monitor-skeleton" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Error state
|
||||
function StatusPageError({ slug }: { slug: string }) {
|
||||
return (
|
||||
<div className="sp-container">
|
||||
<div className="sp-error">
|
||||
<XCircle className="sp-error-icon" />
|
||||
<h2>Status page not found</h2>
|
||||
<p>The status page "{slug}" does not exist or is not public.</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Auto-refresh countdown component
|
||||
function RefreshIndicator({
|
||||
isFetching,
|
||||
refetch
|
||||
}: {
|
||||
isFetching: boolean
|
||||
refetch: () => void
|
||||
}) {
|
||||
const [countdown, setCountdown] = useState(60)
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setCountdown((prev) => {
|
||||
if (prev <= 1) {
|
||||
refetch()
|
||||
return 60
|
||||
}
|
||||
return prev - 1
|
||||
})
|
||||
}, 1000)
|
||||
|
||||
return () => clearInterval(interval)
|
||||
}, [refetch])
|
||||
|
||||
// Reset countdown when data refreshes
|
||||
useEffect(() => {
|
||||
if (!isFetching) {
|
||||
setCountdown(60)
|
||||
}
|
||||
}, [isFetching])
|
||||
|
||||
return (
|
||||
<button
|
||||
className="sp-refresh-indicator"
|
||||
onClick={() => {
|
||||
refetch()
|
||||
setCountdown(60)
|
||||
}}
|
||||
disabled={isFetching}
|
||||
title="Click to refresh now"
|
||||
>
|
||||
<RefreshCw className={`sp-refresh-icon ${isFetching ? 'sp-refresh-spin' : ''}`} />
|
||||
<span className="sp-refresh-text">
|
||||
{isFetching ? 'Refreshing...' : `Refresh in ${countdown}s`}
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
// Main component
|
||||
export default function PublicStatusPage({ slug }: { slug: string }) {
|
||||
const [theme, setTheme] = useState<"light" | "dark">("light")
|
||||
|
||||
// Detect system theme preference
|
||||
useEffect(() => {
|
||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
|
||||
setTheme(mediaQuery.matches ? "dark" : "light")
|
||||
|
||||
const handler = (e: MediaQueryListEvent) => {
|
||||
setTheme(e.matches ? "dark" : "light")
|
||||
}
|
||||
mediaQuery.addEventListener("change", handler)
|
||||
return () => mediaQuery.removeEventListener("change", handler)
|
||||
}, [])
|
||||
|
||||
const { data, isLoading, error, isFetching, refetch } = useQuery({
|
||||
queryKey: ["public-status-page", slug],
|
||||
queryFn: () => getPublicStatusPage(slug),
|
||||
retry: false,
|
||||
refetchInterval: false, // We handle auto-refresh manually with countdown
|
||||
})
|
||||
|
||||
// Update document title
|
||||
useEffect(() => {
|
||||
if (data?.title) {
|
||||
document.title = `${data.title} / Status Page`
|
||||
} else {
|
||||
document.title = "Status Page / Beszel"
|
||||
}
|
||||
}, [data?.title])
|
||||
|
||||
// Apply theme class to document
|
||||
useEffect(() => {
|
||||
document.documentElement.setAttribute("data-sp-theme", theme)
|
||||
}, [theme])
|
||||
|
||||
if (isLoading) {
|
||||
return <StatusPageSkeleton />
|
||||
}
|
||||
|
||||
if (error || !data) {
|
||||
return <StatusPageError slug={slug} />
|
||||
}
|
||||
|
||||
// Group monitors by group name
|
||||
const groupedMonitors = useMemo(() => {
|
||||
const groups: Record<string, PublicMonitorStatus[]> = {}
|
||||
data.monitors.forEach((monitor) => {
|
||||
const group = monitor.group || "Services"
|
||||
if (!groups[group]) {
|
||||
groups[group] = []
|
||||
}
|
||||
groups[group].push(monitor)
|
||||
})
|
||||
return groups
|
||||
}, [data.monitors])
|
||||
|
||||
const groupNames = Object.keys(groupedMonitors).sort()
|
||||
|
||||
// Set favicon if provided
|
||||
useEffect(() => {
|
||||
if (data?.favicon) {
|
||||
const link = document.querySelector('link[rel*="icon"]') as HTMLLinkElement || document.createElement('link')
|
||||
link.rel = 'icon'
|
||||
link.href = data.favicon
|
||||
document.head.appendChild(link)
|
||||
}
|
||||
}, [data?.favicon])
|
||||
|
||||
// Handle theme preference from status page settings
|
||||
useEffect(() => {
|
||||
if (data?.theme && data.theme !== 'auto') {
|
||||
setTheme(data.theme as 'light' | 'dark')
|
||||
}
|
||||
}, [data?.theme])
|
||||
|
||||
return (
|
||||
<div className="sp-page" data-theme={theme}>
|
||||
{/* Grain texture overlay */}
|
||||
<div className="sp-grain" />
|
||||
|
||||
{/* Header */}
|
||||
<header className="sp-header">
|
||||
<div className="sp-header-content">
|
||||
<div className="sp-brand">
|
||||
{data.logo ? (
|
||||
<img src={data.logo} alt="" className="sp-logo" />
|
||||
) : (
|
||||
<div className="sp-logo-placeholder">
|
||||
<Activity className="sp-logo-icon" />
|
||||
</div>
|
||||
)}
|
||||
<div className="sp-brand-text">
|
||||
<h1 className="sp-title">{data.title || data.name}</h1>
|
||||
{data.description && (
|
||||
<p className="sp-description">{data.description}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Main content */}
|
||||
<main className="sp-main">
|
||||
{/* Overall Status Hero */}
|
||||
<section className="sp-hero-section">
|
||||
<div className="sp-hero-panel">
|
||||
<div className="sp-hero-content">
|
||||
<div className="sp-status-pill" style={{
|
||||
backgroundColor: getStatusConfig(data.overall_status).bgColor,
|
||||
color: getStatusConfig(data.overall_status).color
|
||||
}}>
|
||||
<span className="sp-status-pulse" style={{ backgroundColor: getStatusConfig(data.overall_status).color }} />
|
||||
{getStatusConfig(data.overall_status).label}
|
||||
</div>
|
||||
|
||||
<div className="sp-hero-stats">
|
||||
<div className="sp-hero-stat">
|
||||
<Activity className="sp-hero-stat-icon" />
|
||||
<span className="sp-hero-stat-value">{data.monitors.length}</span>
|
||||
<span className="sp-hero-stat-label">Monitors</span>
|
||||
</div>
|
||||
<RefreshIndicator isFetching={isFetching} refetch={refetch} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Monitor Groups */}
|
||||
{groupNames.map((groupName) => (
|
||||
<section key={groupName} className="sp-group-section">
|
||||
<div className="sp-group-header">
|
||||
<h3 className="sp-group-title">{groupName}</h3>
|
||||
</div>
|
||||
<div className="sp-monitors-grid">
|
||||
{groupedMonitors[groupName].map((monitor) => (
|
||||
<MonitorCard key={monitor.id} monitor={monitor} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="sp-footer">
|
||||
<p className="sp-footer-text">
|
||||
Powered by <a href="https://beszel.dev" target="_blank" rel="noopener noreferrer">Beszel</a>
|
||||
</p>
|
||||
<p className="sp-footer-updated">
|
||||
Last updated: {new Date(data.updated_at).toLocaleString()}
|
||||
</p>
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
{/* Apply custom CSS if provided */}
|
||||
{data.custom_css && (
|
||||
<style dangerouslySetInnerHTML={{ __html: data.custom_css }} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,20 +1,33 @@
|
||||
/** biome-ignore-all lint/correctness/useUniqueElementIds: component is only rendered once */
|
||||
import { Trans, useLingui } from "@lingui/react/macro"
|
||||
import { LanguagesIcon, LoaderCircleIcon, SaveIcon } from "lucide-react"
|
||||
import { useState } from "react"
|
||||
import { DownloadCloudIcon, LanguagesIcon, LoaderCircleIcon, RefreshCcwIcon, SaveIcon } from "lucide-react"
|
||||
import { useEffect, useState } from "react"
|
||||
import { useStore } from "@nanostores/react"
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
import { toast } from "@/components/ui/use-toast"
|
||||
import { pb } from "@/lib/api"
|
||||
import Slider from "@/components/ui/slider"
|
||||
import { HourFormat, Unit } from "@/lib/enums"
|
||||
import { dynamicActivate } from "@/lib/i18n"
|
||||
import languages from "@/lib/languages"
|
||||
import { $userSettings, defaultLayoutWidth } from "@/lib/stores"
|
||||
import { $newVersion, $userSettings, defaultLayoutWidth } from "@/lib/stores"
|
||||
import { chartTimeData, currentHour12 } from "@/lib/utils"
|
||||
import type { UserSettings } from "@/types"
|
||||
import type { UpdateInfo, UserSettings } from "@/types"
|
||||
import { saveSettings } from "./layout"
|
||||
|
||||
export default function SettingsProfilePage({ userSettings }: { userSettings: UserSettings }) {
|
||||
@@ -43,6 +56,8 @@ export default function SettingsProfilePage({ userSettings }: { userSettings: Us
|
||||
</p>
|
||||
</div>
|
||||
<Separator className="my-4" />
|
||||
<AppUpdatePanel />
|
||||
<Separator className="my-5" />
|
||||
<form onSubmit={handleSubmit} className="space-y-5">
|
||||
<div className="grid gap-2">
|
||||
<div className="mb-2">
|
||||
@@ -287,3 +302,189 @@ export default function SettingsProfilePage({ userSettings }: { userSettings: Us
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function AppUpdatePanel() {
|
||||
const updateInfo = useStore($newVersion)
|
||||
const [checking, setChecking] = useState(false)
|
||||
const [applying, setApplying] = useState(false)
|
||||
const [restartPending, setRestartPending] = useState(false)
|
||||
|
||||
async function refreshUpdateInfo() {
|
||||
setChecking(true)
|
||||
try {
|
||||
const info = await pb.send<UpdateInfo>("/api/beszel/update", {})
|
||||
$newVersion.set(info)
|
||||
} catch (err) {
|
||||
toast({
|
||||
title: "Update check failed",
|
||||
description: err instanceof Error ? err.message : "Could not check for updates.",
|
||||
variant: "destructive",
|
||||
})
|
||||
} finally {
|
||||
setChecking(false)
|
||||
}
|
||||
}
|
||||
|
||||
async function applyUpdate() {
|
||||
setApplying(true)
|
||||
try {
|
||||
const res = await pb.send<{ message: string }>("/api/beszel/update/apply", { method: "POST" })
|
||||
toast({
|
||||
title: "Update started",
|
||||
description: res.message,
|
||||
})
|
||||
setRestartPending(true)
|
||||
$newVersion.set(updateInfo ? { ...updateInfo, status: "updating", message: res.message } : undefined)
|
||||
const restarted = await waitForRestartAndReload()
|
||||
if (!restarted) {
|
||||
toast({
|
||||
title: "Still waiting for restart",
|
||||
description: "Beszel did not come back before the timeout. Check the Docker container logs.",
|
||||
variant: "destructive",
|
||||
})
|
||||
setRestartPending(false)
|
||||
setApplying(false)
|
||||
await refreshUpdateInfo()
|
||||
}
|
||||
} catch (err) {
|
||||
toast({
|
||||
title: "Update failed",
|
||||
description: err instanceof Error ? err.message : "Could not start the update.",
|
||||
variant: "destructive",
|
||||
})
|
||||
setApplying(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!updateInfo) {
|
||||
refreshUpdateInfo()
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const status = updateInfo?.status ?? "checking"
|
||||
const message = restartPending
|
||||
? "Update started. Waiting for Beszel to restart..."
|
||||
: (updateInfo?.message ?? "Checking GHCR for the latest image.")
|
||||
const canUpdate = Boolean(updateInfo?.canApply && updateInfo?.updateAvailable && !applying && !restartPending)
|
||||
|
||||
return (
|
||||
<div className="rounded-md border bg-card/50 p-4">
|
||||
<div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
|
||||
<div className="space-y-1.5">
|
||||
<h3 className="text-lg font-medium flex items-center gap-2">
|
||||
<DownloadCloudIcon className="h-4 w-4" />
|
||||
<Trans>App update</Trans>
|
||||
</h3>
|
||||
<p className="text-sm text-muted-foreground leading-relaxed">{message}</p>
|
||||
</div>
|
||||
<StatusBadge status={status} updateAvailable={Boolean(updateInfo?.updateAvailable)} />
|
||||
</div>
|
||||
<div className="mt-4 grid gap-2 text-sm sm:grid-cols-2">
|
||||
<UpdateMeta label="Image" value={updateInfo?.image ?? "ghcr.io/dvorinka/beszel:latest"} />
|
||||
<UpdateMeta label="Current version" value={updateInfo?.currentVersion ?? "..."} />
|
||||
<UpdateMeta label="Running digest" value={shortDigest(updateInfo?.currentDigest)} />
|
||||
<UpdateMeta label="Latest digest" value={shortDigest(updateInfo?.latestDigest)} />
|
||||
</div>
|
||||
<div className="mt-4 flex flex-col gap-2 sm:flex-row">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={refreshUpdateInfo}
|
||||
disabled={checking || applying || restartPending}
|
||||
>
|
||||
{checking ? (
|
||||
<LoaderCircleIcon className="me-2 h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<RefreshCcwIcon className="me-2 h-4 w-4" />
|
||||
)}
|
||||
<Trans>Check now</Trans>
|
||||
</Button>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button type="button" disabled={!canUpdate}>
|
||||
{applying || restartPending ? (
|
||||
<LoaderCircleIcon className="me-2 h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<DownloadCloudIcon className="me-2 h-4 w-4" />
|
||||
)}
|
||||
{restartPending ? <Trans>Restarting</Trans> : <Trans>Update now</Trans>}
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
<Trans>Update Beszel now?</Trans>
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
<Trans>
|
||||
Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app.
|
||||
All signed-in users can start this action.
|
||||
</Trans>
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>
|
||||
<Trans>Cancel</Trans>
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={applyUpdate}>
|
||||
<Trans>Start update</Trans>
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function StatusBadge({ status, updateAvailable }: { status: string; updateAvailable: boolean }) {
|
||||
const label = updateAvailable
|
||||
? "Update available"
|
||||
: status === "up-to-date"
|
||||
? "Up to date"
|
||||
: status.replaceAll("-", " ")
|
||||
return (
|
||||
<span className="inline-flex h-7 items-center self-start rounded-md border bg-background px-2.5 text-xs font-medium capitalize text-muted-foreground">
|
||||
{label}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
function UpdateMeta({ label, value }: { label: string; value: string }) {
|
||||
return (
|
||||
<div className="min-w-0 rounded-md bg-muted/45 px-3 py-2">
|
||||
<div className="text-xs text-muted-foreground">{label}</div>
|
||||
<div className="truncate font-mono text-xs">{value}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function shortDigest(value?: string) {
|
||||
if (!value) return "unknown"
|
||||
const digest = value.includes("@") ? value.split("@").at(-1) : value
|
||||
if (!digest) return value
|
||||
return digest.length > 24 ? `${digest.slice(0, 24)}...` : digest
|
||||
}
|
||||
|
||||
async function waitForRestartAndReload() {
|
||||
await sleep(10_000)
|
||||
for (let attempt = 0; attempt < 45; attempt++) {
|
||||
try {
|
||||
const res = await fetch("/api/health", { cache: "no-store" })
|
||||
if (res.ok) {
|
||||
window.location.reload()
|
||||
return true
|
||||
}
|
||||
} catch {
|
||||
// Hub is expected to be unavailable while Docker replaces the container.
|
||||
}
|
||||
await sleep(2_000)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function sleep(ms: number) {
|
||||
return new Promise((resolve) => window.setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
"use client"
|
||||
|
||||
import { useState, useEffect } from "react"
|
||||
import { useState, useEffect, useRef } from "react"
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { z } from "zod"
|
||||
import { useToast } from "@/components/ui/use-toast"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
// Generate slug from name
|
||||
const generateSlug = (name: string): string => {
|
||||
return name
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-|-$/g, '')
|
||||
.slice(0, 50)
|
||||
}
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@@ -38,8 +47,10 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
import {
|
||||
createStatusPage,
|
||||
updateStatusPage,
|
||||
getStatusPageUrl,
|
||||
type StatusPage,
|
||||
} from "@/lib/statuspages"
|
||||
import { ExternalLink, RefreshCw } from "lucide-react"
|
||||
|
||||
const formSchema = z.object({
|
||||
name: z.string().min(1, "Name is required"),
|
||||
@@ -162,6 +173,29 @@ export function StatusPageDialog({
|
||||
|
||||
const isPending = createMutation.isPending || updateMutation.isPending
|
||||
|
||||
// Auto-generate slug from name when creating new status page
|
||||
const lastAutoSlug = useRef<string>("")
|
||||
useEffect(() => {
|
||||
if (isEdit) return // Don't auto-generate in edit mode
|
||||
|
||||
const subscription = form.watch((value, { name: fieldName }) => {
|
||||
if (fieldName === 'name') {
|
||||
const name = value.name || ''
|
||||
const currentSlug = form.getValues('slug') || ''
|
||||
const newSlug = generateSlug(name)
|
||||
|
||||
// Only auto-generate if:
|
||||
// 1. Slug is empty, OR
|
||||
// 2. Current slug matches the last auto-generated slug (user hasn't manually edited)
|
||||
if (!currentSlug || currentSlug === lastAutoSlug.current) {
|
||||
form.setValue('slug', newSlug, { shouldValidate: true })
|
||||
lastAutoSlug.current = newSlug
|
||||
}
|
||||
}
|
||||
})
|
||||
return () => subscription.unsubscribe()
|
||||
}, [form, isEdit])
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:max-w-[600px] max-h-[80vh] overflow-y-auto">
|
||||
@@ -203,12 +237,45 @@ export function StatusPageDialog({
|
||||
name="slug"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>URL Slug</FormLabel>
|
||||
<FormLabel className="flex items-center justify-between">
|
||||
<span>URL Slug</span>
|
||||
{!isEdit && form.getValues('name') && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-6 px-2 text-xs"
|
||||
onClick={() => {
|
||||
const newSlug = generateSlug(form.getValues('name') || '')
|
||||
form.setValue('slug', newSlug, { shouldValidate: true })
|
||||
lastAutoSlug.current = newSlug
|
||||
}}
|
||||
>
|
||||
<RefreshCw className="mr-1 h-3 w-3" />
|
||||
Regenerate
|
||||
</Button>
|
||||
)}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="my-services" {...field} />
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm text-muted-foreground whitespace-nowrap">/status/</span>
|
||||
<Input {...field} placeholder="my-services" className="flex-1" />
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
The URL will be: /status/{field.value}
|
||||
<FormDescription className="flex items-center justify-between">
|
||||
<span>Full URL: {typeof window !== 'undefined' ? window.location.origin : ''}{getStatusPageUrl(field.value)}</span>
|
||||
{field.value && (
|
||||
<a
|
||||
href={getStatusPageUrl(field.value)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-primary hover:underline inline-flex items-center gap-1"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
Preview
|
||||
</a>
|
||||
)}
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
||||
@@ -25,15 +25,15 @@ import {
|
||||
getStatusPageUrl,
|
||||
type StatusPage,
|
||||
} from "@/lib/statuspages"
|
||||
import { MoreHorizontal, Plus, ExternalLink, Globe, Lock } from "lucide-react"
|
||||
import { MoreHorizontal, Plus, ExternalLink, Globe, Lock, Copy, Check, LayoutTemplate, ArrowRight } from "lucide-react"
|
||||
import { StatusPageDialog } from "./status-page-dialog"
|
||||
import { Link } from "@/components/router"
|
||||
|
||||
export function StatusPagesTable() {
|
||||
const { toast } = useToast()
|
||||
const queryClient = useQueryClient()
|
||||
const [dialogOpen, setDialogOpen] = useState(false)
|
||||
const [editingPage, setEditingPage] = useState<StatusPage | null>(null)
|
||||
const [copiedId, setCopiedId] = useState<string | null>(null)
|
||||
|
||||
const { data: pages, isLoading } = useQuery({
|
||||
queryKey: ["status-pages"],
|
||||
@@ -65,14 +65,50 @@ export function StatusPagesTable() {
|
||||
setDialogOpen(true)
|
||||
}
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
if (confirm("Are you sure you want to delete this status page?")) {
|
||||
deleteMutation.mutate(id)
|
||||
const handleDelete = (page: StatusPage) => {
|
||||
if (confirm(`Are you sure you want to delete "${page.name}"?\n\nThis will remove the status page and unlink all ${page.monitor_count} monitor(s). This action cannot be undone.`)) {
|
||||
deleteMutation.mutate(page.id)
|
||||
}
|
||||
}
|
||||
|
||||
const handleCopyUrl = async (page: StatusPage) => {
|
||||
if (!page.public) {
|
||||
toast({ title: "Status page must be public to copy URL", variant: "destructive" })
|
||||
return
|
||||
}
|
||||
const url = window.location.origin + getStatusPageUrl(page.slug)
|
||||
try {
|
||||
await navigator.clipboard.writeText(url)
|
||||
setCopiedId(page.id)
|
||||
toast({ title: "URL copied to clipboard" })
|
||||
setTimeout(() => setCopiedId(null), 2000)
|
||||
} catch {
|
||||
toast({ title: "Failed to copy URL", variant: "destructive" })
|
||||
}
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return <div className="p-4">Loading...</div>
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="h-5 w-32 bg-muted rounded animate-pulse" />
|
||||
<div className="h-9 w-36 bg-muted rounded animate-pulse" />
|
||||
</div>
|
||||
<div className="rounded-md border">
|
||||
<div className="p-4 space-y-3">
|
||||
{[1, 2, 3].map((i) => (
|
||||
<div key={i} className="flex items-center gap-4">
|
||||
<div className="h-4 w-32 bg-muted rounded animate-pulse" />
|
||||
<div className="h-4 w-24 bg-muted rounded animate-pulse" />
|
||||
<div className="h-4 w-16 bg-muted rounded animate-pulse" />
|
||||
<div className="h-4 w-20 bg-muted rounded animate-pulse" />
|
||||
<div className="h-8 w-8 bg-muted rounded animate-pulse ml-auto" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -99,8 +135,22 @@ export function StatusPagesTable() {
|
||||
<TableBody>
|
||||
{pages?.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={5} className="text-center py-8 text-muted-foreground">
|
||||
No status pages yet. Create one to share your service status publicly.
|
||||
<TableCell colSpan={5} className="text-center py-12">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<div className="p-3 bg-muted rounded-full">
|
||||
<LayoutTemplate className="h-6 w-6 text-muted-foreground" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium text-muted-foreground">No status pages yet</p>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
Create one to share your service status publicly
|
||||
</p>
|
||||
</div>
|
||||
<Button onClick={handleAdd} variant="outline" className="mt-2">
|
||||
Create Status Page
|
||||
<ArrowRight className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
@@ -134,20 +184,30 @@ export function StatusPagesTable() {
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
{page.public && (
|
||||
<DropdownMenuItem asChild>
|
||||
<a
|
||||
href={getStatusPageUrl(page.slug)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center"
|
||||
>
|
||||
<ExternalLink className="mr-2 h-4 w-4" />
|
||||
View Public Page
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
<>
|
||||
<DropdownMenuItem onClick={() => handleCopyUrl(page)}>
|
||||
{copiedId === page.id ? (
|
||||
<Check className="mr-2 h-4 w-4 text-green-500" />
|
||||
) : (
|
||||
<Copy className="mr-2 h-4 w-4" />
|
||||
)}
|
||||
{copiedId === page.id ? 'Copied!' : 'Copy URL'}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem asChild>
|
||||
<a
|
||||
href={getStatusPageUrl(page.slug)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center"
|
||||
>
|
||||
<ExternalLink className="mr-2 h-4 w-4" />
|
||||
View Public Page
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
</>
|
||||
)}
|
||||
<DropdownMenuItem
|
||||
onClick={() => handleDelete(page.id)}
|
||||
onClick={() => handleDelete(page)}
|
||||
className="text-destructive"
|
||||
>
|
||||
Delete
|
||||
|
||||
@@ -189,3 +189,595 @@
|
||||
.recharts-yAxis {
|
||||
@apply tabular-nums;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
Public Status Page Styles - Inspired by github-statuses
|
||||
============================================================================ */
|
||||
|
||||
/* CSS Variables for Status Page - Light Mode (default) */
|
||||
.sp-page {
|
||||
--sp-bg: #f6f8fa;
|
||||
--sp-bg-top: #ffffff;
|
||||
--sp-bg-bottom: #f6f8fa;
|
||||
--sp-card: #ffffff;
|
||||
--sp-ink: #24292f;
|
||||
--sp-muted: #57606a;
|
||||
--sp-border: #d0d7de;
|
||||
--sp-accent: #0969da;
|
||||
--sp-operational: #2da44e;
|
||||
--sp-minor: #d97706;
|
||||
--sp-major: #cf222e;
|
||||
--sp-maintenance: #1f6feb;
|
||||
--sp-shadow: 0 20px 40px -30px rgba(0, 0, 0, 0.35);
|
||||
--sp-radius: 18px;
|
||||
--sp-radius-sm: 12px;
|
||||
--sp-bars-empty: #dfe4ea;
|
||||
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
background: linear-gradient(180deg, var(--sp-bg-top) 0%, var(--sp-bg) 55%, var(--sp-bg-bottom) 100%);
|
||||
color: var(--sp-ink);
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Dark Mode */
|
||||
.sp-page[data-theme="dark"] {
|
||||
--sp-bg: #111827;
|
||||
--sp-bg-top: #0d1117;
|
||||
--sp-bg-bottom: #111827;
|
||||
--sp-card: #161b22;
|
||||
--sp-ink: #f0f6fc;
|
||||
--sp-muted: #9da7b3;
|
||||
--sp-border: #30363d;
|
||||
--sp-accent: #58a6ff;
|
||||
--sp-operational: #3fb950;
|
||||
--sp-minor: #d29922;
|
||||
--sp-major: #ff7b72;
|
||||
--sp-maintenance: #58a6ff;
|
||||
--sp-shadow: 0 24px 48px -32px rgba(0, 0, 0, 0.72);
|
||||
--sp-bars-empty: #30363d;
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* Grain texture overlay */
|
||||
.sp-grain {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
|
||||
pointer-events: none;
|
||||
mix-blend-mode: multiply;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.sp-page[data-theme="dark"] .sp-grain {
|
||||
opacity: 0.45;
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.sp-header {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 48px 24px 32px;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.sp-header-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.sp-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.sp-logo {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
object-fit: contain;
|
||||
border-radius: var(--sp-radius-sm);
|
||||
}
|
||||
|
||||
.sp-logo-placeholder {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
border-radius: var(--sp-radius-sm);
|
||||
background: linear-gradient(135deg, var(--sp-operational), var(--sp-accent));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sp-logo-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sp-brand-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sp-title {
|
||||
margin: 0;
|
||||
font-size: clamp(1.8rem, 2.8vw, 2.6rem);
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.sp-description {
|
||||
margin: 8px 0 0;
|
||||
color: var(--sp-muted);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* Main content */
|
||||
.sp-main {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 0 24px 64px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 28px;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Hero Section */
|
||||
.sp-hero-section {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.sp-hero-panel {
|
||||
background: var(--sp-card);
|
||||
border-radius: var(--sp-radius);
|
||||
padding: 28px 32px;
|
||||
border: 1px solid var(--sp-border);
|
||||
box-shadow: var(--sp-shadow);
|
||||
}
|
||||
|
||||
.sp-hero-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.sp-status-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 18px;
|
||||
border-radius: 999px;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.sp-status-pulse {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 0 4px currentColor;
|
||||
opacity: 0.3;
|
||||
animation: sp-pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes sp-pulse {
|
||||
0%, 100% { opacity: 0.3; transform: scale(1); }
|
||||
50% { opacity: 0.6; transform: scale(1.1); }
|
||||
}
|
||||
|
||||
.sp-hero-stats {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.sp-hero-stat {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: var(--sp-muted);
|
||||
}
|
||||
|
||||
.sp-hero-stat-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.sp-hero-stat-value {
|
||||
font-weight: 700;
|
||||
font-size: 1.2rem;
|
||||
color: var(--sp-ink);
|
||||
}
|
||||
|
||||
.sp-hero-stat-label {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* Group Section */
|
||||
.sp-group-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.sp-group-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.sp-group-title {
|
||||
margin: 0;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--sp-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
/* Monitors Grid */
|
||||
.sp-monitors-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.sp-monitors-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Monitor Card */
|
||||
.sp-monitor-card {
|
||||
background: var(--sp-card);
|
||||
border-radius: var(--sp-radius);
|
||||
padding: 20px 24px;
|
||||
border: 1px solid var(--sp-border);
|
||||
box-shadow: 0 4px 12px -8px rgba(0, 0, 0, 0.2);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.sp-monitor-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px -12px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.sp-monitor-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.sp-monitor-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.sp-monitor-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sp-monitor-name {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sp-monitor-group {
|
||||
font-size: 0.8rem;
|
||||
color: var(--sp-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
.sp-monitor-status {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sp-status-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sp-status-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* Uptime Section */
|
||||
.sp-uptime-section {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.sp-uptime-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.sp-uptime-label {
|
||||
font-size: 0.8rem;
|
||||
color: var(--sp-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sp-uptime-value {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.sp-uptime-bars {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(30, minmax(0, 1fr));
|
||||
gap: 3px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.sp-uptime-bar {
|
||||
height: 24px;
|
||||
border-radius: 4px;
|
||||
background: var(--sp-bars-empty);
|
||||
cursor: pointer;
|
||||
transition: transform 0.12s ease;
|
||||
}
|
||||
|
||||
.sp-uptime-bar:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.sp-uptime-bar--operational {
|
||||
background: rgba(45, 164, 78, 0.85);
|
||||
}
|
||||
|
||||
.sp-uptime-bar--minor {
|
||||
background: rgba(217, 119, 6, 0.85);
|
||||
}
|
||||
|
||||
.sp-uptime-bar--major {
|
||||
background: rgba(207, 34, 46, 0.85);
|
||||
}
|
||||
|
||||
.sp-page[data-theme="dark"] .sp-uptime-bar--operational {
|
||||
background: rgba(63, 185, 80, 0.85);
|
||||
}
|
||||
|
||||
.sp-page[data-theme="dark"] .sp-uptime-bar--minor {
|
||||
background: rgba(210, 153, 34, 0.85);
|
||||
}
|
||||
|
||||
.sp-page[data-theme="dark"] .sp-uptime-bar--major {
|
||||
background: rgba(255, 123, 114, 0.85);
|
||||
}
|
||||
|
||||
.sp-uptime-axis {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 0.7rem;
|
||||
color: var(--sp-muted);
|
||||
}
|
||||
|
||||
/* Uptime Stats */
|
||||
.sp-uptime-stats {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--sp-border);
|
||||
}
|
||||
|
||||
.sp-stat {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.sp-stat-label {
|
||||
font-size: 0.7rem;
|
||||
color: var(--sp-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sp-stat-value {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.sp-footer {
|
||||
margin-top: 32px;
|
||||
padding-top: 24px;
|
||||
border-top: 1px solid var(--sp-border);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sp-footer-text {
|
||||
margin: 0;
|
||||
font-size: 0.85rem;
|
||||
color: var(--sp-muted);
|
||||
}
|
||||
|
||||
.sp-footer-text a {
|
||||
color: var(--sp-accent);
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sp-footer-text a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.sp-footer-updated {
|
||||
margin: 8px 0 0;
|
||||
font-size: 0.75rem;
|
||||
color: var(--sp-muted);
|
||||
}
|
||||
|
||||
/* Loading Skeleton */
|
||||
.sp-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
padding: 48px 24px;
|
||||
}
|
||||
|
||||
.sp-header-skeleton {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.sp-skeleton {
|
||||
background: linear-gradient(90deg, var(--sp-border) 25%, var(--sp-bg) 50%, var(--sp-border) 75%);
|
||||
background-size: 200% 100%;
|
||||
border-radius: 8px;
|
||||
animation: sp-skeleton-loading 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.sp-skeleton--logo {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
border-radius: var(--sp-radius-sm);
|
||||
}
|
||||
|
||||
.sp-skeleton--title {
|
||||
width: 300px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.sp-hero-skeleton {
|
||||
height: 120px;
|
||||
background: var(--sp-card);
|
||||
border-radius: var(--sp-radius);
|
||||
margin-bottom: 24px;
|
||||
border: 1px solid var(--sp-border);
|
||||
}
|
||||
|
||||
.sp-monitors-skeleton {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.sp-monitors-skeleton {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.sp-monitor-skeleton {
|
||||
height: 180px;
|
||||
background: var(--sp-card);
|
||||
border-radius: var(--sp-radius);
|
||||
border: 1px solid var(--sp-border);
|
||||
}
|
||||
|
||||
@keyframes sp-skeleton-loading {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
|
||||
/* Error State */
|
||||
.sp-error {
|
||||
text-align: center;
|
||||
padding: 64px 24px;
|
||||
}
|
||||
|
||||
.sp-error-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
color: var(--sp-major);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.sp-error h2 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sp-error p {
|
||||
margin: 0;
|
||||
color: var(--sp-muted);
|
||||
}
|
||||
|
||||
/* Refresh Indicator */
|
||||
.sp-refresh-indicator {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 14px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--sp-border);
|
||||
background: transparent;
|
||||
color: var(--sp-muted);
|
||||
font-size: 0.85rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.sp-refresh-indicator:hover:not(:disabled) {
|
||||
background: var(--sp-bg);
|
||||
border-color: var(--sp-accent);
|
||||
color: var(--sp-accent);
|
||||
}
|
||||
|
||||
.sp-refresh-indicator:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.sp-refresh-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.sp-refresh-spin {
|
||||
animation: sp-spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes sp-spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.sp-refresh-text {
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Last Check */
|
||||
.sp-last-check {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-top: 14px;
|
||||
padding-top: 14px;
|
||||
border-top: 1px solid var(--sp-border);
|
||||
font-size: 0.75rem;
|
||||
color: var(--sp-muted);
|
||||
}
|
||||
|
||||
.sp-last-check-icon {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "سجل التنبيهات"
|
||||
msgid "Alerts"
|
||||
msgstr "التنبيهات"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "جميع الحاويات"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "جميع الأنظمة"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "هل أنت متأكد أنك تريد حذف {name}؟"
|
||||
@@ -338,6 +341,10 @@ msgstr "يدعم بيزيل بروتوكول OpenID Connect والعديد من
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "يستخدم بيزيل <0>Shoutrrr</0> للتكامل مع خدمات الإشعارات الشهيرة."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "ثنائي"
|
||||
@@ -385,6 +392,7 @@ msgstr "يمكن الإيقاف"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "تحقق من {email} للحصول على رابط إعادة التعي
|
||||
msgid "Check logs for more details."
|
||||
msgstr "تحقق من السجلات لمزيد من التفاصيل."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "انقر للنسخ"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "إعادة التشغيل"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "إعدادات SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "الترتيب حسب"
|
||||
msgid "Sort By"
|
||||
msgstr "الترتيب حسب"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "إعدادات SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "وقت البدء"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "قيد التشغيل ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "تحديث"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "عرض أحدث 200 تنبيه."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "الأعمدة الظاهرة"
|
||||
msgid "Visible Fields"
|
||||
msgstr "الأعمدة الظاهرة"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "История на нотификациите"
|
||||
msgid "Alerts"
|
||||
msgstr "Тревоги"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Всички контейнери"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Всички системи"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Сигурен ли си, че искаш да изтриеш {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel поддържа OpenID Connect и много други OAuth2
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel ползва <0>Shoutrrr</0> за да се интегрира с известни услуги за уведомяване."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Двоичен код"
|
||||
@@ -385,6 +392,7 @@ msgstr "Може да се спре"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Провери {email} за линк за нулиране."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Провери log-овете за повече информация."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Настисни за да копираш"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Рестартирания"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Настройки за SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Сортиране по"
|
||||
msgid "Sort By"
|
||||
msgstr "Сортиране по"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Настройки за SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Начален час"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Нагоре ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Актуализирай"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Прегледайте последните си 200 сигнала."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Видими полета"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Видими полета"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Historie upozornění"
|
||||
msgid "Alerts"
|
||||
msgstr "Výstrahy"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Všechny kontejnery"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Všechny systémy"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Opravdu chcete odstranit {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel podporuje OpenID Connect a mnoho poskytovatelů OAuth2 ověřová
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel používá <0>Shoutrrr</0> k integraci s populárními notifikačními službami."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binární"
|
||||
@@ -385,6 +392,7 @@ msgstr "Může zastavit"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Zkontrolujte {email} pro odkaz na obnovení."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Pro více informací zkontrolujte logy."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Klikněte pro zkopírování"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Restarty"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Nastavení SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Seřadit podle"
|
||||
msgid "Sort By"
|
||||
msgstr "Seřadit podle"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Nastavení SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Čas začátku"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Funkční ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Aktualizovat"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Zobrazit vašich 200 nejnovějších upozornění."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Viditelné sloupce"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Viditelné sloupce"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Advarselshistorik"
|
||||
msgid "Alerts"
|
||||
msgstr "Alarmer"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Alle containere"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Alle systemer"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Er du sikker på, at du vil slette {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel understøtter OpenID Connect og mange OAuth2 godkendelsesudbydere
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel bruger <0>Shoutrrr</0> til at integrere med populære notifikationstjenester."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binær"
|
||||
@@ -385,6 +392,7 @@ msgstr "Kan stoppe"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Tjek {email} for et nulstillingslink."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Tjek logfiler for flere detaljer."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Klik for at kopiere"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Genstarter"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP-indstillinger"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Sorter efter"
|
||||
msgid "Sort By"
|
||||
msgstr "Sorter efter"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP-indstillinger"
|
||||
msgid "Start Time"
|
||||
msgstr "Starttid"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Oppe ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Opdater"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Se dine 200 nyeste alarmer."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Synlige felter"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Synlige felter"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Warnungsverlauf"
|
||||
msgid "Alerts"
|
||||
msgstr "Warnungen"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Alle Container"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Alle Systeme"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Möchtest du {name} wirklich löschen?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel unterstützt OpenID Connect und viele OAuth2-Authentifizierungsan
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel verwendet <0>Shoutrrr</0>, um sich mit beliebten Benachrichtigungsdiensten zu integrieren."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binär"
|
||||
@@ -385,6 +392,7 @@ msgstr "Kann stoppen"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Überprüfe {email} auf einen Link zum Zurücksetzen."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Überprüfe die Protokolle für weitere Details."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Zum Kopieren klicken"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Neustarts"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP-Einstellungen"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Sortieren nach"
|
||||
msgid "Sort By"
|
||||
msgstr "Sortieren nach"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP-Einstellungen"
|
||||
msgid "Start Time"
|
||||
msgstr "Startzeit"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Aktiv ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Aktualisieren"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Sieh dir die neusten 200 Alarme an."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Sichtbare Spalten"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Sichtbare Spalten"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -146,8 +146,8 @@ msgid "Add Monitor"
|
||||
msgstr "Add Monitor"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr "Add System"
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr "Add System"
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -198,12 +198,10 @@ msgstr "Alert History"
|
||||
msgid "Alerts"
|
||||
msgstr "Alerts"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr "All ({0})"
|
||||
|
||||
@@ -219,9 +217,14 @@ msgstr "All Containers"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "All Systems"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr "App update"
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Are you sure you want to delete {name}?"
|
||||
@@ -333,6 +336,10 @@ msgstr "Beszel supports OpenID Connect and many OAuth2 authentication providers.
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binary"
|
||||
@@ -380,6 +387,7 @@ msgstr "Can stop"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -442,6 +450,10 @@ msgstr "Check {email} for a reset link."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Check logs for more details."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr "Check now"
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr "Check Now"
|
||||
@@ -477,8 +489,8 @@ msgid "Click to copy"
|
||||
msgstr "Click to copy"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr "Columns"
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr "Columns"
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1745,6 +1757,10 @@ msgstr "Response"
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr "Response Times"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr "Restarting"
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Restarts"
|
||||
@@ -1912,8 +1928,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP settings"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Sort By"
|
||||
msgid "Sort By"
|
||||
msgstr "Sort By"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1924,6 +1940,10 @@ msgstr "SMTP settings"
|
||||
msgid "Start Time"
|
||||
msgstr "Start Time"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr "Start update"
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2243,10 +2263,23 @@ msgstr "Up ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Update"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr "Update available"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr "Update Beszel now?"
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr "Update Monitor"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr "Update now"
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2330,8 +2363,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "View your 200 most recent alerts."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Visible Fields"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Visible Fields"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Historial de alertas"
|
||||
msgid "Alerts"
|
||||
msgstr "Alertas"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Todos los contenedores"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Todos los sistemas"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "¿Estás seguro de que deseas eliminar {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel admite OpenID Connect y muchos proveedores de autenticación OAut
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel utiliza <0>Shoutrrr</0> para integrarse con servicios populares de notificación."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binario"
|
||||
@@ -385,6 +392,7 @@ msgstr "Puede detenerse"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Revisa {email} para un enlace de restablecimiento."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Revisa los registros para más detalles."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Haz clic para copiar"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Reinicios"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Configuración SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Ordenar por"
|
||||
msgid "Sort By"
|
||||
msgstr "Ordenar por"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Configuración SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Hora de inicio"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Activo ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Actualizar"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Ver tus 200 alertas más recientes."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Columnas visibles"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Columnas visibles"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "تاریخچه هشدارها"
|
||||
msgid "Alerts"
|
||||
msgstr "هشدارها"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "همه کانتینرها"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "همه سیستمها"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "آیا مطمئن هستید که میخواهید {name} را حذف کنید؟"
|
||||
@@ -338,6 +341,10 @@ msgstr "بِزل از OpenID Connect و بسیاری از ارائهدهند
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "بِزل از <0>Shoutrrr</0> برای ادغام با سرویسهای اطلاعرسانی محبوب استفاده میکند."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "دودویی"
|
||||
@@ -385,6 +392,7 @@ msgstr "میتواند متوقف شود"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "ایمیل {email} خود را برای لینک بازنشانی برر
|
||||
msgid "Check logs for more details."
|
||||
msgstr "برای جزئیات بیشتر، لاگها را بررسی کنید."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "برای کپی کردن کلیک کنید"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "راهاندازی مجدد"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "تنظیمات SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "مرتبسازی بر اساس"
|
||||
msgid "Sort By"
|
||||
msgstr "مرتبسازی بر اساس"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "تنظیمات SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "زمان شروع"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "فعال ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "بهروزرسانی"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "۲۰۰ هشدار اخیر خود را مشاهده کنید."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "فیلدهای قابل مشاهده"
|
||||
msgid "Visible Fields"
|
||||
msgstr "فیلدهای قابل مشاهده"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Historique des alertes"
|
||||
msgid "Alerts"
|
||||
msgstr "Alertes"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Tous les conteneurs"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Tous les systèmes"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Êtes-vous sûr de vouloir supprimer {name} ?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel prend en charge OpenID Connect et de nombreux fournisseurs d'auth
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel utilise <0>Shoutrrr</0> pour s'intégrer aux services de notification populaires."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binaire"
|
||||
@@ -385,6 +392,7 @@ msgstr "Peut arrêter"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Vérifiez {email} pour un lien de réinitialisation."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Vérifiez les journaux pour plus de détails."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Cliquez pour copier"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Redémarrages"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Paramètres SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Trier par"
|
||||
msgid "Sort By"
|
||||
msgstr "Trier par"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Paramètres SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Heure de début"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Joignable ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Mettre à jour"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Voir vos 200 dernières alertes."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Colonnes visibles"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Colonnes visibles"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "היסטוריית התראות"
|
||||
msgid "Alerts"
|
||||
msgstr "התראות"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "כל הקונטיינרים"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "כל המערכות"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "האם אתה בטוח שברצונך למחוק את {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel תומך ב-OpenID Connect ובספקי אימות רבים של
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel משתמש ב-<0>Shoutrrr</0> לשילוב עם שירותי התראות פופולריים."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "בינרי"
|
||||
@@ -385,6 +392,7 @@ msgstr "יכול לעצור"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "בדוק את {email} לקישור איפוס."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "בדוק לוגים לפרטים נוספים"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "לחץ כדי להעתיק"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "הפעלות מחדש"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "הגדרות SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "מיין לפי"
|
||||
msgid "Sort By"
|
||||
msgstr "מיין לפי"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "הגדרות SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "זמן התחלה"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "למעלה ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "עדכן"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "צפה ב-200 ההתראות האחרונות שלך."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "שדות גלויים"
|
||||
msgid "Visible Fields"
|
||||
msgstr "שדות גלויים"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Povijest Upozorenja"
|
||||
msgid "Alerts"
|
||||
msgstr "Upozorenja"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Svi spremnici"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Svi Sustavi"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Jeste li sigurni da želite izbrisati {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel podržava OpenID Connect i mnoge druge pružatelje OAuth2 autent
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel koristi <0>Shoutrrr</0> za integraciju s popularnim obavještajnim uslugama."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binarni"
|
||||
@@ -385,6 +392,7 @@ msgstr "Može se zaustaviti"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Provjerite {email} za pristup poveznici za resetiranje."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Provjerite zapise (logove) za više detalja."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Pritisnite za kopiranje"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Ponovna pokretanja"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP postavke"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Sortiraj po"
|
||||
msgid "Sort By"
|
||||
msgstr "Sortiraj po"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP postavke"
|
||||
msgid "Start Time"
|
||||
msgstr "Vrijeme početka"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Sustav je podignut ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Ažuriraj"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Pogledajte posljednjih 200 upozorenja."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Vidljiva polja"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Vidljiva polja"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Riasztási előzmények"
|
||||
msgid "Alerts"
|
||||
msgstr "Riasztások"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Minden konténer"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Minden rendszer"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Biztosan törölni szeretnéd {name}-t?"
|
||||
@@ -338,6 +341,10 @@ msgstr "A Beszel támogatja az OpenID Connect-et és számos OAuth2 hitelesíté
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "A Beszel a <0>Shoutrrr</0>-t használja a népszerű értesítési szolgáltatások integrálására."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Bináris"
|
||||
@@ -385,6 +392,7 @@ msgstr "Leállítható"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Ellenőrizd a {email} címet a visszaállító linkért."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Ellenőrizd a naplót a további részletekért."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Kattints a másoláshoz"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Újraindítások"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP beállítások"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Rendezés"
|
||||
msgid "Sort By"
|
||||
msgstr "Rendezés"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP beállítások"
|
||||
msgid "Start Time"
|
||||
msgstr "Kezdési idő"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Online ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Frissítés"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Legfrissebb 200 riasztásod áttekintése."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Látható mezők"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Látható mezők"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Riwayat Peringatan"
|
||||
msgid "Alerts"
|
||||
msgstr "Peringatan"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Semua Container"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Semua Sistem"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Apakah anda yakin ingin menghapus {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel mendukung OpenID Connect dan OAuth2 dari berbagai penyedia layana
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel menggunakan <0>Shoutrrr</0> untuk mengintegrasikan dengan penyedia layanan notifikasi."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binari"
|
||||
@@ -385,6 +392,7 @@ msgstr "Dapat diberhentikan"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Periksa {email} untuk tautan atur ulang password."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Periksa riwayat untuk lebih detail."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Klik untuk menyalin"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Restart"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Pengaturan SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Urutkan Berdasarkan"
|
||||
msgid "Sort By"
|
||||
msgstr "Urutkan Berdasarkan"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Pengaturan SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Waktu Mulai"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Nyala selama ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Perbarui"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Lihat 200 peringatan terbaru anda."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Metrik yang Terlihat"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Metrik yang Terlihat"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Cronologia Avvisi"
|
||||
msgid "Alerts"
|
||||
msgstr "Avvisi"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Tutti i contenitori"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Tutti i Sistemi"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Sei sicuro di voler eliminare {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel supporta OpenID Connect e molti provider di autenticazione OAuth2
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel utilizza <0>Shoutrrr</0> per integrarsi con i servizi di notifica popolari."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binario"
|
||||
@@ -385,6 +392,7 @@ msgstr "Può fermare"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Controlla {email} per un link di reset."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Controlla i log per maggiori dettagli."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Clicca per copiare"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Riavvii"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Impostazioni SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Ordina per"
|
||||
msgid "Sort By"
|
||||
msgstr "Ordina per"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Impostazioni SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Ora di inizio"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Attivo ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Aggiorna"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Visualizza i tuoi 200 avvisi più recenti."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Colonne visibili"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Colonne visibili"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "アラート履歴"
|
||||
msgid "Alerts"
|
||||
msgstr "アラート"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "すべてのコンテナ"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "すべてのシステム"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "{name}を削除してもよろしいですか?"
|
||||
@@ -338,6 +341,10 @@ msgstr "BeszelはOpenID Connectと多くのOAuth2認証プロバイダーをサ
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszelは<0>Shoutrrr</0>を使用して、人気のある通知サービスと統合します。"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "バイナリ"
|
||||
@@ -385,6 +392,7 @@ msgstr "停止可能"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "{email}を確認してリセットリンクを探してください。"
|
||||
msgid "Check logs for more details."
|
||||
msgstr "詳細についてはログを確認してください。"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "クリックしてコピー"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "再起動"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP設定"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "並び替え基準"
|
||||
msgid "Sort By"
|
||||
msgstr "並び替え基準"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP設定"
|
||||
msgid "Start Time"
|
||||
msgstr "開始時間"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "正常 ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "更新"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "直近200件のアラートを表示します。"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "表示列"
|
||||
msgid "Visible Fields"
|
||||
msgstr "表示列"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "알림 기록"
|
||||
msgid "Alerts"
|
||||
msgstr "알림"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "모든 컨테이너"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "모든 시스템"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "{name}을(를) 삭제하시겠습니까?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel은 OpenID Connect 및 많은 OAuth2 인증 제공자를 지원합
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel은 여러 인기 있는 알림 서비스와 연동하기 위해 <0>Shoutrrr</0>을 이용합니다."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "실행 파일"
|
||||
@@ -385,6 +392,7 @@ msgstr "중지 가능"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "{email}에서 재설정 링크를 확인하세요."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "자세한 내용은 로그를 확인하세요."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "클릭하여 복사"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "재시작 횟수"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP 설정"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "정렬 기준"
|
||||
msgid "Sort By"
|
||||
msgstr "정렬 기준"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP 설정"
|
||||
msgid "Start Time"
|
||||
msgstr "시작 시간"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "온라인 ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "업데이트"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "최근 200개의 알림을 봅니다."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "표시할 열"
|
||||
msgid "Visible Fields"
|
||||
msgstr "표시할 열"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Melding geschiedenis"
|
||||
msgid "Alerts"
|
||||
msgstr "Waarschuwingen"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Alle containers"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Alle systemen"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Weet je zeker dat je {name} wilt verwijderen?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel ondersteunt OpenID Connect en vele OAuth2 authenticatieaanbieders
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel gebruikt <0>Shoutrr</0> om te integreren met populaire meldingsdiensten."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binair"
|
||||
@@ -385,6 +392,7 @@ msgstr "Kan stoppen"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Controleer {email} op een reset link."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Controleer de logs voor meer details."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Klik om te kopiëren"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Herstarten"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP-instellingen"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Sorteren op"
|
||||
msgid "Sort By"
|
||||
msgstr "Sorteren op"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP-instellingen"
|
||||
msgid "Start Time"
|
||||
msgstr "Starttijd"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Online ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Bijwerken"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Bekijk je 200 meest recente meldingen."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Zichtbare kolommen"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Zichtbare kolommen"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Varselhistorikk"
|
||||
msgid "Alerts"
|
||||
msgstr "Alarmer"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Alle containere"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Alle Systemer"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Er du sikker på at du vil slette {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel støtter OpenID Connect og mange OAuth2 autentiserings-tilbydere.
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel bruker <0>Shoutrrr</0> for integrering mot populære meldingstjenester."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binær"
|
||||
@@ -385,6 +392,7 @@ msgstr "Kan stoppe"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Sjekk {email} for en nullstillings-link."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Sjekk loggene for flere detaljer."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Klikk for å kopiere"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Omstarter"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP-innstillinger"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Sorter Etter"
|
||||
msgid "Sort By"
|
||||
msgstr "Sorter Etter"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP-innstillinger"
|
||||
msgid "Start Time"
|
||||
msgstr "Starttid"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Oppe ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Oppdater"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Vis de 200 siste varslene."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Synlige Felter"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Synlige Felter"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Historia alertów"
|
||||
msgid "Alerts"
|
||||
msgstr "Alerty"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Wszystkie kontenery"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Wszystkie systemy"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Czy na pewno chcesz usunąć {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel obsługuje OpenID Connect i wielu dostawców uwierzytelniania OAu
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel używa <0>Shoutrrr</0> do integracji z popularnymi serwisami powiadomień."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Plik binarny"
|
||||
@@ -385,6 +392,7 @@ msgstr "Może zatrzymać"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Sprawdź {email}, aby uzyskać link do resetowania."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Sprawdź logi, aby uzyskać więcej informacji."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Kliknij, aby skopiować"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Uruchamia ponownie"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Ustawienia SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Sortuj według"
|
||||
msgid "Sort By"
|
||||
msgstr "Sortuj według"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Ustawienia SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Czas rozpoczęcia"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Działa ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Aktualizuj"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Wyświetl 200 ostatnich alertów."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Widoczne kolumny"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Widoczne kolumny"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Histórico de alertas"
|
||||
msgid "Alerts"
|
||||
msgstr "Alertas"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Todos os Contêineres"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Todos os Sistemas"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Tem certeza de que deseja excluir {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel suporta OpenID Connect e muitos provedores de autenticação OAut
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel usa <0>Shoutrrr</0> para integrar com serviços de notificação populares."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binário"
|
||||
@@ -385,6 +392,7 @@ msgstr "Pode parar"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Verifique {email} para um link de redefinição."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Verifique os logs para mais detalhes."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Clique para copiar"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Reinícios"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Configurações SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Ordenar Por"
|
||||
msgid "Sort By"
|
||||
msgstr "Ordenar Por"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Configurações SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Hora de Início"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Ativo ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Atualizar"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Veja os seus 200 alertas mais recentes."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Campos Visíveis"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Campos Visíveis"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "История оповещений"
|
||||
msgid "Alerts"
|
||||
msgstr "Оповещения"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Все контейнеры"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Все системы"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Вы уверены, что хотите удалить {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel поддерживает OpenID Connect и множество п
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel использует <0>Shoutrrr</0> для интеграции с популярными сервисами уведомлений."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Двоичный"
|
||||
@@ -385,6 +392,7 @@ msgstr "Может остановить"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Проверьте {email} для получения ссылки на
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Проверьте журналы для получения более подробной информации."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Нажмите, чтобы скопировать"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Перезапуски"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Настройки SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Сортировать по"
|
||||
msgid "Sort By"
|
||||
msgstr "Сортировать по"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Настройки SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Время начала"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "В сети ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Обновить"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Просмотреть 200 последних оповещений."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Видимые столбцы"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Видимые столбцы"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Zgodovina opozoril"
|
||||
msgid "Alerts"
|
||||
msgstr "Opozorila"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Vsi kontejnerji"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Vsi sistemi"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Ali ste prepričani, da želite izbrisati {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel podpira OpenID Connect in številne ponudnike preverjanja pristno
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel uporablja <0>Shoutrrr</0> za integracijo s priljubljenimi storitvami obveščanja."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binarno"
|
||||
@@ -385,6 +392,7 @@ msgstr "Lahko ustavi"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Preverite {email} za povezavo za ponastavitev."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Za več podrobnosti preverite dnevnike."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Klikni za kopiranje"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Ponovni zagoni"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP nastavitve"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Razvrsti po"
|
||||
msgid "Sort By"
|
||||
msgstr "Razvrsti po"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP nastavitve"
|
||||
msgid "Start Time"
|
||||
msgstr "Čas začetka"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Delujoči ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Posodobi"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Oglejte si svojih 200 najnovejših opozoril."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Vidna polja"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Vidna polja"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Историја упозорења"
|
||||
msgid "Alerts"
|
||||
msgstr "Упозорења"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Сви контејнери"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Сви системи"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Да ли сте сигурни да желите да избришете {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel подржава OpenID Connect и многе OAuth2 провај
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel користи <0>Shoutrrr</0> за интеграцију са популарним сервисима за обавештавања."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Бинарни"
|
||||
@@ -385,6 +392,7 @@ msgstr "Може се зауставити"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Проверите {email} за линк за ресетовање."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Проверите логове за више детаља."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Кликните да копирате"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Поновна покретања"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP подешавања"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Сортирај по"
|
||||
msgid "Sort By"
|
||||
msgstr "Сортирај по"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP подешавања"
|
||||
msgid "Start Time"
|
||||
msgstr "Време почетка"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Укључен ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Ажурирај"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Погледајте ваших 200 најновијих упозорења."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Видљива поља"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Видљива поља"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Larmhistorik"
|
||||
msgid "Alerts"
|
||||
msgstr "Larm"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Alla behållare"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Alla system"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Är du säker på att du vill ta bort {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel stöder OpenID Connect och många OAuth2-autentiseringsleverantö
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel använder <0>Shoutrrr</0> för att integrera med populära aviseringstjänster."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Binär"
|
||||
@@ -385,6 +392,7 @@ msgstr "Kan stoppa"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Kontrollera {email} för en återställningslänk."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Kontrollera loggarna för mer information."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Klicka för att kopiera"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Omstarter"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP-inställningar"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Sortera efter"
|
||||
msgid "Sort By"
|
||||
msgstr "Sortera efter"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP-inställningar"
|
||||
msgid "Start Time"
|
||||
msgstr "Starttid"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Upp ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Uppdatera"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Visa dina 200 senaste larm."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Synliga fält"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Synliga fält"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Uyarı Geçmişi"
|
||||
msgid "Alerts"
|
||||
msgstr "Uyarılar"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Tüm Konteynerler"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Tüm Sistemler"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "{name} silmek istediğinizden emin misiniz?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel, OpenID Connect ve birçok OAuth2 kimlik doğrulama sağlayıcıs
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel, popüler bildirim hizmetleriyle entegre olmak için <0>Shoutrrr</0> kullanır."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "İkili"
|
||||
@@ -385,6 +392,7 @@ msgstr "Durdurulabilir"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Sıfırlama bağlantısı için {email} kontrol edin."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Daha fazla ayrıntı için günlükleri kontrol edin."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Kopyalamak için tıklayın"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Yeniden başlatmalar"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP ayarları"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Sıralama Ölçütü"
|
||||
msgid "Sort By"
|
||||
msgstr "Sıralama Ölçütü"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP ayarları"
|
||||
msgid "Start Time"
|
||||
msgstr "Başlangıç Saati"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Açık ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Güncelle"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "En son 200 uyarınızı görüntüleyin."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Görünür Alanlar"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Görünür Alanlar"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Історія сповіщень"
|
||||
msgid "Alerts"
|
||||
msgstr "Сповіщення"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Всі контейнери"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Всі системи"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Ви впевнені, що хочете видалити {name}?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel підтримує OpenID Connect та багато постач
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel використовує <0>Shoutrrr</0> для інтеграції з популярними сервісами сповіщень."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Двійковий"
|
||||
@@ -385,6 +392,7 @@ msgstr "Може зупинити"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Перевірте {email} для отримання посилання
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Перевірте журнали для отримання додаткової інформації."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Натисніть, щоб скопіювати"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Перезапуски"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Налаштування SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Сортувати за"
|
||||
msgid "Sort By"
|
||||
msgstr "Сортувати за"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Налаштування SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Час початку"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Працює ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Оновити"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Переглянути 200 останніх сповіщень."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Видимі стовпці"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Видимі стовпці"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "Lịch sử Cảnh báo"
|
||||
msgid "Alerts"
|
||||
msgstr "Cảnh báo"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "Tất cả container"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "Tất cả Hệ thống"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "Bạn có chắc chắn muốn xóa {name} không?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel hỗ trợ OpenID Connect và nhiều nhà cung cấp xác thực
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel sử dụng <0>Shoutrrr</0> để tích hợp với các dịch vụ thông báo phổ biến."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "Nhị phân"
|
||||
@@ -385,6 +392,7 @@ msgstr "Có thể dừng"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "Kiểm tra {email} để lấy liên kết đặt lại."
|
||||
msgid "Check logs for more details."
|
||||
msgstr "Kiểm tra nhật ký để biết thêm chi tiết."
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "Nhấp để sao chép"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "Khởi động lại"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "Cài đặt SMTP"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "Sắp xếp theo"
|
||||
msgid "Sort By"
|
||||
msgstr "Sắp xếp theo"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "Cài đặt SMTP"
|
||||
msgid "Start Time"
|
||||
msgstr "Thời gian bắt đầu"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "Hoạt động ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "Cập nhật"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "Xem 200 cảnh báo gần đây nhất của bạn."
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "Các cột hiển thị"
|
||||
msgid "Visible Fields"
|
||||
msgstr "Các cột hiển thị"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "警报历史"
|
||||
msgid "Alerts"
|
||||
msgstr "警报"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "所有容器"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "所有客户端"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "您确定要删除 {name} 吗?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel 支持 OpenID Connect 和其他 OAuth2 认证方式。"
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel 使用 <0>Shoutrrr</0> 以实现与常见的通知服务集成。"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "二进制"
|
||||
@@ -385,6 +392,7 @@ msgstr "可停止"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "检查 {email} 以获取重置链接。"
|
||||
msgid "Check logs for more details."
|
||||
msgstr "检查日志以获取更多详细信息。"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "点击复制"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "重启次数"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP 设置"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "排序依据"
|
||||
msgid "Sort By"
|
||||
msgstr "排序依据"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP 设置"
|
||||
msgid "Start Time"
|
||||
msgstr "开始时间"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "在线 ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "更新"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "查看您最近的200个警报。"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "可见列"
|
||||
msgid "Visible Fields"
|
||||
msgstr "可见列"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "警報歷史"
|
||||
msgid "Alerts"
|
||||
msgstr "警報"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "所有容器"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "所有系統"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "您確定要刪除 {name} 嗎?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel支持OpenID Connect和許多OAuth2認證提供者。"
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel 使用 <0>Shoutrrr</0> 與流行的通知服務集成。"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "執行檔"
|
||||
@@ -385,6 +392,7 @@ msgstr "可停止"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "檢查 {email} 以獲取重置鏈接。"
|
||||
msgid "Check logs for more details."
|
||||
msgstr "檢查日誌以取得更多資訊。"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "點擊以複製"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "重啟次數"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP設置"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "排序依據"
|
||||
msgid "Sort By"
|
||||
msgstr "排序依據"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP設置"
|
||||
msgid "Start Time"
|
||||
msgstr "開始時間"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "上線 ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "更新"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "檢視最近 200 則警報。"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "可見欄位"
|
||||
msgid "Visible Fields"
|
||||
msgstr "可見欄位"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -151,8 +151,8 @@ msgid "Add Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Add System"
|
||||
msgstr ""
|
||||
#~ msgid "Add System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Add URL"
|
||||
@@ -203,12 +203,10 @@ msgstr "警報歷史"
|
||||
msgid "Alerts"
|
||||
msgstr "警報"
|
||||
|
||||
#. placeholder {0}: data.length
|
||||
#. placeholder {0}: stats.total
|
||||
#. placeholder {0}: statusCounts.total
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/monitors-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All ({0})"
|
||||
msgstr ""
|
||||
|
||||
@@ -224,9 +222,14 @@ msgstr "所有容器"
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "All Systems"
|
||||
msgstr "所有系統"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "App update"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Are you sure you want to delete {name}?"
|
||||
msgstr "您確定要刪除 {name} 嗎?"
|
||||
@@ -338,6 +341,10 @@ msgstr "Beszel 支援 OpenID Connect 和許多 OAuth2 認證提供者。"
|
||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||
msgstr "Beszel 以 <0>Shoutrrr</0> 整合常用的通知服務。"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Beszel will pull ghcr.io/dvorinka/beszel:latest, recreate the running container, and restart the app. All signed-in users can start this action."
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
msgid "Binary"
|
||||
msgstr "執行檔"
|
||||
@@ -385,6 +392,7 @@ msgstr "可停止"
|
||||
#: src/components/domains-table/domains-table.tsx
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||
#: src/components/routes/settings/general.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Cancel"
|
||||
@@ -447,6 +455,10 @@ msgstr "檢查 {email} 以取得重設連結。"
|
||||
msgid "Check logs for more details."
|
||||
msgstr "檢查系統記錄以取得更多資訊。"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Check now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/monitor.tsx
|
||||
msgid "Check Now"
|
||||
msgstr ""
|
||||
@@ -482,8 +494,8 @@ msgid "Click to copy"
|
||||
msgstr "點擊複製"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
#~ msgid "Columns"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
#: src/components/login/forgot-pass-form.tsx
|
||||
@@ -1750,6 +1762,10 @@ msgstr ""
|
||||
#~ msgid "Response Times"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Restarting"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Restarts"
|
||||
msgstr "重啟次數"
|
||||
@@ -1917,8 +1933,8 @@ msgid "SMTP settings"
|
||||
msgstr "SMTP 設定"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Sort By"
|
||||
#~ msgstr "排序"
|
||||
msgid "Sort By"
|
||||
msgstr "排序"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#~ msgid "SSL Certificate"
|
||||
@@ -1929,6 +1945,10 @@ msgstr "SMTP 設定"
|
||||
msgid "Start Time"
|
||||
msgstr "開始時間"
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Start update"
|
||||
msgstr ""
|
||||
|
||||
#. Context: alert state (active or resolved)
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
#: src/components/routes/settings/quiet-hours.tsx
|
||||
@@ -2248,10 +2268,23 @@ msgstr "上線 ({upSystemsLength})"
|
||||
msgid "Update"
|
||||
msgstr "更新"
|
||||
|
||||
#: src/components/navbar.tsx
|
||||
#: src/components/navbar.tsx
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update Beszel now?"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/monitors-table/add-monitor-dialog.tsx
|
||||
msgid "Update Monitor"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/general.tsx
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/containers-table/containers-table-columns.tsx
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
@@ -2335,8 +2368,8 @@ msgid "View your 200 most recent alerts."
|
||||
msgstr "檢視最近 200 則警報。"
|
||||
|
||||
#: src/components/systems-table/systems-table.tsx
|
||||
#~ msgid "Visible Fields"
|
||||
#~ msgstr "顯示欄位"
|
||||
msgid "Visible Fields"
|
||||
msgstr "顯示欄位"
|
||||
|
||||
#: src/components/routes/domain.tsx
|
||||
#: src/components/routes/monitor.tsx
|
||||
|
||||
@@ -13,7 +13,7 @@ import Settings from "@/components/routes/settings/layout.tsx"
|
||||
import { ThemeProvider } from "@/components/theme-provider.tsx"
|
||||
import { Toaster } from "@/components/ui/toaster.tsx"
|
||||
import { alertManager } from "@/lib/alerts"
|
||||
import { isAdmin, pb, updateUserSettings } from "@/lib/api.ts"
|
||||
import { pb, updateUserSettings } from "@/lib/api.ts"
|
||||
import { dynamicActivate, getLocale } from "@/lib/i18n"
|
||||
import {
|
||||
$authenticated,
|
||||
@@ -35,6 +35,7 @@ const SystemDetail = lazy(() => import("@/components/routes/system.tsx"))
|
||||
const DomainDetail = lazy(() => import("@/components/routes/domain.tsx"))
|
||||
const MonitorDetail = lazy(() => import("@/components/routes/monitor.tsx"))
|
||||
const StatusPages = lazy(() => import("@/components/routes/status-pages.tsx"))
|
||||
const PublicStatusPage = lazy(() => import("@/components/routes/public-status-page.tsx"))
|
||||
const Incidents = lazy(() => import("@/components/routes/incidents.tsx"))
|
||||
const Calendar = lazy(() => import("@/components/routes/calendar.tsx"))
|
||||
const Monitoring = lazy(() => import("@/components/routes/monitoring.tsx"))
|
||||
@@ -52,7 +53,7 @@ const App = memo(() => {
|
||||
pb.send<BeszelInfo>("/api/beszel/info", {}).then((data) => {
|
||||
$publicKey.set(data.key)
|
||||
// check for updates if enabled
|
||||
if (data.cu && isAdmin()) {
|
||||
if (data.cu) {
|
||||
pb.send<UpdateInfo>("/api/beszel/update", {}).then($newVersion.set)
|
||||
}
|
||||
})
|
||||
@@ -94,6 +95,8 @@ const App = memo(() => {
|
||||
return <Settings />
|
||||
} else if (page.route === "status_pages") {
|
||||
return <StatusPages />
|
||||
} else if (page.route === "public_status") {
|
||||
return <PublicStatusPage slug={page.params.slug} />
|
||||
} else if (page.route === "incidents") {
|
||||
return <Incidents />
|
||||
} else if (page.route === "calendar") {
|
||||
@@ -108,17 +111,26 @@ const Layout = () => {
|
||||
const copyContent = useStore($copyContent)
|
||||
const direction = useStore($direction)
|
||||
const { layoutWidth } = useStore($userSettings, { keys: ["layoutWidth"] })
|
||||
const page = useStore($router)
|
||||
|
||||
useEffect(() => {
|
||||
document.documentElement.dir = direction
|
||||
}, [direction])
|
||||
|
||||
// Public status page doesn't require authentication
|
||||
const isPublicStatusPage = page?.route === "public_status"
|
||||
|
||||
return (
|
||||
<DirectionProvider dir={direction}>
|
||||
{!authenticated ? (
|
||||
{!authenticated && !isPublicStatusPage ? (
|
||||
<Suspense>
|
||||
<LoginPage />
|
||||
</Suspense>
|
||||
) : isPublicStatusPage ? (
|
||||
// Public status page renders without navbar/layout
|
||||
<Suspense>
|
||||
<App />
|
||||
</Suspense>
|
||||
) : (
|
||||
<div style={{ "--container": `${layoutWidth ?? defaultLayoutWidth}px` } as React.CSSProperties}>
|
||||
<div className="container">
|
||||
|
||||
Vendored
+45
-34
@@ -1,4 +1,5 @@
|
||||
import type { RecordModel } from "pocketbase"
|
||||
import type { LucideIcon } from "lucide-react"
|
||||
import type { Unit, Os, BatteryState, HourFormat, ConnectionType, ServiceStatus, ServiceSubState } from "@/lib/enums"
|
||||
|
||||
// global window properties
|
||||
@@ -324,7 +325,7 @@ export interface ChartData {
|
||||
export interface AlertInfo {
|
||||
name: () => string
|
||||
unit: string
|
||||
icon: any
|
||||
icon: LucideIcon
|
||||
desc: () => string
|
||||
max?: number
|
||||
min?: number
|
||||
@@ -423,7 +424,7 @@ export interface SystemdRecord extends RecordModel {
|
||||
|
||||
export interface SystemdServiceDetails {
|
||||
AccessSELinuxContext: string
|
||||
ActivationDetails: any[]
|
||||
ActivationDetails: unknown[]
|
||||
ActiveEnterTimestamp: number
|
||||
ActiveEnterTimestampMonotonic: number
|
||||
ActiveExitTimestamp: number
|
||||
@@ -434,12 +435,12 @@ export interface SystemdServiceDetails {
|
||||
AssertResult: boolean
|
||||
AssertTimestamp: number
|
||||
AssertTimestampMonotonic: number
|
||||
Asserts: any[]
|
||||
Asserts: unknown[]
|
||||
Before: string[]
|
||||
BindsTo: any[]
|
||||
BoundBy: any[]
|
||||
BindsTo: unknown[]
|
||||
BoundBy: unknown[]
|
||||
CPUUsageNSec: number
|
||||
CanClean: any[]
|
||||
CanClean: unknown[]
|
||||
CanFreeze: boolean
|
||||
CanIsolate: boolean
|
||||
CanLiveMount: boolean
|
||||
@@ -450,15 +451,15 @@ export interface SystemdServiceDetails {
|
||||
ConditionResult: boolean
|
||||
ConditionTimestamp: number
|
||||
ConditionTimestampMonotonic: number
|
||||
Conditions: any[]
|
||||
ConflictedBy: any[]
|
||||
Conditions: unknown[]
|
||||
ConflictedBy: unknown[]
|
||||
Conflicts: string[]
|
||||
ConsistsOf: any[]
|
||||
ConsistsOf: unknown[]
|
||||
DebugInvocation: boolean
|
||||
DefaultDependencies: boolean
|
||||
Description: string
|
||||
Documentation: string[]
|
||||
DropInPaths: any[]
|
||||
DropInPaths: unknown[]
|
||||
ExecMainPID: number
|
||||
FailureAction: string
|
||||
FailureActionExitStatus: number
|
||||
@@ -477,46 +478,46 @@ export interface SystemdServiceDetails {
|
||||
JobTimeoutAction: string
|
||||
JobTimeoutRebootArgument: string
|
||||
JobTimeoutUSec: number
|
||||
JoinsNamespaceOf: any[]
|
||||
JoinsNamespaceOf: unknown[]
|
||||
LoadError: string[]
|
||||
LoadState: string
|
||||
MainPID: number
|
||||
Markers: any[]
|
||||
Markers: unknown[]
|
||||
MemoryCurrent: number
|
||||
MemoryLimit: number
|
||||
MemoryPeak: number
|
||||
NRestarts: number
|
||||
Names: string[]
|
||||
NeedDaemonReload: boolean
|
||||
OnFailure: any[]
|
||||
OnFailure: unknown[]
|
||||
OnFailureJobMode: string
|
||||
OnFailureOf: any[]
|
||||
OnSuccess: any[]
|
||||
OnFailureOf: unknown[]
|
||||
OnSuccess: unknown[]
|
||||
OnSuccessJobMode: string
|
||||
OnSuccessOf: any[]
|
||||
PartOf: any[]
|
||||
OnSuccessOf: unknown[]
|
||||
PartOf: unknown[]
|
||||
Perpetual: boolean
|
||||
PropagatesReloadTo: any[]
|
||||
PropagatesStopTo: any[]
|
||||
PropagatesReloadTo: unknown[]
|
||||
PropagatesStopTo: unknown[]
|
||||
RebootArgument: string
|
||||
Refs: any[]
|
||||
Refs: unknown[]
|
||||
RefuseManualStart: boolean
|
||||
RefuseManualStop: boolean
|
||||
ReloadPropagatedFrom: any[]
|
||||
RequiredBy: any[]
|
||||
ReloadPropagatedFrom: unknown[]
|
||||
RequiredBy: unknown[]
|
||||
Requires: string[]
|
||||
RequiresMountsFor: any[]
|
||||
Requisite: any[]
|
||||
RequisiteOf: any[]
|
||||
RequiresMountsFor: unknown[]
|
||||
Requisite: unknown[]
|
||||
RequisiteOf: unknown[]
|
||||
Result: string
|
||||
SliceOf: any[]
|
||||
SliceOf: unknown[]
|
||||
SourcePath: string
|
||||
StartLimitAction: string
|
||||
StartLimitBurst: number
|
||||
StartLimitIntervalUSec: number
|
||||
StateChangeTimestamp: number
|
||||
StateChangeTimestampMonotonic: number
|
||||
StopPropagatedFrom: any[]
|
||||
StopPropagatedFrom: unknown[]
|
||||
StopWhenUnneeded: boolean
|
||||
SubState: string
|
||||
SuccessAction: string
|
||||
@@ -526,14 +527,14 @@ export interface SystemdServiceDetails {
|
||||
TasksMax: number
|
||||
Transient: boolean
|
||||
TriggeredBy: string[]
|
||||
Triggers: any[]
|
||||
Triggers: unknown[]
|
||||
UnitFilePreset: string
|
||||
UnitFileState: string
|
||||
UpheldBy: any[]
|
||||
Upholds: any[]
|
||||
WantedBy: any[]
|
||||
UpheldBy: unknown[]
|
||||
Upholds: unknown[]
|
||||
WantedBy: unknown[]
|
||||
Wants: string[]
|
||||
WantsMountsFor: any[]
|
||||
WantsMountsFor: unknown[]
|
||||
}
|
||||
|
||||
export interface BeszelInfo {
|
||||
@@ -543,6 +544,16 @@ export interface BeszelInfo {
|
||||
}
|
||||
|
||||
export interface UpdateInfo {
|
||||
v: string // new version
|
||||
url: string // url to new version
|
||||
v?: string // new version / tag
|
||||
url?: string // package url
|
||||
currentVersion: string
|
||||
image: string
|
||||
currentImageId?: string
|
||||
currentDigest?: string
|
||||
latestDigest?: string
|
||||
updateAvailable: boolean
|
||||
canApply: boolean
|
||||
status: string
|
||||
message: string
|
||||
lastCheck: string
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineConfig } from "vite"
|
||||
import path from "path"
|
||||
import path from "node:path"
|
||||
import tailwindcss from "@tailwindcss/vite"
|
||||
import react from "@vitejs/plugin-react-swc"
|
||||
import { lingui } from "@lingui/vite-plugin"
|
||||
|
||||
Reference in New Issue
Block a user