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:
Tomas Dvorak
2026-04-30 14:38:13 +02:00
parent 67254f89a9
commit 7727be166b
63 changed files with 582907 additions and 636 deletions
+7
View File
@@ -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
+9
View File
@@ -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 |
+1
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
/home/tdvorak/.local/share/uv/tools/graphifyy/bin/python
+75
View File
@@ -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
View File
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
+1
View File
@@ -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())
+3 -43
View File
@@ -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
}
return e.JSON(http.StatusOK, info)
}
+567
View File
@@ -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
}
+48
View File
@@ -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)
}
})
}
}
+5
View File
@@ -64,6 +64,11 @@
}
},
"overrides": [
{
"includes": ["src/locales/**/*.ts"],
"formatter": { "enabled": false },
"linter": { "enabled": false }
},
{
"includes": ["**/*.jsx", "**/*.tsx"],
"linter": {
+80 -90
View File
@@ -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) => {
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
caches
.open(CACHE_NAME)
.then((cache) => {
return cache.addAll(STATIC_ASSETS);
return cache.addAll(STATIC_ASSETS)
})
.then(() => self.skipWaiting())
);
});
)
})
// Activate event - clean up old caches
self.addEventListener('activate', (event) => {
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames
.filter((name) => name !== CACHE_NAME)
.map((name) => caches.delete(name))
);
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;
if (request.method !== "GET") {
return
}
// Skip API requests
if (url.pathname.startsWith('/api/')) {
return;
if (url.pathname.startsWith("/api/")) {
return
}
// Skip PocketBase API
if (url.pathname.startsWith('/_/')) {
return;
if (url.pathname.startsWith("/_/")) {
return
}
event.respondWith(
caches.match(request).then((cached) => {
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);
});
cache.put(request, response)
})
}
});
return cached;
})
return cached
}
// Fetch from network
return fetch(request).then((response) => {
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
if (!response || response.status !== 200 || response.type !== "basic") {
return response
}
const responseToCache = response.clone();
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');
cache.put(request, responseToCache)
})
);
});
return response
})
})
.catch(() => {
// Return offline page if available
return caches.match("/offline.html")
})
)
})
// Push notification event
self.addEventListener('push', (event) => {
self.addEventListener("push", (event) => {
if (!event.data) {
return;
return
}
const data = event.data.json();
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',
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' }
]
};
{ 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) => {
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();
if (client.url === urlToOpen && "focus" in client) {
return client.focus()
}
}
// Open new window if not found
if (clients.openWindow) {
return clients.openWindow(urlToOpen);
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() {
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');
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() {
function checkForUpdates() {
// Check for new data and show notifications if needed
console.log('Periodic sync executed');
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
+34 -2
View File
@@ -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
+1
View File
@@ -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,16 +523,59 @@ 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>
<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"
@@ -540,17 +585,30 @@ export default memo(function MonitorDetail({ id }: { id: string }) {
linked: isLinked,
})
}}
disabled={updateStatusPagesMutation.isPending}
>
{isLinked ? "Linked" : "Link"}
{isLinked ? (
<>
<CheckCircle2 className="mr-1 h-3 w-3" />
Linked
</>
) : (
"Link"
)}
</Button>
</div>
</div>
)
})}
</div>
) : (
<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 &quot;{slug}&quot; 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,6 +184,15 @@ export function StatusPagesTable() {
Edit
</DropdownMenuItem>
{page.public && (
<>
<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)}
@@ -145,9 +204,10 @@ export function StatusPagesTable() {
View Public Page
</a>
</DropdownMenuItem>
</>
)}
<DropdownMenuItem
onClick={() => handleDelete(page.id)}
onClick={() => handleDelete(page)}
className="text-destructive"
>
Delete
+592
View File
@@ -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;
}
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+43 -10
View File
@@ -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
+15 -3
View File
@@ -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">
+45 -34
View File
@@ -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 -1
View File
@@ -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"